From 139c3114693b225d9042d24153c6c9a115ef8a8b Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 20:33:13 +0100 Subject: [PATCH 01/23] Sign CI config --- .drone.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.drone.yml b/.drone.yml index 0fc8a25..ab9d252 100644 --- a/.drone.yml +++ b/.drone.yml @@ -13,4 +13,8 @@ steps: commands: - nginx -t +--- +kind: signature +hmac: f0a4a11afdeeb438700c0abb4a1a3f11c368b6b586cd53ab5735fd5ed4f43224 +... From 27494331762ed41b8d7b2623df3d9b54c5ab53fe Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 21:41:06 +0100 Subject: [PATCH 02/23] Compile nginx w/ dynamic modules --- .drone.yml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index ab9d252..6fc1a2a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,14 +7,37 @@ platform: os: linux arch: amd64 +environment: + NGINX_VERSION: 1.24.0 + NGINX_MODULES_DIR: /opt/nginx-modules + HEADERS_MORE_VERSION: 'v0.35' + steps: - - name: Verify nginx confiy + - name: Compile nginx image: nginx:1.25-bookworm commands: - - nginx -t + - apt update + - apt install wget + - mkdir -p /opt/nginx-modules + - wget "https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/$${HEADERS_MORE_VERSION}.tar.gz" + - tar -xvzf $${HEADERS_MORE_VERSION}.tar.gz + - mv headers-more-nginx-module-* $${NGINX_MODULES_DIR}/headers-more-nginx-module + - mkdir -p /opt/nginx + - wget "http://nginx.org/download/nginx-$${NGINX_VERSION}.tar.gz" + - tar -xvzf nginx-$${NGINX_VERSION}.tar.gz + - cd nginx-$${NGINX_VERSION} + - ./configure --prefix=/opt/nginx --add-dynamic-module=$${NGINX_MODULES_DIR}/headers-more-nginx-module --with-compat + - cd nginx-$${NGINX_VERSION} + - make + - make install + + - name: Verify nginx confiy + image: nginx:$${NGINX_VERSION}-bookworm + commands: + - nginx -p /opt/nginx -t --- kind: signature -hmac: f0a4a11afdeeb438700c0abb4a1a3f11c368b6b586cd53ab5735fd5ed4f43224 +hmac: 889f2181f1c89b0906b3a95b4fe08fb6a9e91faaf02059c4fe264dac06ce9c1d ... From a05620bb152336373e23a56568e652af94ac1abb Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 21:53:26 +0100 Subject: [PATCH 03/23] Changed image to ubuntu/nginx --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index 6fc1a2a..b584332 100644 --- a/.drone.yml +++ b/.drone.yml @@ -14,10 +14,10 @@ environment: steps: - name: Compile nginx - image: nginx:1.25-bookworm + image: ubuntu/nginx:1.24-23.10_beta commands: - apt update - - apt install wget + - apt install wget -y - mkdir -p /opt/nginx-modules - wget "https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/$${HEADERS_MORE_VERSION}.tar.gz" - tar -xvzf $${HEADERS_MORE_VERSION}.tar.gz From 419df607907ab1ad6443fbacdaae92aaaf22369e Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 21:55:27 +0100 Subject: [PATCH 04/23] Add build-essentials apt package for cc --- .drone.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.drone.yml b/.drone.yml index b584332..2c4b3e0 100644 --- a/.drone.yml +++ b/.drone.yml @@ -13,11 +13,16 @@ environment: HEADERS_MORE_VERSION: 'v0.35' steps: + - name: Verify nginx config + image: ubuntu/nginx:1.24-23.10_beta + commands: + - nginx -t + - name: Compile nginx image: ubuntu/nginx:1.24-23.10_beta commands: - apt update - - apt install wget -y + - apt install wget build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev -y - mkdir -p /opt/nginx-modules - wget "https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/$${HEADERS_MORE_VERSION}.tar.gz" - tar -xvzf $${HEADERS_MORE_VERSION}.tar.gz @@ -27,15 +32,9 @@ steps: - tar -xvzf nginx-$${NGINX_VERSION}.tar.gz - cd nginx-$${NGINX_VERSION} - ./configure --prefix=/opt/nginx --add-dynamic-module=$${NGINX_MODULES_DIR}/headers-more-nginx-module --with-compat - - cd nginx-$${NGINX_VERSION} - make - make install - - name: Verify nginx confiy - image: nginx:$${NGINX_VERSION}-bookworm - commands: - - nginx -p /opt/nginx -t - --- kind: signature hmac: 889f2181f1c89b0906b3a95b4fe08fb6a9e91faaf02059c4fe264dac06ce9c1d From 1419563c6a5a1c2dc54f2b87d308197536b21e55 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 22:11:54 +0100 Subject: [PATCH 05/23] Moved more_header nginx module into repo as submodule --- .drone.yml | 26 +++++++++++++++------ .gitmodules | 3 +++ modules-available/headers-more-nginx-module | 1 + 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 .gitmodules create mode 160000 modules-available/headers-more-nginx-module diff --git a/.drone.yml b/.drone.yml index 2c4b3e0..d59809b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -13,6 +13,11 @@ environment: HEADERS_MORE_VERSION: 'v0.35' steps: + - name: submodules + image: alpine/git + commands: + - git submodule update --init --recursive + - name: Verify nginx config image: ubuntu/nginx:1.24-23.10_beta commands: @@ -21,19 +26,26 @@ steps: - name: Compile nginx image: ubuntu/nginx:1.24-23.10_beta commands: + - NGINX_CONFIG_PATH=$(pwd) - apt update - - apt install wget build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev -y - - mkdir -p /opt/nginx-modules - - wget "https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/$${HEADERS_MORE_VERSION}.tar.gz" - - tar -xvzf $${HEADERS_MORE_VERSION}.tar.gz - - mv headers-more-nginx-module-* $${NGINX_MODULES_DIR}/headers-more-nginx-module - - mkdir -p /opt/nginx + - apt install -y + wget + build-essential + libpcre3 + libpcre3-dev + zlib1g + zlib1g-dev + libssl-dev + tree - wget "http://nginx.org/download/nginx-$${NGINX_VERSION}.tar.gz" - tar -xvzf nginx-$${NGINX_VERSION}.tar.gz - cd nginx-$${NGINX_VERSION} - - ./configure --prefix=/opt/nginx --add-dynamic-module=$${NGINX_MODULES_DIR}/headers-more-nginx-module --with-compat + - ./configure --prefix=/opt/nginx + --add-dynamic-module=../modules-available/headers-more-nginx-module + --with-compat - make - make install + - tree /opt/nginx --- kind: signature diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..657b89b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "modules-available/headers-more-nginx-module"] + path = modules-available/headers-more-nginx-module + url = https://github.com/openresty/headers-more-nginx-module diff --git a/modules-available/headers-more-nginx-module b/modules-available/headers-more-nginx-module new file mode 160000 index 0000000..db45361 --- /dev/null +++ b/modules-available/headers-more-nginx-module @@ -0,0 +1 @@ +Subproject commit db45361256a665e4e076465249628bb4631c3354 From 960e4b4015431fe9825a0638d47c637d5d645709 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 22:26:19 +0100 Subject: [PATCH 06/23] Deploy submodule and nginx config files --- .drone.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.drone.yml b/.drone.yml index d59809b..c273437 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,22 +1,27 @@ --- kind: pipeline type: docker -name: Verify +name: Build & deploy platform: os: linux arch: amd64 +clone: + disable: true + environment: NGINX_VERSION: 1.24.0 NGINX_MODULES_DIR: /opt/nginx-modules HEADERS_MORE_VERSION: 'v0.35' steps: - - name: submodules + - name: Clone w/ submodules image: alpine/git commands: - - git submodule update --init --recursive + - git clone $DRONE_REPO_LINK . + - git checkout $DRONE_COMMIT + - git submodule update --init --recursive - name: Verify nginx config image: ubuntu/nginx:1.24-23.10_beta @@ -26,7 +31,7 @@ steps: - name: Compile nginx image: ubuntu/nginx:1.24-23.10_beta commands: - - NGINX_CONFIG_PATH=$(pwd) + - mkdir -p $DRONE_WORKSPACE/nginx-build - apt update - apt install -y wget @@ -40,12 +45,16 @@ steps: - wget "http://nginx.org/download/nginx-$${NGINX_VERSION}.tar.gz" - tar -xvzf nginx-$${NGINX_VERSION}.tar.gz - cd nginx-$${NGINX_VERSION} - - ./configure --prefix=/opt/nginx + - ./configure --prefix=$DRONE_WORKSPACE/nginx-build --add-dynamic-module=../modules-available/headers-more-nginx-module --with-compat - make - make install - - tree /opt/nginx + + - name: Deploy + image: alpine/git + commands: + - tree $DRONE_WORKSPACE/nginx-build --- kind: signature From 9321c229b4244d8d49598977e7c8ca3dda4282e6 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 22:40:12 +0100 Subject: [PATCH 07/23] Deploy credentials setup & deploy --- .drone.yml | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index c273437..e2e75da 100644 --- a/.drone.yml +++ b/.drone.yml @@ -15,6 +15,7 @@ environment: NGINX_MODULES_DIR: /opt/nginx-modules HEADERS_MORE_VERSION: 'v0.35' + steps: - name: Clone w/ submodules image: alpine/git @@ -22,13 +23,14 @@ steps: - git clone $DRONE_REPO_LINK . - git checkout $DRONE_COMMIT - git submodule update --init --recursive + - ls -l - - name: Verify nginx config + - name: Verify config image: ubuntu/nginx:1.24-23.10_beta commands: - nginx -t - - name: Compile nginx + - name: Compile image: ubuntu/nginx:1.24-23.10_beta commands: - mkdir -p $DRONE_WORKSPACE/nginx-build @@ -51,10 +53,33 @@ steps: - make - make install + - name: Verify config post build + image: ubuntu/nginx:1.24-23.10_beta + commands: + - nginx -t + + - name: Setup credentials + image: alpine/git + commands: + - mkdir .ssh + - echo $NGINX_DEPLOY_KEY | base64 -di > .ssh/id_ed25519 + - echo "" >> .ssh/id_ed25519 + - chmod 600 .ssh/id_ed25519 + environment: + NGINX_DEPLOY_KEY: + from_secret: NGINX_DEPLOY_KEY + - name: Deploy image: alpine/git commands: - - tree $DRONE_WORKSPACE/nginx-build + - echo $NGINX_USER + - echo $NGINX_HOST + - ssh -i .ssh/id_ed25519 -o StrictHostKeyChecking=no $NGINX_USER@$NGINX_HOST ls + environment: + NGINX_USER: + from_secret: NGINX_USER + NGINX_HOST: + from_secret: NGINX_HOST --- kind: signature From 00f70d24bfaff335db68721184fc8b35436c9b2f Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 23:39:33 +0100 Subject: [PATCH 08/23] Relative paths for anything located in /etc/nginx --- nginx.conf | 8 ++++---- sites-available/adtech.conf | 2 +- sites-available/mc.conf | 6 +++--- sites-available/request.conf | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/nginx.conf b/nginx.conf index d02521f..017a7b8 100644 --- a/nginx.conf +++ b/nginx.conf @@ -11,7 +11,7 @@ events { } http { - include /etc/nginx/mime.types; + include mime.types; default_type text/plain; ################## @@ -55,7 +55,7 @@ http { access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log; - include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-enabled/*.conf; - include /etc/nginx/cloudflare; + include conf.d/*.conf; + include sites-enabled/*.conf; + include cloudflare; } diff --git a/sites-available/adtech.conf b/sites-available/adtech.conf index f609232..13e1f05 100644 --- a/sites-available/adtech.conf +++ b/sites-available/adtech.conf @@ -20,7 +20,7 @@ server { proxy_pass http://adtech.schleppe:3000; client_max_body_size 2000M; - include /etc/nginx/snippets/proxy-params.conf; + include snippets/proxy-params.conf; } ssl_certificate /etc/letsencrypt/live/adtech.schleppe.cloud/fullchain.pem; # managed by Certbot diff --git a/sites-available/mc.conf b/sites-available/mc.conf index 38bf873..d48c0ff 100644 --- a/sites-available/mc.conf +++ b/sites-available/mc.conf @@ -12,8 +12,8 @@ server { ssl_certificate /etc/letsencrypt/live/mc.kevinmidboe.com-0001/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/mc.kevinmidboe.com-0001/privkey.pem; # managed by Certbot - include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot +# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot +# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } @@ -29,4 +29,4 @@ server { return 404; # managed by Certbot -} \ No newline at end of file +} diff --git a/sites-available/request.conf b/sites-available/request.conf index 5410865..8636b55 100644 --- a/sites-available/request.conf +++ b/sites-available/request.conf @@ -19,7 +19,7 @@ server { resolver 10.0.0.72; proxy_pass http://seasoned.schleppe:31459; - include /etc/nginx/snippets/proxy-params.conf; + include snippets/proxy-params.conf; } @@ -27,7 +27,7 @@ server { resolver 10.0.0.72; proxy_pass http://seasoned.schleppe:5000; - include /etc/nginx/snippets/proxy-params.conf; + include snippets/proxy-params.conf; } ssl_certificate /etc/letsencrypt/live/request.movie-0001/fullchain.pem; # managed by Certbot @@ -44,7 +44,7 @@ server { resolver 10.0.0.72; proxy_pass http://seasoned.schleppe:31459; - include /etc/nginx/snippets/proxy-params.conf; + include snippets/proxy-params.conf; } ssl_certificate /etc/letsencrypt/live/api.request.movie/fullchain.pem; # managed by Certbot @@ -63,7 +63,7 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_cache_bypass $http_upgrade; - include /etc/nginx/snippets/proxy-params.conf; + include snippets/proxy-params.conf; } From bf3a8a150de966c870235ea01ff93f27ea40f57d Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 23:43:08 +0100 Subject: [PATCH 09/23] Load custom built headers_more dynamic module --- nginx.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nginx.conf b/nginx.conf index 017a7b8..eeb0fbf 100644 --- a/nginx.conf +++ b/nginx.conf @@ -4,7 +4,8 @@ worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; -include /etc/nginx/modules-enabled/*.conf; + +load_module /etc/nginx/modules/ngx_http_headers_more_filter_module.so; events { worker_connections 1024; From 8e831a7bc628178c20e9d9091a30c8674f2f69b6 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 9 Nov 2023 23:43:18 +0100 Subject: [PATCH 10/23] Transfer config files to host --- .drone.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.drone.yml b/.drone.yml index e2e75da..e84d5ac 100644 --- a/.drone.yml +++ b/.drone.yml @@ -33,7 +33,7 @@ steps: - name: Compile image: ubuntu/nginx:1.24-23.10_beta commands: - - mkdir -p $DRONE_WORKSPACE/nginx-build + - mkdir -p /tmp/nginx-build - apt update - apt install -y wget @@ -44,14 +44,18 @@ steps: zlib1g-dev libssl-dev tree + - cd /tmp - wget "http://nginx.org/download/nginx-$${NGINX_VERSION}.tar.gz" - tar -xvzf nginx-$${NGINX_VERSION}.tar.gz - cd nginx-$${NGINX_VERSION} - - ./configure --prefix=$DRONE_WORKSPACE/nginx-build - --add-dynamic-module=../modules-available/headers-more-nginx-module + - ./configure --prefix=/tmp/nginx-build + --add-dynamic-module=$DRONE_WORKSPACE/modules-available/headers-more-nginx-module --with-compat - make - make install + - cd $DRONE_WORKSPACE + - mv /tmp/nginx-build/modules/* . + - tree - name: Verify config post build image: ubuntu/nginx:1.24-23.10_beta @@ -62,6 +66,7 @@ steps: image: alpine/git commands: - mkdir .ssh + - echo $NGINX_FINGERPRINT | base64 -di > .ssh/known_hosts - echo $NGINX_DEPLOY_KEY | base64 -di > .ssh/id_ed25519 - echo "" >> .ssh/id_ed25519 - chmod 600 .ssh/id_ed25519 @@ -72,9 +77,7 @@ steps: - name: Deploy image: alpine/git commands: - - echo $NGINX_USER - - echo $NGINX_HOST - - ssh -i .ssh/id_ed25519 -o StrictHostKeyChecking=no $NGINX_USER@$NGINX_HOST ls + - ssh -i .ssh/id_ed25519 $NGINX_USER@$NGINX_HOST ls environment: NGINX_USER: from_secret: NGINX_USER From a3163352d835331e08448b3b06327a042026cf15 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 00:13:52 +0100 Subject: [PATCH 11/23] Include prebuild version of nginx more_headers module --- .drone.yml | 4 +++- modules/ngx_http_headers_more_filter_module.so | Bin 0 -> 190704 bytes 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100755 modules/ngx_http_headers_more_filter_module.so diff --git a/.drone.yml b/.drone.yml index e84d5ac..5c4cb22 100644 --- a/.drone.yml +++ b/.drone.yml @@ -54,7 +54,7 @@ steps: - make - make install - cd $DRONE_WORKSPACE - - mv /tmp/nginx-build/modules/* . + - mv /tmp/nginx-build/modules/* modules - tree - name: Verify config post build @@ -71,6 +71,8 @@ steps: - echo "" >> .ssh/id_ed25519 - chmod 600 .ssh/id_ed25519 environment: + NGINX_FINGERPRINT: + from_secret: NGINX_FINGERPRINT NGINX_DEPLOY_KEY: from_secret: NGINX_DEPLOY_KEY diff --git a/modules/ngx_http_headers_more_filter_module.so b/modules/ngx_http_headers_more_filter_module.so new file mode 100755 index 0000000000000000000000000000000000000000..006f7ca65e99eacf4afb5ed75c4d5d901602c26d GIT binary patch literal 190704 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
K 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 Date: Fri, 10 Nov 2023 00:34:53 +0100 Subject: [PATCH 12/23] ssh-add deploy key & keyscan to populate known_hosts --- .drone.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.drone.yml b/.drone.yml index 5c4cb22..e2c76e3 100644 --- a/.drone.yml +++ b/.drone.yml @@ -65,16 +65,20 @@ steps: - name: Setup credentials image: alpine/git commands: - - mkdir .ssh - - echo $NGINX_FINGERPRINT | base64 -di > .ssh/known_hosts - - echo $NGINX_DEPLOY_KEY | base64 -di > .ssh/id_ed25519 + - mkdir -p .ssh + - apk update + - apk add openssh-client + - eval $(ssh-agent -s) + - echo "$NGINX_DEPLOY_KEY" | base64 -di > .ssh/id_ed25519 - echo "" >> .ssh/id_ed25519 - - chmod 600 .ssh/id_ed25519 + - cat .ssh/id_ed25519 | tr -d '\r' | ssh-add - > /dev/null + - touch .ssh/known_hosts + - ssh-keyscan $NGINX_HOST >> .ssh/known_hosts environment: - NGINX_FINGERPRINT: - from_secret: NGINX_FINGERPRINT NGINX_DEPLOY_KEY: from_secret: NGINX_DEPLOY_KEY + NGINX_HOST: + from_secret: NGINX_HOST - name: Deploy image: alpine/git From 714be4b62ccb6faffe70cd6160b66a00aebfddda Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 00:59:21 +0100 Subject: [PATCH 13/23] deploy modules over rysnc --- .drone.yml | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/.drone.yml b/.drone.yml index e2c76e3..64d5bb0 100644 --- a/.drone.yml +++ b/.drone.yml @@ -12,9 +12,6 @@ clone: environment: NGINX_VERSION: 1.24.0 - NGINX_MODULES_DIR: /opt/nginx-modules - HEADERS_MORE_VERSION: 'v0.35' - steps: - name: Clone w/ submodules @@ -23,7 +20,6 @@ steps: - git clone $DRONE_REPO_LINK . - git checkout $DRONE_COMMIT - git submodule update --init --recursive - - ls -l - name: Verify config image: ubuntu/nginx:1.24-23.10_beta @@ -55,7 +51,7 @@ steps: - make install - cd $DRONE_WORKSPACE - mv /tmp/nginx-build/modules/* modules - - tree + - tree -I modules-available - name: Verify config post build image: ubuntu/nginx:1.24-23.10_beta @@ -63,35 +59,41 @@ steps: - nginx -t - name: Setup credentials - image: alpine/git + image: alpine:3.18.4 commands: - - mkdir -p .ssh - - apk update - - apk add openssh-client - - eval $(ssh-agent -s) - - echo "$NGINX_DEPLOY_KEY" | base64 -di > .ssh/id_ed25519 + - mkdir .ssh + - echo $NGINX_DEPLOY_KEY | base64 -di > .ssh/id_ed25519 - echo "" >> .ssh/id_ed25519 - - cat .ssh/id_ed25519 | tr -d '\r' | ssh-add - > /dev/null - - touch .ssh/known_hosts - - ssh-keyscan $NGINX_HOST >> .ssh/known_hosts + - chmod 600 .ssh/id_ed25519 +# - apk update +# - apk add openssh-client +# - eval $(ssh-agent -s) +# - cat .ssh/id_ed25519 | tr -d '\r' | ssh-add - > /dev/null +# - touch .ssh/known_hosts +# - ssh-keyscan $NGINX_HOST >> .ssh/known_hosts environment: NGINX_DEPLOY_KEY: from_secret: NGINX_DEPLOY_KEY - NGINX_HOST: - from_secret: NGINX_HOST - name: Deploy - image: alpine/git + image: alpine:3.18.4 commands: - - ssh -i .ssh/id_ed25519 $NGINX_USER@$NGINX_HOST ls + - apk update + - apk add rsync openssh + - rsync + -av + -e "ssh -i .ssh/id_ed25519 -o StrictHostKeyChecking=no" + --exclude available-modules + modules $NGINX_USER@$NGINX_HOST:/etc/nginx/ environment: NGINX_USER: from_secret: NGINX_USER NGINX_HOST: from_secret: NGINX_HOST + --- kind: signature -hmac: 889f2181f1c89b0906b3a95b4fe08fb6a9e91faaf02059c4fe264dac06ce9c1d +hmac: 144bbd73dc3b83d6a6f1f4bacca7b83b377b12dc56021db7c723988b0ad2ec3c ... From 9b8d9502dee7d7417366b61b8570b5c1c956f162 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 01:34:16 +0100 Subject: [PATCH 14/23] Generate fake SSL certs for config validation --- .drone.yml | 38 +++++++++++++++++++++++++++++++++++--- nginx.conf | 2 +- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.drone.yml b/.drone.yml index 64d5bb0..bfe7ffc 100644 --- a/.drone.yml +++ b/.drone.yml @@ -10,6 +10,10 @@ platform: clone: disable: true +# TODO +# grep on ssl_certificate and create fake certificates +# for nginx -p $DRONE_WORKSPACE -c $DRONE_WORKSPACE/nginx.conf + environment: NGINX_VERSION: 1.24.0 @@ -24,7 +28,34 @@ steps: - name: Verify config image: ubuntu/nginx:1.24-23.10_beta commands: - - nginx -t + - apt update + - apt install openssl + - cd $DRONE_WORKSPACE + - mkdir .ssl + - openssl req + -x509 + -nodes + -days 1 + -newkey rsa:4096 + -keyout .ssl/ssl-cert-snakeoil.key + -out .ssl/ssl-cert-snakeoil.pem + -batch + + - echo "Creating letsencrypt folders"; + grep -ro 'ssl_certificate[^;]*;' sites-available snippets | awk -F' ' '{print $2}' RS=';' | + while read -r file; do if [ ! -z $file ]; then mkdir -p $(dirname $file); fi; done + + - echo "Creating snakeoil symlinks for ssl_cert references in nginx configs"; + grep -ro 'ssl_certificate [^;]*;' sites-available snippets | + awk -F ' ' '{print $2}' RS=';' | + while read -r file; do if [ ! -z $file ]; then ln -sf $PWD/.ssl/ssl-cert-snakeoil.pem $file; fi; done + + - echo "Creating snakeoil symlinks for ssl_cert_key references in nginx configs"; + grep -ro 'ssl_certificate_key [^;]*;' sites-available snippets | + awk -F ' ' '{print $2}' RS=';' | + while read -r file; do if [ ! -z $file ]; then ln -sf $PWD/.ssl/ssl-cert-snakeoil.key $file; fi; done + + - nginx -p $DRONE_WORKSPACE -c $DRONE_WORKSPACE/nginx.conf -t - name: Compile image: ubuntu/nginx:1.24-23.10_beta @@ -44,7 +75,8 @@ steps: - wget "http://nginx.org/download/nginx-$${NGINX_VERSION}.tar.gz" - tar -xvzf nginx-$${NGINX_VERSION}.tar.gz - cd nginx-$${NGINX_VERSION} - - ./configure --prefix=/tmp/nginx-build + - ./configure + --prefix=/tmp/nginx-build --add-dynamic-module=$DRONE_WORKSPACE/modules-available/headers-more-nginx-module --with-compat - make @@ -94,6 +126,6 @@ steps: --- kind: signature -hmac: 144bbd73dc3b83d6a6f1f4bacca7b83b377b12dc56021db7c723988b0ad2ec3c +hmac: 03972a40959e14601d6c922c10f2d96f77f84f1ea88cc49e40aa0c69c755266b ... diff --git a/nginx.conf b/nginx.conf index eeb0fbf..59f0e4d 100644 --- a/nginx.conf +++ b/nginx.conf @@ -5,7 +5,7 @@ worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; -load_module /etc/nginx/modules/ngx_http_headers_more_filter_module.so; +load_module modules/ngx_http_headers_more_filter_module.so; events { worker_connections 1024; From b809373abb3175564b7b221967a4f7f2b608e199 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 11:42:52 +0100 Subject: [PATCH 15/23] Volumes for persistent /etc/letsencrypt & /etc/ssl --- .drone.yml | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.drone.yml b/.drone.yml index bfe7ffc..fbd1175 100644 --- a/.drone.yml +++ b/.drone.yml @@ -17,6 +17,12 @@ clone: environment: NGINX_VERSION: 1.24.0 +volumes: + - name: letsencrypt + temp: {} + - name: ssl + temp: {} + steps: - name: Clone w/ submodules image: alpine/git @@ -25,11 +31,16 @@ steps: - git checkout $DRONE_COMMIT - git submodule update --init --recursive - - name: Verify config - image: ubuntu/nginx:1.24-23.10_beta + - name: Setup environment + image: alpine:3.18.4 + volumes: + - name: letsencrypt + path: /etc/letsencrypt + - name: ssl + path: /etc/ssl commands: - - apt update - - apt install openssl + - apk update + - apk add openssl - cd $DRONE_WORKSPACE - mkdir .ssl - openssl req @@ -55,6 +66,14 @@ steps: awk -F ' ' '{print $2}' RS=';' | while read -r file; do if [ ! -z $file ]; then ln -sf $PWD/.ssl/ssl-cert-snakeoil.key $file; fi; done + - name: Verify config + image: ubuntu/nginx:1.24-23.10_beta + volumes: + - name: letsencrypt + path: /etc/letsencrypt + - name: ssl + path: /etc/ssl + commands: - nginx -p $DRONE_WORKSPACE -c $DRONE_WORKSPACE/nginx.conf -t - name: Compile @@ -87,8 +106,13 @@ steps: - name: Verify config post build image: ubuntu/nginx:1.24-23.10_beta + volumes: + - name: letsencrypt + path: /etc/letsencrypt + - name: ssl + path: /etc/ssl commands: - - nginx -t + - nginx -p $DRONE_WORKSPACE -c $DRONE_WORKSPACE/nginx.conf -t - name: Setup credentials image: alpine:3.18.4 @@ -126,6 +150,6 @@ steps: --- kind: signature -hmac: 03972a40959e14601d6c922c10f2d96f77f84f1ea88cc49e40aa0c69c755266b +hmac: 1b941ff6cc5afce923caebaee1724e778f9963e390bb0ddbbee7c123b17e4aed ... From 939bb52523281a4aee02606184d786b47ab4e0cd Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 13:24:52 +0100 Subject: [PATCH 16/23] Use ubuntu pinned version as prod host & install nginx from apt - Use alpine latest instead of pinned - make only modules and not entire nginx package --- .drone.yml | 57 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/.drone.yml b/.drone.yml index fbd1175..8fc9766 100644 --- a/.drone.yml +++ b/.drone.yml @@ -10,10 +10,6 @@ platform: clone: disable: true -# TODO -# grep on ssl_certificate and create fake certificates -# for nginx -p $DRONE_WORKSPACE -c $DRONE_WORKSPACE/nginx.conf - environment: NGINX_VERSION: 1.24.0 @@ -52,36 +48,40 @@ steps: -out .ssl/ssl-cert-snakeoil.pem -batch - - echo "Creating letsencrypt folders"; - grep -ro 'ssl_certificate[^;]*;' sites-available snippets | awk -F' ' '{print $2}' RS=';' | + - grep -ro 'ssl_certificate[^;]*;' sites-available snippets | awk -F' ' '{print $2}' RS=';' | while read -r file; do if [ ! -z $file ]; then mkdir -p $(dirname $file); fi; done - - echo "Creating snakeoil symlinks for ssl_cert references in nginx configs"; - grep -ro 'ssl_certificate [^;]*;' sites-available snippets | + - grep -ro 'ssl_certificate [^;]*;' sites-available snippets | awk -F ' ' '{print $2}' RS=';' | while read -r file; do if [ ! -z $file ]; then ln -sf $PWD/.ssl/ssl-cert-snakeoil.pem $file; fi; done - - echo "Creating snakeoil symlinks for ssl_cert_key references in nginx configs"; - grep -ro 'ssl_certificate_key [^;]*;' sites-available snippets | + - grep -ro 'ssl_certificate_key [^;]*;' sites-available snippets | awk -F ' ' '{print $2}' RS=';' | while read -r file; do if [ ! -z $file ]; then ln -sf $PWD/.ssl/ssl-cert-snakeoil.key $file; fi; done - name: Verify config - image: ubuntu/nginx:1.24-23.10_beta + image: alpine:3.18.4 volumes: - name: letsencrypt path: /etc/letsencrypt - name: ssl path: /etc/ssl commands: - - nginx -p $DRONE_WORKSPACE -c $DRONE_WORKSPACE/nginx.conf -t + - apk update + - apk add nginx~$${NGINX_VERSION} + - cd /etc/nginx + - cp -r $DRONE_WORKSPACE/* . + - cat nginx.conf | sed 's/load_module/#load_module/g' > nginx-module-less.conf + - nginx -t -p $PWD -c nginx-module-less.conf + - rm nginx-module-less.conf - - name: Compile - image: ubuntu/nginx:1.24-23.10_beta + - name: Compile modules + image: ubuntu:22.04 commands: - - mkdir -p /tmp/nginx-build - - apt update - - apt install -y + - mkdir -p $DRONE_WORKSPACE/nginx-build + - apt -q update + - apt -y -qq install -o Dpkg::Progress-Fancy="0" -o APT::Color="0" -o Dpkg::Use-Pty="0" + nginx wget build-essential libpcre3 @@ -95,24 +95,33 @@ steps: - tar -xvzf nginx-$${NGINX_VERSION}.tar.gz - cd nginx-$${NGINX_VERSION} - ./configure - --prefix=/tmp/nginx-build + --prefix=$DRONE_WORKSPACE/nginx-build --add-dynamic-module=$DRONE_WORKSPACE/modules-available/headers-more-nginx-module + --with-http_ssl_module + --with-http_v2_module + --with-http_stub_status_module + --with-http_gzip_static_module + --with-http_realip_module --with-compat - - make + - make modules - make install - cd $DRONE_WORKSPACE - - mv /tmp/nginx-build/modules/* modules + - mv nginx-build/modules/* modules + - mv nginx-build/sbin . - tree -I modules-available - - name: Verify config post build - image: ubuntu/nginx:1.24-23.10_beta + - name: Verify config w/ modules + image: ubuntu:22.04 volumes: - name: letsencrypt path: /etc/letsencrypt - name: ssl path: /etc/ssl commands: - - nginx -p $DRONE_WORKSPACE -c $DRONE_WORKSPACE/nginx.conf -t + - mkdir -p /var/log/nginx + - touch /var/log/nginx/error.log + - useradd nginx + - sbin/nginx -t -p $PWD -c nginx.conf -e /var/log/nginx/error.log - name: Setup credentials image: alpine:3.18.4 @@ -140,6 +149,8 @@ steps: -av -e "ssh -i .ssh/id_ed25519 -o StrictHostKeyChecking=no" --exclude available-modules + --exclude sbin + --exclude nginx-build modules $NGINX_USER@$NGINX_HOST:/etc/nginx/ environment: NGINX_USER: From c775aa2406851ecbe6025e69710b21eb2f013494 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 17:23:27 +0100 Subject: [PATCH 17/23] Rename directive add_header -> more_set_header --- nginx.conf | 2 +- sites-available/000-default.conf | 9 ++++---- sites-available/planetposen.conf | 36 +++++++++++--------------------- snippets/proxy-params.conf | 2 +- 4 files changed, 19 insertions(+), 30 deletions(-) diff --git a/nginx.conf b/nginx.conf index 59f0e4d..e5c9e7b 100644 --- a/nginx.conf +++ b/nginx.conf @@ -35,7 +35,7 @@ http { # Headers # ################## - add_header X-Web-Entry "Bifrost" always; + more_set_header 'X-Web-Entry Bifrost'; ################## # SSL settings # diff --git a/sites-available/000-default.conf b/sites-available/000-default.conf index 5c90913..546f24c 100644 --- a/sites-available/000-default.conf +++ b/sites-available/000-default.conf @@ -10,8 +10,8 @@ server { server_name _; - add_header X-Dead-End true; - add_header Content-Type text/plain; + more_set_header 'X-Dead-End true'; + more_set_header 'Content-Type text/plain'; return 200 ok; } @@ -24,8 +24,9 @@ server { server_name _; - add_header X-Dead-End true; - add_header Content-Type text/plain; + more_set_header 'X-Dead-End true'; + more_set_header 'Content-Type text/plain'; + return 425 "SSL not supported here."; ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; diff --git a/sites-available/planetposen.conf b/sites-available/planetposen.conf index 03299a1..f0410d5 100644 --- a/sites-available/planetposen.conf +++ b/sites-available/planetposen.conf @@ -24,7 +24,7 @@ server { server_name planetposen.no planet.schleppe.cloud; - add_header Upgrading Connection; + more_set_header Upgrading Connection; return 302 https://$host$request_uri; } @@ -49,6 +49,8 @@ server { server_name planet.schleppe.cloud; + include snippets/proxy-params.conf; + location /ws { resolver 10.0.0.72; proxy_pass http://planetposen-ws; @@ -56,23 +58,17 @@ server { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /api/v1/images { resolver 10.0.0.72; proxy_pass http://planetposen-images/api/v1/images; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_request_buffering off; - add_header 'Access-Control-Allow-Origin' 'planet.schleppe.cloud'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - add_header 'Access-Control-Allow-Headers' 'Content-Type'; + more_set_header 'Access-Control-Allow-Origin planet.schleppe.cloud'; + more_set_header 'Access-Control-Allow-Methods GET, POST, OPTIONS'; + more_set_header 'Access-Control-Allow-Headers Content-Type'; client_max_body_size 5M; } @@ -81,27 +77,19 @@ server { resolver 10.0.0.72; proxy_pass http://planetposen-backend/api; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # add_header 'Access-Control-Allow-Origin' 'planet.schleppe.cloud'; - add_header 'Access-Control-Allow-Origin' '*'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - add_header 'Access-Control-Allow-Headers' 'Content-Type'; + more_set_header 'Access-Control-Allow-Origin *'; + more_set_header 'Access-Control-Allow-Methods GET, POST, OPTIONS'; + more_set_header 'Access-Control-Allow-Headers Content-Type'; } location / { resolver 10.0.0.72; proxy_pass http://planetposen-frontend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - add_header 'Access-Control-Allow-Origin' 'planet.schleppe.cloud'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - add_header 'Access-Control-Allow-Headers' 'Content-Type'; + more_set_header 'Access-Control-Allow-Origin planet.schleppe.cloud'; + more_set_header 'Access-Control-Allow-Methods GET, POST, OPTIONS'; + more_set_header 'Access-Control-Allow-Headers Content-Type'; } ssl_certificate /etc/letsencrypt/live/planet.schleppe.cloud/fullchain.pem; # managed by Certbot diff --git a/snippets/proxy-params.conf b/snippets/proxy-params.conf index 75d3c81..19ddff1 100644 --- a/snippets/proxy-params.conf +++ b/snippets/proxy-params.conf @@ -3,4 +3,4 @@ proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; proxy_set_header Host $host; -add_header X-Proxy-Params Applied always; \ No newline at end of file +more_set_header 'X-Proxy-Params Applied'; From e319e94b4bc832ffbc015ae10ca2f06cedfc807e Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 17:27:44 +0100 Subject: [PATCH 18/23] Disable initial verify step --- .drone.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.drone.yml b/.drone.yml index 8fc9766..38f8fa8 100644 --- a/.drone.yml +++ b/.drone.yml @@ -59,21 +59,21 @@ steps: awk -F ' ' '{print $2}' RS=';' | while read -r file; do if [ ! -z $file ]; then ln -sf $PWD/.ssl/ssl-cert-snakeoil.key $file; fi; done - - name: Verify config - image: alpine:3.18.4 - volumes: - - name: letsencrypt - path: /etc/letsencrypt - - name: ssl - path: /etc/ssl - commands: - - apk update - - apk add nginx~$${NGINX_VERSION} - - cd /etc/nginx - - cp -r $DRONE_WORKSPACE/* . - - cat nginx.conf | sed 's/load_module/#load_module/g' > nginx-module-less.conf - - nginx -t -p $PWD -c nginx-module-less.conf - - rm nginx-module-less.conf +# - name: Verify config +# image: alpine:3.18.4 +# volumes: +# - name: letsencrypt +# path: /etc/letsencrypt +# - name: ssl +# path: /etc/ssl +# commands: +# - apk update +# - apk add nginx~$${NGINX_VERSION} +# - cd /etc/nginx +# - cp -r $DRONE_WORKSPACE/* . +# - cat nginx.conf | sed 's/load_module/#load_module/g' > nginx-module-less.conf +# - nginx -t -p $PWD -c nginx-module-less.conf +# - rm nginx-module-less.conf - name: Compile modules image: ubuntu:22.04 From 63d445ba93d5df83338e82ed9abf5dcec7c368af Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 17:31:39 +0100 Subject: [PATCH 19/23] Updated syntax error more_set_headers --- nginx.conf | 2 +- sites-available/000-default.conf | 8 ++++---- sites-available/planetposen.conf | 20 ++++++++++---------- snippets/proxy-params.conf | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/nginx.conf b/nginx.conf index e5c9e7b..0d02224 100644 --- a/nginx.conf +++ b/nginx.conf @@ -35,7 +35,7 @@ http { # Headers # ################## - more_set_header 'X-Web-Entry Bifrost'; + more_set_headers 'X-Web-Entry Bifrost'; ################## # SSL settings # diff --git a/sites-available/000-default.conf b/sites-available/000-default.conf index 546f24c..7e5f634 100644 --- a/sites-available/000-default.conf +++ b/sites-available/000-default.conf @@ -10,8 +10,8 @@ server { server_name _; - more_set_header 'X-Dead-End true'; - more_set_header 'Content-Type text/plain'; + more_set_headers 'X-Dead-End true'; + more_set_headers 'Content-Type text/plain'; return 200 ok; } @@ -24,8 +24,8 @@ server { server_name _; - more_set_header 'X-Dead-End true'; - more_set_header 'Content-Type text/plain'; + more_set_headers 'X-Dead-End true'; + more_set_headers 'Content-Type text/plain'; return 425 "SSL not supported here."; diff --git a/sites-available/planetposen.conf b/sites-available/planetposen.conf index f0410d5..2476289 100644 --- a/sites-available/planetposen.conf +++ b/sites-available/planetposen.conf @@ -24,7 +24,7 @@ server { server_name planetposen.no planet.schleppe.cloud; - more_set_header Upgrading Connection; + more_set_headers Upgrading Connection; return 302 https://$host$request_uri; } @@ -66,9 +66,9 @@ server { proxy_request_buffering off; - more_set_header 'Access-Control-Allow-Origin planet.schleppe.cloud'; - more_set_header 'Access-Control-Allow-Methods GET, POST, OPTIONS'; - more_set_header 'Access-Control-Allow-Headers Content-Type'; + more_set_headers 'Access-Control-Allow-Origin planet.schleppe.cloud'; + more_set_headers 'Access-Control-Allow-Methods GET, POST, OPTIONS'; + more_set_headers 'Access-Control-Allow-Headers Content-Type'; client_max_body_size 5M; } @@ -78,18 +78,18 @@ server { proxy_pass http://planetposen-backend/api; # add_header 'Access-Control-Allow-Origin' 'planet.schleppe.cloud'; - more_set_header 'Access-Control-Allow-Origin *'; - more_set_header 'Access-Control-Allow-Methods GET, POST, OPTIONS'; - more_set_header 'Access-Control-Allow-Headers Content-Type'; + more_set_headers 'Access-Control-Allow-Origin *'; + more_set_headers 'Access-Control-Allow-Methods GET, POST, OPTIONS'; + more_set_headers 'Access-Control-Allow-Headers Content-Type'; } location / { resolver 10.0.0.72; proxy_pass http://planetposen-frontend; - more_set_header 'Access-Control-Allow-Origin planet.schleppe.cloud'; - more_set_header 'Access-Control-Allow-Methods GET, POST, OPTIONS'; - more_set_header 'Access-Control-Allow-Headers Content-Type'; + more_set_headers 'Access-Control-Allow-Origin planet.schleppe.cloud'; + more_set_headers 'Access-Control-Allow-Methods GET, POST, OPTIONS'; + more_set_headers 'Access-Control-Allow-Headers Content-Type'; } ssl_certificate /etc/letsencrypt/live/planet.schleppe.cloud/fullchain.pem; # managed by Certbot diff --git a/snippets/proxy-params.conf b/snippets/proxy-params.conf index 19ddff1..c9a4ab4 100644 --- a/snippets/proxy-params.conf +++ b/snippets/proxy-params.conf @@ -3,4 +3,4 @@ proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; proxy_set_header Host $host; -more_set_header 'X-Proxy-Params Applied'; +more_set_headers 'X-Proxy-Params Applied'; From 7e8a8f826d326e03e2054de3a44574c5862f3662 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 17:35:15 +0100 Subject: [PATCH 20/23] Sign drone config --- .drone.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index 38f8fa8..5366b05 100644 --- a/.drone.yml +++ b/.drone.yml @@ -75,7 +75,7 @@ steps: # - nginx -t -p $PWD -c nginx-module-less.conf # - rm nginx-module-less.conf - - name: Compile modules + - name: Compile nginx & modules image: ubuntu:22.04 commands: - mkdir -p $DRONE_WORKSPACE/nginx-build @@ -149,7 +149,6 @@ steps: -av -e "ssh -i .ssh/id_ed25519 -o StrictHostKeyChecking=no" --exclude available-modules - --exclude sbin --exclude nginx-build modules $NGINX_USER@$NGINX_HOST:/etc/nginx/ environment: @@ -161,6 +160,6 @@ steps: --- kind: signature -hmac: 1b941ff6cc5afce923caebaee1724e778f9963e390bb0ddbbee7c123b17e4aed +hmac: 6ed9cbea425c2de2a531f66069583ec40e77877b7606647dfcf6593b27f3838c ... From 9452242ac761fe94372a79129b762f5158dcd888 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 17:42:51 +0100 Subject: [PATCH 21/23] Deploy all files to remote host --- .drone.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.drone.yml b/.drone.yml index 5366b05..68110a1 100644 --- a/.drone.yml +++ b/.drone.yml @@ -146,11 +146,13 @@ steps: - apk update - apk add rsync openssh - rsync - -av + -avr -e "ssh -i .ssh/id_ed25519 -o StrictHostKeyChecking=no" - --exclude available-modules - --exclude nginx-build - modules $NGINX_USER@$NGINX_HOST:/etc/nginx/ + --exclude=modules-available + --exclude=nginx-build + --exclude=".*" + --exclude="*_temp" + * $NGINX_USER@$NGINX_HOST:/etc/nginx/ environment: NGINX_USER: from_secret: NGINX_USER @@ -160,6 +162,6 @@ steps: --- kind: signature -hmac: 6ed9cbea425c2de2a531f66069583ec40e77877b7606647dfcf6593b27f3838c +hmac: 0a809793762413ba82e7f71d5d77000422cb0532512bd93c5d9d000ffa689564 ... From e0ef0447cf25a66fa166a7ea5d5b12c119709a39 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 18:26:25 +0100 Subject: [PATCH 22/23] Updated README --- README.md | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 255a7b7..3303fbb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,43 @@ -# nginx -Nginx configuration files +# Nginx config + +Includes all nginx sites, snippets & required modules for homelab. + +# Modules + +Current configuration files require the following modules: + - [headers-more-nginx-module](#headers-more-nginx-module) + +We need to compile static modules like this from source (`modules-available/`) into `*.so` dynamic module files that can be loaded from `modules/`.[^1] + + +[^1]: [https://www.nginx.com/resources/wiki/extending/converting](https://www.nginx.com/resources/wiki/extending/converting) + +## headers-more-nginx-module + - [github.com/openresty/headers-more-nginx-module](https://github.com/openresty/headers-more-nginx-module) + +We want to add headers from snippets, and in `server` & `location` blocks, through snippets and define in `location` blocks. Nginx `add_header` directive by design only adds headers if not previously added, this means `server` & snippet headers will be removed from response if `location` block uses `add_header`. + +> There could be several add_header directives. These directives are inherited from the previous configuration level if and only if there are no add_header directives defined on the current level.[^2] + +Instead we use module `headers-more` to replace directive `add_header 'key' 'value'` with `more_set_headers 'key value`. This will prevent removing previously defined headers and enable setting headers from snippets, and in `server` & `location` blocks. + +[^2]: [https://nginx.org/en/docs/http/ngx_http_headers_module.html](https://nginx.org/en/docs/http/ngx_http_headers_module.html) + +# CI/CD + +[Drone CI config file](https://github.com/kevinmidboe/nginx/blob/main/.drone.yml) defines compiling modules from source and transfering to nginx host during deploy step. + +**Setup environment:** +Current configs have references to SSL cert & key location. To validate nginx config with these references dummy cert & key files are created and symlinked to SSL cert & key locations defined in configs. + +**Compiling nginx binary & modules:** +It is setup to pull git submodules and build `modules-available/` from source. This requires us to pull latest nginx source-code, configure it, build and folder reference in `--add-dynamic-module` flag when compiling nginx. + +Since we compile nginx binary from source we need to enable flags for all common nginx modules we use in configs. View flags in [.circleci compile step](https://github.com/kevinmidboe/nginx/blob/main/.drone.yml). Flags currently set (prefix with `--with-{NGINX_MODULE_NAME}`): + + - [http_ssl_module](https://nginx.org/en/docs/http/ngx_http_ssl_module.html) + - [http_v2_module](https://nginx.org/en/docs/http/ngx_http_v2_module.html) + - [http_stub_status_module](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html) + - [http_gzip_static_module](https://nginx.org/en/docs/http/ngx_http_gzip_static_module.html) + - [http_realip_module](https://nginx.org/en/docs/http/ngx_http_realip_module.html) + From 9137856ed24a490ed0535d1b221354df8b81021a Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 10 Nov 2023 18:40:07 +0100 Subject: [PATCH 23/23] Only deploy on main commits --- .drone.yml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/.drone.yml b/.drone.yml index 68110a1..93687ff 100644 --- a/.drone.yml +++ b/.drone.yml @@ -130,15 +130,17 @@ steps: - echo $NGINX_DEPLOY_KEY | base64 -di > .ssh/id_ed25519 - echo "" >> .ssh/id_ed25519 - chmod 600 .ssh/id_ed25519 -# - apk update -# - apk add openssh-client -# - eval $(ssh-agent -s) -# - cat .ssh/id_ed25519 | tr -d '\r' | ssh-add - > /dev/null -# - touch .ssh/known_hosts -# - ssh-keyscan $NGINX_HOST >> .ssh/known_hosts environment: NGINX_DEPLOY_KEY: from_secret: NGINX_DEPLOY_KEY + when: + event: + include: + - push + exclude: + - pull_request + branch: + - main - name: Deploy image: alpine:3.18.4 @@ -158,10 +160,17 @@ steps: from_secret: NGINX_USER NGINX_HOST: from_secret: NGINX_HOST - + when: + event: + include: + - push + exclude: + - pull_request + branch: + - main --- kind: signature -hmac: 0a809793762413ba82e7f71d5d77000422cb0532512bd93c5d9d000ffa689564 +hmac: 7e392f769559ba043b923bbc35197ad955864d15a179979949528362731cbf29 ...