turbot/net_insights

Query: dns_mx_report

Usage

powerpipe query net_insights.query.dns_mx_report

Steampipe Tables

SQL

with domain_list as (
select
distinct domain
from
net_dns_record
where
domain = $1
),
domain_mx_records as (
select
*
from
net_dns_record
where
domain = $1
and type = 'MX'
),
domain_mx_count as (
select
domain,
count(*)
from
domain_mx_records
where
domain = $1
group by
domain
),
mx_ips as (
select
*
from
net_dns_record
where
domain in (
select
target
from
domain_mx_records
)
and type = 'A'
),
mx_with_public_ips as (
select
domain_mx_records.domain,
domain_mx_records.target,
count(*)
from
domain_mx_records
inner join mx_ips on domain_mx_records.target = mx_ips.domain
group by
domain_mx_records.domain,
domain_mx_records.target
),
mx_record_with_ip as (
select
domain_mx_records.domain,
domain_mx_records.target,
mx_ips.ip,
(
mx_ips.ip << '10.0.0.0/8' :: inet
or mx_ips.ip << '100.64.0.0/10' :: inet
or mx_ips.ip << '172.16.0.0/12' :: inet
or mx_ips.ip << '192.0.0.0/24' :: inet
or mx_ips.ip << '192.168.0.0/16' :: inet
or mx_ips.ip << '198.18.0.0/15' :: inet
) as is_private
from
domain_mx_records
inner join mx_ips on domain_mx_records.target = mx_ips.domain
),
mx_record_with_private_ip as (
select
distinct domain
from
mx_record_with_ip
where
is_private
),
mx_record_with_ip_count as (
select
domain,
count(*)
from
domain_mx_records
where
domain = $1
and (
select
target ~ '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
)
group by
domain
),
mx_count_public_ips as (
select
domain_mx_records.domain,
count(*) as ip_usage_count
from
domain_mx_records
inner join mx_ips on domain_mx_records.target = mx_ips.domain
where
mx_ips.type = 'A'
group by
domain_mx_records.domain,
mx_ips.ip
),
mx_public_ips_count_by_domain as (
select
domain,
count(*)
from
mx_count_public_ips
where
ip_usage_count > 1
group by
domain
),
mx_records as (
select
domain,
rtrim(target, '.') as target,
rtrim(target, '.') ~ '^[^.].*[^-_.]$' as is_valid
from
domain_mx_records
where
domain = $1
),
mx_with_reverse_add as (
select
domain,
target,
(
select
concat(
array_to_string(
array(
select
nums [ i ]
from
generate_subscripts(nums, 1) as indices(i)
order by
i desc
),
'.'
),
'.in-addr.arpa'
) as reversed
from
(
select
string_to_array(host(ip), '.') as nums
) as data
) as reverse
from
mx_record_with_ip
),
mx_with_ptr_record_stats as (
select
domain,
case
when (
select
count(*)
from
net_dns_record
where
domain = mx_with_reverse_add.reverse
and type = 'PTR'
group by
domain
) is not null then true
else false
end as has_ptr_record,
reverse as rev_add
from
mx_with_reverse_add
),
mx_record_count_by_domain as (
select
domain,
count(*)
from
mx_record_with_ip
group by
domain
order by
domain
),
domain_name_with_dmarc as (
select
domain as full_domain,
concat('_dmarc.', domain) as dmarc_domain
from
domain_list
order by
domain
),
domain_dmarc_list as (
select
domain,
value
from
net_dns_record
where
domain in (
select
dmarc_domain
from
domain_name_with_dmarc
)
order by
domain
)
select
'MX records valid hostname' as "Recommendation",
case
when (
select
count(*)
from
mx_records
where
domain = domain_list.domain
and not is_valid
) > 0 then '❌'
else '✅'
end as "Status",
case
when (
select
count(*)
from
mx_records
where
domain = domain_list.domain
and not is_valid
) > 0 then 'Invalid MX record hostname(s): ' || (
select
string_agg(target, ', ')
from
mx_records
where
domain = domain_list.domain
and not is_valid
) || '.'
else 'No MX records have invalid hostname.'
end || ' It is recommended that MX record should have a valid domain or sub domain name and the name not starts or ends with a dot(.).' as "Result"
from
domain_list
UNION
select
'Multiple MX records' as "Recommendation",
case
when mx_record_count_by_domain.domain is null then '❌'
when mx_record_count_by_domain.count < 2 then '❌'
else '✅'
end as "Status",
case
when (
select
count(*)
from
domain_mx_records
where
domain = domain_list.domain
) < 2
and mx_record_count_by_domain.count > 2 then domain_list.domain || ' has 1 MX record, but that MX record has multiple IPs.'
else domain_list.domain || ' has ' || (
select
count(*)
from
domain_mx_records
where
domain = domain_list.domain
) || ' MX record(s).'
end || ' It is recommended to use at least 2 MX records so that backup server can receive mail when one server goes down.' as "Result"
from
domain_list
left join mx_record_count_by_domain on domain_list.domain = mx_record_count_by_domain.domain
UNION
select
'MX IPs are public' as "Recommendation",
case
when mx_record_with_private_ip.domain is null then '✅'
else '❌'
end as "Status",
case
when mx_record_with_private_ip.domain is null then 'All MX records appear to use public IPs.'
else domain_list.domain || ' has MX records using private IPs [' || (
select
host(ip)
from
mx_record_with_ip
where
domain = domain_list.domain
and is_private
) || '].'
end || ' For a server to be accessible on the public internet, it needs a public DNS record, and its IP address needs to be reachable on the internet.' as "Result"
from
domain_list
left join mx_record_with_private_ip on domain_list.domain = mx_record_with_private_ip.domain
UNION
select
'MX is not IP' as "Recommendation",
case
when i.domain is null then '✅'
else '❌'
end as "Status",
case
when i.domain is null then 'MX records doesn''t contain IP address.'
else 'At least one MX record contains IP address.'
end || ' As per RFC1035 MX record domain name must point to a host which itself can be resolved in the DNS.
An IP address could not be used as it would be interpreted as an unqualified domain name, which cannot be resolved.' as "Result"
from
domain_list as d
left join mx_record_with_ip_count as i on d.domain = i.domain
UNION
select
'No duplicate MX A records' as "Recommendation",
case
when p.domain is null then '✅'
else '❌'
end as "Status",
case
when p.domain is null then 'MX records do not have duplicate IPs.'
else 'MX records have duplicate IPs.'
end || ' It is recommended to use different IPs for records so that if server goes down, other server can receive mail.' as "Result"
from
domain_mx_count as d
left join mx_public_ips_count_by_domain as p on d.domain = p.domain
UNION
select
'Reverse MX A records' as "Recommendation",
case
when (
select
count(*)
from
mx_with_ptr_record_stats
where
domain = domain_list.domain
and not has_ptr_record
group by
domain
) is not null then '❌'
else '✅'
end as "Status",
case
when (
select
count(*)
from
mx_with_ptr_record_stats
where
domain = domain_list.domain
and not has_ptr_record
group by
domain
) is not null then domain || ' MX records have no reverse DNS (PTR) entries: [' || (
select
string_agg(rev_add, ', ')
from
mx_with_ptr_record_stats
where
domain = domain_list.domain
and not has_ptr_record
) || '].'
else domain || ' has PTR records for all MX records.'
end || ' A PTR record is reverse version of an A record. In general A record maps a domain name to an IP address, but PTR record maps IP address to a hostname. It is recommended to use PTR record when using both internal or external mail servers. It allows the receiving end to check the hostname of your IP address.' as "Result"
from
domain_list
UNION
select
'DMARC Record Published' as "Recommendation",
case
when dl.domain is null then '❌'
when not dl.value like 'v=DMARC1%' then '❌'
else '✅'
end as "Status",
case
when dl.domain is null
or not dl.value like 'v=DMARC1%' then 'DMARC record not found.'
else 'DMARC record found.'
end || ' Domain-based Message Authentication, Reporting & Conformance (DMARC) is an email authentication, policy, and reporting protocol. It builds on the widely deployed SPF and DKIM protocols, adding linkage to the author ("From:") domain name, published policies for recipient handling of authentication failures, and reporting from receivers to senders, to improve and monitor protection of the domain from fraudulent email.' as "Result"
from
domain_name_with_dmarc as d
left join domain_dmarc_list as dl on d.dmarc_domain = dl.domain

Params

ArgsNameDefaultDescriptionVariable
$1domain_name_input

    Dashboards

    The query is used in the dashboards: