diff --git a/Vagrantfile b/Vagrantfile index 9576c27e..a199f175 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -20,7 +20,7 @@ Vagrant.configure("2") do |config| # started quickly. export PUBLIC_IP=auto export PUBLIC_IPV6=auto - export PUBLIC_HOSTNAME=auto-easy + export PRIMARY_HOSTNAME=auto-easy export CSR_COUNTRY=US # Start the setup script. diff --git a/management/buy_certificate.py b/management/buy_certificate.py index cf895679..21d277a1 100755 --- a/management/buy_certificate.py +++ b/management/buy_certificate.py @@ -17,9 +17,9 @@ from web_update import get_web_domains, get_domain_ssl_files, get_web_root from whats_next import check_certificate def buy_ssl_certificate(api_key, domain, command, env): - if domain != env['PUBLIC_HOSTNAME'] \ + if domain != env['PRIMARY_HOSTNAME'] \ and domain not in get_web_domains(env): - raise ValueError("Domain is not %s or a domain we're serving a website for." % env['PUBLIC_HOSTNAME']) + raise ValueError("Domain is not %s or a domain we're serving a website for." % env['PRIMARY_HOSTNAME']) # Initialize. @@ -131,9 +131,9 @@ def buy_ssl_certificate(api_key, domain, command, env): print("The certificate has been installed in %s. Restarting services..." % ssl_certificate) - # Restart dovecot and if this is for PUBLIC_HOSTNAME. + # Restart dovecot and if this is for PRIMARY_HOSTNAME. - if domain == env['PUBLIC_HOSTNAME']: + if domain == env['PRIMARY_HOSTNAME']: shell('check_call', ["/usr/sbin/service", "dovecot", "restart"]) shell('check_call', ["/usr/sbin/service", "postfix", "restart"]) diff --git a/management/dns_update.py b/management/dns_update.py index fb789865..43c63c10 100755 --- a/management/dns_update.py +++ b/management/dns_update.py @@ -10,10 +10,10 @@ from utils import shell, load_env_vars_from_file, safe_domain_name, sort_domains def get_dns_domains(env): # Add all domain names in use by email users and mail aliases and ensure - # PUBLIC_HOSTNAME is in the list. + # PRIMARY_HOSTNAME is in the list. domains = set() domains |= get_mail_domains(env) - domains.add(env['PUBLIC_HOSTNAME']) + domains.add(env['PRIMARY_HOSTNAME']) return domains def get_dns_zones(env): @@ -130,11 +130,11 @@ def build_zone(domain, subdomains, additional_records, env, with_ns=True): # For top-level zones, define ourselves as the authoritative name server. if with_ns: - records.append((None, "NS", "ns1.%s." % env["PUBLIC_HOSTNAME"])) - records.append((None, "NS", "ns2.%s." % env["PUBLIC_HOSTNAME"])) + records.append((None, "NS", "ns1.%s." % env["PRIMARY_HOSTNAME"])) + records.append((None, "NS", "ns2.%s." % env["PRIMARY_HOSTNAME"])) # The MX record says where email for the domain should be delivered: Here! - records.append((None, "MX", "10 %s." % env["PUBLIC_HOSTNAME"])) + records.append((None, "MX", "10 %s." % env["PRIMARY_HOSTNAME"])) # SPF record: Permit the box ('mx', see above) to send mail on behalf of # the domain, and no one else. @@ -151,8 +151,8 @@ def build_zone(domain, subdomains, additional_records, env, with_ns=True): child_qname += "." + subdomain_qname records.append((child_qname, child_rtype, child_value)) - # In PUBLIC_HOSTNAME... - if domain == env["PUBLIC_HOSTNAME"]: + # In PRIMARY_HOSTNAME... + if domain == env["PRIMARY_HOSTNAME"]: # Define ns1 and ns2. records.append(("ns1", "A", env["PUBLIC_IP"])) records.append(("ns2", "A", env["PUBLIC_IP"])) @@ -252,7 +252,7 @@ $TTL 86400 ; default time to live """ # Replace replacement strings. - zone = zone.format(domain=domain, primary_domain=env["PUBLIC_HOSTNAME"]) + zone = zone.format(domain=domain, primary_domain=env["PRIMARY_HOSTNAME"]) # Add records. for subdomain, querytype, value in records: diff --git a/management/utils.py b/management/utils.py index db3f3bc8..a7d53b34 100644 --- a/management/utils.py +++ b/management/utils.py @@ -17,15 +17,15 @@ def safe_domain_name(name): return urllib.parse.quote(name, safe='') def sort_domains(domain_names, env): - # Put domain names in a nice sorted order. For web_update, PUBLIC_HOSTNAME + # Put domain names in a nice sorted order. For web_update, PRIMARY_HOSTNAME # must appear first so it becomes the nginx default server. - # First group PUBLIC_HOSTNAME and its subdomains, then parent domains of PUBLIC_HOSTNAME, then other domains. + # First group PRIMARY_HOSTNAME and its subdomains, then parent domains of PRIMARY_HOSTNAME, then other domains. groups = ( [], [], [] ) for d in domain_names: - if d == env['PUBLIC_HOSTNAME'] or d.endswith("." + env['PUBLIC_HOSTNAME']): + if d == env['PRIMARY_HOSTNAME'] or d.endswith("." + env['PRIMARY_HOSTNAME']): groups[0].append(d) - elif env['PUBLIC_HOSTNAME'].endswith("." + d): + elif env['PRIMARY_HOSTNAME'].endswith("." + d): groups[1].append(d) else: groups[2].append(d) diff --git a/management/web_update.py b/management/web_update.py index 6f034db6..95dd5fe2 100644 --- a/management/web_update.py +++ b/management/web_update.py @@ -14,10 +14,10 @@ def get_web_domains(env): # Add all domain names in use by email users and mail aliases. domains |= get_mail_domains(env) - # Ensure the PUBLIC_HOSTNAME is in the list. - domains.add(env['PUBLIC_HOSTNAME']) + # Ensure the PRIMARY_HOSTNAME is in the list. + domains.add(env['PRIMARY_HOSTNAME']) - # Sort the list. Put PUBLIC_HOSTNAME first so it becomes the + # Sort the list. Put PRIMARY_HOSTNAME first so it becomes the # default server (nginx's default_server). domains = sort_domains(domains, env) @@ -72,17 +72,17 @@ def get_web_root(domain, env): def get_domain_ssl_files(domain, env): # What SSL private key will we use? Allow the user to override this, but # in many cases using the same private key for all domains would be fine. - # Don't allow the user to override the key for PUBLIC_HOSTNAME because + # Don't allow the user to override the key for PRIMARY_HOSTNAME because # that's what's in the main file. ssl_key = os.path.join(env["STORAGE_ROOT"], 'ssl/ssl_private_key.pem') alt_key = os.path.join(env["STORAGE_ROOT"], 'ssl/domains/%s_private_key.pem' % safe_domain_name(domain)) - if domain != env['PUBLIC_HOSTNAME'] and os.path.exists(alt_key): + if domain != env['PRIMARY_HOSTNAME'] and os.path.exists(alt_key): ssl_key = alt_key # What SSL certificate will we use? This has to be differnet for each - # domain name. For PUBLIC_HOSTNAME, use the one we generated at set-up + # domain name. For PRIMARY_HOSTNAME, use the one we generated at set-up # time. - if domain == env['PUBLIC_HOSTNAME']: + if domain == env['PRIMARY_HOSTNAME']: ssl_certificate = os.path.join(env["STORAGE_ROOT"], 'ssl/ssl_certificate.pem') else: ssl_certificate = os.path.join(env["STORAGE_ROOT"], 'ssl/domains/%s_certifiate.pem' % safe_domain_name(domain)) @@ -93,10 +93,10 @@ def get_domain_ssl_files(domain, env): return ssl_key, ssl_certificate, csr_path def ensure_ssl_certificate_exists(domain, ssl_key, ssl_certificate, csr_path, env): - # For domains besides PUBLIC_HOSTNAME, generate a self-signed certificate if one doesn't + # For domains besides PRIMARY_HOSTNAME, generate a self-signed certificate if one doesn't # already exist. See setup/mail.sh for documentation. - if domain == env['PUBLIC_HOSTNAME']: + if domain == env['PRIMARY_HOSTNAME']: return if os.path.exists(ssl_certificate): diff --git a/management/whats_next.py b/management/whats_next.py index 6f927ca8..8bf1f9b0 100755 --- a/management/whats_next.py +++ b/management/whats_next.py @@ -53,7 +53,7 @@ def run_domain_checks(env): print(domain) print("=" * len(domain)) - if domain == env["PUBLIC_HOSTNAME"]: + if domain == env["PRIMARY_HOSTNAME"]: check_primary_hostname_dns(domain, env) if domain in dns_domains: @@ -62,8 +62,8 @@ def run_domain_checks(env): if domain in mail_domains: check_mail_domain(domain, env) - if domain == env["PUBLIC_HOSTNAME"] or domain in web_domains: - # We need a SSL certificate for PUBLIC_HOSTNAME because that's where the + if domain == env["PRIMARY_HOSTNAME"] or domain in web_domains: + # We need a SSL certificate for PRIMARY_HOSTNAME because that's where the # user will log in with IMAP or webmail. Any other domain we serve a # website for also needs a signed certificate. check_ssl_cert(domain, env) @@ -75,29 +75,29 @@ def check_primary_hostname_dns(domain, env): # comes from the TLD since the information is set at the registrar. ip = query_dns("ns1." + domain, "A") + '/' + query_dns("ns2." + domain, "A") if ip == env['PUBLIC_IP'] + '/' + env['PUBLIC_IP']: - print_ok("Nameserver IPs are correct at registrar. [ns1/ns2.%s => %s]" % (env['PUBLIC_HOSTNAME'], env['PUBLIC_IP'])) + print_ok("Nameserver IPs are correct at registrar. [ns1/ns2.%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: print_error("""Nameserver IP addresses are incorrect. The ns1.%s and ns2.%s nameservers must be configured at your domain name registrar as having the IP address %s. They currently report addresses of %s. It may take several hours for public DNS to update after a change.""" - % (env['PUBLIC_HOSTNAME'], env['PUBLIC_HOSTNAME'], env['PUBLIC_IP'], ip)) + % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ip)) - # Check that PUBLIC_HOSTNAME resolves to PUBLIC_IP in public DNS. + # Check that PRIMARY_HOSTNAME resolves to PUBLIC_IP in public DNS. ip = query_dns(domain, "A") if ip == env['PUBLIC_IP']: - print_ok("Domain resolves to box's IP address. [%s => %s]" % (env['PUBLIC_HOSTNAME'], env['PUBLIC_IP'])) + print_ok("Domain resolves to box's IP address. [%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: print_error("""This domain must resolve to your box's IP address (%s) in public DNS but it currently resolves to %s. It may take several hours for public DNS to update after a change. This problem may result from other issues listed here.""" % (env['PUBLIC_IP'], ip)) - # Check reverse DNS on the PUBLIC_HOSTNAME. Note that it might not be + # Check reverse DNS on the PRIMARY_HOSTNAME. Note that it might not be # a DNS zone if it is a subdomain of another domain we have a zone for. ipaddr_rev = dns.reversename.from_address(env['PUBLIC_IP']) existing_rdns = query_dns(ipaddr_rev, "PTR") if existing_rdns == domain: - print_ok("Reverse DNS is set correctly at ISP. [%s => %s]" % (env['PUBLIC_IP'], env['PUBLIC_HOSTNAME'])) + print_ok("Reverse DNS is set correctly at ISP. [%s => %s]" % (env['PUBLIC_IP'], env['PRIMARY_HOSTNAME'])) else: print_error("""Your box's reverse DNS is currently %s, but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box at %s.""" % (existing_rdns, domain, env['PUBLIC_IP']) ) @@ -116,7 +116,7 @@ def check_dns_zone(domain, env, dns_zonefiles): # We provide a DNS zone for the domain. It should have NS records set up # at the domain name's registrar pointing to this box. existing_ns = query_dns(domain, "NS") - correct_ns = "ns1.BOX; ns2.BOX".replace("BOX", env['PUBLIC_HOSTNAME']) + correct_ns = "ns1.BOX; ns2.BOX".replace("BOX", env['PRIMARY_HOSTNAME']) if existing_ns == correct_ns: print_ok("Nameservers are set correctly at registrar. [%s]" % correct_ns) else: @@ -125,9 +125,9 @@ def check_dns_zone(domain, env, dns_zonefiles): % (existing_ns, correct_ns) ) # See if the domain's A record resolves to our PUBLIC_IP. This is already checked - # for PUBLIC_HOSTNAME, for which it is required. For other domains it is just nice + # for PRIMARY_HOSTNAME, for which it is required. For other domains it is just nice # to have if we want web. - if domain != env['PUBLIC_HOSTNAME']: + if domain != env['PRIMARY_HOSTNAME']: ip = query_dns(domain, "A") if ip == env['PUBLIC_IP']: print_ok("Domain resolves to this box's IP address. [%s => %s]" % (domain, env['PUBLIC_IP'])) @@ -160,7 +160,7 @@ def check_dns_zone(domain, env, dns_zonefiles): def check_mail_domain(domain, env): # Check the MX record. mx = query_dns(domain, "MX") - expected_mx = "10 " + env['PUBLIC_HOSTNAME'] + expected_mx = "10 " + env['PRIMARY_HOSTNAME'] if mx == expected_mx: print_ok("Domain's email is directed to this domain. [%s => %s]" % (domain, mx)) else: diff --git a/setup/mail.sh b/setup/mail.sh index 4ff6978b..831a6f10 100755 --- a/setup/mail.sh +++ b/setup/mail.sh @@ -30,7 +30,7 @@ mkdir -p $STORAGE_ROOT/mail # there is no true local mail delivery). Also set the banner (must have the hostname first, then anything). tools/editconf.py /etc/postfix/main.cf \ inet_interfaces=all \ - myhostname=$PUBLIC_HOSTNAME\ + myhostname=$PRIMARY_HOSTNAME\ smtpd_banner="\$myhostname ESMTP Hi, I'm a Mail-in-a-Box (Ubuntu/Postfix; see https://github.com/joshdata/mailinabox)" \ mydestination=localhost @@ -235,7 +235,7 @@ EOF # postmaster_address seems to be required or LMTP won't start tools/editconf.py /etc/dovecot/conf.d/15-lda.conf \ - postmaster_address=postmaster@$PUBLIC_HOSTNAME + postmaster_address=postmaster@$PRIMARY_HOSTNAME # Drew Crawford sets the auth-worker process to run as the mail user, but we don't care if it runs as root. diff --git a/setup/ssl.sh b/setup/ssl.sh index 724bf459..95e5e849 100755 --- a/setup/ssl.sh +++ b/setup/ssl.sh @@ -4,14 +4,14 @@ # # Create a self-signed SSL certificate if one has not yet been created. # -# The certificate is for PUBLIC_HOSTNAME specifically and is used for: +# The certificate is for PRIMARY_HOSTNAME specifically and is used for: # # * IMAP # * SMTP submission (port 587) and opportunistic TLS (when on the receiving end) # * the DNSSEC DANE TLSA record for SMTP -# * HTTPS (for PUBLIC_HOSTNAME only) +# * HTTPS (for PRIMARY_HOSTNAME only) # -# When other domains besides PUBLIC_HOSTNAME are served over HTTPS, +# When other domains besides PRIMARY_HOSTNAME are served over HTTPS, # we generate a domain-specific self-signed certificate in the management # daemon (web_update.py) as needed. @@ -29,7 +29,7 @@ fi if [ ! -f $STORAGE_ROOT/ssl/ssl_cert_sign_req.csr ]; then # Generate a certificate signing request if one doesn't already exist. openssl req -new -key $STORAGE_ROOT/ssl/ssl_private_key.pem -out $STORAGE_ROOT/ssl/ssl_cert_sign_req.csr \ - -subj "/C=$CSR_COUNTRY/ST=/L=/O=/CN=$PUBLIC_HOSTNAME" + -subj "/C=$CSR_COUNTRY/ST=/L=/O=/CN=$PRIMARY_HOSTNAME" fi if [ ! -f $STORAGE_ROOT/ssl/ssl_certificate.pem ]; then # Generate a SSL certificate by self-signing if a SSL certificate doesn't yet exist. diff --git a/setup/start.sh b/setup/start.sh index f05ba81e..e022402a 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -23,10 +23,10 @@ fi # Gather information from the user about the hostname and public IP # address of this host. -if [ -z "$PUBLIC_HOSTNAME" ]; then - if [ -z "$DEFAULT_PUBLIC_HOSTNAME" ]; then +if [ -z "$PRIMARY_HOSTNAME" ]; then + if [ -z "$DEFAULT_PRIMARY_HOSTNAME" ]; then # set a default on first run - DEFAULT_PUBLIC_HOSTNAME=`get_default_hostname` + DEFAULT_PRIMARY_HOSTNAME=`get_default_hostname` fi echo @@ -36,7 +36,7 @@ if [ -z "$PUBLIC_HOSTNAME" ]; then echo "be similar." echo - read -e -i "$DEFAULT_PUBLIC_HOSTNAME" -p "Hostname: " PUBLIC_HOSTNAME + read -e -i "$DEFAULT_PRIMARY_HOSTNAME" -p "Hostname: " PRIMARY_HOSTNAME fi if [ -z "$PUBLIC_IP" ]; then @@ -102,10 +102,10 @@ if [ "$PUBLIC_IPV6" = "auto" ]; then PUBLIC_IPV6=`get_default_publicipv6` echo "IPv6 Address: $PUBLIC_IPV6" fi -if [ "$PUBLIC_HOSTNAME" = "auto-easy" ]; then +if [ "$PRIMARY_HOSTNAME" = "auto-easy" ]; then # Generate a probably-unique subdomain under our justtesting.email domain. - PUBLIC_HOSTNAME=m`get_default_publicip | sha1sum | cut -c1-5`.justtesting.email - echo "Public Hostname: $PUBLIC_HOSTNAME" + PRIMARY_HOSTNAME=m`get_default_publicip | sha1sum | cut -c1-5`.justtesting.email + echo "Public Hostname: $PRIMARY_HOSTNAME" fi @@ -123,7 +123,7 @@ fi cat > /etc/mailinabox.conf << EOF; STORAGE_USER=$STORAGE_USER STORAGE_ROOT=$STORAGE_ROOT -PUBLIC_HOSTNAME=$PUBLIC_HOSTNAME +PRIMARY_HOSTNAME=$PRIMARY_HOSTNAME PUBLIC_IP=$PUBLIC_IP PUBLIC_IPV6=$PUBLIC_IPV6 CSR_COUNTRY=$CSR_COUNTRY @@ -154,10 +154,10 @@ if [ -z "`tools/mail.py user`" ]; then if [ -t 0 ]; then echo echo "Let's create your first mail user." - read -e -i "user@$PUBLIC_HOSTNAME" -p "Email Address: " EMAIL_ADDR + read -e -i "user@$PRIMARY_HOSTNAME" -p "Email Address: " EMAIL_ADDR else - # Use me@PUBLIC_HOSTNAME - EMAIL_ADDR=me@$PUBLIC_HOSTNAME + # Use me@PRIMARY_HOSTNAME + EMAIL_ADDR=me@$PRIMARY_HOSTNAME EMAIL_PW=1234 echo echo "Creating a new mail account for $EMAIL_ADDR with password $EMAIL_PW." @@ -165,7 +165,7 @@ if [ -z "`tools/mail.py user`" ]; then fi tools/mail.py user add $EMAIL_ADDR $EMAIL_PW # will ask for password if none given - tools/mail.py alias add hostmaster@$PUBLIC_HOSTNAME $EMAIL_ADDR - tools/mail.py alias add postmaster@$PUBLIC_HOSTNAME $EMAIL_ADDR + tools/mail.py alias add hostmaster@$PRIMARY_HOSTNAME $EMAIL_ADDR + tools/mail.py alias add postmaster@$PRIMARY_HOSTNAME $EMAIL_ADDR fi