From 111c7319d54d32eb1360c731c443b1675edc3ded Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 8 Oct 2023 00:23:44 +0900 Subject: feat(proxy): mioproxy --- Makefile | 24 ++--- acme-challenge/.gitignore | 2 - docker-compose.yml | 38 ------- letsencrypt/.gitignore | 2 - letsencrypt/lego/.gitignore | 2 + .../webroot/.well-known/acme-challenge/.gitignore | 2 + mioproxy.local.hcl | 16 +++ mioproxy.prod.hcl | 29 ++++++ nginx/acme-challenge.conf | 9 -- nginx/proxy.conf | 33 ------- provisioning/.gitignore | 1 + provisioning/recipe.rb | 110 +++++++++++++++++++++ provisioning/run.sh | 28 ++++++ vhosts/blog/Makefile | 6 +- vhosts/blog/docker-compose.local.yml | 2 +- vhosts/blog/docker-compose.yml | 11 +-- 16 files changed, 200 insertions(+), 115 deletions(-) delete mode 100644 acme-challenge/.gitignore delete mode 100644 docker-compose.yml delete mode 100644 letsencrypt/.gitignore create mode 100644 letsencrypt/lego/.gitignore create mode 100644 letsencrypt/webroot/.well-known/acme-challenge/.gitignore create mode 100644 mioproxy.local.hcl create mode 100644 mioproxy.prod.hcl delete mode 100644 nginx/acme-challenge.conf delete mode 100644 nginx/proxy.conf create mode 100644 provisioning/.gitignore create mode 100644 provisioning/recipe.rb create mode 100755 provisioning/run.sh diff --git a/Makefile b/Makefile index ce0c997e..8b8186cc 100644 --- a/Makefile +++ b/Makefile @@ -2,32 +2,22 @@ all: deploy .PHONY: deploy -deploy: build serve +deploy: clean build serve -.PHONY: setup -setup: .nsfisis_dev_shared_network certbot - cd vhosts/blog; make setup +.PHONY: provision +provision: + sudo sh provisioning/run.sh .PHONY: build build: - docker-compose build cd vhosts/blog; make build .PHONY: serve -serve: .nsfisis_dev_shared_network - docker-compose up -d +serve: + sudo systemctl start mioproxy cd vhosts/blog; make serve .PHONY: clean clean: cd vhosts/blog; make clean - docker-compose down - docker network ls | grep nsfisis_dev_shared > /dev/null && docker network rm nsfisis_dev_shared - -.PHONY: .nsfisis_dev_shared_network -.nsfisis_dev_shared_network: - docker network ls | grep nsfisis_dev_shared > /dev/null || docker network create nsfisis_dev_shared - -.PHONY: certbot -certbot: - docker-compose run --rm --entrypoint 'certbot certonly --register-unsafely-without-email --webroot -w /var/letsencrypt/www -d nsfisis.dev,blog.nsfisis.dev,www.nsfisis.dev' certbot + sudo systemctl stop mioproxy diff --git a/acme-challenge/.gitignore b/acme-challenge/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/acme-challenge/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 6f3e157b..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: '3' - -services: - proxy: - image: nginx - volumes: - - ./nginx/proxy.conf:/etc/nginx/conf.d/default.conf - - ./letsencrypt:/etc/letsencrypt - ports: - - 443:443 - environment: - TZ: Asia/Tokyo - command: "/bin/sh -c 'while :; do sleep 36h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" - restart: always - - acme-challenge: - image: nginx - volumes: - - ./nginx/acme-challenge.conf:/etc/nginx/conf.d/default.conf - - ./acme-challenge:/var/letsencrypt/www - ports: - - 80:80 - environment: - TZ: Asia/Tokyo - restart: always - - certbot: - image: certbot/certbot - volumes: - - ./acme-challenge:/var/letsencrypt/www - - ./letsencrypt:/etc/letsencrypt - entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" - restart: always - -networks: - default: - external: - name: nsfisis_dev_shared diff --git a/letsencrypt/.gitignore b/letsencrypt/.gitignore deleted file mode 100644 index d6b7ef32..00000000 --- a/letsencrypt/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/letsencrypt/lego/.gitignore b/letsencrypt/lego/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/letsencrypt/lego/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/letsencrypt/webroot/.well-known/acme-challenge/.gitignore b/letsencrypt/webroot/.well-known/acme-challenge/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/letsencrypt/webroot/.well-known/acme-challenge/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/mioproxy.local.hcl b/mioproxy.local.hcl new file mode 100644 index 00000000..a92c0991 --- /dev/null +++ b/mioproxy.local.hcl @@ -0,0 +1,16 @@ +user = "ken" + +server http { + host = "127.0.0.1" + port = 8000 + + proxy blog { + from { + host = "blog.localhost" + } + to { + host = "127.0.0.1" + port = 8001 + } + } +} diff --git a/mioproxy.prod.hcl b/mioproxy.prod.hcl new file mode 100644 index 00000000..a9e99051 --- /dev/null +++ b/mioproxy.prod.hcl @@ -0,0 +1,29 @@ +user = "ken" + +server http { + host = "0.0.0.0" + port = 80 + + redirect_to_https = true + acme_challenge { + root = "letsencrypt/webroot" + } +} + +server https { + host = "0.0.0.0" + port = 443 + + tls_cert_file = "letsencrypt/lego/certificates/nsfisis.dev.crt" + tls_key_file = "letsencrypt/lego/certificates/nsfisis.dev.key" + + proxy blog { + from { + host = "blog.nsfisis.dev" + } + to { + host = "127.0.0.1" + port = 8001 + } + } +} diff --git a/nginx/acme-challenge.conf b/nginx/acme-challenge.conf deleted file mode 100644 index 66ed996e..00000000 --- a/nginx/acme-challenge.conf +++ /dev/null @@ -1,9 +0,0 @@ -server { - listen 80 default; - listen [::]:80; - server_name nsfisis.dev; - - location ^~ /.well-known/acme-challenge { - root /var/letsencrypt/www; - } -} diff --git a/nginx/proxy.conf b/nginx/proxy.conf deleted file mode 100644 index 97b2ac48..00000000 --- a/nginx/proxy.conf +++ /dev/null @@ -1,33 +0,0 @@ -ssl_certificate /etc/letsencrypt/live/nsfisis.dev/fullchain.pem; -ssl_certificate_key /etc/letsencrypt/live/nsfisis.dev/privkey.pem; -ssl_session_timeout 1d; -ssl_session_cache shared:SSL:10m; -ssl_session_tickets off; - -proxy_redirect off; -proxy_set_header Host $host; -proxy_set_header X-Real-IP $remote_addr; -proxy_set_header X-Forwarded-Host $host; -proxy_set_header X-Forwarded-Server $host; -proxy_set_header X-Forwarded-Proto $scheme; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - -server { - listen 443 ssl; - listen [::]:443 ssl; - server_name nsfisis.dev; - - location / { - root /usr/share/nginx/html; - } -} - -server { - listen 443 ssl; - listen [::]:443 ssl; - server_name blog.nsfisis.dev; - - location / { - proxy_pass http://blog_nsfisis_nginx:80; - } -} diff --git a/provisioning/.gitignore b/provisioning/.gitignore new file mode 100644 index 00000000..69b81016 --- /dev/null +++ b/provisioning/.gitignore @@ -0,0 +1 @@ +/.bin diff --git a/provisioning/recipe.rb b/provisioning/recipe.rb new file mode 100644 index 00000000..99d935b0 --- /dev/null +++ b/provisioning/recipe.rb @@ -0,0 +1,110 @@ +BIN_ROOT = ENV['BIN_ROOT'] || raise +REPO_ROOT = ENV['REPO_ROOT'] || raise +LEGO_VERSION = ENV['LEGO_VERSION'] || raise +LEGO_ARCH = ENV['LEGO_ARCH'] || raise +LEGO_CONF_EMAIL = ENV['LEGO_CONF_EMAIL'] || raise +LEGO_CONF_WEBROOT = ENV['LEGO_CONF_WEBROOT'] || raise +LEGO_CONF_PATH = ENV['LEGO_CONF_PATH'] || raise +LEGO_CONF_DOMAINS = ENV['LEGO_CONF_DOMAINS'] || raise +GOLANG_VERSION = ENV['GOLANG_VERSION'] || raise +MIOPROXY_VERSION = ENV['MIOPROXY_VERSION'] || raise + +lego_tarball = "lego_#{LEGO_VERSION}_linux_#{LEGO_ARCH}.tar.gz" +lego_tarball_url = "https://github.com/go-acme/lego/releases/download/#{LEGO_VERSION}/#{lego_tarball}" +lego_conf_domains = LEGO_CONF_DOMAINS.split(',') +lego_conf_primary_domain = lego_conf_domains.first || raise +lego_run_cmdline = [ + "#{BIN_ROOT}/lego", + '--accept-tos', + '--email', LEGO_CONF_EMAIL, + '--http', + '--path', LEGO_CONF_PATH, + *lego_conf_domains.map { ['--domains', _1] }, + 'run', +].join(' ') +lego_renew_cmdline = [ + "#{BIN_ROOT}/lego", + '--accept-tos', + '--email', LEGO_CONF_EMAIL, + '--http', + '--http.webroot', LEGO_CONF_WEBROOT, + '--path', LEGO_CONF_PATH, + *lego_conf_domains.map { ['--domains', _1] }, + 'renew', + '--renew-hook', "'systemctl restart mioproxy'", +].join(' ') + +http_request "#{BIN_ROOT}/lego.tar.gz" do + url lego_tarball_url +end + +execute "tar xf #{BIN_ROOT}/lego.tar.gz -C #{BIN_ROOT}" + +file "#{BIN_ROOT}/CHANGELOG.md" do action :delete end +file "#{BIN_ROOT}/LICENSE" do action :delete end +file "#{BIN_ROOT}/lego.tar.gz" do action :delete end + +execute lego_run_cmdline do + not_if "test -f '#{LEGO_CONF_PATH}/certificates/#{lego_conf_primary_domain}.crt' -a -f '#{LEGO_CONF_PATH}/certificates/#{lego_conf_primary_domain}.key'" +end + +execute "docker run --rm golang:#{GOLANG_VERSION} sh -c 'go install github.com/nsfisis/mioproxy@#{MIOPROXY_VERSION}; cat \"$(go env GOPATH)/bin/mioproxy\"' > #{BIN_ROOT}/mioproxy" + +file "#{BIN_ROOT}/mioproxy" do + mode '755' +end + +file '/etc/systemd/system/mioproxy.service' do + content <<~EOS + [Unit] + Description=MioProxy + + [Service] + ExecStart=#{BIN_ROOT}/mioproxy #{REPO_ROOT}/mioproxy.prod.hcl + Restart=always + User=root + Group=root + WorkingDirectory=#{REPO_ROOT} + + [Install] + WantedBy=multi-user.target + EOS +end + +service 'mioproxy.service' do + action [:enable, :start] +end + +file '/etc/systemd/system/lego-renew.service' do + content <<~EOS + [Unit] + Description=Lego Renew + + [Service] + Type=oneshot + ExecStart=#{lego_renew_cmdline} + User=root + Group=root + EOS +end + +file '/etc/systemd/system/lego-renew.timer' do + content <<~EOS + [Unit] + Description=Lego Renew Timer + + [Timer] + Persistent=true + OnCalendar=*-*-* 1:23 + RandomizedDelaySec=1h + + [Install] + WantedBy=timers.target + EOS +end + +service 'lego-renew.timer' do + action [:enable, :start] +end + +# ken ALL=(ALL:ALL) NOPASSWD: /usr/bin/systemctl status mioproxy, /usr/bin/systemctl start mioproxy, /usr/bin/systemctl stop mioproxy, /usr/bin/systemctl restart mioproxy diff --git a/provisioning/run.sh b/provisioning/run.sh new file mode 100755 index 00000000..1986a20d --- /dev/null +++ b/provisioning/run.sh @@ -0,0 +1,28 @@ +set -eu + +this_dir="$(cd "$(dirname "$0")"; pwd)" +export BIN_ROOT="${this_dir}/.bin" +export REPO_ROOT="$(cd "${this_dir}/.."; pwd)" + +export MITAMAE_VERSION=v1.14.0 +export MITAMAE_ARCH=x86_64-linux +export LEGO_VERSION=v4.14.2 +export LEGO_ARCH=amd64 +export LEGO_CONF_EMAIL=nsfisis@gmail.com +export LEGO_CONF_WEBROOT="${REPO_ROOT}/letsencrypt/webroot" +export LEGO_CONF_PATH="${REPO_ROOT}/letsencrypt/lego" +export LEGO_CONF_DOMAINS=nsfisis.dev,blog.nsfisis.dev +export GOLANG_VERSION=1.21.1 +export MIOPROXY_VERSION=v0.1.0 + +mitamae_bin_url="https://github.com/itamae-kitchen/mitamae/releases/download/${MITAMAE_VERSION}/mitamae-${MITAMAE_ARCH}.tar.gz" + +rm -rf "${BIN_ROOT}" +mkdir "${BIN_ROOT}" + +curl -L -o "${BIN_ROOT}/mitamae.tar.gz" "${mitamae_bin_url}" +tar xf "${BIN_ROOT}/mitamae.tar.gz" -C "${BIN_ROOT}" +mv "${BIN_ROOT}/mitamae-${MITAMAE_ARCH}" "${BIN_ROOT}/mitamae" +rm -f '${BIN_ROOT}/mitamae.tar.gz' + +"${BIN_ROOT}/mitamae" local "${this_dir}/recipe.rb" diff --git a/vhosts/blog/Makefile b/vhosts/blog/Makefile index e57db10d..8348a0b0 100644 --- a/vhosts/blog/Makefile +++ b/vhosts/blog/Makefile @@ -2,11 +2,7 @@ all: deploy .PHONY: deploy -deploy: build serve - -.PHONY: setup -setup: - true +deploy: clean build serve .PHONY: build build: diff --git a/vhosts/blog/docker-compose.local.yml b/vhosts/blog/docker-compose.local.yml index ea78e676..a88e3b03 100644 --- a/vhosts/blog/docker-compose.local.yml +++ b/vhosts/blog/docker-compose.local.yml @@ -1,7 +1,7 @@ version: '3' services: - blog_nsfisis_nginx: + nginx: image: nginx volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf diff --git a/vhosts/blog/docker-compose.yml b/vhosts/blog/docker-compose.yml index f6eef3d4..30e141ef 100644 --- a/vhosts/blog/docker-compose.yml +++ b/vhosts/blog/docker-compose.yml @@ -1,18 +1,13 @@ version: '3' services: - blog_nsfisis_nginx: + nginx: image: nginx volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf - ./public:/public - expose: - - 80 + ports: + - 8001:80 environment: TZ: Asia/Tokyo restart: always - -networks: - default: - external: - name: nsfisis_dev_shared -- cgit v1.2.3-70-g09d2