Commit Graph

129 Commits

Author SHA1 Message Date
PortableTech 415f95b792 Add TLSA record for HTTPS connections.
While not widely supported, there are some browser addons that can
validate DNSSEC and TLSA for additional out-of-band verification of
certificates when browsing the web.  Costs nothing to implement and
might improve security in some situations.
2015-07-13 09:12:13 -04:00
Joshua Tauberer 5dd5fc4a1c clean up multiple secondary nameservers and zone xfr ip addresses 2015-07-10 15:42:33 +00:00
Brian Bustin 09133c8f59 Initial backend changes to make it possible to have one or more secondary name servers 2015-07-10 14:59:38 +00:00
Joshua Tauberer 299a2315c1 dkim 2048 bits - migration and zone file generation changes
* Add a migration to delete any existing DKIM key so that existing machines get a fresh 2048-bit key. (Sadly we don't support key rotation so the change is immediate.)
* Because the DNS record for a 2048-bit key is so much longer, the way we read OpenDKIM's DNS record text file had to be modified to combine an arbitrary number of TXT record quoted ("...") strings.
* When writing out the TXT record value, the string must be split into quoted ("...") strings with a maximum length of 255 bytes each, per the DNS spec.
* Added a changelog entry.
2015-06-25 13:06:29 +00:00
Joshua Tauberer 2af557139d default IPv6 AAAA records were missing
This was broken by the ability to have multiple TXT records in 9f1d633ae4.
2015-06-17 06:47:22 -04:00
Joshua Tauberer 95173bb327 provide redirects from www subdomains of zones to their parent domain
* Split the nginx templates again so we have just the part needed to make a domain do a redirect separate from the rest.
* Add server blocks to the nginx config for these domains.
* List these domains in the SSL certificate install admin panel.
* Generate default 'www' records just for domains we provide default redirects for.

Fixes #321.
2015-06-04 12:19:01 +00:00
David Piggott f78bbab289 Make SPF forbid any outbound mail from non-mail domains 2015-05-28 18:11:44 +01:00
David Piggott 7b9b978a6d Improve DMARC and SPF record descriptions 2015-05-28 16:34:58 +01:00
Joshua Tauberer 8886c9b6bc move the server: block of nsd.conf out of the management daemon and into the setup scripts 2015-05-04 11:24:40 +00:00
Joshua Tauberer 9f1d633ae4 re-do the custom DNS get/set routines so it is possible to store more than one record for a qname-rtype pair, like multiple TXT records 2015-05-03 13:43:38 +00:00
Joshua Tauberer 322a5779f1 store IDNs (internationalized domain names) in IDNA (ASCII) in our database, not in Unicode
I changed my mind. In 1bf8f1991f I allowed Unicode domain names to go into the database. I thought that was nice because it's what the user *means*. But it's not how the web works. Web and DNS were working, but mail wasn't. Postfix (as shipped with Ubuntu 14.04 without support for SMTPUTF8) exists in an ASCII-only world. When it goes to the users/aliases table, it queries in ASCII (IDNA) only and had no hope of delivering mail if the domain was in full Unicode in the database. I was thinking ahead to SMTPUTF8, where we *could* put Unicode in the database (though that would prevent IDNA-encoded addressing from being deliverable) not realizing it isn't well supported yet anyway.

It's IDNA that goes on the wire in most places anyway (SMTP without SMTPUTF8 (and therefore how Postfix queries our users/aliases tables), DNS zone files, nginx config, CSR 'CN' field, X509 Common Name and Subject Alternative Names fields), so we should really be talking in terms of IDNA (i.e. ASCII).

This partially reverts commit 1bf8f1991f, where I added a lot of Unicode=>IDNA conversions when writing configuration files. Instead I'm doing Unicode=>IDNA before email addresses get into the users/aliases table. Now we assume the database uses IDNA-encoded ASCII domain names. When adding/removing aliases, addresses are converted to ASCII (w/ IDNA). User accounts must be ASCII-only anyway because of Dovecot's auth limitations, so we don't do any IDNA conversion (don't want to change the user's login info behind their back!). The aliases control panel page converts domains back to Unicode for display to be nice. The status checks converts the domains to Unicode just for the output headings.

A migration is added to convert existing aliases with Unicode domains into IDNA. Any custom DNS or web settings with Unicode may need to be changed.

Future support for SMTPUTF8 will probably need to add columns in the users/aliases table so that it lists both IDNA and Unicode forms.
2015-04-09 14:46:02 +00:00
Joshua Tauberer 14b16b2f36 allow custom DNS TXT records for SPF, DKIM, and DMARC to override the ones we want to set
fixes #323
fixes #324
2015-03-30 01:20:03 +00:00
Joshua Tauberer cbc7e280d6 set the SPF record after custom DNS records so that the SPF record doesn't prevent all custom TXT records from coming in 2015-03-30 01:18:05 +00:00
Ben Schumacher 6558f05d1d Give the DNS update tool the ability to customize MX records. Useful if you want a subdomain to send mail to another host. 2015-03-04 13:32:35 -05:00
Joshua Tauberer 348d2b8701 Merge pull request #326 from dhpiggott/custom-dns-filter-secondary-nameserver
Do not show '_secondary_nameserver' in Custom DNS table
2015-02-17 08:31:34 -05:00
David Piggott 12f0dcb23b Do not show '_secondary_nameserver' in Custom DNS table
It's redundant and potentially confusing, as any secondary NS shows in "Using a
Secondary Nameserver".
2015-02-17 13:28:48 +00:00
Joshua Tauberer 143bbf37f4 all mail domains, not just (top-level) zones, must have an entry in the opendkim key tables so that such outgoing mail gets signed
If you had both x.y.com and y.com configured here, x.y.com mail would not get DKIM-signed.
2015-02-16 18:13:51 -05:00
Joshua Tauberer 21b00e8fbb if a custom A record is set, dont put in a default AAAA record pointing to the box because it will probably be wrong --- the user should either set an AAAA record or let the domain not resolve on IPv6 2015-02-03 21:51:19 -05:00
Joshua Tauberer 1bf8f1991f internationalized domain names (DNS, web, CSRs, normalize to Unicode in database, prohibit non-ASCII characters in user account names)
* For non-ASCII domain names, we will keep the Unicode encoding in our users/aliases table. This is nice for the user and also simplifies things like sorting domain names (using Unicode lexicographic order is good, using ASCII lexicogrpahic order on IDNA is confusing).
* Write nsd config, nsd zone files, nginx config, and SSL CSRs with domains in IDNA-encoded ASCII.
* When checking SSL certificates, treat the CN and SANs as IDNA.
* Since Chrome has an interesting feature of converting Unicode to IDNA in <input type="email"> form fields, we'll also forcibly convert IDNA to Unicode in the domain part of email addresses before saving email addresses in the users/aliases tables so that the table is normalized to Unicode.
* Don't allow non-ASCII characters in user account email addresses. Dovecot gets confused when querying the Sqlite database (which we observed even for non-word ASCII characters too, so it may not be related to the character encoding).
2015-01-19 23:31:55 +00:00
Joshua Tauberer 24cc108147 if a custom CNAME record is set, don't add a default A/AAAA record, e.g. for 'www'
see https://discourse.mailinabox.email/t/multiple-domains-in-mail-in-a-box-with-the-domains-being-hosted-elsewhere/56/18
2015-01-19 22:04:21 +00:00
Joshua Tauberer fddab5d432 allow the dns api to set srv records
see https://discourse.mailinabox.email/t/create-srv-record-at-the-dns-server/225
2015-01-02 23:39:09 +00:00
Joshua Tauberer 90592bb157 add a control panel for setting custom dns records so that we dont have to use the api manually 2014-12-21 11:31:24 -05:00
Joshua Tauberer be59bcd47d for .fund domains use RSASHA256 DNSSEC keys 2014-12-05 12:03:21 -05:00
Joshua Tauberer a7710e9058 dns.resolver.query treats hostnames as relative names if they don't end in a period
Relative hostnames have a fall-back lookup with the machine's hostname appended, which makes no sense. Add a period, e.g. "my.hostname.com" => "my.hostname.com.", to prevent that.

This caused false positive Spamhaus checks. Fixes #185.
2014-11-21 15:16:59 +00:00
Joshua Tauberer d790cae0e2 DNSSEC: use RSASHA256 for the .guide tld too 2014-10-23 17:03:23 +00:00
David Piggott ca57560f11 Pass additional_records to recursive build_zone calls, closes #229
The problem was that custom records defined for a subdomain where implicit
records are otherwise defined (e.g. A/AAAA records for the root) were ignored.

Though additional_records for a subdomain are processed in the base call to
build_zone (the call for the parent domain), and so custom records that don't
override implicits were working fine, those that overrode implicits were
ignored.

This was because the recursive call to build_zone for the subdomain creates the
implicit records (including A/AAAA records for the root), and so by relying on
the base call to add the additional_records fails because has_rec returned
true.

Adding a subdomain's additional_records in the child call works because has_rec
returns false when testing whether to add an e.g. A/AAAA override for the root,
as the defaults have not yet been added.
2014-10-11 17:04:35 +01:00
Joshua Tauberer bf9b770255 sort SSHFP records so that DNS updates don't trigger spurrious zone changes 2014-10-07 15:15:22 +00:00
Joshua Tauberer f42a1c5a74 allow overriding the second nameserver with a secondary/slave server
fixes #151
fixes #223
2014-10-05 14:53:42 +00:00
Joshua Tauberer 4ae76aa2dd dnssec: use RSASHA256 keys for .email domains 2014-10-04 17:29:42 +00:00
Joshua Tauberer ab47144ae3 add strict SPF and DMARC records to any subdomains (including custom records) that do not have SPF/DMARC set
closes #208
2014-09-26 14:01:03 +00:00
Joshua Tauberer 9b6f9859d1 dns_update: assume DKIM is present 2014-09-26 14:01:03 +00:00
Joshua Tauberer c7c3bd33cf DNS API should reject qnames that aren't in a zone managed by the box
see https://discourse.mailinabox.email/t/set-www-a-and-other-dns-records-after-install/63/10
2014-09-21 13:37:30 +00:00
Joshua Tauberer 16e2350fef revise the description of A records on domains: the A record must be present for good deliverability so that the envelope domain resolves, but it doesn't have to resolve to this machine 2014-09-15 06:00:50 -04:00
Joshua Tauberer 110e0f90d9 dns: move the quoting of TXT records to when we write the zone file so that we can display it unquoted in the External DNS instructions 2014-09-07 11:42:20 +00:00
Joshua Tauberer 7a449c76a1 set the DNS TTL to 30 minutes rather than 1 day
Also updating the values for secondary DNS, but we're not set up
for secondary DNS so it won't matter.

see #172
2014-09-01 23:06:55 +00:00
Joshua Tauberer 10a37cd033 add SSHFP records to DNS 2014-08-27 12:59:40 +00:00
Ben Schumacher d5efb05f31 Fix typo in dns_update.py. 2014-08-26 15:58:34 -04:00
Joshua Tauberer ed8ce16fb5 show custom DNS records in the control panel too, fixes #155 2014-08-25 23:35:44 +00:00
Joshua Tauberer df20d447a9 add an api for setting custom DNS records
Works like this:

```curl -d "" --user email:password https://.../admin/dns/set/qname/rtype/value```

where the rtype and value default to "A" and the remote IP address of the request, so that a simple, empty POST to

```https://.../admin/dns/set/desktop.mydomain.com```

will point desktop.mydomain.com to the caller's IPv4 address.

closes #140
2014-08-23 23:03:45 +00:00
Joshua Tauberer b30d7ad80a web-based administrative UI
closes #19
2014-08-17 22:46:06 +00:00
Joshua Tauberer ba8e015795 dns_update: dont restart the opendkim process if nothing changed 2014-08-17 20:42:17 +00:00
Joshua Tauberer 6d4fab1e6a whats_next: offer DNSSEC DS parameters rather than the full record and in validation allow for other digests than the one we suggest using
fixes #120 (hopefully), in which Gandi generates a SHA1 digest but we were only checking against a SHA256 digest

Also see http://discourse.mailinabox.email/t/how-to-set-ds-record-for-gandi-net/24/1 in which a user asks about the DS parameters that Gandi asks for.
2014-08-01 12:15:05 +00:00
Joshua Tauberer 30178ef019 add a --force flag to dns_update 2014-08-01 12:05:34 +00:00
Joshua Tauberer 168c06939d have nsd bind to the network interaface that is connected to the Internet, rather than all non-loopback network interfaces
hopefully fixes #121; thanks for the help @sfPlayer1
2014-07-29 20:07:26 -04:00
Joshua Tauberer 8042ab66ac dont serve web for domains with custom DNS records that point A/AAAA elsewhere, and in whats_next only check that an A record exists on a domain if we are serving web on the domain 2014-07-20 15:23:17 +00:00
Joshua Tauberer 8354d9732a in the custom DNS yaml config, treat 'local' as an alias for the box's own IP/IPv6 addresses 2014-07-20 14:53:55 +00:00
Joshua Tauberer 1ad9c70887 refactor custom DNS records 2014-07-20 14:48:20 +00:00
Joshua Tauberer 2e0680de4f the check for whether a custom DNS setting is valid was in the wrong place 2014-07-20 14:41:02 +00:00
sfPlayer1 89acbe4127 Update dns_update.py
Add new extra bool parameter.
2014-07-18 13:05:32 +02:00
sfPlayer1 0e893626c8 Add IPv6 glue records as well
The dns_update script didn't generate IPv6 (AAAA) glue records for the name servers.

This caused http://dnscheck.pingdom.com to complain about a mismatch between the glue records reported by the parent name server and mailinabox nsd.

Here's the failing dnscheck output for reference:
> Checking glue for ns1.my.domain.tld (1.2.3.4).
> Child glue for bgwe.eu found: ns1.my.domain.tld (1.2.3.4)
> Checking glue for ns1.my.domain.tld (1234::1).
> Missing glue at child: ns1.my.domain.tld
> Checking glue for ns2.my.domain.tld (1.2.3.4).
> Child glue for bgwe.eu found: ns2.my.domain.tld (1.2.3.4)
> Checking glue for ns2.my.domain.tld (1234::1).
> Missing glue at child: ns2.my.domain.tld

I'm not very familiar with Python and DNS, please verify ;)
2014-07-18 13:03:09 +02:00
Joshua Tauberer 42c891032d don't create a www. subdomain on any domains that are themselves subdomains within a zone, i.e. don't create www.PUBLIC_HOSTNAME if PUBLIC_HOSTNAME is a subdomain of another domain, which is what we normally recommend 2014-07-17 13:08:05 +00:00
Joshua Tauberer d7a9e7cc17 run management/dns_update.py from the console to dump the DNS records, with explanations, in case the user wants to host DNS off of the box 2014-07-17 13:08:05 +00:00
Joshua Tauberer 7803ac9ca4 write explanatory text as we build DNS zones so we can help the user manage DNS off of the box 2014-07-17 13:08:05 +00:00
Joshua Tauberer 49d5561933 when adding/removing mail addresses also update nginx's config 2014-07-06 12:16:50 +00:00
Joshua Tauberer fed5959288 s/PUBLIC_HOSTNAME/PRIMARY_HOSTNAME/ throughout 2014-06-30 09:15:36 -04:00
Joshua Tauberer 87f001a5d5 some comments 2014-06-24 03:24:41 +00:00
Joshua Tauberer 5aa09c3f9b let the user override some DNS records in a different way
Moved the configuration to a single YAML file, rather than one per domain, to be clearer.

re-does 33f06f29c1
2014-06-22 19:33:30 +00:00
Joshua Tauberer 343886d818 add mail alias checks and other cleanup 2014-06-22 16:28:55 +00:00
Joshua Tauberer deab8974ec if we handle mail for both a domain and any subdomain, only create a zone for the domain and put the subdomain's DNS records in the main domain's zone file 2014-06-22 16:24:15 +00:00
Joshua Tauberer 4668367420 first pass at a management tool for checking what the user must do to finish his configuration: set NS records, DS records, sign his certificates, etc. 2014-06-22 15:54:22 +00:00
Joshua Tauberer 67d31ed998 move the SSL setup into its own bash script since it is used for much more than email now 2014-06-21 22:16:46 +00:00
Joshua Tauberer 5faa1cae71 manage the nginx conf in the management daemon too so we can have nginx operate on all domains that we serve mail for 2014-06-20 01:55:12 +00:00
Joshua Tauberer 126ea94ccf drop support for ADSP which since last November is no longer recommended per http://datatracker.ietf.org/doc/status-change-adsp-rfc5617-to-historic/ 2014-06-18 22:56:55 -04:00
Joshua Tauberer 95e61bc110 add DANE TLSA records to the PUBLIC_HOSTNAME's DNS
Postfix has a tls_security_level called "dane" which uses DNS-Based Authentication of Named Entities (DANE)
to require, if specified in the DNS of the MX host, an encrpyted connection with a known certificate.

This commit adds TLSA records.
2014-06-19 01:39:27 +00:00
Joshua Tauberer 699bccad80 missing spaces in nsd.conf (has no effect but looks proper) 2014-06-18 23:53:52 +00:00
Joshua Tauberer afb6c26c8b run bind9 on the loopback interface for ensuring we are using a DNSSEC-aware nameserver to resolve our own DNS queries (i.e. when sending mail) since we can't trust that the network configuration provided for us gives us a DNSSEC-aware DNS server
see #71
2014-06-18 19:45:47 -04:00
Joshua Tauberer 761fac729b nsd.conf wasn't properly using the signed zone files 2014-06-18 23:30:35 +00:00
Joshua Tauberer dd15bf4384 use a better sort order for records in DNS zone files 2014-06-17 23:34:06 +00:00
Joshua Tauberer 14396e58f8 dont create a separate zone for PUBLIC_HOSTNAME if it is a subdomain of another zone (hmm, this is a general principle that could apply to any two domains the box is serving) 2014-06-17 23:30:00 +00:00
Joshua Tauberer 33f06f29c1 let the user override some DNS records 2014-06-17 22:21:51 +00:00
Joshua Tauberer 88709506f8 add DNSSEC
* sign zones
* in a cron job, periodically re-sign zones because they expire (not tested)
2014-06-17 22:21:12 +00:00
Joshua Tauberer aaa735dbfe write nsd.conf zones in a predictable order so that we don't keep rewriting it 2014-06-12 22:28:37 -04:00
Joshua Tauberer e9cde52a48 two more cases of shelling out external programs in a more secure way, see cecda9cec5 2014-06-12 21:06:04 -04:00
Michael Kropat ae67409603 Support dual-stack IPv4/IPv6 mail servers
Addresses #3

Added support by adding parallel code wherever `$PUBLIC_IP` was used.
Providing an IPv6 address is completely optional.

Playing around on my IPv6-enabled mail server revealed that — before
this change — mailinabox might try to use an IPv6 address as the value
for `$PUBLIC_IP`, which wouldn't work out well.
2014-06-08 18:32:52 -04:00
Joshua Tauberer f1dac1fe13 show less output when updating DNS configuration 2014-06-06 10:51:36 -04:00
Joshua Tauberer 295981828f Vagrantize
* adding a Vagrantfile
* in a non-interactive setup like this, create the user's first email account for them
* let the machine auto-detect its IP address using http://icanhazip.com/
* use our own justtesting.email domain to provision a subdomain for users so they can quickly get started
2014-06-04 19:39:58 -04:00
Joshua Tauberer 7fa4862f1a refactor dns_update so that the zone is first generated in a file-format agnostic way 2014-06-04 19:00:31 -04:00
Joshua Tauberer 8ed15168c0 the new dns_update totally forgot to write the OpenDKIM tables 2014-06-04 18:44:13 -04:00
Joshua Tauberer c54b0cbefc move management into a daemon service running as root
* Created a new Python/flask-based management daemon.
* Moved the mail user management core code from tools/mail.py to the new daemon.
* tools/mail.py is a wrapper around the daemon and can be run as a non-root user.
* Adding a new initscript for the management daemon.
* Moving dns_update.sh to the management daemon, called via curl'ing the daemon's API.

This also now runs the DNS update after mail users and aliases are added/removed,
which sets up new domains' DNS as needed.
2014-06-03 13:56:40 +00:00