Mercurial Hosting > luan
changeset 2076:385ab09fb2ca ssltesting
initial draft
| author | Violet7 |
|---|---|
| date | Tue, 09 Dec 2025 16:37:56 -0800 |
| parents | db677318ce63 |
| children | 6016342e54ea |
| files | host/renewSsl.sh host/startup/nginx/nginx.acme_setup.conf.luan src/luan/host/https.luan |
| diffstat | 3 files changed, 76 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
diff -r db677318ce63 -r 385ab09fb2ca host/renewSsl.sh --- a/host/renewSsl.sh Mon Dec 08 11:26:31 2025 -0700 +++ b/host/renewSsl.sh Tue Dec 09 16:37:56 2025 -0800 @@ -1,13 +1,21 @@ #!/bin/bash set -e -# for now - fschmidt -echo 'totally fucked up' -exit 1 - -cd "$1" || exit 1 +if [ -n "$1" ]; then + cd "$1" || echo "no first argument passed, staying in cwd" +fi ROOTPWD=$(pwd) +# this awkward method is used for portability +ROOTPWDOWNER=$(ls -ld $ROOTPWD | awk '{printf "%s", $3}') + +# change to owner of host/ if running as root +# prevents nginx being unable to read files owned by root +if [ "$(id -u)" -eq 0 ]; then + echo "switching to $ROOTPWDOWNER in order to preserve permissions" + exec sudo -u $ROOTPWDOWNER "$0" "$@" +fi + KEYFILE="$ROOTPWD/local/tiny_account.key" for SITEROOT in "$ROOTPWD"/sites/*; do { @@ -34,7 +42,16 @@ --account-key "$KEYFILE" \ --csr "$CSRFILE" \ --acme-dir "$CHALLENGEDIR" \ - > "$TMPOUT" + >"$TMPOUT" + + wc -c <$TMPOUT + + # If TMPOUT is empty, something failed. + if [ ! -s "$TMPOUT" ]; then + echo "Error: $TMPOUT is empty - please see previous output for details.\nContinuing to next domain..." + rm -f "$TMPOUT" + continue + fi # check if exists if [ -f "$FULLCHAIN" ]; then
diff -r db677318ce63 -r 385ab09fb2ca host/startup/nginx/nginx.acme_setup.conf.luan --- a/host/startup/nginx/nginx.acme_setup.conf.luan Mon Dec 08 11:26:31 2025 -0700 +++ b/host/startup/nginx/nginx.acme_setup.conf.luan Tue Dec 09 16:37:56 2025 -0800 @@ -12,12 +12,13 @@ error_log <%=rootDir%>/error.log; access_log <%=rootDir%>/access.log; - root <%=rootDir%>; - index index.html; - - location / { + location /.well-known/acme-challenge/ { + root <%=rootDir%>; try_files $uri $uri/ =404; } + + include nginx.default.conf; + } <%
diff -r db677318ce63 -r 385ab09fb2ca src/luan/host/https.luan --- a/src/luan/host/https.luan Mon Dec 08 11:26:31 2025 -0700 +++ b/src/luan/host/https.luan Tue Dec 09 16:37:56 2025 -0800 @@ -21,10 +21,17 @@ local function do_set_https(is_https,domain,site_dir,luanhost_dir,dry_run) local nginx_file = site_dir.child("nginx.ssl.conf") - local key_file = site_dir.child(domain..".key") - local csr_file = site_dir.child(domain..".csr") + + -- for storing csr and key, but not fullchain + -- TODO: store fullchain in here, + -- not done yet for backwards compatibility + local ssl_files_dir = site_dir.child("ssl/") + ssl_files_dir.mkdir() + + local key_file = ssl_files_dir.child(domain..".key") + local csr_file = ssl_files_dir.child(domain..".csr") + local tmp_cert_out = ssl_files_dir.child(domain..".crt.tmp") local local_cer_file = site_dir.child("fullchain.cer") - local local_ca_file = site_dir.child("ca.cer") -- luan/host local luanhost_file = "file:"..luanhost_dir.to_string().."/" local luanhost_dir_str = luanhost_dir.canonical().to_string() @@ -59,29 +66,26 @@ -- Clean out old temp files temp_dir.delete() - -- create all needed dirs at once by using - -- mkdir -p on the deepest nested dir (acme-challenge) - local webroot = temp_dir.to_string().."/webroot" - local acme_challenges = webroot.."/.well-known/acme-challenge" - uri("file:"..acme_challenges).mkdir() + -- CHANGEME + dry_run = true - -- Create the nginx config from the template - -- The *output* file, where the generated config is stored - local acme_nginx_file = temp_dir.child("nginx.acme_setup.conf") + -- make the challenge dir. note that this is + -- directly under sites/DOMAIN, and *not* under + -- sites/DOMAIN/site. + local wellknown = site_dir.child(".well-known/") + wellknown.mkdir() + local acme_challenges = wellknown.child("acme-challenge/") + acme_challenges.mkdir() + + -- generate and write the conf + -- TODO: maybe store this in the ssl files dir? local conf = load_file(luanhost_file.."startup/nginx/nginx.acme_setup.conf.luan") - local acme_nginx = ` conf(webroot,domain) ` - acme_nginx_file.write(acme_nginx) + local acme_nginx = ` conf(site_dir_str,domain) ` + local outfile = site_dir.child("nginx.acme_setup.conf") + outfile.write(acme_nginx) - -- Create an index.html to search for in the logs - -- to verify everything is working - local index_file = webroot.."/index.html" - local cmd = "echo 'if you are seeing this, ssl setup has failed. please check the logs.' > "..index_file - local s = uri("bash:"..cmd).read_text() - - -- The config in ./local/nginx.conf has a directive to - -- glob include confs in /tmp/acme_setup/*/nginx.acme_setup.conf - -- so we just need to reload it so it can find the one we just made - local cmd = [[ + -- reload nginx + local cmd = [[ sudo $(which nginx) -t -c "]]..luanhost_dir_str..[[/local/nginx.conf" && \ sudo $(which nginx) -s reload -c "]]..luanhost_dir_str..[[/local/nginx.conf"; ]] @@ -95,28 +99,44 @@ local s = uri("bash:"..cmd).read_text() logger.info("create domain key\n"..s) - -- create the cert, signed with the key we just made + -- create the certificate signing request (CSR), signed with the key we just made local csr_file_str = csr_file.canonical().to_string() local cmd = 'openssl req -new -sha256 -key '..key_file_str..' -subj "/CN='..domain..'" > '..csr_file_str local s = uri("bash:"..cmd).read_text() - logger.info("create cert\n"..s) + logger.info("create csr\n"..s) - -- Finally, get our cert signed by letsencrypt. + -- Finally, get our cert from letsencrypt. local cmd = [[ ]]..luanhost_dir_str..[[/acme_tiny --account-key ]]..luanhost_dir_str..[[/local/tiny_account.key \ --csr ]]..csr_file_str..[[ \ --acme-dir ]]..acme_challenges..[[ \ ]] + + -- TODO: this often doesn't work and I don't know if it's + -- because of this code or because of letsencrypt. + -- fix if broken. if dry_run then local dry_run_dir_url = "https://acme-staging-v02.api.letsencrypt.org/directory" cmd = cmd.." --directory-url "..dry_run_dir_url end - local local_cer_file_str = local_cer_file.canonical().to_string() - cmd = cmd.."> "..local_cer_file_str + cmd = cmd.." > "..tmp_cert_out.canonical().to_string() local s = uri("bash:"..cmd).read_text() logger.info("get cert signed by letsencrypt\n"..s) + if tmp_cert_out.length() == 0 then + -- TODO: this should fail non-gracefully, + -- all failures here are almost certainly bugs. + logger.error("FAILED getting cert from letsencrypt.\nSee previous output.\nNot writing to fullchain.cer") + else + local tmp_out_str = tmp_cert_out.canonical().to_string() + local local_cer_file_str = local_cer_file.canonical().to_string() + + local cmd = "mv "..tmp_out_str.." "..local_cer_file_str + local s = uri("bash:"..cmd).read_text() + logger.info("move temp output to fullchain.cer\n"..s) + end + catch e logger.error("Error setting up ACME: "..e) finally @@ -143,7 +163,6 @@ changed = true nginx_file.delete() local_cer_file.delete() - local_ca_file.delete() local ptn = domain.."." for _, file in ipairs(site_dir.children()) do if starts_with(file.name(),ptn) then
