s/PUBLIC_HOSTNAME/PRIMARY_HOSTNAME/ throughout

pull/103/head
Joshua Tauberer 10 years ago
parent 573faa2bf5
commit fed5959288
  1. 2
      Vagrantfile
  2. 8
      management/buy_certificate.py
  3. 16
      management/dns_update.py
  4. 8
      management/utils.py
  5. 18
      management/web_update.py
  6. 26
      management/whats_next.py
  7. 4
      setup/mail.sh
  8. 8
      setup/ssl.sh
  9. 26
      setup/start.sh

2
Vagrantfile vendored

@ -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.

@ -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"])

@ -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:

@ -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)

@ -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):

@ -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:

@ -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.

@ -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.

@ -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

Loading…
Cancel
Save