Mercurial Hosting > luan
changeset 2036:2740f8a9ba3a acme-tiny tip
First test prototype (also convert spaces to tabs and remove *.orig files)
| author | Violet7 |
|---|---|
| date | Wed, 05 Nov 2025 21:49:39 -0800 |
| parents | 00bbfef1a86b |
| children | |
| files | backup/start.sh.orig backup/stop.sh.orig host/startup/nginx/nginx.acme_setup.conf.luan src/luan/host/https.luan |
| diffstat | 4 files changed, 120 insertions(+), 140 deletions(-) [+] |
line wrap: on
line diff
diff -r 00bbfef1a86b -r 2740f8a9ba3a backup/start.sh.orig --- a/backup/start.sh.orig Wed Nov 05 11:20:47 2025 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -#!/bin/bash -e - -ROOTPWD=$(pwd); -logsdir=${ROOTPWD}"/logs"; -servelog=${logsdir}"/server.log"; - -mkdir -p "$logsdir" - -if [ "$1" == "launchd" ]; then - ${ROOTPWD}/luan.sh server.luan $* &2>${servelog} -else - ${ROOTPWD}/luan.sh server.luan $* &2>${servelog}& -fi;
diff -r 00bbfef1a86b -r 2740f8a9ba3a backup/stop.sh.orig --- a/backup/stop.sh.orig Wed Nov 05 11:20:47 2025 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -#!/bin/bash - -LUAN_PIDS=$(ps ax | awk '/[s]erver.luan/ {print $1}') - -if [ -n "$LUAN_PIDS" ]; then - echo "Killing luan processes: $LUAN_PIDS" - kill -TERM $LUAN_PIDS -else - echo "Info: No luan processes found, continuing." -fi - -exit 0
diff -r 00bbfef1a86b -r 2740f8a9ba3a host/startup/nginx/nginx.acme_setup.conf.luan --- a/host/startup/nginx/nginx.acme_setup.conf.luan Wed Nov 05 11:20:47 2025 -0700 +++ b/host/startup/nginx/nginx.acme_setup.conf.luan Wed Nov 05 21:49:39 2025 -0800 @@ -1,24 +1,24 @@ local rootDir, domain = ... %> - # This config exists to serve up acme challenges on - # .well-known for initial domain verification by letsencrypt. - # see set_https in luan/src/luan/host/https.luan for more. - server { - server_name <%=domain%>; - listen 80; - listen [::]:80; + # This config exists to serve up acme challenges on + # .well-known for initial domain verification by letsencrypt. + # see set_https in luan/src/luan/host/https.luan for more. + server { + server_name <%=domain%>; + listen 80; + listen [::]:80; - error_log <%=rootDir%>/error.log; - access_log <%=rootDir%>/access.log; + error_log <%=rootDir%>/error.log; + access_log <%=rootDir%>/access.log; - root <%=rootDir%>; - index index.html; + root <%=rootDir%>; + index index.html; - location / { - try_files $uri $uri/ =404; - } - } + location / { + try_files $uri $uri/ =404; + } + } <%
diff -r 00bbfef1a86b -r 2740f8a9ba3a src/luan/host/https.luan --- a/src/luan/host/https.luan Wed Nov 05 11:20:47 2025 -0700 +++ b/src/luan/host/https.luan Wed Nov 05 21:49:39 2025 -0800 @@ -22,136 +22,141 @@ return end local domain = Http.domain - local dir = uri("site:").parent() - local nginx_file = dir.child("nginx.ssl.conf") - local key_file = dir.child(domain..".key") - local key_file_str = key_file.canonical().to_string() - local csr_file = dir.child(domain..".csr") - local csr_file_str = csr_file.canonical().to_string() - local local_cer_file = dir.child("fullchain.cer") - local local_cer_file_str = local_cer_file.canonical().to_string() - local local_ca_file = dir.child("ca.cer") - local top_dir = uri("file:.").canonical().to_string() + local site_dir = uri("site:").parent() + local nginx_file = site_dir.child("nginx.ssl.conf") + local key_file = site_dir.child(domain..".key") + local key_file_str = key_file.canonical().to_string() + local csr_file = site_dir.child(domain..".csr") + local csr_file_str = csr_file.canonical().to_string() + local local_cer_file = site_dir.child("fullchain.cer") + local local_cer_file_str = local_cer_file.canonical().to_string() + local local_ca_file = site_dir.child("ca.cer") + -- luan/host + local luanhost_dir = uri("file:.").canonical().to_string() local changed = false - -- use for testing, so as to not hit rate limits - -- on the real letsencrypt servers - local dry_run = true + -- use for testing, so as to not hit rate limits + -- on the real letsencrypt servers + local dry_run = true + local dry_run_dir_url = "https://acme-staging-v02.api.letsencrypt.org/directory" if is_https then -- https if not key_file.exists() then local is_local = ip(domain) == "127.0.0.1" logger.info("is_local "..is_local) - -- Use openssl directly to make a self-signed cert, - -- no external cert authority involved + -- Use openssl directly to make a self-signed cert, + -- no external cert authority involved if is_local then - -- set up a temporary barebones nginx conf - -- to serve acme challenges on the domain + local cmd = [[ + ./local_https.sh "]]..domain..[[" + ]] + local s = uri("bash:"..cmd).read_text() + logger.info("issue local certificate") + else + -- set up a temporary barebones nginx conf + -- to serve acme challenges on the domain - local temp_dir_string = "/tmp/acme_setup/"..domain + local temp_dir_string = "/tmp/acme_setup/"..domain - -- recursion guard, must have this to prevent - -- the http request from invoking this code - -- and causing an infinite recursion. - local guard_file = temp_dir_string.."/recursionguard.lock" - local guard_uri = uri("file:"..guard_file) - if guard_uri.exists() then - logger.info("set_https already running for "..domain..", skipping") - return - end + -- recursion guard, must have this to prevent + -- the http request from invoking this code + -- and causing an infinite recursion. + local cmd = "mkdir -p /tmp/acme_setup_locks/" + local s = uri("bash:"..cmd).read_text() + local guard_file = "/tmp/acme_setup_locks/"..domain..".lock" + local guard_uri = uri("file:"..guard_file) + if guard_uri.exists() then + logger.info("set_https already running for "..domain..", skipping") + return + end - -- Clean out old temp files - local cmd = "rm -rf "..temp_dir_string + -- Clean out old temp files + local cmd = "rm -rf "..temp_dir_string local s = uri("bash:"..cmd).read_text() - -- create all the dirs needed - local webroot = temp_dir_string.."/webroot" - local acme_challenges = webroot.."/.well-known/acme-challenge" - local cmd = "mkdir -p "..acme_challenges + -- create all needed dirs at once by using + -- mkdir -p on the deepest nested dir (acme-challenge) + local webroot = temp_dir_string.."/webroot" + local acme_challenges = webroot.."/.well-known/acme-challenge" + local cmd = "mkdir -p "..acme_challenges local s = uri("bash:"..cmd).read_text() - guard_uri.write("this is a recursion guard, see https.luan") + guard_uri.write("this is a recursion guard, see https.luan") - -- Create the nginx config from the template - local temp_dir = uri("file:"..temp_dir_string) - -- The *output* file, where the generated config is stored - local acme_nginx_file = temp_dir.child("nginx.acme_setup.conf") - local conf = load_file "file:startup/nginx/nginx.acme_setup.conf.luan" + -- Create the nginx config from the template + local temp_dir = uri("file:"..temp_dir_string) + -- The *output* file, where the generated config is stored + local acme_nginx_file = temp_dir.child("nginx.acme_setup.conf") + local conf = load_file "file:startup/nginx/nginx.acme_setup.conf.luan" local acme_nginx = ` conf(webroot,domain) ` acme_nginx_file.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 'hi, testing' > "..index_file - local s = uri("bash:"..cmd).read_text() + -- Create an index.html to search for in the logs + -- to verify everything is working + local index_file = webroot.."/index.html" + local cmd = "echo 'hi, testing' > "..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 = [[ - sudo $(which nginx) -t -c "]]..top_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload; - ]] - local s = uri("bash:"..cmd).read_text() - logger.info("reload_nginx "..s) + -- 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 = [[ + sudo $(which nginx) -t -c "]]..luanhost_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload; + ]] + local s = uri("bash:"..cmd).read_text() + logger.info("reload_nginx "..s) - -- We've set up nginx to serve from our temp root, now we need to - -- create a *domain key*, which we then use to sign our cert. - local cmd = "openssl genrsa 4096 > "..key_file_str - local s = uri("bash:"..cmd).read_text() - logger.info("create domain key"..s) + -- We've set up nginx to serve from our temp root, now we need to + -- create a *domain key*, which we then use to sign our cert. + local cmd = "openssl genrsa 4096 > "..key_file_str + local s = uri("bash:"..cmd).read_text() + logger.info("create domain key\n"..s) - -- create the cert, signed with the key we just made - 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 domain key"..s) + -- create the cert, signed with the key we just made + 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) - -- Finally, get our cert signed by letsencrypt. - local cmd = [[ - python acme_tiny.py --account-key ./local/tiny_account.key \ - --csr ]]..csr_file_str..[[ \ - --acme-dir ]]..acme_challenges..[[ \ - > ./local/]]..domain..[[_signed_chain.crt - ]] - local s = uri("bash:"..cmd).read_text() - logger.info("create domain key"..s) + -- Finally, get our cert signed by letsencrypt. + local cmd = [[ + python acme_tiny.py --account-key ./local/tiny_account.key \ + --csr ]]..csr_file_str..[[ \ + --acme-dir ]]..acme_challenges..[[ \ + ]] + if dry_run then + cmd = cmd.." --directory-url "..dry_run_dir_url + end + cmd = cmd.."> "..local_cer_file_str - - - -- testing if there is an http server on the domain - -- that is serving files - local cmd = "./testhttp.sh "..domain local s = uri("bash:"..cmd).read_text() - logger.info("test if http up") - -- The above http request is the only thing that causes a recursion - -- so it is safe to delete the guard here. - guard_uri.delete() + logger.info("get cert signed by letsencrypt\n"..s) + + -- The above http requests made by acme_tiny are the only thing + -- that could cause a recursion so it is safe to delete the guard here. + guard_uri.delete() - local cmd = [[ - ./local_https.sh "]]..domain..[[" - ]] - local s = uri("bash:"..cmd).read_text() - logger.info("issue local certificate") - else - -- 1. Generate certificate - -- 2. Put it in the - local cmd = [[ - ./acme.sh --debug --issue -d "]]..domain..[[" --stateless --server letsencrypt \ - --config-home "]]..top_dir..[[/local/letsencrypt/config" \ - --key-file "]]..key_file.canonical().to_string()..[[" \ - --ca-file "]]..local_ca_file.canonical().to_string()..[[" \ - --fullchain-file "]]..local_cer_file.canonical().to_string()..[[" ; - ]] - local s = uri("bash:"..cmd).read_text() + -- We now have our certificate! + -- Now we just need to generate the nginx config + -- that uses it, place it in luan/host/sites/*/nginx.ssl.conf + -- and tell luan-host to reload nginx. + + -- local cmd = [[ + -- ./acme.sh --debug --issue -d "]]..domain..[[" --stateless --server letsencrypt \ + -- --config-home "]]..luanhost_dir..[[/local/letsencrypt/config" \ + -- --key-file "]]..key_file.canonical().to_string()..[[" \ + -- --ca-file "]]..local_ca_file.canonical().to_string()..[[" \ + -- --fullchain-file "]]..local_cer_file.canonical().to_string()..[[" ; + -- ]] + -- local s = uri("bash:"..cmd).read_text() logger.info("issue certificate "..s) end if key_file.exists() and local_cer_file.exists() then changed = true - -- the nginx config only requires 2 files: - -- fullchain.cer and DOMAIN.key + -- the nginx config only requires 2 files: + -- fullchain.cer and DOMAIN.key local conf = load_file "file:startup/nginx/nginx.ssl.conf.luan" - local nginx = ` conf(top_dir,domain) ` + local nginx = ` conf(luanhost_dir,domain) ` nginx_file.write(nginx) end end @@ -162,7 +167,7 @@ local_cer_file.delete() local_ca_file.delete() local ptn = domain.."." - for _, file in ipairs(dir.children()) do + for _, file in ipairs(site_dir.children()) do if starts_with(file.name(),ptn) then file.delete() end @@ -171,7 +176,7 @@ end if changed then local cmd = [[ -sudo $(which nginx) -t -c "]]..top_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload; +sudo $(which nginx) -t -c "]]..luanhost_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload; ]] local s = uri("bash:"..cmd).read_text() logger.info("reload_nginx "..s)
