mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2024-11-23 02:27:05 +00:00
drop the CSR_COUNTRY setting and ask within the control panel
This commit is contained in:
parent
392d33b902
commit
d53332b7cf
@ -18,6 +18,7 @@ Control panel:
|
|||||||
* Better messages if external DNS is used and, weirdly, custom secondary nameservers are set.
|
* Better messages if external DNS is used and, weirdly, custom secondary nameservers are set.
|
||||||
* Add POP to the mail client settings documentation.
|
* Add POP to the mail client settings documentation.
|
||||||
* The box's IP address is added to the fail2ban whitelist so that the status checks don't trigger the machine banning itself, which results in the status checks showing services down even though they are running.
|
* The box's IP address is added to the fail2ban whitelist so that the status checks don't trigger the machine banning itself, which results in the status checks showing services down even though they are running.
|
||||||
|
* For SSL certificates, rather than asking you what country you are in during setup, ask at the time a CSR is generated. The default system self-signed certificate now omits a country in the subject (it was never needed). The CSR_COUNTRY Mail-in-a-Box setting is dropped entirely.
|
||||||
|
|
||||||
System:
|
System:
|
||||||
|
|
||||||
|
1
Vagrantfile
vendored
1
Vagrantfile
vendored
@ -22,7 +22,6 @@ Vagrant.configure("2") do |config|
|
|||||||
export PUBLIC_IP=auto
|
export PUBLIC_IP=auto
|
||||||
export PUBLIC_IPV6=auto
|
export PUBLIC_IPV6=auto
|
||||||
export PRIMARY_HOSTNAME=auto-easy
|
export PRIMARY_HOSTNAME=auto-easy
|
||||||
export CSR_COUNTRY=US
|
|
||||||
#export SKIP_NETWORK_CHECKS=1
|
#export SKIP_NETWORK_CHECKS=1
|
||||||
|
|
||||||
# Start the setup script.
|
# Start the setup script.
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
# This list is derived from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2.
|
# This list is derived from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2.
|
||||||
# The columns are ISO_3166-1_alpha-2 code, display name, Wikipedia page name.
|
# The columns are ISO_3166-1_alpha-2 code, display name, Wikipedia page name.
|
||||||
# The top 20 countries by number of Internet users are grouped first, see
|
# The top 21 countries by number of Internet users are grouped first, see
|
||||||
# https://en.wikipedia.org/wiki/List_of_countries_by_number_of_Internet_users.
|
# https://en.wikipedia.org/wiki/List_of_countries_by_number_of_Internet_users.
|
||||||
BR Brazil
|
|
||||||
CA Canada
|
|
||||||
CN China
|
CN China
|
||||||
EG Egypt
|
|
||||||
FR France
|
|
||||||
DE Germany
|
|
||||||
IN India
|
IN India
|
||||||
ID Indonesia
|
|
||||||
IT Italy
|
|
||||||
JP Japan
|
|
||||||
MX Mexico
|
|
||||||
NG Nigeria
|
|
||||||
PH Philippines
|
|
||||||
RU Russian Federation Russia
|
|
||||||
ES Spain
|
|
||||||
KR South Korea
|
|
||||||
TR Turkey
|
|
||||||
GB United Kingdom
|
|
||||||
US United States
|
US United States
|
||||||
|
JP Japan
|
||||||
|
BR Brazil
|
||||||
|
RU Russian Federation Russia
|
||||||
|
DE Germany
|
||||||
|
NG Nigeria
|
||||||
|
GB United Kingdom
|
||||||
|
FR France
|
||||||
|
MX Mexico
|
||||||
|
EG Egypt
|
||||||
|
KR South Korea
|
||||||
VN Vietnam
|
VN Vietnam
|
||||||
|
ID Indonesia
|
||||||
|
PH Philippines
|
||||||
|
TR Turkey
|
||||||
|
IT Italy
|
||||||
|
PK Pakistan
|
||||||
|
ES Spain
|
||||||
|
CA Canada
|
||||||
AD Andorra
|
AD Andorra
|
||||||
AE United Arab Emirates
|
AE United Arab Emirates
|
||||||
AF Afghanistan
|
AF Afghanistan
|
||||||
@ -183,7 +184,6 @@ PA Panama
|
|||||||
PE Peru
|
PE Peru
|
||||||
PF French Polynesia
|
PF French Polynesia
|
||||||
PG Papua New Guinea
|
PG Papua New Guinea
|
||||||
PK Pakistan
|
|
||||||
PL Poland
|
PL Poland
|
||||||
PM Saint Pierre and Miquelon
|
PM Saint Pierre and Miquelon
|
||||||
PN Pitcairn Pitcairn Islands
|
PN Pitcairn Pitcairn Islands
|
Can't render this file because it has a wrong number of fields in line 5.
|
@ -28,6 +28,14 @@ try:
|
|||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# for generating CSRs we need a list of country codes
|
||||||
|
csr_country_codes = []
|
||||||
|
with open(os.path.join(os.path.dirname(me), "csr_country_codes.tsv")) as f:
|
||||||
|
for line in f:
|
||||||
|
if line.strip() == "" or line.startswith("#"): continue
|
||||||
|
code, name = line.strip().split("\t")[0:2]
|
||||||
|
csr_country_codes.append((code, name))
|
||||||
|
|
||||||
app = Flask(__name__, template_folder=os.path.abspath(os.path.join(os.path.dirname(me), "templates")))
|
app = Flask(__name__, template_folder=os.path.abspath(os.path.join(os.path.dirname(me), "templates")))
|
||||||
|
|
||||||
# Decorator to protect views that require a user with 'admin' privileges.
|
# Decorator to protect views that require a user with 'admin' privileges.
|
||||||
@ -101,9 +109,12 @@ def index():
|
|||||||
return render_template('index.html',
|
return render_template('index.html',
|
||||||
hostname=env['PRIMARY_HOSTNAME'],
|
hostname=env['PRIMARY_HOSTNAME'],
|
||||||
storage_root=env['STORAGE_ROOT'],
|
storage_root=env['STORAGE_ROOT'],
|
||||||
|
|
||||||
no_users_exist=no_users_exist,
|
no_users_exist=no_users_exist,
|
||||||
no_admins_exist=no_admins_exist,
|
no_admins_exist=no_admins_exist,
|
||||||
|
|
||||||
backup_s3_hosts=backup_s3_hosts,
|
backup_s3_hosts=backup_s3_hosts,
|
||||||
|
csr_country_codes=csr_country_codes,
|
||||||
)
|
)
|
||||||
|
|
||||||
@app.route('/me')
|
@app.route('/me')
|
||||||
@ -321,7 +332,7 @@ def dns_get_dump():
|
|||||||
def ssl_get_csr(domain):
|
def ssl_get_csr(domain):
|
||||||
from ssl_certificates import create_csr
|
from ssl_certificates import create_csr
|
||||||
ssl_private_key = os.path.join(os.path.join(env["STORAGE_ROOT"], 'ssl', 'ssl_private_key.pem'))
|
ssl_private_key = os.path.join(os.path.join(env["STORAGE_ROOT"], 'ssl', 'ssl_private_key.pem'))
|
||||||
return create_csr(domain, ssl_private_key, env)
|
return create_csr(domain, ssl_private_key, request.form.get('countrycode', ''), env)
|
||||||
|
|
||||||
@app.route('/ssl/install', methods=['POST'])
|
@app.route('/ssl/install', methods=['POST'])
|
||||||
@authorized_personnel_only
|
@authorized_personnel_only
|
||||||
|
@ -137,12 +137,12 @@ def get_domain_ssl_files(domain, ssl_certificates, env, allow_missing_cert=False
|
|||||||
|
|
||||||
return cert_info['private-key'], cert_info['certificate'], via
|
return cert_info['private-key'], cert_info['certificate'], via
|
||||||
|
|
||||||
def create_csr(domain, ssl_key, env):
|
def create_csr(domain, ssl_key, country_code, env):
|
||||||
return shell("check_output", [
|
return shell("check_output", [
|
||||||
"openssl", "req", "-new",
|
"openssl", "req", "-new",
|
||||||
"-key", ssl_key,
|
"-key", ssl_key,
|
||||||
"-sha256",
|
"-sha256",
|
||||||
"-subj", "/C=%s/ST=/L=/O=/CN=%s" % (env["CSR_COUNTRY"], domain)])
|
"-subj", "/C=%s/ST=/L=/O=/CN=%s" % (country_code, domain)])
|
||||||
|
|
||||||
def install_cert(domain, ssl_cert, ssl_chain, env):
|
def install_cert(domain, ssl_cert, ssl_chain, env):
|
||||||
# Write the combined cert+chain to a temporary path and validate that it is OK.
|
# Write the combined cert+chain to a temporary path and validate that it is OK.
|
||||||
|
@ -28,6 +28,15 @@
|
|||||||
|
|
||||||
<p><select id="ssldomain" onchange="show_csr()" class="form-control" style="width: auto"></select></p>
|
<p><select id="ssldomain" onchange="show_csr()" class="form-control" style="width: auto"></select></p>
|
||||||
|
|
||||||
|
<p>What country are you in? This is required by some SSL certificate providers. You may leave this blank if you know your SSL certificate provider doesn't require it.</p>
|
||||||
|
|
||||||
|
<p><select id="sslcc" onchange="show_csr()" class="form-control" style="width: auto">
|
||||||
|
<option value="">(Select)</option>
|
||||||
|
{% for code, name in csr_country_codes %}
|
||||||
|
<option value="{{code}}">{{name}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select></p>
|
||||||
|
|
||||||
<div id="csr_info" style="display: none">
|
<div id="csr_info" style="display: none">
|
||||||
<p>You will need to provide the SSL certificate provider this Certificate Signing Request (CSR):</p>
|
<p>You will need to provide the SSL certificate provider this Certificate Signing Request (CSR):</p>
|
||||||
|
|
||||||
@ -94,6 +103,7 @@ function show_csr() {
|
|||||||
"/ssl/csr/" + $('#ssldomain').val(),
|
"/ssl/csr/" + $('#ssldomain').val(),
|
||||||
"POST",
|
"POST",
|
||||||
{
|
{
|
||||||
|
countrycode: $('#sslcc').val()
|
||||||
},
|
},
|
||||||
function(data) {
|
function(data) {
|
||||||
$('#ssl_csr').text(data);
|
$('#ssl_csr').text(data);
|
||||||
|
@ -168,35 +168,6 @@ if [[ -z "$PRIVATE_IP" && -z "$PRIVATE_IPV6" ]]; then
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# We need a country code to generate a certificate signing request. However
|
|
||||||
# if a CSR already exists then we won't be generating a new one and there's
|
|
||||||
# no reason to ask for the country code now. $STORAGE_ROOT has not yet been
|
|
||||||
# set so we'll check if $DEFAULT_STORAGE_ROOT and $DEFAULT_CSR_COUNTRY are
|
|
||||||
# set (the values from the current mailinabox.conf) and if the CSR exists
|
|
||||||
# in the expected location.
|
|
||||||
if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $DEFAULT_STORAGE_ROOT/ssl/ssl_cert_sign_req.csr ]; then
|
|
||||||
CSR_COUNTRY=$DEFAULT_CSR_COUNTRY
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$CSR_COUNTRY" ]; then
|
|
||||||
# Get a list of country codes. Separate codes from country names with a ^.
|
|
||||||
# The input_menu function modifies shell word expansion to ignore spaces
|
|
||||||
# (since country names can have spaces) and use ^ instead.
|
|
||||||
country_code_list=$(grep -v "^#" setup/csr_country_codes.tsv | sed "s/\(..\)\t\([^\t]*\).*/\1^\2/")
|
|
||||||
|
|
||||||
input_menu "Country Code" \
|
|
||||||
"Choose the country where you live or where your organization is based.
|
|
||||||
\n\n(This is used to create an SSL certificate.)
|
|
||||||
\n\nCountry Code:" \
|
|
||||||
"$country_code_list" \
|
|
||||||
CSR_COUNTRY
|
|
||||||
|
|
||||||
if [ -z "$CSR_COUNTRY" ]; then
|
|
||||||
# user hit ESC/cancel
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Automatic configuration, e.g. as used in our Vagrant configuration.
|
# Automatic configuration, e.g. as used in our Vagrant configuration.
|
||||||
if [ "$PUBLIC_IP" = "auto" ]; then
|
if [ "$PUBLIC_IP" = "auto" ]; then
|
||||||
# Use a public API to get our public IP address, or fall back to local network configuration.
|
# Use a public API to get our public IP address, or fall back to local network configuration.
|
||||||
|
@ -74,7 +74,7 @@ if [ ! -f $STORAGE_ROOT/ssl/ssl_certificate.pem ]; then
|
|||||||
CSR=/tmp/ssl_cert_sign_req-$$.csr
|
CSR=/tmp/ssl_cert_sign_req-$$.csr
|
||||||
hide_output \
|
hide_output \
|
||||||
openssl req -new -key $STORAGE_ROOT/ssl/ssl_private_key.pem -out $CSR \
|
openssl req -new -key $STORAGE_ROOT/ssl/ssl_private_key.pem -out $CSR \
|
||||||
-sha256 -subj "/C=$CSR_COUNTRY/ST=/L=/O=/CN=$PRIMARY_HOSTNAME"
|
-sha256 -subj "/C=/ST=/L=/O=/CN=$PRIMARY_HOSTNAME"
|
||||||
|
|
||||||
# Generate the self-signed certificate.
|
# Generate the self-signed certificate.
|
||||||
CERT=$STORAGE_ROOT/ssl/$PRIMARY_HOSTNAME-selfsigned-$(date --rfc-3339=date | sed s/-//g).pem
|
CERT=$STORAGE_ROOT/ssl/$PRIMARY_HOSTNAME-selfsigned-$(date --rfc-3339=date | sed s/-//g).pem
|
||||||
|
@ -47,7 +47,7 @@ source setup/start.sh
|
|||||||
EOF
|
EOF
|
||||||
chmod +x /usr/local/bin/mailinabox
|
chmod +x /usr/local/bin/mailinabox
|
||||||
|
|
||||||
# Ask the user for the PRIMARY_HOSTNAME, PUBLIC_IP, PUBLIC_IPV6, and CSR_COUNTRY
|
# Ask the user for the PRIMARY_HOSTNAME, PUBLIC_IP, and PUBLIC_IPV6,
|
||||||
# if values have not already been set in environment variables. When running
|
# if values have not already been set in environment variables. When running
|
||||||
# non-interactively, be sure to set values for all! Also sets STORAGE_USER and
|
# non-interactively, be sure to set values for all! Also sets STORAGE_USER and
|
||||||
# STORAGE_ROOT.
|
# STORAGE_ROOT.
|
||||||
@ -89,7 +89,6 @@ PUBLIC_IP=$PUBLIC_IP
|
|||||||
PUBLIC_IPV6=$PUBLIC_IPV6
|
PUBLIC_IPV6=$PUBLIC_IPV6
|
||||||
PRIVATE_IP=$PRIVATE_IP
|
PRIVATE_IP=$PRIVATE_IP
|
||||||
PRIVATE_IPV6=$PRIVATE_IPV6
|
PRIVATE_IPV6=$PRIVATE_IPV6
|
||||||
CSR_COUNTRY=$CSR_COUNTRY
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Start service configuration.
|
# Start service configuration.
|
||||||
|
@ -458,7 +458,6 @@ class BashScript(Grammar):
|
|||||||
|
|
||||||
v = re.sub(r"(\$?)PRIMARY_HOSTNAME", r"<b>box.yourdomain.com</b>", v)
|
v = re.sub(r"(\$?)PRIMARY_HOSTNAME", r"<b>box.yourdomain.com</b>", v)
|
||||||
v = re.sub(r"\$STORAGE_ROOT", r"<b>$STORE</b>", v)
|
v = re.sub(r"\$STORAGE_ROOT", r"<b>$STORE</b>", v)
|
||||||
v = re.sub(r"\$CSR_COUNTRY", r"<b>US</b>", v)
|
|
||||||
v = v.replace("`pwd`", "<code><b>/path/to/mailinabox</b></code>")
|
v = v.replace("`pwd`", "<code><b>/path/to/mailinabox</b></code>")
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
Loading…
Reference in New Issue
Block a user