diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 212f443..f61653d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: - centos - alpine - ubuntu - - openresty1.13 + - openresty1.21 - lua51 steps: - uses: actions/checkout@v1 diff --git a/.luacheckrc b/.luacheckrc index 2557bff..4fa48a8 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -3,7 +3,6 @@ globals = { } exclude_files = { - "lib/resty/auto-ssl/vendor/shell.lua", } max_line_length = false diff --git a/Dockerfile-test b/Dockerfile-test index b044892..a3f5642 100644 --- a/Dockerfile-test +++ b/Dockerfile-test @@ -1,9 +1,8 @@ -FROM openresty/openresty:1.15.8.1-4-centos +FROM openresty/openresty:1.21.4.1-0-centos # Runtime dependencies RUN yum -y install \ bash \ - coreutils \ curl \ diffutils \ grep \ @@ -25,8 +24,10 @@ RUN yum -y install epel-release && \ lua \ procps-ng \ redis \ - sudo \ - https://bin.equinox.io/a/6iuHhJeWypm/ngrok-2.3.34-linux-amd64.rpm + sudo +RUN curl -fsSL -o /tmp/ngrok.tar.gz https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz && \ + tar -xvf /tmp/ngrok.tar.gz -C /usr/local/bin/ && \ + rm -f /tmp/ngrok.tar.gz RUN mkdir /app WORKDIR /app diff --git a/Dockerfile-test-alpine b/Dockerfile-test-alpine index 0d2d56d..e42de6b 100644 --- a/Dockerfile-test-alpine +++ b/Dockerfile-test-alpine @@ -1,4 +1,4 @@ -FROM openresty/openresty:1.15.8.2-1-alpine-fat +FROM openresty/openresty:1.21.4.1-0-alpine-fat RUN mkdir /app WORKDIR /app @@ -27,11 +27,10 @@ RUN apk add --no-cache \ redis \ sudo \ tzdata \ - wget && \ - curl -fsSL -o /tmp/ngrok.tar.gz https://bin.equinox.io/a/naDTyS8Kyxv/ngrok-2.3.34-linux-386.tar.gz && \ + wget +RUN curl -fsSL -o /tmp/ngrok.tar.gz https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-386.tgz && \ tar -xvf /tmp/ngrok.tar.gz -C /usr/local/bin/ && \ - rm -f /tmp/ngrok.tar.gz && \ - chmod +x /usr/local/bin/ngrok + rm -f /tmp/ngrok.tar.gz COPY Makefile /app/Makefile RUN make install-test-deps diff --git a/Dockerfile-test-lua51 b/Dockerfile-test-lua51 index 4509620..bfedf12 100644 --- a/Dockerfile-test-lua51 +++ b/Dockerfile-test-lua51 @@ -1,9 +1,8 @@ -FROM openresty/openresty:1.11.2.1-centos +FROM openresty/openresty:1.21.4.1-0-centos # Runtime dependencies RUN yum -y install \ bash \ - coreutils \ curl \ diffutils \ grep \ @@ -22,8 +21,10 @@ RUN yum -y install epel-release && \ lua \ procps-ng \ redis \ - sudo \ - https://bin.equinox.io/a/6iuHhJeWypm/ngrok-2.3.34-linux-amd64.rpm + sudo +RUN curl -fsSL -o /tmp/ngrok.tar.gz https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz && \ + tar -xvf /tmp/ngrok.tar.gz -C /usr/local/bin/ && \ + rm -f /tmp/ngrok.tar.gz ENV PATH /usr/local/openresty/luajit/bin:/usr/local/openresty/bin:/usr/local/openresty/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ENV TEST_NGINX_RESOLVER 127.0.0.11 ipv6=off diff --git a/Dockerfile-test-openresty1.13 b/Dockerfile-test-openresty1.21 similarity index 74% rename from Dockerfile-test-openresty1.13 rename to Dockerfile-test-openresty1.21 index 3a285d3..6c7f3cc 100644 --- a/Dockerfile-test-openresty1.13 +++ b/Dockerfile-test-openresty1.21 @@ -1,9 +1,8 @@ -FROM openresty/openresty:1.13.6.2-2-centos +FROM openresty/openresty:1.21.4.1-0-centos # Runtime dependencies RUN yum -y install \ bash \ - coreutils \ curl \ diffutils \ grep \ @@ -22,8 +21,10 @@ RUN yum -y install epel-release && \ lua \ procps-ng \ redis \ - sudo \ - https://bin.equinox.io/a/6iuHhJeWypm/ngrok-2.3.34-linux-amd64.rpm + sudo +RUN curl -fsSL -o /tmp/ngrok.tar.gz https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz && \ + tar -xvf /tmp/ngrok.tar.gz -C /usr/local/bin/ && \ + rm -f /tmp/ngrok.tar.gz RUN mkdir /app WORKDIR /app diff --git a/Dockerfile-test-ubuntu b/Dockerfile-test-ubuntu index fff7566..9756af0 100644 --- a/Dockerfile-test-ubuntu +++ b/Dockerfile-test-ubuntu @@ -1,4 +1,4 @@ -FROM openresty/openresty:1.15.8.2-1-bionic +FROM openresty/openresty:1.21.4.1-0-jammy ENV DEBIAN_FRONTEND noninteractive @@ -6,7 +6,6 @@ ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && \ apt-get -y install \ bash \ - coreutils \ curl \ diffutils \ grep \ @@ -22,13 +21,17 @@ RUN apt-get update && \ apt-get -y install \ git \ lsof \ - lua5.2 \ + lua5.4 \ redis-server \ sudo \ - tzdata && \ - curl -fsSL -o /tmp/ngrok.deb https://bin.equinox.io/a/b2wQezFbsHk/ngrok-2.3.34-linux-amd64.deb && \ - dpkg -i /tmp/ngrok.deb || apt-get -fy install && \ - rm -f /tmp/ngrok.deb + tzdata \ + bsdmainutils +RUN curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | \ + sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \ + echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | \ + sudo tee /etc/apt/sources.list.d/ngrok.list && \ + sudo apt update && \ + sudo apt install ngrok RUN mkdir /app WORKDIR /app diff --git a/Makefile b/Makefile index 0636d73..7b8641f 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) BUILD_DIR?=$(ROOT_DIR)/build -DEHYDRATED_VERSION:=05eda91a2fbaed1e13c733230238fc68475c535e -LUA_RESTY_SHELL_VERSION:=955243d70506c21e7cc29f61d745d1a8a718994f -SOCKPROC_VERSION:=92aba736027bb5d96e190b71555857ac5bb6b2be +DEHYDRATED_VERSION:=ea841998631561543357f032fa7c06598c34d517 RUNTIME_DEPENDENCIES:=bash curl cut date diff grep mktemp openssl sed @@ -18,9 +16,7 @@ RUNTIME_DEPENDENCIES:=bash curl cut date diff grep mktemp openssl sed all: \ check-dependencies \ - $(BUILD_DIR)/stamp-dehydrated-2-$(DEHYDRATED_VERSION) \ - $(BUILD_DIR)/stamp-lua-resty-shell-$(LUA_RESTY_SHELL_VERSION) \ - $(BUILD_DIR)/stamp-sockproc-2-$(SOCKPROC_VERSION) + $(BUILD_DIR)/stamp-dehydrated-2-$(DEHYDRATED_VERSION) check-dependencies: $(foreach bin,$(RUNTIME_DEPENDENCIES),\ @@ -51,14 +47,9 @@ install: check-dependencies install -m 644 lib/resty/auto-ssl/utils/random_seed.lua $(INST_LUADIR)/resty/auto-ssl/utils/random_seed.lua install -m 644 lib/resty/auto-ssl/utils/shell_execute.lua $(INST_LUADIR)/resty/auto-ssl/utils/shell_execute.lua install -m 644 lib/resty/auto-ssl/utils/shuffle_table.lua $(INST_LUADIR)/resty/auto-ssl/utils/shuffle_table.lua - install -m 644 lib/resty/auto-ssl/utils/start_sockproc.lua $(INST_LUADIR)/resty/auto-ssl/utils/start_sockproc.lua - install -d $(INST_LUADIR)/resty/auto-ssl/vendor - install -m 644 lib/resty/auto-ssl/vendor/shell.lua $(INST_LUADIR)/resty/auto-ssl/vendor/shell.lua install -d $(INST_BINDIR)/resty-auto-ssl install -m 755 bin/letsencrypt_hooks $(INST_BINDIR)/resty-auto-ssl/letsencrypt_hooks - install -m 755 bin/start_sockproc $(INST_BINDIR)/resty-auto-ssl/start_sockproc install -m 755 $(BUILD_DIR)/bin/dehydrated $(INST_BINDIR)/resty-auto-ssl/dehydrated - install -m 755 $(BUILD_DIR)/bin/sockproc $(INST_BINDIR)/resty-auto-ssl/sockproc $(BUILD_DIR): mkdir -p $@ @@ -70,21 +61,6 @@ $(BUILD_DIR)/stamp-dehydrated-2-$(DEHYDRATED_VERSION): | $(BUILD_DIR) chmod +x $(BUILD_DIR)/bin/dehydrated touch $@ -$(BUILD_DIR)/stamp-lua-resty-shell-$(LUA_RESTY_SHELL_VERSION): | $(BUILD_DIR) - rm -f $(BUILD_DIR)/stamp-lua-resty-shell-* - curl -sSLo $(ROOT_DIR)/lib/resty/auto-ssl/vendor/shell.lua "https://raw.githubusercontent.com/juce/lua-resty-shell/$(LUA_RESTY_SHELL_VERSION)/lib/resty/shell.lua" - touch $@ - -$(BUILD_DIR)/stamp-sockproc-2-$(SOCKPROC_VERSION): | $(BUILD_DIR) - rm -f $(BUILD_DIR)/stamp-sockproc-* - mkdir -p $(BUILD_DIR)/bin - cd $(BUILD_DIR) && curl -sSLo sockproc-$(SOCKPROC_VERSION).tar.gz "https://github.com/juce/sockproc/archive/$(SOCKPROC_VERSION).tar.gz" - cd $(BUILD_DIR) && tar -xf sockproc-$(SOCKPROC_VERSION).tar.gz - cd $(BUILD_DIR)/sockproc-$(SOCKPROC_VERSION) && make - cp $(BUILD_DIR)/sockproc-$(SOCKPROC_VERSION)/sockproc $(BUILD_DIR)/bin/sockproc - chmod +x $(BUILD_DIR)/bin/sockproc - touch $@ - # # Testing # @@ -95,11 +71,11 @@ install-test-deps: luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install busted 2.0.0-1 luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install etlua 1.3.0-1 luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install inspect 3.1.1-0 - luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install lua-resty-http 0.15-0 + luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install lua-resty-http 0.17.1-0 luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install luacheck 0.23.0-1 luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install luaposix 34.1.1-1 luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install penlight 1.5.4-1 - luarocks install luarocks-fetch-gitrec && luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install process 1.9.0-1 + luarocks install luarocks-fetch-gitrec && luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install process 1.9.1-1 luarocks --tree=/tmp/resty-auto-ssl-test-luarocks install shell-games 1.0.1-1 lint: diff --git a/README.md b/README.md index 8e71aee..b4bc2ec 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This OpenResty plugin automatically and transparently issues SSL certificates fr - If the system already has a SSL certificate for that domain, it is immediately returned (with OCSP stapling). - If the system does not yet have an SSL certificate for this domain, it issues a new SSL certificate from Let's Encrypt. Domain validation is handled for you. After receiving the new certificate (usually within a few seconds), the new certificate is saved, cached, and returned to the client (without dropping the original request). -This uses the `ssl_certificate_by_lua` functionality in OpenResty 1.9.7.2+. +This uses the `ssl_certificate_by_lua` functionality. By using lua-resty-auto-ssl to register SSL certificates with Let's Encrypt, you agree to the [Let's Encrypt Subscriber Agreement](https://letsencrypt.org/repository/). @@ -22,9 +22,7 @@ Used in production (but the internal APIs might still be in flux). Requirements: -- [OpenResty](http://openresty.org/#Download) 1.9.7.2 or higher - - **Recommended:** OpenResty 1.15.8.1 or higher is recommended for best performance and stability. - - Or nginx patched with [ssl_cert_cb_yield](https://github.com/openresty/openresty/blob/v1.11.2.2/patches/nginx-1.11.2-ssl_cert_cb_yield.patch) and built with [ngx_lua](https://github.com/openresty/lua-nginx-module#installation) 0.10.0 or higher +- [OpenResty](http://openresty.org/#Download) 1.15.8.1 or higher - OpenSSL 1.0.2e or higher - [LuaRocks](http://openresty.org/#UsingLuaRocks) - gcc, make (for initial install via LuaRocks) @@ -413,4 +411,4 @@ To release a new version to LuaRocks: - Document and formalize the API for other storage adapters. - Open source the MongoDB storage adapter we're using in API Umbrella. - Add the ability to encrypt data at rest for any storage adapter (based on what we built for API Umbrella's MongoDB storage adapter). -- We currently rely on [dehydrated](https://github.com/lukas2511/dehydrated) as our Let's Encrypt client. It's called in a non-blocking fashion via [lua-resty-shell](https://github.com/juce/lua-resty-shell) and [sockproc](https://github.com/juce/sockproc), however it might be simpler to eventually replace this approach with a native OpenResty Let's Encrypt client someday. +- We currently rely on [dehydrated](https://github.com/lukas2511/dehydrated) as our Let's Encrypt client. It's called in a non-blocking fashion via [lua-resty-shell](https://github.com/openresty/lua-resty-shell), however it might be simpler to eventually replace this approach with a native OpenResty Let's Encrypt client someday. diff --git a/bin/start_sockproc b/bin/start_sockproc deleted file mode 100755 index a9ef037..0000000 --- a/bin/start_sockproc +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env bash - -set -Eeuo pipefail - -sock_file=/tmp/shell.sock -pid_file=/tmp/auto-ssl-sockproc.pid - -# This script inherits the current directory from wherever nginx is launched, -# which may be a private directory. To prevent the "find" command below from -# generating "failed to restore initial working directory: Permission denied" -# errors, change to the root directory where the nginx user will have -# permissions. -cd / || (echo "WARNING: start_sockproc could not set current directory to /" 1>&2) - -# We want to launch sockproc from inside nginx using os.execute (mainly just to -# simplify the deployment of auto-ssl, so you don't have to worry about running -# sockproc). But we need to clear the file descriptors we pass to sockproc, or -# else when nginx is stopped, sockproc inherits the port nginx was listening to, -# and then sockproc holds that port open, preventing nginx from starting -# again. -# -# This wipes any file descriptors > 2 that nginx might pass along (so only -# stdin, stdout, and stderr are retained). -# -# See: -# http://stackoverflow.com/a/4839945/222487 -# http://stackoverflow.com/a/23104923/222487 -file_descriptors_cleared="false" -if [ -d /proc ]; then - current_pid=$BASHPID - file_descriptors=$(find /proc/"$current_pid"/fd -type l) - for fd_path in $file_descriptors; do - # Extract just the fd number from the end of the path. - fd=${fd_path##*/} - if ((fd > 2)); then - eval "exec $fd>&-" && file_descriptors_cleared="true" - fi - done -fi - -# If /proc isn't supported (eg, OS X), or an error occurred during the -# proc-based "find", then fallback to a simpler, naive mechanism to wipe file -# descriptors > 2. -if [ "$file_descriptors_cleared" != "true" ]; then - END=255 - for ((fd=3; fd <= END; fd++)); do - eval "exec $fd>&-" - done -fi - -# When nginx shuts down, the sockproc daemon continues to run. So when nginx -# subsequently starts again, we'll also make sure we restart sockproc. -if [ -e "$pid_file" ]; then - PID=$(cat "$pid_file") - kill "$PID" || true -fi - -# Just make sure the socket file is cleaned up. -rm -f "$sock_file" || true - -# Start the sockproc daemon. -bin_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -"$bin_dir"/sockproc "$sock_file" "$pid_file" diff --git a/docker-compose.yml b/docker-compose.yml index abfa231..7942fcb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -36,13 +36,13 @@ services: - ubuntu_build_cache:/app/build sysctls: net.core.somaxconn: 1024 - openresty1.13: + openresty1.21: build: context: . - dockerfile: Dockerfile-test-openresty1.13 + dockerfile: Dockerfile-test-openresty1.21 volumes: - .:/app - - openresty1.13_build_cache:/app/build + - openresty1.21_build_cache:/app/build sysctls: net.core.somaxconn: 1024 lua51: @@ -59,5 +59,5 @@ volumes: centos_build_cache: alpine_build_cache: ubuntu_build_cache: - openresty1.13_build_cache: + openresty1.21_build_cache: lua51_build_cache: diff --git a/lib/resty/auto-ssl/init_worker.lua b/lib/resty/auto-ssl/init_worker.lua index e2fce9b..e509a5a 100644 --- a/lib/resty/auto-ssl/init_worker.lua +++ b/lib/resty/auto-ssl/init_worker.lua @@ -1,7 +1,6 @@ local random_seed = require "resty.auto-ssl.utils.random_seed" local renewal_job = require "resty.auto-ssl.jobs.renewal" local shell_blocking = require "shell-games" -local start_sockproc = require "resty.auto-ssl.utils.start_sockproc" return function(auto_ssl_instance) local base_dir = auto_ssl_instance:get("dir") @@ -19,18 +18,6 @@ return function(auto_ssl_instance) -- call in the init_worker phase. random_seed() - -- Startup sockproc. This background process allows for non-blocking shell - -- commands with resty.shell. - -- - -- We do this in the init_worker phase, so that it will always be started - -- with the same permissions as the nginx workers (and not the elevated - -- permissions of the nginx master process). - -- - -- If we implement a native resty Let's Encrypt ACME client (rather than - -- relying on dehydrated), then we could get rid of the need for this - -- background process, which would be nice. - start_sockproc() - local storage = auto_ssl_instance.storage local storage_adapter = storage.adapter if storage_adapter.setup_worker then diff --git a/lib/resty/auto-ssl/ssl_certificate.lua b/lib/resty/auto-ssl/ssl_certificate.lua index ab71cfd..22a1d29 100644 --- a/lib/resty/auto-ssl/ssl_certificate.lua +++ b/lib/resty/auto-ssl/ssl_certificate.lua @@ -207,9 +207,24 @@ local function get_ocsp_response(fullchain_der, auto_ssl_instance) return ocsp_resp end -local function set_ocsp_stapling(domain, cert_der, auto_ssl_instance) - -- Fetch the OCSP stapling response from the cache, or make the request to - -- fetch it. +local function get_ocsp_response_unlock(local_lock) + local _, local_unlock_err = local_lock:unlock() + if local_unlock_err then + ngx.log(ngx.ERR, "auto-ssl: failed to unlock: ", local_unlock_err) + end +end + +local function get_ocsp_response_lock(domain, cert_der, auto_ssl_instance) + -- Before issuing a cert, create a local lock to ensure multiple workers + -- don't simultaneously try to get OCSP response for the same cert. + local local_lock, new_local_lock_err = lock:new("auto_ssl", { exptime = 30, timeout = 5 }) + if new_local_lock_err then + return nil, "auto-ssl: failed to create lock: " .. (new_local_lock_err or "") + end + local _, local_lock_err = local_lock:lock("set_ocsp_stapling:" .. domain) + if local_lock_err then + return nil, "auto-ssl: failed to obtain lock: " .. (local_lock_err or "") + end local ocsp_resp = ngx.shared.auto_ssl:get("domain:ocsp:" .. domain) if not ocsp_resp then -- If the certificate was just issued on the current request, wait 1 second @@ -222,7 +237,8 @@ local function set_ocsp_stapling(domain, cert_der, auto_ssl_instance) local ocsp_response_err ocsp_resp, ocsp_response_err = get_ocsp_response(cert_der["fullchain_der"], auto_ssl_instance) if ocsp_response_err then - return false, "failed to get ocsp response: " .. (ocsp_response_err or "") + get_ocsp_response_unlock(local_lock) + return nil, "failed to get ocsp response: " .. (ocsp_response_err or "") end -- Cache the OCSP stapling response for 1 hour (this is what nginx does by @@ -235,6 +251,23 @@ local function set_ocsp_stapling(domain, cert_der, auto_ssl_instance) end end + get_ocsp_response_unlock(local_lock) + + return ocsp_resp +end + +local function set_ocsp_stapling(domain, cert_der, auto_ssl_instance) + -- Fetch the OCSP stapling response from the cache, or make the request to + -- fetch it. + local ocsp_resp = ngx.shared.auto_ssl:get("domain:ocsp:" .. domain) + if not ocsp_resp then + local ocsp_response_err + ocsp_resp, ocsp_response_err = get_ocsp_response_lock(domain, cert_der, auto_ssl_instance) + if not ocsp_resp then + return false, ocsp_response_err + end + end + -- Set the OCSP stapling response. local ok, ocsp_status_err = ocsp.set_ocsp_status_resp(ocsp_resp) if not ok then diff --git a/lib/resty/auto-ssl/ssl_providers/lets_encrypt.lua b/lib/resty/auto-ssl/ssl_providers/lets_encrypt.lua index 570432f..b2b16d7 100644 --- a/lib/resty/auto-ssl/ssl_providers/lets_encrypt.lua +++ b/lib/resty/auto-ssl/ssl_providers/lets_encrypt.lua @@ -23,7 +23,7 @@ function _M.issue_cert(auto_ssl_instance, domain) -- -- Disable dehydrated's locking, since we perform our own domain-specific -- locking using the storage adapter. - local result, err = shell_execute({ + local result = shell_execute({ "env", "HOOK_SECRET=" .. hook_secret, "HOOK_SERVER_PORT=" .. hook_port, @@ -43,8 +43,8 @@ function _M.issue_cert(auto_ssl_instance, domain) -- (in which case these files aren't of much additional use). _M.cleanup(auto_ssl_instance, domain) - if result["status"] ~= 0 then - ngx.log(ngx.ERR, "auto-ssl: dehydrated failed: ", result["command"], " status: ", result["status"], " out: ", result["output"], " err: ", err) + if not result["ok"] then + ngx.log(ngx.ERR, "auto-ssl: dehydrated failed: ", result["command"], " status: ", result["status"], " out: ", result["output"], " err: ", result["err"]) return nil, "dehydrated failure" end @@ -71,9 +71,9 @@ function _M.cleanup(auto_ssl_instance, domain) assert(string.find(domain, "%.%.") == nil) local dir = auto_ssl_instance:get("dir") .. "/letsencrypt/certs/" .. domain - local _, rm_err = shell_execute({ "rm", "-rf", dir }) - if rm_err then - ngx.log(ngx.ERR, "auto-ssl: failed to cleanup certs: ", rm_err) + local result = shell_execute({ "rm", "-rf", dir }) + if not result["ok"] then + ngx.log(ngx.ERR, "auto-ssl: failed to cleanup certs: ", result["err"]) end end diff --git a/lib/resty/auto-ssl/utils/shell_execute.lua b/lib/resty/auto-ssl/utils/shell_execute.lua index bb689c6..6b5373e 100644 --- a/lib/resty/auto-ssl/utils/shell_execute.lua +++ b/lib/resty/auto-ssl/utils/shell_execute.lua @@ -1,44 +1,17 @@ -local shell = require "resty.auto-ssl.vendor.shell" +local shell = require "resty.shell" local shell_join = require("shell-games").join -local start_sockproc = require "resty.auto-ssl.utils.start_sockproc" return function(args) - -- Make sure the sockproc has started before trying to execute any commands - -- (since it's started by only a single worker in init_worker, it's possible - -- other workers have already finished their init_worker phases before the - -- process is actually started). - if not ngx.shared.auto_ssl_settings:get("sockproc_started") then - start_sockproc() - - local wait_time = 0 - local sleep_time = 0.01 - local max_time = 5 - while not ngx.shared.auto_ssl_settings:get("sockproc_started") do - ngx.sleep(sleep_time) - wait_time = wait_time + sleep_time - - if wait_time > max_time then - ngx.log(ngx.ERR, "auto-ssl: sockproc did not start in expected amount of time") - break - end - end - end - - local options = { timeout = 60000 } local command = shell_join(args) - local status, out, err = shell.execute(command, options) - - -- If the script fails due to a missing sockproc socket, try starting up - -- the sockproc process again and then retry. - if status ~= 0 and err == "no such file or directory" then - ngx.log(ngx.ERR, "auto-ssl: sockproc unexpectedly not available, trying to restart") - start_sockproc(true) - status, out, err = shell.execute(command, options) - end + local ok, stdout, stderr, reason, status = + shell.run(command, nil, 60000) return { + ok = ok, + reason = reason, command = command, status = status, - output = out, - }, err + output = stdout, + err = stderr + } end diff --git a/lib/resty/auto-ssl/utils/start_sockproc.lua b/lib/resty/auto-ssl/utils/start_sockproc.lua deleted file mode 100644 index 96f44f5..0000000 --- a/lib/resty/auto-ssl/utils/start_sockproc.lua +++ /dev/null @@ -1,50 +0,0 @@ -local auto_ssl = require "resty.auto-ssl" -local lock = require "resty.lock" -local shell_blocking = require "shell-games" - -local function start() - local _, set_false_err = ngx.shared.auto_ssl_settings:safe_set("sockproc_started", false) - if set_false_err then - ngx.log(ngx.ERR, "auto-ssl: failed to set shdict for sockproc_started: ", set_false_err) - end - - ngx.log(ngx.NOTICE, "auto-ssl: starting sockproc") - - local _, run_err = shell_blocking.capture_combined({ auto_ssl.lua_root .. "/bin/resty-auto-ssl/start_sockproc" }, { umask = "0022" }) - if run_err then - ngx.log(ngx.ERR, "auto-ssl: failed to start sockproc: ", run_err) - else - local _, set_err = ngx.shared.auto_ssl_settings:safe_set("sockproc_started", true) - if set_err then - ngx.log(ngx.ERR, "auto-ssl: failed to set shdict for sockproc_started: ", set_err) - end - end -end - -return function(force) - if ngx.shared.auto_ssl_settings:get("sockproc_started") and not force then - return - end - - -- Add lock to ensure only a single start command is attempted at a time. - local start_lock, new_lock_err = lock:new("auto_ssl_settings", { exptime = 600, timeout = 0 }) - if new_lock_err then - ngx.log(ngx.ERR, "Failed to create lock: ", new_lock_err) - return - end - - local _, lock_err = start_lock:lock("start_sockproc") - if lock_err then - return - end - - local ok, err = pcall(start) - if not ok then - ngx.log(ngx.ERR, "auto-ssl: failed to run start_sockproc: ", err) - end - - local unlock_ok, unlock_err = start_lock:unlock() - if not unlock_ok then - ngx.log(ngx.ERR, "auto-ssl: failed to unlock: ", unlock_err) - end -end diff --git a/spec/certs/letsencrypt-stg-root-x1.pem b/spec/certs/letsencrypt-stg-root-x1.pem new file mode 100644 index 0000000..37655b2 --- /dev/null +++ b/spec/certs/letsencrypt-stg-root-x1.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFmDCCA4CgAwIBAgIQU9C87nMpOIFKYpfvOHFHFDANBgkqhkiG9w0BAQsFADBm +MQswCQYDVQQGEwJVUzEzMDEGA1UEChMqKFNUQUdJTkcpIEludGVybmV0IFNlY3Vy +aXR5IFJlc2VhcmNoIEdyb3VwMSIwIAYDVQQDExkoU1RBR0lORykgUHJldGVuZCBQ +ZWFyIFgxMB4XDTE1MDYwNDExMDQzOFoXDTM1MDYwNDExMDQzOFowZjELMAkGA1UE +BhMCVVMxMzAxBgNVBAoTKihTVEFHSU5HKSBJbnRlcm5ldCBTZWN1cml0eSBSZXNl +YXJjaCBHcm91cDEiMCAGA1UEAxMZKFNUQUdJTkcpIFByZXRlbmQgUGVhciBYMTCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALbagEdDTa1QgGBWSYkyMhsc +ZXENOBaVRTMX1hceJENgsL0Ma49D3MilI4KS38mtkmdF6cPWnL++fgehT0FbRHZg +jOEr8UAN4jH6omjrbTD++VZneTsMVaGamQmDdFl5g1gYaigkkmx8OiCO68a4QXg4 +wSyn6iDipKP8utsE+x1E28SA75HOYqpdrk4HGxuULvlr03wZGTIf/oRt2/c+dYmD +oaJhge+GOrLAEQByO7+8+vzOwpNAPEx6LW+crEEZ7eBXih6VP19sTGy3yfqK5tPt +TdXXCOQMKAp+gCj/VByhmIr+0iNDC540gtvV303WpcbwnkkLYC0Ft2cYUyHtkstO +fRcRO+K2cZozoSwVPyB8/J9RpcRK3jgnX9lujfwA/pAbP0J2UPQFxmWFRQnFjaq6 +rkqbNEBgLy+kFL1NEsRbvFbKrRi5bYy2lNms2NJPZvdNQbT/2dBZKmJqxHkxCuOQ +FjhJQNeO+Njm1Z1iATS/3rts2yZlqXKsxQUzN6vNbD8KnXRMEeOXUYvbV4lqfCf8 +mS14WEbSiMy87GB5S9ucSV1XUrlTG5UGcMSZOBcEUpisRPEmQWUOTWIoDQ5FOia/ +GI+Ki523r2ruEmbmG37EBSBXdxIdndqrjy+QVAmCebyDx9eVEGOIpn26bW5LKeru +mJxa/CFBaKi4bRvmdJRLAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBS182Xy/rAKkh/7PH3zRKCsYyXDFDANBgkqhkiG +9w0BAQsFAAOCAgEAncDZNytDbrrVe68UT6py1lfF2h6Tm2p8ro42i87WWyP2LK8Y +nLHC0hvNfWeWmjZQYBQfGC5c7aQRezak+tHLdmrNKHkn5kn+9E9LCjCaEsyIIn2j +qdHlAkepu/C3KnNtVx5tW07e5bvIjJScwkCDbP3akWQixPpRFAsnP+ULx7k0aO1x +qAeaAhQ2rgo1F58hcflgqKTXnpPM02intVfiVVkX5GXpJjK5EoQtLceyGOrkxlM/ +sTPq4UrnypmsqSagWV3HcUlYtDinc+nukFk6eR4XkzXBbwKajl0YjztfrCIHOn5Q +CJL6TERVDbM/aAPly8kJ1sWGLuvvWYzMYgLzDul//rUF10gEMWaXVZV51KpS9DY/ +5CunuvCXmEQJHo7kGcViT7sETn6Jz9KOhvYcXkJ7po6d93A/jy4GKPIPnsKKNEmR +xUuXY4xRdh45tMJnLTUDdC9FIU0flTeO9/vNpVA8OPU1i14vCz+MU8KX1bV3GXm/ +fxlB7VBBjX9v5oUep0o/j68R/iDlCOM4VVfRa8gX6T2FU7fNdatvGro7uQzIvWof +gN9WUwCbEMBy/YhBSrXycKA8crgGg3x1mIsopn88JKwmMBa68oS7EHM9w7C4y71M +7DiA+/9Qdp9RBWJpTS9i/mDnJg1xvo8Xz49mrrgfmcAXTCJqXi24NatI3Oc= +-----END CERTIFICATE----- diff --git a/spec/certs/letsencrypt_staging_chain.pem b/spec/certs/letsencrypt_staging_chain.pem deleted file mode 100644 index 1c458f4..0000000 --- a/spec/certs/letsencrypt_staging_chain.pem +++ /dev/null @@ -1,56 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFATCCAumgAwIBAgIRAKc9ZKBASymy5TLOEp57N98wDQYJKoZIhvcNAQELBQAw -GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDMyMzIyNTM0NloXDTM2 -MDMyMzIyNTM0NlowGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMIICIjANBgkq -hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+pYHvQw5iU3v2b3iNuYNKYgsWD6KU7aJ -diddtZQxSWYzUI3U0I1UsRPTxnhTifs/M9NW4ZlV13ZfB7APwC8oqKOIiwo7IwlP -xg0VKgyz+kT8RJfYr66PPIYP0fpTeu42LpMJ+CKo9sbpgVNDZN2z/qiXrRNX/VtG -TkPV7a44fZ5bHHVruAxvDnylpQxJobtCBWlJSsbIRGFHMc2z88eUz9NmIOWUKGGj -EmP76x8OfRHpIpuxRSCjn0+i9+hR2siIOpcMOGd+40uVJxbRRP5ZXnUFa2fF5FWd -O0u0RPI8HON0ovhrwPJY+4eWKkQzyC611oLPYGQ4EbifRsTsCxUZqyUuStGyp8oa -aoSKfF6X0+KzGgwwnrjRTUpIl19A92KR0Noo6h622OX+4sZiO/JQdkuX5w/HupK0 -A0M0WSMCvU6GOhjGotmh2VTEJwHHY4+TUk0iQYRtv1crONklyZoAQPD76hCrC8Cr -IbgsZLfTMC8TWUoMbyUDgvgYkHKMoPm0VGVVuwpRKJxv7+2wXO+pivrrUl2Q9fPe -Kk055nJLMV9yPUdig8othUKrRfSxli946AEV1eEOhxddfEwBE3Lt2xn0hhiIedbb -Ftf/5kEWFZkXyUmMJK8Ra76Kus2ABueUVEcZ48hrRr1Hf1N9n59VbTUaXgeiZA50 -qXf2bymE6F8CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wHQYDVR0OBBYEFMEmdKSKRKDm+iAo2FwjmkWIGHngMA0GCSqGSIb3DQEBCwUA -A4ICAQBCPw74M9X/Xx04K1VAES3ypgQYH5bf9FXVDrwhRFSVckria/7dMzoF5wln -uq9NGsjkkkDg17AohcQdr8alH4LvPdxpKr3BjpvEcmbqF8xH+MbbeUEnmbSfLI8H -sefuhXF9AF/9iYvpVNC8FmJ0OhiVv13VgMQw0CRKkbtjZBf8xaEhq/YqxWVsgOjm -dm5CAQ2X0aX7502x8wYRgMnZhA5goC1zVWBVAi8yhhmlhhoDUfg17cXkmaJC5pDd -oenZ9NVhW8eDb03MFCrWNvIh89DDeCGWuWfDltDq0n3owyL0IeSn7RfpSclpxVmV -/53jkYjwIgxIG7Gsv0LKMbsf6QdBcTjhvfZyMIpBRkTe3zuHd2feKzY9lEkbRvRQ -zbh4Ps5YBnG6CKJPTbe2hfi3nhnw/MyEmF3zb0hzvLWNrR9XW3ibb2oL3424XOwc -VjrTSCLzO9Rv6s5wi03qoWvKAQQAElqTYRHhynJ3w6wuvKYF5zcZF3MDnrVGLbh1 -Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4 -8iyIYUyQAbsvx8oD2M8kRvrIRSrRJSl6L957b4AFiLIQ/GgV2curs0jje7Edx34c -idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEqTCCApGgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+QwDQYJKoZIhvcNAQELBQAw -GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDMyMzIyNTkwNFoXDTM2 -MDMyMzIyNTkwNFowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0 -8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym -oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0 -ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN -xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56 -dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9 -AgMBAAGjgeEwgd4wDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw -HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHgGCCsGAQUFBwEBBGwwajAz -BggrBgEFBQcwAYYnaHR0cDovL29jc3Auc3RnLWludC14MS5sZXRzZW5jcnlwdC5v -cmcvMDMGCCsGAQUFBzAChidodHRwOi8vY2VydC5zdGctaW50LXgxLmxldHNlbmNy -eXB0Lm9yZy8wHwYDVR0jBBgwFoAUwSZ0pIpEoOb6ICjYXCOaRYgYeeAwDQYJKoZI -hvcNAQELBQADggIBAHODDwZVaO5EqEYoVvEPPzaZas5BNVRHUAdc+xNg4oKACBAW -o3mnX1tKr9lsWSDxLrCE7y+mdRq37PKzapEaL1q8KYXgzI1Ua7JeyOvCs4IMmhSZ -HLSJMFgAv77nD28kB6teMlJI+NxmvD5cmsDl+1C2D862DFuiy3R/80c++ZIqfWg3 -CvsQmwx0bategh3cT8mPwQEdRW0LpgomT37kSxZSGn9TzPXQ+NSvD/CpEF0mVQWM -09aiOE3QWg8BpdzxpbbmEhtWv4MNU1U3iyYNjaPzqD1J3R/7IjJmsNbDY5XKoqIB -AeHPisSzP8CdCwQpJC8rBDefUfrbYqvhWuCff+amrUe01nvp9jtWefwUWWSwcjEg -xYwz2vt6TgLNw5wBWk854x6yc323se/Wp7u7F9lguCRIUMPVH9MfBzR1wyUfpbZa -eFVPFkHQsKv5ydKNQlk8fO97xXhpK4yueMNLnjbWEDKnEvJtCsbqlQm3XHWvqhz9 -B/V1c95n8Z9Av2uVZ5HvZKnA9OXi4WF1ES6hkiFzom/exWxBxd+skh6yJuX1edpX -L5TSN5XTa5OPONWh3AQfz7/0aenJNhyPJ4687pwQpGir4ctvT1k3enSRNqO6Vwxv -0BB50f7tpC0k/XzGyQyCVXo6jjDv1057VbZTUB+Y7BzXvcm7aglHPA71K3nW ------END CERTIFICATE----- diff --git a/spec/config/busted-nginx.conf b/spec/config/busted-nginx.conf index c21b5c7..4ff94c1 100644 --- a/spec/config/busted-nginx.conf +++ b/spec/config/busted-nginx.conf @@ -1,3 +1,3 @@ -lua_ssl_trusted_certificate /app/spec/certs/letsencrypt_staging_chain.pem; +lua_ssl_trusted_certificate /app/spec/certs/letsencrypt-stg-root-x1.pem; lua_ssl_verify_depth 5; lua_shared_dict test_counts 128k; diff --git a/spec/proxy_spec.lua b/spec/proxy_spec.lua index 8c7c2b3..726d700 100644 --- a/spec/proxy_spec.lua +++ b/spec/proxy_spec.lua @@ -44,7 +44,7 @@ describe("proxy", function() local error_log = server.read_error_log() assert.matches("auto-ssl: issuing new certificate for " .. server.ngrok_hostname, error_log, nil, true) assert.matches("http proxy auth: Basic ZGVtbzp0ZXN0", error_log, nil, true) - assert.matches("auto-ssl: failed to set ocsp stapling for " .. server.ngrok_hostname .. " - continuing anyway - failed to get ocsp response: OCSP responder returns bad response body (http://ocsp.stg-int-x1.letsencrypt.org): ,", error_log, nil, true) + assert.matches("auto-ssl: failed to set ocsp stapling for " .. server.ngrok_hostname .. " - continuing anyway - failed to get ocsp response: OCSP responder returns bad response body (http://stg-e1.o.lencr.org): ,", error_log, nil, true) assert.Not.matches("[warn]", error_log, nil, true) assert.matches("[error]", error_log, nil, true) assert.Not.matches("[alert]", error_log, nil, true) diff --git a/spec/sockproc_file_descriptors_spec.lua b/spec/sockproc_file_descriptors_spec.lua deleted file mode 100644 index 21d30b2..0000000 --- a/spec/sockproc_file_descriptors_spec.lua +++ /dev/null @@ -1,150 +0,0 @@ -local cjson = require "cjson.safe" -local http = require "resty.http" -local server = require "spec.support.server" -local shell_blocking = require "shell-games" - -local function get_sockproc_file_descriptors(as_user, expect_no_results) - local result, shell_err = shell_blocking.capture({ "sudo", "-u", as_user, "lsof", "-n", "-P", "-l", "-R", "-c", "sockproc", "-a", "-d", "0-255", "-F", "pnf" }) - if expect_no_results and shell_err and result["output"] == "" then - return {} - end - assert.equal(nil, shell_err) - - local lines = {} - local index = 1 - for line in string.gmatch(result["output"], "[^\n]+") do - if index > 1 then - local _, err - line, _, err = ngx.re.sub(line, "\\s*type=STREAM", "") - assert.equal(nil, err) - - line, _, err = ngx.re.sub(line, "^n/.*logs/error.log$", "n/dev/null") - assert.equal(nil, err) - - table.insert(lines, line) - end - - index = index + 1 - end - - return lines -end - -describe("sockproc file descriptors", function() - before_each(server.stop) - after_each(server.stop) - - it("does not inherit nginx file descriptors", function() - server.start({ - auto_ssl_http_server_config = [[ - location /get-lua-root { - content_by_lua_block { - local cjson = require "cjson.safe" - ngx.print(cjson.encode({ - lua_root = auto_ssl.lua_root, - })) - } - } - ]], - }) - - local httpc = http.new() - local res, err = httpc:request_uri("http://127.0.0.1:9080/get-lua-root") - assert.equal(nil, err) - assert.equal(200, res.status) - local data, json_err = cjson.decode(res.body) - assert.equal(nil, json_err) - local lua_root = data["lua_root"] - assert.String(lua_root) - - -- Already running - assert.same({ - "f0", "n/dev/null", - "f1", "n/dev/null", - "f2", "n/dev/null", - "f3", "n/tmp/shell.sock", - }, get_sockproc_file_descriptors("root")) - - -- sockproc not running - server.stop_sockproc() - assert.same({}, get_sockproc_file_descriptors("root", true)) - - -- current dir as current user - server.stop_sockproc() - shell_blocking.capture_combined({ lua_root .. "/bin/resty-auto-ssl/start_sockproc" }, { umask = "0022" }) - assert.same({ - "f0", "n/dev/null", - "f1", "n/dev/null", - "f2", "n/dev/null", - "f3", "n/tmp/shell.sock", - }, get_sockproc_file_descriptors("root")) - - -- /tmp dir as current user - server.stop_sockproc() - shell_blocking.capture_combined({ lua_root .. "/bin/resty-auto-ssl/start_sockproc" }, { umask = "0022", chdir = "/tmp" }) - assert.same({ - "f0", "n/dev/null", - "f1", "n/dev/null", - "f2", "n/dev/null", - "f3", "n/tmp/shell.sock", - }, get_sockproc_file_descriptors("root")) - end) - - it("does not inherit nginx file descriptors when nginx started from directory workers don't have permissions to", function() - server.start({ - pwd = "/root", - master_process = "on", - auto_ssl_http_server_config = [[ - location /get-lua-root { - content_by_lua_block { - local cjson = require "cjson.safe" - ngx.print(cjson.encode({ - lua_root = auto_ssl.lua_root, - })) - } - } - ]], - }) - - local httpc = http.new() - local res, err = httpc:request_uri("http://127.0.0.1:9080/get-lua-root") - assert.equal(nil, err) - assert.equal(200, res.status) - local data, json_err = cjson.decode(res.body) - assert.equal(nil, json_err) - local lua_root = data["lua_root"] - assert.String(lua_root) - - -- Already running - assert.same({ - "f0", "n/dev/null", - "f1", "n/dev/null", - "f2", "n/dev/null", - "f3", "n/tmp/shell.sock", - }, get_sockproc_file_descriptors(server.nobody_user)) - - -- sockproc not running - server.stop_sockproc() - assert.same({}, get_sockproc_file_descriptors(server.nobody_user, true)) - - -- current dir as current user - server.stop_sockproc() - shell_blocking.capture_combined({ "sudo", "-u", server.nobody_user, lua_root .. "/bin/resty-auto-ssl/start_sockproc" }, { umask = "0022" }) - assert.same({ - "f0", "n/dev/null", - "f1", "n/dev/null", - "f2", "n/dev/null", - "f3", "n/tmp/shell.sock", - }, get_sockproc_file_descriptors(server.nobody_user)) - - -- /tmp dir as current user - server.stop_sockproc() - shell_blocking.capture_combined({ "sudo", "-u", server.nobody_user, lua_root .. "/bin/resty-auto-ssl/start_sockproc" }, { umask = "0022", chdir = "/tmp" }) - assert.same({ - "f0", "n/dev/null", - "f1", "n/dev/null", - "f2", "n/dev/null", - "f3", "n/tmp/shell.sock", - }, get_sockproc_file_descriptors(server.nobody_user)) - end) -end) diff --git a/spec/support/server.lua b/spec/support/server.lua index d41cc7a..ca34562 100644 --- a/spec/support/server.lua +++ b/spec/support/server.lua @@ -49,12 +49,12 @@ end local function start_ngrok() if not _M.ngrok_hostname then assert(dir.makepath(_M.ngrok_test_dir)) - local ngrok_process, exec_err = process.exec("ngrok", { "http", "9080", "--log", _M.ngrok_test_dir .. "/ngrok.log", "--log-format", "logfmt", "--log-level", "debug" }) + local ngrok_process, exec_err = process.exec("ngrok", { "http", "9080", "--scheme", "http", "--log", _M.ngrok_test_dir .. "/ngrok.log", "--log-format", "logfmt", "--log-level", "debug" }) assert(not exec_err, exec_err) _M.ngrok_process = ngrok_process local log = log_tail.new(_M.ngrok_test_dir .. "/ngrok.log") - local ok, output = log:read_until("start tunnel listen.*Hostname:[a-z0-9]+.ngrok.io") + local ok, output = log:read_until("started tunnel.*url=https?://[a-z0-9-]+.ngrok.io") if not ok then print(ngrok_process:stdout()) print(ngrok_process:stderr()) @@ -68,7 +68,7 @@ local function start_ngrok() error("ngrok did not startup as expected") end - local matches, match_err = ngx.re.match(output, "Hostname:([a-z0-9]+.ngrok.io)", "jo") + local matches, match_err = ngx.re.match(output, "url=https?://([a-z0-9-]+.ngrok.io)", "jo") assert(not match_err, match_err) _M.ngrok_hostname = matches[1] end @@ -161,7 +161,6 @@ function _M.start(options) start_ngrok() start_redis() - _M.stop_sockproc() if not options then options = {} @@ -240,8 +239,6 @@ function _M.stop() kill(_M.nginx_process) _M.nginx_process = nil - - _M.stop_sockproc() end end @@ -250,10 +247,4 @@ function _M.read_error_log() return log:read() end -function _M.stop_sockproc() - shell_blocking.capture_combined({ "pkill", "sockproc" }) - local _, err = shell_blocking.capture_combined({ "rm", "-f", "/tmp/shell.sock", "/tmp/auto-ssl-sockproc.pid" }) - assert(not err, err) -end - return _M