1st commit: add vh_le.py script (mode test) with templates and conf files
This commit is contained in:
commit
fca07587b2
|
@ -0,0 +1,4 @@
|
||||||
|
attention version de test !
|
||||||
|
pour utiliser en prod, supprimer à la ligne 405: +"_final"
|
||||||
|
et remplacer vh_le.conf par vh_le_final.conf
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
DOMAINS="{{ main_domain }}"
|
||||||
|
_UNAME="{{ second_domains }}"
|
||||||
|
_DIR="{{ le_certificate_folder }}/{{ main_domain }}"
|
||||||
|
|
||||||
|
KEY="$_DIR/$_UNAME.key"
|
||||||
|
CRT="$_DIR/$_UNAME.crt"
|
||||||
|
CSR="$_DIR/$_UNAME.csr"
|
||||||
|
CHAINED="$_DIR/$_UNAME.chained"
|
||||||
|
INTERMEDIATE="$_DIR/$_UNAME.intermediate"
|
||||||
|
ACME_KEY="$_DIR/$_UNAME.acme.key"
|
||||||
|
ACME_CHALLENGE_ROOT=~acme/challenges
|
||||||
|
ACME_CHALLENGE_URL=/.well-known/acme-challenge
|
||||||
|
ACME_CHALLENGE_DIR="${ACME_CHALLENGE_ROOT}/${ACME_CHALLENGE_URL}"
|
||||||
|
RESTART_SERVICE=nginx
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
##
|
||||||
|
# Auto-generated configuration for Hadoly Virtual Hosts
|
||||||
|
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen [::]:80;
|
||||||
|
server_name {{ second_domains }};
|
||||||
|
|
||||||
|
# configuration for Let's Encrypt ACME
|
||||||
|
location ~ /.well-known/acme-challenge/ {
|
||||||
|
default_type "text/plain";
|
||||||
|
root /var/lib/acme/challenges;
|
||||||
|
}
|
||||||
|
location = /.well-known/acme-challenge/ {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
# redirect http to https
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen [::]:80;
|
||||||
|
server_name {{ second_domains }};
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
# conf for https
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen [::]:443;
|
||||||
|
server_name {{ second_domains }};
|
||||||
|
|
||||||
|
|
||||||
|
# conf for LE ACME
|
||||||
|
location ~ /.well-known/acme-challenge/ {
|
||||||
|
default_type "text/plain";
|
||||||
|
root /var/lib/acme/challenges ;
|
||||||
|
}
|
||||||
|
location = /.well-known/acme-challenge/ {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# TLS conf
|
||||||
|
ssl on;
|
||||||
|
ssl_certificate /etc/nginx/sites/{{ main_domain }}/{{ main_domain }}.chained;
|
||||||
|
ssl_certificate_key /etc/nginx/sites/{{ main_domain }}/{{ main_domain }}.key;
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
add_header Strict-Transport-Security max-age=2678400;
|
||||||
|
ssl_dhparam /etc/nginx/dh4096.pem;
|
||||||
|
ssl_session_cache shared:SSL:50m;
|
||||||
|
|
||||||
|
|
||||||
|
# reverse proxy
|
||||||
|
location / {
|
||||||
|
proxy_pass http://[{{ ip6_back }}];
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Ssl on;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
domain_main = "www.hadoly.fr"
|
||||||
|
|
||||||
|
tld = ['fr', 'org']
|
||||||
|
name = "hadoly"
|
||||||
|
sub = ['www']
|
||||||
|
|
||||||
|
ip6_back = "2001:0912:3064:XXXX"
|
||||||
|
|
||||||
|
main_zone = "merlin.hadoly"
|
||||||
|
|
||||||
|
template_nginx_vhost = "./nginx_vhost_template"
|
||||||
|
template_le_nginx_vhost = "./nginx_le_vhost_template"
|
||||||
|
template_acme_conf = "./acme_config_template"
|
||||||
|
available_path = "./available"
|
||||||
|
enabled_path = "./enabled"
|
||||||
|
|
||||||
|
le_certificate_folder = "./sites"
|
||||||
|
acme_folder = "./acme"
|
||||||
|
|
|
@ -0,0 +1,438 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
from jinja2 import Template
|
||||||
|
import codecs
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
__version__ = "0.1"
|
||||||
|
__author__ = "Adel Daouzli"
|
||||||
|
__licence__ = "GPL3"
|
||||||
|
|
||||||
|
|
||||||
|
g_config_file = "./vh_le.conf"
|
||||||
|
|
||||||
|
global g_verbosity
|
||||||
|
g_verbosity = False
|
||||||
|
|
||||||
|
|
||||||
|
# parse command line arguments
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Deploy a DNS configuration with Let's Encrypt configuration. Each provided option will override the config file options.")
|
||||||
|
|
||||||
|
parser.add_argument('-l', '--ls-steps', help='show the list of available steps',
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument('-s', '--step', dest='step', help='run a given step (e.g. 3)')
|
||||||
|
parser.add_argument('-f', '--from-step', dest='from_step',
|
||||||
|
help='run from a given step to the end (e.g. 3)')
|
||||||
|
parser.add_argument('-v', '--verbose', help='If set will print more informations',
|
||||||
|
action="store_true")
|
||||||
|
|
||||||
|
parser.add_argument('-c', '--config-file', dest='config_file',
|
||||||
|
help='the configuration file of the script (default ./vh_le.conf)')
|
||||||
|
|
||||||
|
parser.add_argument('-d', '--main-domain', dest='main_domain',
|
||||||
|
help='the main domain (e.g. www.hadoly.fr)')
|
||||||
|
parser.add_argument('-t', '--tld', dest='tld',
|
||||||
|
help='list of TLDs used to determine the secondary domains (e.g. ["fr", "org"])')
|
||||||
|
parser.add_argument('-b', '--sub', dest='sub',
|
||||||
|
help='list of subdomains used to determine the secondary domains (e.g. ["www"])')
|
||||||
|
parser.add_argument('-n', '--name', dest='name',
|
||||||
|
help="domain's base name used to determine the secondary domains (e.g. hadoly)")
|
||||||
|
parser.add_argument('-z', '--main-zone', dest='main_zone',
|
||||||
|
help="the main zone record without extension (e.g. merlin.hadoly)")
|
||||||
|
parser.add_argument('-i', '--ip6-back', dest='ip6_back',
|
||||||
|
help="the IPv6 (e.g. 2001:912:3064:131::1:)")
|
||||||
|
|
||||||
|
parser.add_argument('--certif-folder', dest='certif_folder',
|
||||||
|
help="path for Let'sEncrypt certificate (default /etc/nginx/sites)")
|
||||||
|
parser.add_argument('--acme-folder', dest='acme_folder',
|
||||||
|
help="path for ACME configuration (default /etc/acme)")
|
||||||
|
|
||||||
|
parser.add_argument('--template-vhost', dest='template_vhost',
|
||||||
|
help="the template Vhost file (default ./nginx_vhost_template)")
|
||||||
|
parser.add_argument('--template-le-vhost', dest='template_le_vhost',
|
||||||
|
help="the temporary template Vhost file for Let's Encrypt (default ./nginx_le_vhost_template)")
|
||||||
|
parser.add_argument('--template-acme', dest='template_acme',
|
||||||
|
help="the template file for ACME config (default ./acme_config_template)")
|
||||||
|
|
||||||
|
parser.add_argument('--sites-available', dest='sites_available',
|
||||||
|
help="path to sites-available (default /etc/nginx/sites-available)")
|
||||||
|
parser.add_argument('--sites-enabled', dest='sites_available',
|
||||||
|
help="path to sites-enabled (default /etc/nginx/sites-enabled)")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
#g_tld = ['fr', 'org']
|
||||||
|
#g_name = "hadoly"
|
||||||
|
#g_sub = ['www']
|
||||||
|
#g_domain_main = "www.hadoly.fr"
|
||||||
|
|
||||||
|
#g_ip6_back = "2001:0912:3064:XXXX"
|
||||||
|
|
||||||
|
#g_main_zone = "merlin.hadoly.fr"
|
||||||
|
|
||||||
|
#g_template_nginx_vhost = "./nginx_vhost_template"
|
||||||
|
#g_template_le_nginx_vhost = "./nginx_le_vhost_template"
|
||||||
|
#g_template_acme_conf = "./acme_config_template"
|
||||||
|
#g_available_path = "./available" # "/etc/nginx/sites-available"
|
||||||
|
#g_enabled_path = "./enabled" # "/etc/nginx/sites-enabled"
|
||||||
|
|
||||||
|
#g_le_certificate_folder = "./sites" # "/etc/nginx/sites"
|
||||||
|
#g_acme_folder = "./acme" # "/etc/acme"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
############# Functions
|
||||||
|
|
||||||
|
def print_info(msg):
|
||||||
|
print(msg)
|
||||||
|
|
||||||
|
def print_debug(msg):
|
||||||
|
if g_verbosity:
|
||||||
|
print("DEBUG: " + str(msg))
|
||||||
|
|
||||||
|
def print_error(msg):
|
||||||
|
print("ERROR: " + str(msg))
|
||||||
|
|
||||||
|
|
||||||
|
def _interpret(value):
|
||||||
|
"""Interpret a value as a string (with " or ') or a list
|
||||||
|
|
||||||
|
:param value: the value to interpret (should be a string)
|
||||||
|
:type: str
|
||||||
|
:return: string or a list
|
||||||
|
"""
|
||||||
|
if type(value) is str:
|
||||||
|
value = value.strip()
|
||||||
|
# string
|
||||||
|
if (value.startswith("'") and value.endswith("'")) or \
|
||||||
|
(value.startswith('"') and value.endswith('"')):
|
||||||
|
value = value[1:-1]
|
||||||
|
# list
|
||||||
|
elif value.startswith("[") and value.endswith("]"):
|
||||||
|
value = [_interpret(e) for e in value[1:-1].split(",")]
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_config_from_file(filename):
|
||||||
|
"""Read the parameters from a configuration file
|
||||||
|
|
||||||
|
:param filename: the configuration file name
|
||||||
|
:return: a dictionary with the configuration
|
||||||
|
"""
|
||||||
|
config = {}
|
||||||
|
with open(filename) as f:
|
||||||
|
print_debug("Get config from file '{}'".format(filename))
|
||||||
|
for line in f.readlines():
|
||||||
|
line = line.strip()
|
||||||
|
# ignore empty lines and comments
|
||||||
|
if line == "" or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
param, value = line.split("=", 1)
|
||||||
|
param, value = param.strip(), value.strip()
|
||||||
|
value = _interpret(value)
|
||||||
|
config[param] = value
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def shell_command(cmd, get_stderr=False, **kwargs):
|
||||||
|
"""Run a shell command
|
||||||
|
|
||||||
|
:param cmd: the command with parameters separated by spaces
|
||||||
|
:param get_stderr: if True will get also stderr
|
||||||
|
:return: stdout or (stdout, stderr) if get_stderr or None if failed
|
||||||
|
"""
|
||||||
|
ret = None
|
||||||
|
try:
|
||||||
|
if get_stderr:
|
||||||
|
ret = subprocess.check_output(cmd.split(' '), **kwargs)
|
||||||
|
else:
|
||||||
|
ret = subprocess.check_output(cmd.split(' '), stderr=subprocess.PIPE, **kwargs)
|
||||||
|
print_debug("run command '{}'".format(cmd))
|
||||||
|
except Exception as e:
|
||||||
|
print_debug("failed to run command: {}\n got exception: <{}>".format(cmd, e))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def check_dns_record(domain, expected=None, record_type="CNAME", resolver=None):
|
||||||
|
"""Check if a DNS record is correct for a domain
|
||||||
|
|
||||||
|
:param domain: the domain name to check (e.g. "www.hadoly.fr")
|
||||||
|
:param expected: the expected record in a tuple base name and TLDs
|
||||||
|
(e.g ("merlin.hadoly", ["fr", "org"])) or a string. If None will just
|
||||||
|
expect a record (default None)
|
||||||
|
:param record_type: the record type (default "CNAME")
|
||||||
|
:param resolver: a resolver to use. If None will use the local system one
|
||||||
|
(default None)
|
||||||
|
:return: True if success else False
|
||||||
|
"""
|
||||||
|
ret = False
|
||||||
|
if resolver:
|
||||||
|
res = shell_command("dig +short {} {} @{}".format(record_type, domain, resolver))
|
||||||
|
else:
|
||||||
|
res = shell_command("dig +short {} {}".format(record_type, domain))
|
||||||
|
if type(expected) is str and type(res) is str and res.startswith(expected):
|
||||||
|
ret = True
|
||||||
|
elif type(expected) is tuple and type(res) is str:
|
||||||
|
base, tlds = expected
|
||||||
|
tlds = [tlds] if type(tlds) is str else tlds
|
||||||
|
for tld in tlds:
|
||||||
|
tld = tld[1:] if tld[0] == '.' else tld
|
||||||
|
if res.startswith(base + "." + tld):
|
||||||
|
print_debug("found DNS record : {}".format(res))
|
||||||
|
ret = True
|
||||||
|
break
|
||||||
|
elif expected is None and res:
|
||||||
|
ret = True
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def generate_file(template_file, output_file, data):
|
||||||
|
"""Generate a file based on a template file
|
||||||
|
|
||||||
|
:param template_file: the input template file
|
||||||
|
:param output_file: the output file to generate
|
||||||
|
:param data: the data to provide to the template
|
||||||
|
:type data: dict
|
||||||
|
:return: True if success else False
|
||||||
|
"""
|
||||||
|
ret = False
|
||||||
|
#print_debug("generate_file(template_file={}, output_file={}, data={})".format(template_file, output_file, data))
|
||||||
|
with open(template_file) as f:
|
||||||
|
print_debug("Use template '{}'".format(template_file))
|
||||||
|
d=f.read()
|
||||||
|
template = Template(d)
|
||||||
|
content = template.render(**data)
|
||||||
|
with codecs.open(output_file, "w", 'utf-8') as fo:
|
||||||
|
fo.write(content)
|
||||||
|
ret = True
|
||||||
|
print_debug("file '{}' generated !".format(output_file))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
################################################################################
|
||||||
|
################################################################################
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
### list steps and stop
|
||||||
|
|
||||||
|
steps = '''
|
||||||
|
STEP 1 : DNS records
|
||||||
|
STEP 2 : Create Nginx available configuration
|
||||||
|
STEP 3 : Create sites-enabled Nginx link
|
||||||
|
STEP 4 : Reload Nginx
|
||||||
|
STEP 5 : create Nginx folder that will receive the Let's Encrypt certificate
|
||||||
|
STEP 6 : create the acme configuration file
|
||||||
|
STEP 7 : acme create
|
||||||
|
STEP 8 : acme renew
|
||||||
|
STEP 9 : update the Nginx enable final configuration file
|
||||||
|
STEP 10 : reload Nginx
|
||||||
|
'''
|
||||||
|
if args.ls_steps:
|
||||||
|
print (steps)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
############### Prepare config
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# read configuration from file
|
||||||
|
|
||||||
|
if args.config_file:
|
||||||
|
conf_file = args.config_file
|
||||||
|
else:
|
||||||
|
conf_file = g_config_file
|
||||||
|
|
||||||
|
c = get_config_from_file(conf_file)
|
||||||
|
|
||||||
|
|
||||||
|
# overwrite configuration with command line args
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
g_verbosity = True
|
||||||
|
|
||||||
|
if args.main_domain:
|
||||||
|
c['domain_main'] = args.main_domain
|
||||||
|
if args.tld:
|
||||||
|
c['tld'] = args.tld
|
||||||
|
if args.sub:
|
||||||
|
c['sub'] = args.sub
|
||||||
|
if args.name:
|
||||||
|
c['name'] = args.name
|
||||||
|
if args.ip6_back:
|
||||||
|
c['ip6_back'] = args.ip6_back
|
||||||
|
if args.main_zone:
|
||||||
|
c['main_zone'] = args.main_zone
|
||||||
|
|
||||||
|
if args.certif_folder:
|
||||||
|
c['le_certificate_folder'] = args.certif_folder
|
||||||
|
if args.acme_folder:
|
||||||
|
c['acme_folder'] = args.acme_folder
|
||||||
|
|
||||||
|
if args.template_vhost:
|
||||||
|
c['template_nginx_vhost'] = args.template_vhost
|
||||||
|
if args.template_le_vhost:
|
||||||
|
c['template_le_nginx_vhost'] = args.template_le_vhost
|
||||||
|
if args.template_acme:
|
||||||
|
c['template_acme_conf'] = args.template_acme
|
||||||
|
if args.sites_available:
|
||||||
|
c['available_path'] = args.sites_available
|
||||||
|
if args.sites_available:
|
||||||
|
c['enabled_path'] = args.sites_available
|
||||||
|
|
||||||
|
|
||||||
|
# build secondary domains
|
||||||
|
|
||||||
|
domains = []
|
||||||
|
for tld in c['tld']:
|
||||||
|
domains.append(c['name'] + '.' + tld)
|
||||||
|
for sub in c['sub']:
|
||||||
|
domains.append(sub + '.' + c['name'] + '.' + tld)
|
||||||
|
|
||||||
|
# determine the steps to run
|
||||||
|
|
||||||
|
if args.step:
|
||||||
|
step = {i+1: False for i in range(10)}
|
||||||
|
step[int(args.step)] = True
|
||||||
|
elif args.from_step:
|
||||||
|
step = {i+1: False for i in range(10)}
|
||||||
|
for i in range(11 - int(args.from_step)):
|
||||||
|
step[i+int(args.from_step)] = True
|
||||||
|
else:
|
||||||
|
step = {i+1: True for i in range(10)}
|
||||||
|
|
||||||
|
|
||||||
|
############# Steps
|
||||||
|
|
||||||
|
|
||||||
|
##### DNS records (CNAME)
|
||||||
|
if step[1]:
|
||||||
|
print_info("\n++++++ STEP 1 : DNS records ++++++")
|
||||||
|
|
||||||
|
# check each domain for DNS record
|
||||||
|
no_dns_record = []
|
||||||
|
for domain in [c['domain_main']] + domains:
|
||||||
|
res = check_dns_record(domain, expected=(c['main_zone'], c['tld']))
|
||||||
|
if not res:
|
||||||
|
no_dns_record.append(domain)
|
||||||
|
print_info("warning: No DNS record for '{domain}'".format(domain=domain))
|
||||||
|
|
||||||
|
# check if main domain had expected record else stop
|
||||||
|
if c['domain_main'] in no_dns_record:
|
||||||
|
msg = """No DNS record for '{domain}'. Please record it before
|
||||||
|
running this script. You may add in your DNS zone something like:
|
||||||
|
{domain} CNAME {entry}
|
||||||
|
""".format(domain=c['domain_main'], entry=c['main_zone'] + '.' + tld[0])
|
||||||
|
print_error(msg)
|
||||||
|
sys.exit(1)
|
||||||
|
print_info("Valid DNS record ({} -> {})".format(c['domain_main'], c['main_zone']))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### Create Nginx available configuration
|
||||||
|
|
||||||
|
if step[2]:
|
||||||
|
print_info("\n++++++ STEP 2 : Create Nginx available configuration ++++++")
|
||||||
|
|
||||||
|
shell_command("sudo mkdir -p {} 2>/dev/null".format(c['available_path']))
|
||||||
|
if generate_file(c['template_le_nginx_vhost'],
|
||||||
|
c['available_path'] + "/" + c['domain_main'],
|
||||||
|
{'second_domains': ' '.join(domains)}) == False:
|
||||||
|
print_error("Failed to generate temporary Nginx VHost configuration file for LE")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
##### Create sites-enabled Nginx link
|
||||||
|
|
||||||
|
if step[3]:
|
||||||
|
print_info("\n++++++ STEP 3 : Create sites-enabled Nginx link ++++++")
|
||||||
|
|
||||||
|
shell_command("ln -s {} {}".format(os.path.abspath(c['available_path'] + "/" + c['domain_main']),
|
||||||
|
c['domain_main']),
|
||||||
|
cwd=c['enabled_path'])
|
||||||
|
|
||||||
|
##### Reload Nginx
|
||||||
|
# Note: after that if a server on internet request on
|
||||||
|
# http://$domaine/.well-known/acme-challenge/ it will be challenged
|
||||||
|
|
||||||
|
if step[4]:
|
||||||
|
print_info("\n++++++ STEP 4 : Reload Nginx ++++++")
|
||||||
|
|
||||||
|
shell_command("sudo service nginx restart", get_stderr=True)
|
||||||
|
|
||||||
|
|
||||||
|
##### create Nginx folder that will receive the Let's Encrypt certificate
|
||||||
|
|
||||||
|
if step[5]:
|
||||||
|
print_info("\n++++++ STEP 5 : create Nginx folder that will receive the Let's Encrypt certificate ++++++")
|
||||||
|
|
||||||
|
shell_command("sudo mkdir -p {}/{}".format(c['le_certificate_folder'],
|
||||||
|
c['domain_main']))
|
||||||
|
|
||||||
|
##### create the acme configuration file
|
||||||
|
|
||||||
|
if step[6]:
|
||||||
|
print_info("\n++++++ STEP 6 : create the acme configuration file ++++++")
|
||||||
|
|
||||||
|
shell_command("sudo mkdir -p {} 2>/dev/null".format(c['acme_folder']))
|
||||||
|
config_file = "{}/{}.conf".format(c['acme_folder'], c['domain_main'])
|
||||||
|
if generate_file(c['template_acme_conf'], config_file,
|
||||||
|
{"main_domain": c['domain_main'],
|
||||||
|
"le_certificate_folder": c['le_certificate_folder'],
|
||||||
|
"second_domains": ' '.join(domains)}) == False:
|
||||||
|
print_error("Failed to generate ACME configuration file")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
##### acme create
|
||||||
|
|
||||||
|
if step[7]:
|
||||||
|
print_info("\n++++++ STEP 7 : acme create ++++++")
|
||||||
|
|
||||||
|
shell_command("sudo mkdir -p {} 2>/dev/null".format(c['acme_folder']))
|
||||||
|
cmd = "sudo /usr/local/bin/acme_create --config {}/{}.conf"
|
||||||
|
shell_command(cmd.format(c['acme_folder'], c['domain_main']), get_stderr=True)
|
||||||
|
|
||||||
|
|
||||||
|
##### acme renew
|
||||||
|
|
||||||
|
if step[8]:
|
||||||
|
print_info("\n++++++ STEP 8 : acme renew ++++++")
|
||||||
|
|
||||||
|
shell_command("sudo mkdir -p {} 2>/dev/null".format(c['acme_folder']))
|
||||||
|
cmd = "sudo -u acme /usr/local/bin/acme_renew --config {}/{}.conf"
|
||||||
|
shell_command(cmd.format(c['acme_folder'], c['domain_main']), get_stderr=True)
|
||||||
|
|
||||||
|
|
||||||
|
##### update the Nginx enable final configuration file
|
||||||
|
|
||||||
|
if step[9]:
|
||||||
|
print_info("\n++++++ STEP 9 : update the Nginx enable final configuration file ++++++")
|
||||||
|
|
||||||
|
if generate_file(c['template_nginx_vhost'],
|
||||||
|
c['available_path'] + "/" + c['domain_main']+"_final", #TODO remove _final
|
||||||
|
{"main_domain": c['domain_main'],
|
||||||
|
"second_domains": ' '.join(domains),
|
||||||
|
"ip6_back": c['ip6_back']}) == False:
|
||||||
|
print_error("Failed to generate Nginx VHost configuration file")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
##### reload Nginx
|
||||||
|
|
||||||
|
if step[10]:
|
||||||
|
print_info("\n++++++ STEP 10 : reload Nginx ++++++")
|
||||||
|
|
||||||
|
shell_command("sudo service nginx restart", get_stderr=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
# the main domain
|
||||||
|
domain_main = "www.hadoly.fr"
|
||||||
|
|
||||||
|
# list of TLDs used to determine the secondary domains
|
||||||
|
tld = ['fr', 'org']
|
||||||
|
# domain's base name used to determine the secondary domains
|
||||||
|
name = "hadoly"
|
||||||
|
# list of subdomains used to determine the secondary domains
|
||||||
|
sub = ['www']
|
||||||
|
|
||||||
|
# the IPv6
|
||||||
|
ip6_back = "2001:0912:3064:XXXX"
|
||||||
|
|
||||||
|
# the main zone record without extension
|
||||||
|
main_zone = "merlin.hadoly"
|
||||||
|
|
||||||
|
|
||||||
|
# path for Let'sEncrypt certificate
|
||||||
|
le_certificate_folder = "/etc/nginx/sites"
|
||||||
|
|
||||||
|
# path for ACME configuration
|
||||||
|
acme_folder = "/etc/acme"
|
||||||
|
|
||||||
|
|
||||||
|
# the template Vhost file
|
||||||
|
template_nginx_vhost = "./nginx_vhost_template"
|
||||||
|
|
||||||
|
# the temporary template Vhost file for Let's Encrypt
|
||||||
|
template_le_nginx_vhost = "./nginx_le_vhost_template"
|
||||||
|
|
||||||
|
# the template file for ACME config
|
||||||
|
template_acme_conf = "./acme_config_template"
|
||||||
|
|
||||||
|
|
||||||
|
# path to sites-available
|
||||||
|
available_path = "/etc/nginx/sites-available"
|
||||||
|
|
||||||
|
# path to sites-enabled
|
||||||
|
enabled_path = "/etc/nginx/sites-enabled"
|
||||||
|
|
Loading…
Reference in New Issue