[mod] role:tlscert_acme_inwx:eigene umsetzung und automatische erneuerung
This commit is contained in:
parent
f25589f56b
commit
0aa3cb5303
|
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys as _sys
|
||||||
import os as _os
|
import os as _os
|
||||||
import json as _json
|
import json as _json
|
||||||
import argparse as _argparse
|
import argparse as _argparse
|
||||||
|
|
@ -21,17 +22,12 @@ def main():
|
||||||
type = str,
|
type = str,
|
||||||
dest = "conf_path",
|
dest = "conf_path",
|
||||||
metavar = "<conf-path>",
|
metavar = "<conf-path>",
|
||||||
default = "./tls-renew-conf.json",
|
default = _os.path.join(_os.environ["HOME"], ".tls-renew-conf.json"),
|
||||||
)
|
)
|
||||||
argument_parser.add_argument(
|
argument_parser.add_argument(
|
||||||
type = str,
|
type = str,
|
||||||
dest = "domain_base",
|
dest = "domain",
|
||||||
metavar = "<domain-base>",
|
metavar = "<domain>",
|
||||||
)
|
|
||||||
argument_parser.add_argument(
|
|
||||||
type = str,
|
|
||||||
dest = "domain_path",
|
|
||||||
metavar = "<domain-path>",
|
|
||||||
)
|
)
|
||||||
argument_parser.add_argument(
|
argument_parser.add_argument(
|
||||||
"-t",
|
"-t",
|
||||||
|
|
@ -59,45 +55,84 @@ def main():
|
||||||
metavar = "<delay>",
|
metavar = "<delay>",
|
||||||
help = "seconds to wait at end of certbot auth hook",
|
help = "seconds to wait at end of certbot auth hook",
|
||||||
)
|
)
|
||||||
|
argument_parser.add_argument(
|
||||||
|
"-q",
|
||||||
|
"--dry-run",
|
||||||
|
dest = "dry_run",
|
||||||
|
action = "store_true",
|
||||||
|
default = False,
|
||||||
|
help = "whether to only print the command on stdout instead of executing it",
|
||||||
|
)
|
||||||
args = argument_parser.parse_args()
|
args = argument_parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
## vars
|
## vars
|
||||||
conf = _json.loads(file_read(args.conf_path))
|
conf = _json.loads(file_read(args.conf_path))
|
||||||
domain = (args.domain_base + args.domain.path)
|
le_dir = "/etc/letsencrypt/live"
|
||||||
|
|
||||||
## exec
|
## exec
|
||||||
command_hook_parts = [
|
command_hook_parts = [
|
||||||
("/usr/local/bin/inwx"),
|
("/usr/local/bin/inwx"),
|
||||||
("--username='%s'" % conf["inwx_account"]["username"]),
|
("--username=\"%s\"" % conf["inwx_account"]["username"]),
|
||||||
("--password='%s'" % conf["inwx_account"]["password"]),
|
("--password=\"%s\"" % conf["inwx_account"]["password"]),
|
||||||
("--challenge-prefix='%s'" % args.challenge_prefix),
|
("certbot-hook")
|
||||||
("--delay=%.4f" % args.delay),
|
|
||||||
("save"),
|
|
||||||
(args.domain_base),
|
|
||||||
("_acme-challenge.%s" % args.domain.path),
|
|
||||||
("TXT"),
|
|
||||||
("'\${CERTBOT_VALIDATION}'"),
|
|
||||||
]
|
]
|
||||||
command_hook = " ".join(command_hook_parts)
|
command_hook = " ".join(command_hook_parts)
|
||||||
|
|
||||||
command_certbot_parts = [
|
command_certbot_parts = [
|
||||||
("certbot"),
|
("certbot"),
|
||||||
|
("certonly"),
|
||||||
("--email='%s'" % conf["acme_account"]["email"]),
|
("--email='%s'" % conf["acme_account"]["email"]),
|
||||||
("--work-dir='%s'" % conf["misc"]["working_directory"]),
|
# ("--work-dir='%s'" % conf["misc"]["working_directory"]),
|
||||||
("--preferred-challenges='dns'"),
|
("--preferred-challenges='dns'"),
|
||||||
("--non-interactive"),
|
("--non-interactive"),
|
||||||
("--key-path='%s'" % _os.path.join(args.target_directory, "private", "%s.pem" % domain)),
|
("--agree-tos"),
|
||||||
("--cert-path='%s'" % _os.path.join(args.target_directory, "certs", "%s.pem" % domain)),
|
("--domain='%s'" % args.domain),
|
||||||
("--chain-path='%s'" % _os.path.join(args.target_directory, "chains", "%s.pem" % domain)),
|
("--manual"),
|
||||||
("--fullchain-path='%s'" % _os.path.join(args.target_directory, "fullchains", "%s.pem" % domain)),
|
|
||||||
("--domain='%s'" % domain),
|
|
||||||
("--manual-auth-hook='%s'" % command_hook),
|
("--manual-auth-hook='%s'" % command_hook),
|
||||||
("renew"),
|
# ("--key-path='%s'" % _os.path.join(args.target_directory, "private", "%s.pem" % args.domain)),
|
||||||
|
# ("--cert-path='%s'" % _os.path.join(args.target_directory, "certs", "%s.pem" % args.domain)),
|
||||||
|
# ("--chain-path='%s'" % _os.path.join(args.target_directory, "chains", "%s.pem" % args.domain)),
|
||||||
|
# ("--fullchain-path='%s'" % _os.path.join(args.target_directory, "fullchains", "%s.pem" % args.domain)),
|
||||||
]
|
]
|
||||||
command_certbot = " ".join(command_certbot_parts)
|
command_certbot = " ".join(command_certbot_parts)
|
||||||
|
|
||||||
_os.system(command_certbot)
|
if (args.dry_run):
|
||||||
|
_sys.stdout.write(command_certbot + "\n")
|
||||||
|
else:
|
||||||
|
_os.system(command_certbot)
|
||||||
|
_os.system(
|
||||||
|
"mkdir --parents %s && cp --dereference %s %s"
|
||||||
|
% (
|
||||||
|
_os.path.join(args.target_directory, "private"),
|
||||||
|
_os.path.join(le_dir, args.domain, "privkey.pem"),
|
||||||
|
_os.path.join(args.target_directory, "private", "%s.pem" % args.domain),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_os.system(
|
||||||
|
"mkdir --parents %s && cp --dereference %s %s"
|
||||||
|
% (
|
||||||
|
_os.path.join(args.target_directory, "certs"),
|
||||||
|
_os.path.join(le_dir, args.domain, "cert.pem"),
|
||||||
|
_os.path.join(args.target_directory, "certs", "%s.pem" % args.domain),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_os.system(
|
||||||
|
"mkdir --parents %s && cp --dereference %s %s"
|
||||||
|
% (
|
||||||
|
_os.path.join(args.target_directory, "chains"),
|
||||||
|
_os.path.join(le_dir, args.domain, "chain.pem"),
|
||||||
|
_os.path.join(args.target_directory, "chains", "%s.pem" % args.domain),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_os.system(
|
||||||
|
"mkdir --parents %s && cp --dereference %s %s"
|
||||||
|
% (
|
||||||
|
_os.path.join(args.target_directory, "fullchains"),
|
||||||
|
_os.path.join(le_dir, args.domain, "fullchain.pem"),
|
||||||
|
_os.path.join(args.target_directory, "fullchains", "%s.pem" % args.domain),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
## Beschreibung
|
||||||
|
|
||||||
|
- richtet die regelmäßige TLS-Zertifikats-Erstellung für eine Domäne und führt eine Erstellung direkt aus
|
||||||
|
|
||||||
|
|
||||||
## Verweise
|
## Verweise
|
||||||
|
|
||||||
- [Digital Ocean | How To Acquire a Let's Encrypt Certificate Using Ansible](https://www.digitalocean.com/community/tutorials/how-to-acquire-a-let-s-encrypt-certificate-using-ansible-on-ubuntu-18-04)
|
- [Digital Ocean | How To Acquire a Let's Encrypt Certificate Using Ansible](https://www.digitalocean.com/community/tutorials/how-to-acquire-a-let-s-encrypt-certificate-using-ansible-on-ubuntu-18-04)
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,19 @@
|
||||||
"update_cache": true,
|
"update_cache": true,
|
||||||
"pkg": [
|
"pkg": [
|
||||||
"openssl",
|
"openssl",
|
||||||
"python3-cryptography"
|
"python3-cryptography",
|
||||||
|
"certbot"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "directories | ssl",
|
"name": "directories",
|
||||||
"become": true,
|
"become": true,
|
||||||
"loop": [
|
"loop": [
|
||||||
"{{var_tlscert_acme_inwx_ssl_directory}}/private",
|
"{{var_tlscert_acme_inwx_ssl_directory}}/private",
|
||||||
"{{var_tlscert_acme_inwx_ssl_directory}}/csr",
|
"{{var_tlscert_acme_inwx_ssl_directory}}/csr",
|
||||||
"{{var_tlscert_acme_inwx_ssl_directory}}/certs",
|
"{{var_tlscert_acme_inwx_ssl_directory}}/certs",
|
||||||
|
"{{var_tlscert_acme_inwx_ssl_directory}}/chains",
|
||||||
"{{var_tlscert_acme_inwx_ssl_directory}}/fullchains"
|
"{{var_tlscert_acme_inwx_ssl_directory}}/fullchains"
|
||||||
],
|
],
|
||||||
"ansible.builtin.file": {
|
"ansible.builtin.file": {
|
||||||
|
|
@ -25,54 +27,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "directories | Let's Encrypt account key",
|
"name": "tools | inwx",
|
||||||
"become": true,
|
|
||||||
"ansible.builtin.file": {
|
|
||||||
"state": "directory",
|
|
||||||
"path": "{{var_tlscert_acme_inwx_acme_account_key_path | dirname}}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "key",
|
|
||||||
"become": true,
|
|
||||||
"community.crypto.openssl_privatekey": {
|
|
||||||
"path": "{{var_tlscert_acme_inwx_ssl_directory}}/private/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "csr",
|
|
||||||
"become": true,
|
|
||||||
"community.crypto.openssl_csr": {
|
|
||||||
"common_name": "{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}",
|
|
||||||
"privatekey_path": "{{var_tlscert_acme_inwx_ssl_directory}}/private/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem",
|
|
||||||
"path": "{{var_tlscert_acme_inwx_ssl_directory}}/csr/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "acme | account key",
|
|
||||||
"become": true,
|
|
||||||
"ansible.builtin.shell": {
|
|
||||||
"cmd": "test -f {{var_tlscert_acme_inwx_acme_account_key_path}} || openssl genrsa 4096 > {{var_tlscert_acme_inwx_acme_account_key_path}}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "acme | init",
|
|
||||||
"become": true,
|
|
||||||
"community.crypto.acme_certificate": {
|
|
||||||
"acme_version": 2,
|
|
||||||
"acme_directory": "https://acme-v02.api.letsencrypt.org/directory",
|
|
||||||
"account_email": "{{var_tlscert_acme_inwx_acme_account_email}}",
|
|
||||||
"account_key_src": "{{var_tlscert_acme_inwx_acme_account_key_path}}",
|
|
||||||
"terms_agreed": true,
|
|
||||||
"csr": "{{var_tlscert_acme_inwx_ssl_directory}}/csr/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem",
|
|
||||||
"challenge": "dns-01",
|
|
||||||
"dest": "{{var_tlscert_acme_inwx_ssl_directory}}/certs/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem",
|
|
||||||
"fullchain_dest": "{{var_tlscert_acme_inwx_ssl_directory}}/fullchains/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem"
|
|
||||||
},
|
|
||||||
"register": "temp_acme_data"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "dns challenge | place script",
|
|
||||||
"become": true,
|
"become": true,
|
||||||
"ansible.builtin.copy": {
|
"ansible.builtin.copy": {
|
||||||
"src": "inwx",
|
"src": "inwx",
|
||||||
|
|
@ -81,33 +36,60 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dns challenge | execute",
|
"name": "tools | tls-renew | script",
|
||||||
"when": "'challenge_data' in temp_acme_data",
|
|
||||||
"ansible.builtin.command": {
|
|
||||||
"cmd": "/usr/local/bin/inwx --username={{var_tlscert_acme_inwx_inwx_account_username}} --password={{var_tlscert_acme_inwx_inwx_account_password}} save {{var_tlscert_acme_inwx_domain_base}} _acme-challenge.{{var_tlscert_acme_inwx_domain_path}} TXT {{temp_acme_data['challenge_data'][var_tlscert_acme_inwx_domain_path + '.' + var_tlscert_acme_inwx_domain_base]['dns-01']['resource_value']}}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "dns challenge | wait",
|
|
||||||
"when": "'challenge_data' in temp_acme_data",
|
|
||||||
"ansible.builtin.pause": {
|
|
||||||
"seconds": 60
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "acme | finalize",
|
|
||||||
"become": true,
|
"become": true,
|
||||||
"community.crypto.acme_certificate": {
|
"ansible.builtin.file": {
|
||||||
"acme_version": 2,
|
"src": "tls-renew",
|
||||||
"acme_directory": "https://acme-v02.api.letsencrypt.org/directory",
|
"dest": "/usr/local/bin/tls-renew",
|
||||||
"account_email": "{{var_tlscert_acme_inwx_acme_account_email}}",
|
"mode": "a+x"
|
||||||
"account_key_src": "{{var_tlscert_acme_inwx_acme_account_key_path}}",
|
}
|
||||||
"terms_agreed": true,
|
},
|
||||||
"csr": "{{var_tlscert_acme_inwx_ssl_directory}}/csr/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem",
|
{
|
||||||
"challenge": "dns-01",
|
"name": "tools | tls-renew | conf",
|
||||||
"dest": "{{var_tlscert_acme_inwx_ssl_directory}}/certs/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem",
|
"become": true,
|
||||||
"fullchain_dest": "{{var_tlscert_acme_inwx_ssl_directory}}/fullchains/{{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}.pem",
|
"ansible.builtin.template": {
|
||||||
"data": "{{temp_acme_data}}"
|
"src": "tls-renew-conf.json.j2",
|
||||||
|
"dest": "/root/.tls-renew-conf.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tools | pseudo queue | setup",
|
||||||
|
"become": true,
|
||||||
|
"ansible.builtin.cron": {
|
||||||
|
"state": "present",
|
||||||
|
"disabled": false,
|
||||||
|
"name": "pseudo queue",
|
||||||
|
"special_time": "reboot",
|
||||||
|
"job": "bash -c \"test -p /var/pseudoqueue || (mkfifo --mode=0600 /var/pseudoqueue && (while true ; do bash < /var/pseudoqueue ; done))\""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tools | pseudo queue | run",
|
||||||
|
"become": true,
|
||||||
|
"ansible.builtin.shell": {
|
||||||
|
"cmd": "bash -c \"test -p /var/pseudoqueue || (mkfifo --mode=0600 /var/pseudoqueue && (while true ; do bash < /var/pseudoqueue ; done))\""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "setup auto renewal",
|
||||||
|
"become": true,
|
||||||
|
"ansible.builtin.cron": {
|
||||||
|
"state": "present",
|
||||||
|
"disabled": false,
|
||||||
|
"name": "TLS certificate for {{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}}",
|
||||||
|
"minute": "0",
|
||||||
|
"hour": "2",
|
||||||
|
"day": "1",
|
||||||
|
"month": "*",
|
||||||
|
"weekday": "*",
|
||||||
|
"job": "echo '/usr/local/bin/tls-renew --conf-path=/root/.tls-renew-conf.json {{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}} --target-directory={{var_tlscert_acme_inwx_ssl_directory}}' > /var/pseudoqueue"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "run",
|
||||||
|
"become": true,
|
||||||
|
"ansible.builtin.shell": {
|
||||||
|
"cmd": "echo '/usr/local/bin/tls-renew --conf-path=/root/.tls-renew-conf.json {{var_tlscert_acme_inwx_domain_path}}.{{var_tlscert_acme_inwx_domain_base}} --target-directory={{var_tlscert_acme_inwx_ssl_directory}}' > /var/pseudoqueue"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"acme_account": {
|
"acme_account": {
|
||||||
"email": "{{var_tlscert_acme_inwx_acme_account_email}}"
|
"email": "{{var_tlscert_acme_inwx_acme_account_email}}"
|
||||||
},
|
},
|
||||||
"inwx_account: {
|
"inwx_account": {
|
||||||
"username": "{{var_tlscert_acme_inwx_inwx_account_username}}",
|
"username": "{{var_tlscert_acme_inwx_inwx_account_username}}",
|
||||||
"password": "{{var_tlscert_acme_inwx_inwx_account_password}}"
|
"password": "{{var_tlscert_acme_inwx_inwx_account_password}}"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue