add SSHFP records to DNS
This commit is contained in:
parent
684d9b3c70
commit
10a37cd033
|
@ -13,7 +13,7 @@ Why build this? Mass electronic surveillance by governments revealed over the la
|
||||||
The Box
|
The Box
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Mail-in-a-Box turns a fresh Ubuntu 14.04 LTS 64-bit machine into a working mail server, including SMTP ([postfix](http://www.postfix.org/)), IMAP ([dovecot](http://dovecot.org/)), Exchange ActiveSync ([z-push](https://github.com/fmbiete/Z-Push-contrib)), webmail ([Roundcube](http://roundcube.net/)), spam filtering ([spamassassin](https://spamassassin.apache.org/)), greylisting ([postgrey](http://postgrey.schweikert.ch/)), CardDAV/CalDAV ([ownCloud](http://owncloud.org/)), DNS, [SPF](https://en.wikipedia.org/wiki/Sender_Policy_Framework), DKIM ([OpenDKIM](http://www.opendkim.org/)), [DMARC](https://en.wikipedia.org/wiki/DMARC), [DNSSEC](https://en.wikipedia.org/wiki/DNSSEC), [DANE TLSA](https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities), and basic system services like a firewall, intrusion protection, and setting the system clock.
|
Mail-in-a-Box turns a fresh Ubuntu 14.04 LTS 64-bit machine into a working mail server, including SMTP ([postfix](http://www.postfix.org/)), IMAP ([dovecot](http://dovecot.org/)), Exchange ActiveSync ([z-push](https://github.com/fmbiete/Z-Push-contrib)), webmail ([Roundcube](http://roundcube.net/)), spam filtering ([spamassassin](https://spamassassin.apache.org/)), greylisting ([postgrey](http://postgrey.schweikert.ch/)), CardDAV/CalDAV ([ownCloud](http://owncloud.org/)), DNS, [SPF](https://en.wikipedia.org/wiki/Sender_Policy_Framework), DKIM ([OpenDKIM](http://www.opendkim.org/)), [DMARC](https://en.wikipedia.org/wiki/DMARC), [DNSSEC](https://en.wikipedia.org/wiki/DNSSEC), [DANE TLSA](https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities), [SSHFP](https://tools.ietf.org/html/rfc4255), and basic system services like a firewall, intrusion protection, and setting the system clock.
|
||||||
|
|
||||||
This setup is what has been powering my own personal email since September 2013.
|
This setup is what has been powering my own personal email since September 2013.
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# and mail aliases and restarts nsd.
|
# and mail aliases and restarts nsd.
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
import os, os.path, urllib.parse, datetime, re, hashlib
|
import os, os.path, urllib.parse, datetime, re, hashlib, base64
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import rtyaml
|
import rtyaml
|
||||||
|
|
||||||
|
@ -160,6 +160,10 @@ def build_zone(domain, all_domains, additional_records, env, is_zone=True):
|
||||||
# Add a DANE TLSA record for SMTP.
|
# Add a DANE TLSA record for SMTP.
|
||||||
records.append(("_25._tcp", "TLSA", build_tlsa_record(env), "Recommended when DNSSEC is enabled. Advertises to mail servers connecting to the box that mandatory encryption should be used."))
|
records.append(("_25._tcp", "TLSA", build_tlsa_record(env), "Recommended when DNSSEC is enabled. Advertises to mail servers connecting to the box that mandatory encryption should be used."))
|
||||||
|
|
||||||
|
# Add a SSHFP records to help SSH key validation. One per available SSH key on this system.
|
||||||
|
for value in build_sshfp_records():
|
||||||
|
records.append((None, "SSHFP", value, "Optional. Provides an out-of-band method for verifying an SSH key before connecting. Use 'VerifyHostKeyDNS yes' (or 'VerifyHostKeyDNS ask') when connecting with ssh."))
|
||||||
|
|
||||||
# The MX record says where email for the domain should be delivered: Here!
|
# The MX record says where email for the domain should be delivered: Here!
|
||||||
records.append((None, "MX", "10 %s." % env["PRIMARY_HOSTNAME"], "Required. Specifies the hostname (and priority) of the machine that handles @%s mail." % domain))
|
records.append((None, "MX", "10 %s." % env["PRIMARY_HOSTNAME"], "Required. Specifies the hostname (and priority) of the machine that handles @%s mail." % domain))
|
||||||
|
|
||||||
|
@ -289,6 +293,41 @@ def build_tlsa_record(env):
|
||||||
# 1: The certificate is SHA256'd here.
|
# 1: The certificate is SHA256'd here.
|
||||||
return "3 0 1 " + certhash
|
return "3 0 1 " + certhash
|
||||||
|
|
||||||
|
def build_sshfp_records():
|
||||||
|
# The SSHFP record is a way for us to embed this server's SSH public
|
||||||
|
# key fingerprint into the DNS so that remote hosts have an out-of-band
|
||||||
|
# method to confirm the fingerprint. See RFC 4255 and RFC 6594. This
|
||||||
|
# depends on DNSSEC.
|
||||||
|
#
|
||||||
|
# On the client side, set SSH's VerifyHostKeyDNS option to 'ask' to
|
||||||
|
# include this info in the key verification prompt or 'yes' to trust
|
||||||
|
# the SSHFP record.
|
||||||
|
#
|
||||||
|
# See https://github.com/xelerance/sshfp for inspiriation.
|
||||||
|
|
||||||
|
algorithm_number = {
|
||||||
|
"ssh-rsa": 1,
|
||||||
|
"ssh-dss": 2,
|
||||||
|
"ecdsa-sha2-nistp256": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get our local fingerprints by running ssh-keyscan. The output looks
|
||||||
|
# like the known_hosts file: hostname, keytype, fingerprint.
|
||||||
|
keys = shell("check_output", ["ssh-keyscan", "localhost"])
|
||||||
|
for key in keys.split("\n"):
|
||||||
|
if key.strip() == "" or key[0] == "#": continue
|
||||||
|
try:
|
||||||
|
host, keytype, pubkey = key.split(" ")
|
||||||
|
yield "%d %d ( %s )" % (
|
||||||
|
algorithm_number[keytype],
|
||||||
|
2, # specifies we are using SHA-256 on next line
|
||||||
|
hashlib.sha256(base64.b64decode(pubkey)).hexdigest().upper(),
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
# Lots of things can go wrong. Don't let it disturb the DNS
|
||||||
|
# zone.
|
||||||
|
pass
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
def write_nsd_zone(domain, zonefile, records, env, force):
|
def write_nsd_zone(domain, zonefile, records, env, force):
|
||||||
|
@ -497,7 +536,7 @@ def sign_zone(domain, zonefile, env):
|
||||||
# Remove our temporary file.
|
# Remove our temporary file.
|
||||||
for fn in files_to_kill:
|
for fn in files_to_kill:
|
||||||
os.unlink(fn)
|
os.unlink(fn)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
def write_opendkim_tables(zonefiles, env):
|
def write_opendkim_tables(zonefiles, env):
|
||||||
|
|
|
@ -22,8 +22,12 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Okay now install the packages.
|
# Okay now install the packages.
|
||||||
|
#
|
||||||
|
# nsd: The non-recursive nameserver that publishes our DNS records.
|
||||||
|
# ldnsutils: Helper utilities for signing DNSSEC zones.
|
||||||
|
# openssh-client: Provides ssh-keyscan which we use to create SSHFP records.
|
||||||
|
|
||||||
apt_install nsd ldnsutils
|
apt_install nsd ldnsutils openssh-client
|
||||||
|
|
||||||
# Prepare nsd's configuration.
|
# Prepare nsd's configuration.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue