PHP Script
<?php
function aws(string $command) : array|false {
$aws_command = 'aws --no-cli-pager --no-paginate --output json ' . $command;
$output = [];
$result_code = NULL;
if (exec($aws_command, $output, $result_code)) {
if ($result_code !== 0) {
return FALSE;
}
$json_output = implode(PHP_EOL, $output);
try {
$result = json_decode($json_output, TRUE, JSON_THROW_ON_ERROR);
return $result;
}
catch (\JsonException) {
return FALSE;
}
}
return FALSE;
}
function ses_list_identities() : array {
$results = aws('ses list-identities');
if (empty($results['Identities']) || !is_array($results['Identities'])) {
return [];
}
return $results['Identities'];
}
function ses_get_identity_verification_attributes(array $identities) : array {
$verification_attributes = [];
$chunks = array_chunk($identities, 50);
foreach ($chunks as $chunk_identities) {
$command = 'ses get-identity-verification-attributes --identities ' . implode(' ', $chunk_identities);
$results = aws($command);
if (!empty($results['VerificationAttributes']) && is_array($results['VerificationAttributes'])) {
foreach ($results['VerificationAttributes'] as $identity => $attributes) {
$verification_attributes[$identity]['Verified'] = get_success_attribute('VerificationStatus', $attributes);
}
}
}
return $verification_attributes;
}
function ses_get_identity_dkim_attributes(array $identities) : array {
$dkim_attributes = [];
$chunks = array_chunk($identities, 50);
foreach ($chunks as $chunk_identities) {
$command = 'ses get-identity-dkim-attributes --identities ' . implode(' ', $chunk_identities);
$results = aws($command);
if (!empty($results['DkimAttributes']) && is_array($results['DkimAttributes'])) {
foreach ($results['DkimAttributes'] as $identity => $attributes) {
$dkim_attributes[$identity]['DKIM On'] = get_bool_attribute('DkimEnabled', $attributes);
$dkim_attributes[$identity]['DKIM State'] = get_success_attribute('DkimVerificationStatus', $attributes);
}
}
}
return $dkim_attributes;
}
function ses_get_identity_notification_attributes(array $identities) : array {
$notification_attributes = [];
$chunks = array_chunk($identities, 50);
foreach ($chunks as $chunk_identities) {
$command = 'ses get-identity-notification-attributes --identities ' . implode(' ', $chunk_identities);
$results = aws($command);
if (!empty($results['NotificationAttributes']) && is_array($results['NotificationAttributes'])) {
foreach ($results['NotificationAttributes'] as $identity => $attributes) {
$notification_attributes[$identity]['Bounce Notify'] = get_sns_topic('BounceTopic', $attributes, ' -');
$notification_attributes[$identity]['Complaint Notify'] = get_sns_topic('ComplaintTopic', $attributes, ' -');
$notification_attributes[$identity]['Delivery Notify'] = get_sns_topic('DeliveryTopic', $attributes, ' -');
$notification_attributes[$identity]['Forwarding'] = get_bool_attribute('ForwardingEnabled', $attributes);
$notification_attributes[$identity]['Headers in Bounce'] = get_bool_attribute('HeadersInBounceNotificationsEnabled', $attributes);
$notification_attributes[$identity]['Headers in Complaint'] = get_bool_attribute('HeadersInComplaintNotificationsEnabled', $attributes);
$notification_attributes[$identity]['Headers in Delivery'] = get_bool_attribute('HeadersInDeliveryNotificationsEnabled', $attributes);
}
}
}
return $notification_attributes;
}
function ses_get_identity_main_from_domain_attributes(array $identities) : array {
$mail_attributes = [];
$chunks = array_chunk($identities, 50);
foreach ($chunks as $chunk_identities) {
$command = 'ses get-identity-mail-from-domain-attributes --identities ' . implode(' ', $chunk_identities);
$results = aws($command);
if (!empty($results['MailFromDomainAttributes']) && is_array($results['MailFromDomainAttributes'])) {
foreach ($results['MailFromDomainAttributes'] as $identity => $attributes) {
$mail_attributes[$identity]['Mail From Status'] = get_success_attribute('MailFromDomainStatus', $attributes);
$mail_attributes[$identity]['Main From Domain'] = get_attribute('MailFromDomain', $attributes);
}
}
}
return $mail_attributes;
}
function ses_get_identity_policies(array $identities) : array {
$policies_count = [];
foreach ($identities as $identity) {
$command = 'ses list-identity-policies --identity ' . $identity;
$results = aws($command);
if (!empty($results['PolicyNames']) && is_array($results['PolicyNames'])) {
$policies_count[$identity]['Policies'] = count($results['PolicyNames']);
}
else {
$policies_count[$identity]['Policies'] = ' ';
}
}
return $policies_count;
}
function get_attribute(string $attribute, array $attributes, string $default = ' ') : mixed {
return $attributes[$attribute] ?? $default;
}
function get_bool_attribute(string $attribute, array $attributes) : string {
$value = get_attribute($attribute, $attributes);
return !empty($value) ? 'β
' : ' ';
}
function get_success_attribute(string $attribute, array $attributes, string $empty = ' ') : string {
$value = get_attribute($attribute, $attributes, '');
if (is_bool($value)) {
return $value ? 'π’' : 'π΄';
}
if (empty($value)) {
return $empty;
}
return $value === 'Success' ? 'π’' : 'π΄';
}
function get_sns_topic(string $attribute, array $attributes, string $default = ' ') : string {
$value = get_attribute($attribute, $attributes, $default);
if (is_string($value) && !empty($value)) {
$arn = explode(':', $value);
return end($arn);
}
return $default;
}
function merge_table(array &$table, array $data) : void {
foreach ($data as $identity => $attributes) {
if (empty($table[$identity])) {
$table[$identity] = [];
}
$table[$identity] = array_merge($table[$identity], $attributes);
}
}
$header = [
'Domain / Email',
'Verified',
'DKIM On',
'DKIM State',
'Bounce Notify',
'Complaint Notify',
'DeliveryNotify',
'Forwarding',
'Headers in Bounce',
'Headers in Complaint',
'Headers in Delivery',
'Mail From Status',
'Mail From Domain',
'Policies',
];
$audit_table = [];
$identities = ses_list_identities();
$verification_attributes = ses_get_identity_verification_attributes($identities);
merge_table($audit_table, $verification_attributes);
$dkim_attributes = ses_get_identity_dkim_attributes($identities);
merge_table($audit_table, $dkim_attributes);
$notif_attributes = ses_get_identity_notification_attributes($identities);
merge_table($audit_table, $notif_attributes);
$email_attributes = ses_get_identity_main_from_domain_attributes($identities);
merge_table($audit_table, $email_attributes);
$policies = ses_get_identity_policies($identities);
merge_table($audit_table, $policies);
uksort($audit_table, 'strnatcasecmp');
fwrite(STDOUT, '| ' . implode(' | ', $header) . ' |' . PHP_EOL);
fwrite(STDOUT, '| ' . implode(' | ', array_fill(0, count($header), '---')) . ' |' . PHP_EOL);
foreach ($audit_table as $identity => $row) {
array_unshift($row, $identity);
fwrite(STDOUT, '| ' . implode(' | ', $row) . ' |' . PHP_EOL);
}Example:
AWS_PROFILE=my-aws php -f audit-aws-ses.php > /tmp/aws-ses-audit.md