This commit is contained in:
tostaki 2016-01-29 10:11:15 +00:00
commit 5c646478d8
6 changed files with 169 additions and 22 deletions

View file

@ -277,6 +277,10 @@ domain:
full: --dyndns
help: Subscribe to the DynDNS service
action: store_true
-l:
full: --noletsencrypt
help: Subscribe to the DynDNS service
action: store_true
### domain_remove()
remove:
@ -291,6 +295,30 @@ domain:
extra:
pattern: *pattern_domain
### domain_letsencrypt()
letsencrypt:
action_help: Manage let's encrypt certificate for a domain
api: POST /letsencrypt
configuration:
authenticate: all
arguments:
domain:
help: Domain to manage
extra:
pattern: *pattern_domain
-c:
full: --create
help: Create a Let's encrypt certificate
action: store_true
-r:
full: --renew
help: Force renewal of a Let's encrypt certificate
action: store_true
-d:
full: --revoke
help: Revoke a Let's encrypt certificate
action: store_true
### domain_info()
# info:
# action_help: Get domain informations

View file

@ -0,0 +1,31 @@
#!/bin/bash
set -e
force=$1
function safe_copy () {
if [ $force ]; then
sudo yunohost service safecopy \
-s letsencrypt \
$1 $2 \
--force
else
sudo yunohost service safecopy \
-s letsencrypt \
$1 $2
fi
}
# Install let's encrypt if not present
if [ ! -d /etc/letsencrypt ]; then
cd /root
git clone https://github.com/letsencrypt/letsencrypt /root
mkdir -p /etc/letsencrypt/webrootauth
fi
domain_list=$(sudo yunohost domain list --plain)
for domain in $domain_list; do
if [ ! -d /etc/letsencrypt/live/$domain ]; then
yunohost domain letsencrypt -c $domain
fi
done

View file

@ -11,6 +11,14 @@ server {
rewrite ^ https://$http_host$request_uri? permanent;
}
root /etc/letsencrypt/webrootauth;
location /.well-known/acme-challenge {
alias /etc/letsencrypt/webrootauth/.well-known/acme-challenge;
location ~ /.well-known/acme-challenge/(.*) {
add_header Content-Type application/jose+json;
}
}
access_log /var/log/nginx/{{ domain }}-access.log;
error_log /var/log/nginx/{{ domain }}-error.log;
}

View file

@ -62,6 +62,13 @@
"domain_deleted" : "Domain successfully deleted",
"no_internet_connection": "Server not connected to the Internet",
"no_ipv6_connectivity": "IPv6 connectivity is not available",
"domain_letsencrypt_created" : "Let's encrypt certificate successfully created.",
"domain_letsencrypt_create_failed" : "Unable to create Let's encrypt certificate.",
"domain_letsencrypt_renewed" : "Let's encrypt certificate successfully renewed.",
"domain_letsencrypt_renew_failed" : "Unable to renew Let's encrypt certificate.",
"domain_letsencrypt_revoked" : "Let's encrypt certificate successfully revoked.",
"domain_letsencrypt_revoke_failed" : "Unable to revoke Let's encrypt certificate.",
"domain_letsencrypt_badarg" : "Bad argument, choose between create, renew or revoke.",
"dyndns_key_generating" : "DNS key is being generated, it may take a while...",
"dyndns_unavailable" : "Unavailable DynDNS subdomain",

View file

@ -965,7 +965,7 @@ def app_ssowatconf(auth):
redirected_regex.update(app_settings['redirected_regex'])
for domain in domains:
skipped_urls.extend([domain + '/yunohost/admin', domain + '/yunohost/api'])
skipped_urls.extend([domain + '/yunohost/admin', domain + '/yunohost/api', domain + '/.well-known/acme-challenge'])
conf_dict = {
'portal_domain': main_domain,

View file

@ -69,8 +69,7 @@ def domain_list(auth, raw=False, filter=None, limit=None, offset=None):
else:
return { 'domains': result_list }
def domain_add(auth, domain, dyndns=False):
def domain_add(auth, domain, dyndns=False, noletsencrypt=False):
"""
Create a custom domain
@ -125,6 +124,7 @@ def domain_add(auth, domain, dyndns=False):
try: os.listdir(ssl_domain_path)
except OSError: os.makedirs(ssl_domain_path)
if noletsencrypt:
command_list = [
'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path),
'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, ssl_domain_path),
@ -143,6 +143,10 @@ def domain_add(auth, domain, dyndns=False):
'chown root:metronome %s/crt.pem' % ssl_domain_path,
'cat %s/ca.pem >> %s/crt.pem' % (ssl_domain_path, ssl_domain_path)
]
else:
command_list = [
'yunohost domain letsencrypt -c %s' % domain
]
for command in command_list:
if os.system(command) != 0:
@ -206,7 +210,22 @@ def domain_remove(auth, domain, force=False):
m18n.n('domain_uninstall_app_first'))
if auth.remove('virtualdomain=' + domain + ',ou=domains') or force:
os.system('rm -rf /etc/yunohost/certs/%s' % domain)
command_list = [
'rm -rf /etc/yunohost/certs/%s' % domain,
]
if os.path.exists('/etc/letsencrypt/live/%s' % domain):
command_list.extend([
'yunohost domain letsencrypt revoke %s' % domain,
'rm -rf /etc/letsencrypt/archive/%s /etc/letsencrypt/live/%s' % domain,
'rm -f /etc/letsencrypt/renewal/%s.conf' % domain,
'rm -f /etc/cron.d/letsencrypt-{domain}' % domain
])
for command in command_list:
if os.system(command) != 0:
msignals.display(m18n.n('path_removal_failed', command[7:]),
'warning')
else:
raise MoulinetteError(errno.EIO, m18n.n('domain_deletion_failed'))
@ -218,3 +237,57 @@ def domain_remove(auth, domain, force=False):
hook_callback('post_domain_remove', args=[domain])
msignals.display(m18n.n('domain_deleted'), 'success')
def domain_letsencrypt(auth, domain, create=False, renew=False, revoke=False):
"""
Manage let's encrypt certificate for a domain
Keyword argument:
domain -- Domain to delete
create -- Create a Let's encrypt certificate
renew -- Force renewal of a Let's encrypt certificate
revoke -- Revoke a Let's encrypt certificate
"""
if domain not in domain_list(auth)['domains']:
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
if create and not renew and not revoke:
# backup self signed certificate if exist
if os.path.exists('/etc/yunohost/certs/%s/cert.pem' % domain):
os.system('mkdir -p /etc/yunohost/certs/%s/yunohost_self_signed' % domain)
os.system('sudo mv /etc/yunohost/certs/%s/*.pem /etc/yunohost/certs/%s/*.cnf /etc/yunohost/certs/%s/yunohost_self_signed/' % domain)
os.system('sudo rm -f /etc/yunohost/certs/%s/*.pem /etc/yunohost/certs/%s/*.cnf' % domain)
# create certificate
try:
os.system('sudo /root/letsencrypt/letsencrypt-auto -a webroot --renew-by-default --agree-dev-preview --agree-tos --webroot-path /etc/letsencrypt/webrootauth -m root@%s -d %s auth' % domain)
# restore right for metronome
os.system('sudo chown root:metronome /etc/letsencrypt/archive/%s/*' % domain)
# create cron
os.system('echo "@monthly root yunohost domain letsencrypt -r %s" > /etc/cron.d/letsencrypt-%s' % domain)
# symbolic link for cert and key
os.system('ln -s /etc/letsencrypt/live/%s/privkey.pem /etc/yunohost/certs/%s/key.pem' % domain)
os.system('ln -s /etc/letsencrypt/live/%s/fullchain.pem /etc/yunohost/certs/%s/crt.pem' % domain)
msignals.display(m18n.n('domain_letsencrypt_created'), 'success')
except:
raise MoulinetteError(errno.EIO, m18n.n('domain_letsencrypt_create_failed'))
elif renew and not create and not revoke:
try:
os.system('sudo /root/letsencrypt/letsencrypt-auto -a webroot --renew-by-default --agree-dev-preview --agree-tos --webroot-path /etc/letsencrypt/webrootauth -m root@%s -d %s auth' % domain)
# restore right for metronome
os.system('sudo chown root:metronome /etc/letsencrypt/archive/%s/*' % domain)
msignals.display(m18n.n('domain_letsencrypt_renewed'), 'success')
except:
raise MoulinetteError(errno.EIO, m18n.n('domain_letsencrypt_renew_failed'))
elif revoke and not create and not renew:
try:
os.system('sudo /root/letsencrypt/letsencrypt-auto -a webroot --renew-by-default --agree-dev-preview --agree-tos --webroot-path /etc/letsencrypt/webrootauth -m root@%s -d %s auth' % domain)
msignals.display(m18n.n('domain_letsencrypt_revoked'), 'success')
except:
raise MoulinetteError(errno.EIO, m18n.n('domain_letsencrypt_revoke_failed'))
else:
raise MoulinetteError(errno.EIO, m18n.n('domain_letsencrypt_badarg'))