From 8e7b08392008329ef74c9ad6f22265783b20809d Mon Sep 17 00:00:00 2001 From: Adar Nimrod <nimrod@shore.co.il> Date: Mon, 23 Nov 2020 10:01:03 +0200 Subject: [PATCH] My work thus far. --- .dockerignore | 4 + .env | 1 + .gitlab-ci.yml | 46 ++++++++++ .pre-commit-config.yaml | 34 ++++++++ Dockerfile | 29 +++++++ conf.d/autoconfig.shore.co.il.conf | 15 ++++ conf.d/git.shore.co.il.conf | 24 ++++++ conf.d/global.conf | 7 ++ conf.d/mail.shore.co.il.conf | 27 ++++++ conf.d/nextcloud.shore.co.il.conf | 25 ++++++ conf.d/registry.shore.co.il.conf | 23 +++++ conf.d/shore.co.il.conf | 25 ++++++ conf.d/status.conf | 7 ++ conf.d/www.shore.co.il.conf | 83 +++++++++++++++++++ docker-compose.yml | 32 +++++++ snippets/allow-private-ips.conf | 5 ++ snippets/common-headers.conf | 5 ++ snippets/nextcloud-well-known.conf | 11 +++ snippets/proxy-headers.conf | 5 ++ snippets/redirect-https.conf | 1 + snippets/ssl.conf | 13 +++ snippets/www-acme-challenge.conf | 1 + snippets/z-push.conf | 19 +++++ .../mail/config-v1.1.xml | 24 ++++++ www/mail.shore.co.il/.well-known/mta-sts.txt | 4 + .../google88c23a5c89fa3cb3.html | 1 + www/www.shore.co.il/robots.txt | 3 + 27 files changed, 474 insertions(+) create mode 100644 .dockerignore create mode 100644 .env create mode 100644 .gitlab-ci.yml create mode 100644 .pre-commit-config.yaml create mode 100644 Dockerfile create mode 100644 conf.d/autoconfig.shore.co.il.conf create mode 100644 conf.d/git.shore.co.il.conf create mode 100644 conf.d/global.conf create mode 100644 conf.d/mail.shore.co.il.conf create mode 100644 conf.d/nextcloud.shore.co.il.conf create mode 100644 conf.d/registry.shore.co.il.conf create mode 100644 conf.d/shore.co.il.conf create mode 100644 conf.d/status.conf create mode 100644 conf.d/www.shore.co.il.conf create mode 100644 docker-compose.yml create mode 100644 snippets/allow-private-ips.conf create mode 100644 snippets/common-headers.conf create mode 100644 snippets/nextcloud-well-known.conf create mode 100644 snippets/proxy-headers.conf create mode 100644 snippets/redirect-https.conf create mode 100644 snippets/ssl.conf create mode 100644 snippets/www-acme-challenge.conf create mode 100644 snippets/z-push.conf create mode 100644 www/autoconfig.shore.co.il/mail/config-v1.1.xml create mode 100644 www/mail.shore.co.il/.well-known/mta-sts.txt create mode 100644 www/www.shore.co.il/google88c23a5c89fa3cb3.html create mode 100644 www/www.shore.co.il/robots.txt diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..380e2e6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +* +!conf.d/ +!www/ +!snippets/ diff --git a/.env b/.env new file mode 100644 index 0000000..2f5dd33 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +COMPOSE_PROJECT_NAME=web-proxy diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..23796b5 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,46 @@ +--- +image: adarnimrod/ci-images:docker + +stages: + - test + - build + - run + +pre-commit: + stage: test + image: adarnimrod/ci-images:pre-commit + variables: + XDG_CACHE_HOME: "$CI_PROJECT_DIR/.cache" + # Disabled until https://github.com/pre-commit/pre-commit/issues/1387 is + # resolved. + SKIP: "hadolint,docker-compose" + script: + - pre-commit run --all-files + cache: + paths: + - .cache/ + +build: + stage: build + tags: ["host01.shore.co.il"] + variables: + COMPOSE_DOCKER_CLI_BUILD: "1" + DOCKER_BUILDKIT: "1" + script: + - docker-compose build --no-cache --pull + - docker-compose pull --quiet + +run: + stage: run + tags: ["host01.shore.co.il"] + when: manual + script: + - docker-compose up --detach --remove-orphans + # yamllint disable rule:line-length + - | + for i in $(seq 12) + do + docker container inspect --format '{{ .State.Health.Status }}' $(docker-compose ps -q) | grep -v '^healthy$' || break + sleep 10 + done + ! docker container inspect --format '{{ .State.Health.Status }}' $(docker-compose ps -q) | grep -v '^healthy$' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7e1749c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,34 @@ +# vim:ff=unix ts=2 sw=2 ai expandtab +--- +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-added-large-files + - id: check-merge-conflict + - id: detect-private-key + - id: trailing-whitespace + - repo: https://github.com/adrienverge/yamllint + rev: v1.17.0 + hooks: + - id: yamllint + - repo: https://github.com/amperser/proselint/ + rev: 0.10.2 + hooks: + - id: proselint + types: [plain-text] + exclude: LICENSE + - repo: https://github.com/Yelp/detect-secrets + rev: v0.13.0 + hooks: + - id: detect-secrets + - repo: https://git.shore.co.il/nimrod/docker-pre-commit.git/ + rev: v0.3.0 + hooks: + - id: docker-compose + - id: hadolint + - repo: https://git.shore.co.il/nimrod/shell-pre-commit.git/ + rev: v0.6.0 + hooks: + - id: shell-lint + - id: shellcheck diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0671814 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM nginx:1.19-alpine +# hadolint ignore=DL3018 +RUN rm -rf /etc/nginx/conf./* && \ + chmod 777 /run && \ + apk add --no-cache --update libcap openssl && \ + curl https://letsencrypt.org/certs/isrg-root-ocsp-x1.pem.txt > /etc/ssl/ocsp.pem && \ + mkdir /var/ssl &&\ + curl https://ssl-config.mozilla.org/ffdhe2048.txt > /var/ssl/dhparams &&\ + chmod 644 /var/ssl/dhparams && \ + install -d -m 755 -o root -g root /etc/nginx/snippets && \ + install -d -m 755 -o root -g root /var/ssl && \ + install -d -m 700 -o nginx -g nginx /var/cache/nginx && \ + openssl req -x509 \ + -newkey rsa:4096 \ + -keyout /var/ssl/site.key \ + -nodes \ + -out /var/ssl/site.crt \ + -days 2 \ + -subj "/C=US/ST=IL/L=None/O=None/OU=None/CN=localhost/" && \ + cp /var/ssl/site.crt /var/ssl/mail.crt && \ + cp /var/ssl/site.key /var/ssl/mail.key && \ + setcap CAP_NET_BIND_SERVICE=+ep "$(command -v nginx)" && \ + chown nginx /var/ssl/site.* /var/ssl/mail.* +COPY www/ /var/www/ +COPY conf.d/ /etc/nginx/conf.d/ +COPY snippets/ /etc/nginx/snippets/ +USER nginx +RUN nginx -t +HEALTHCHECK CMD curl --fail --verbose --user-agent 'Docker health check' http://localhost/ || exit 1 diff --git a/conf.d/autoconfig.shore.co.il.conf b/conf.d/autoconfig.shore.co.il.conf new file mode 100644 index 0000000..62b1be4 --- /dev/null +++ b/conf.d/autoconfig.shore.co.il.conf @@ -0,0 +1,15 @@ +server { + listen 80; + listen [::]:80; + server_name autoconfig.shore.co.il; + root /var/www/autoconfig.shore.co.il/; + include snippets/www-acme-challenge.conf; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name autoconfig.shore.co.il; + root /var/www/autoconfig.shore.co.il/; + include snippets/ssl.conf; +} diff --git a/conf.d/git.shore.co.il.conf b/conf.d/git.shore.co.il.conf new file mode 100644 index 0000000..733fa63 --- /dev/null +++ b/conf.d/git.shore.co.il.conf @@ -0,0 +1,24 @@ +map $host $git { default gitlab; } + +server { + listen 80; + listen [::]:80; + server_name git.shore.co.il; + include snippets/www-acme-challenge.conf; + include snippets/redirect-https.conf; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name git.shore.co.il; + include snippets/ssl.conf; + + location / { + proxy_pass http://$git$request_uri; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + proxy_set_header X-Forwarded-Ssl on; + client_max_body_size 512m; + } +} diff --git a/conf.d/global.conf b/conf.d/global.conf new file mode 100644 index 0000000..664abdf --- /dev/null +++ b/conf.d/global.conf @@ -0,0 +1,7 @@ +# The resolver for the Docker network. +resolver 127.0.0.11; +gzip on; +tcp_nopush on; +tcp_nodelay on; +server_tokens off; +include snippets/common-headers.conf; diff --git a/conf.d/mail.shore.co.il.conf b/conf.d/mail.shore.co.il.conf new file mode 100644 index 0000000..ed74238 --- /dev/null +++ b/conf.d/mail.shore.co.il.conf @@ -0,0 +1,27 @@ +server { + listen 80; + listen [::]:80; + server_name imap.shore.co.il smtp.shore.co.il mta-sts.shore.co.il; + root /var/www/mail.shore.co.il/; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name mta-sts.shore.co.il; + root /var/www/mail.shore.co.il/; + + # Copied from snippetes/ssl.conf. + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; + include snippets/common-headers.conf; + ssl_certificate /var/ssl/mail.crt; + ssl_certificate_key /var/ssl/mail.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers !kRSA:!3DES:!RC4:!DES:!MD5:!aNULL:!NULL:AESGCM+ECDH:AES256+ECDH:AES128:+SHA1; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:50m; + ssl_session_timeout 5m; + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate /etc/ssl/ocsp.pem; +} diff --git a/conf.d/nextcloud.shore.co.il.conf b/conf.d/nextcloud.shore.co.il.conf new file mode 100644 index 0000000..19b8a1d --- /dev/null +++ b/conf.d/nextcloud.shore.co.il.conf @@ -0,0 +1,25 @@ +map $host $nextcloud { default nextcloud; } + +server { + listen 80; + listen [::]:80; + server_name nextcloud.shore.co.il; + include snippets/www-acme-challenge.conf; + include snippets/redirect-https.conf; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name nextcloud.shore.co.il; + include snippets/ssl.conf; + include snippets/nextcloud-well-known.conf; + + location / { + proxy_pass http://$nextcloud$request_uri; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + proxy_hide_header X-Frame-Options; + client_max_body_size 512m; + } +} diff --git a/conf.d/registry.shore.co.il.conf b/conf.d/registry.shore.co.il.conf new file mode 100644 index 0000000..07a2902 --- /dev/null +++ b/conf.d/registry.shore.co.il.conf @@ -0,0 +1,23 @@ +map $host $registry { default registy; } + +server { + listen 80; + listen [::]:80; + server_name registry.shore.co.il; + include snippets/www-acme-challenge.conf; + include snippets/redirect-https.conf; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name registry.shore.co.il; + include snippets/ssl.conf; + + location / { + proxy_pass http://$registry$request_uri; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + include snippets/allow-private-ips.conf; + } +} diff --git a/conf.d/shore.co.il.conf b/conf.d/shore.co.il.conf new file mode 100644 index 0000000..543f0bb --- /dev/null +++ b/conf.d/shore.co.il.conf @@ -0,0 +1,25 @@ +map $host $z_push { default z-push; } + +server { + listen 80; + listen [::]:80; + server_name shore.co.il; + location = / { return 301 https://$host/blog/; } + location /repo/ { + root /var/www/www.shore.co.il/; + autoindex on; + } + include snippets/redirect-https.conf; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name shore.co.il; + include snippets/ssl.conf; + include snippets/nextcloud-well-known.conf; + include snippets/z-push.conf; + + location = / { return 301 https://www.shore.co.il/blog/; } + location / { return 301 https://www.shore.co.il$request_uri; } +} diff --git a/conf.d/status.conf b/conf.d/status.conf new file mode 100644 index 0000000..6ecb7d8 --- /dev/null +++ b/conf.d/status.conf @@ -0,0 +1,7 @@ +server { + listen 80; + listen [::]:80; + server_name status; + location = / { stub_status; } + include snippets/allow-private-ips.conf; +} diff --git a/conf.d/www.shore.co.il.conf b/conf.d/www.shore.co.il.conf new file mode 100644 index 0000000..a2fdeaa --- /dev/null +++ b/conf.d/www.shore.co.il.conf @@ -0,0 +1,83 @@ +map $host $cgit { default cgit; } +map $host $lam { default ldap-account-manager; } +map $host $kodi { default kodi.shore.co.il; } + +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name www.shore.co.il; + location = / { return 301 https://$host/blog/; } + location /repo/ { + root /var/www/www.shore.co.il/; + autoindex on; + } + location / { return 301 https://$host$request_uri; } +} + +server { + listen 443 ssl default_server; + listen [::]:443 ssl default_server; + server_name www.shore.co.il; + include snippets/ssl.conf; + root /var/www/www.shore.co.il/; + error_page 404 /; + + location /repo/ { autoindex on; } + location = /resume { try_files $uri /resume/resume.html; } + location = /resume/ { index resume.html; } + + location = / { return 301 https://$host/blog/; } + location /about { return 301 https://$host/blog/pages/about-me.html; } + location /spam { return 301 https://$host/blog/pages/spam.html; } + location = /blog { + try_files $uri /blog/index.html; + charset UTF-8; + } + + location /cgit/ { + proxy_pass http://$cgit$uri; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + } + + location /git { + rewrite ^/git /cgit/; + } + + location /git/ { + rewrite ^/git/(.*) /cgit/$1; + } + + location /cgit-css/ { + proxy_pass http://$cgit$request_uri; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + } + + location /lam { + proxy_pass http://$lam$request_uri; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + include snippets/allow-private-ips.conf; + } + + location /jellyfin { return 302 $scheme://$host/jellyfin/; } + location /jellyfin/ { + proxy_pass http://$kodi:8096/jellyfin/; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + include snippets/common-headers.conf; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + + # Disable buffering when the nginx proxy gets very resource heavy upon streaming + proxy_buffering off; + } + + location /d16ebf5287f85724083b0e20a9c300f3/ { + proxy_pass http://kodi.shore.co.il:9091/; + proxy_http_version 1.1; + include snippets/proxy-headers.conf; + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f60cc75 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +--- +version: '3.5' +services: + proxy: + build: + context: ./ + #command: ["nginx", "-g", "daemon off;"] + hostname: &hostname www.shore.co.il + networks: + default: + aliases: + - *hostname + - nextcloud.shore.co.il + - git.shore.co.il + ports: + - '80:80' + - '443:443' + restart: always + volumes: + - '/var/www/www.shore.co.il/blog:/var/www/www.shore.co.il/blog:ro' + - '/var/www/www.shore.co.il/resume:/var/www/www.shore.co.il/resume:ro' + - '/var/www/www.shore.co.il/.well-known/acme-challenge:/var/www/www.shore.co.il/.well-known/acme-challenge:ro' + - '/var/www/mail.shore.co.il/.well-known/acme-challenge:/var/www/mail.shore.co.il/.well-known/acme-challenge:ro' + - '/var/ssl/site.key:/var/ssl/site.key:ro' + - '/var/ssl/site.crt:/var/ssl/site.crt:ro' + - '/var/ssl/mail.key:/var/ssl/mail.key:ro' + - '/var/ssl/mail.crt:/var/ssl/mail.crt:ro' + - '/var/ssl/dhparams:/var/ssl/dhparams:ro' + +networks: + default: + name: shore diff --git a/snippets/allow-private-ips.conf b/snippets/allow-private-ips.conf new file mode 100644 index 0000000..154262a --- /dev/null +++ b/snippets/allow-private-ips.conf @@ -0,0 +1,5 @@ +allow 127.0.0.0/8; +allow 10.0.0.0/8; +allow 192.168.0.0/16; +allow 172.16.0.0/12; +deny all; diff --git a/snippets/common-headers.conf b/snippets/common-headers.conf new file mode 100644 index 0000000..84e4742 --- /dev/null +++ b/snippets/common-headers.conf @@ -0,0 +1,5 @@ +# add_headers are inherited from previous level if and only if there are no +# add_header directives defined on the current level. So any time there's an +# add_header directive there should be an `include snippets/common-headers.conf` +# directive as well. +add_header X-Frame-Options SAMEORIGIN always; diff --git a/snippets/nextcloud-well-known.conf b/snippets/nextcloud-well-known.conf new file mode 100644 index 0000000..f615565 --- /dev/null +++ b/snippets/nextcloud-well-known.conf @@ -0,0 +1,11 @@ +location /.well-known/caldav { + return 301 https://nextcloud.shore.co.il/remote.php/dav; +} + +location /.well-known/carddav { + return 301 https://nextcloud.shore.co.il/remote.php/dav; +} + +location /.well-known/webfinger { + return 301 https://nextcloud.shore.co.il/public.php?service=webfinger; +} diff --git a/snippets/proxy-headers.conf b/snippets/proxy-headers.conf new file mode 100644 index 0000000..30311b6 --- /dev/null +++ b/snippets/proxy-headers.conf @@ -0,0 +1,5 @@ +proxy_set_header X-Forwarded-Host $host; +proxy_set_header X-Forwarded-Proto $scheme; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; diff --git a/snippets/redirect-https.conf b/snippets/redirect-https.conf new file mode 100644 index 0000000..991d593 --- /dev/null +++ b/snippets/redirect-https.conf @@ -0,0 +1 @@ +location / { return 301 https://$host$request_uri; } diff --git a/snippets/ssl.conf b/snippets/ssl.conf new file mode 100644 index 0000000..a209d98 --- /dev/null +++ b/snippets/ssl.conf @@ -0,0 +1,13 @@ +add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; +include snippets/common-headers.conf; +ssl_certificate /var/ssl/site.crt; +ssl_certificate_key /var/ssl/site.key; +ssl_dhparam /var/ssl/dhparams; +ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; +ssl_ciphers !kRSA:!3DES:!RC4:!DES:!MD5:!aNULL:!NULL:AESGCM+ECDH:AES256+ECDH:AES128:+SHA1; +ssl_prefer_server_ciphers on; +ssl_session_cache shared:SSL:50m; +ssl_session_timeout 5m; +ssl_stapling on; +ssl_stapling_verify on; +ssl_trusted_certificate /etc/ssl/ocsp.pem; diff --git a/snippets/www-acme-challenge.conf b/snippets/www-acme-challenge.conf new file mode 100644 index 0000000..ba3c0b7 --- /dev/null +++ b/snippets/www-acme-challenge.conf @@ -0,0 +1 @@ +location /.well-known/acme-challenge/ { root /var/www/www.shore.co.il; } diff --git a/snippets/z-push.conf b/snippets/z-push.conf new file mode 100644 index 0000000..85a21d6 --- /dev/null +++ b/snippets/z-push.conf @@ -0,0 +1,19 @@ +location /AutoDiscover/ { + proxy_pass http://$z_push$request_uri; + include snippets/proxy-headers.conf; +} + +location /Autodiscover/ { + proxy_pass http://$z_push$request_uri; + include snippets/proxy-headers.conf; +} + +location /autodiscover/ { + proxy_pass http://$z_push$request_uri; + include snippets/proxy-headers.conf; +} + +location /Microsoft-Server-ActiveSync { + proxy_pass http://$z_push$request_uri; + include snippets/proxy-headers.conf; +} diff --git a/www/autoconfig.shore.co.il/mail/config-v1.1.xml b/www/autoconfig.shore.co.il/mail/config-v1.1.xml new file mode 100644 index 0000000..47a4197 --- /dev/null +++ b/www/autoconfig.shore.co.il/mail/config-v1.1.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<clientConfig version="1.1"> + <emailProvider id="shore.co.il"> + <domain>shore.co.il</domain> + <displayName>Shore technologies</displayName> + <displayShortName>Shore</displayShortName> + <incomingServer type="imap"> + <hostname>imap.shore.co.il</hostname> + <port>993</port> + <socketType>SSL</socketType> + <authentication>password-cleartext</authentication> + <username>%EMAILLOCALPART%</username> + </incomingServer> + <outgoingServer type="smtp"> + <hostname>smtp.shore.co.il</hostname> + <port>587</port> + <socketType>STARTTLS</socketType> + <authentication>password-cleartext</authentication> + <username>%EMAILLOCALPART%</username> + </outgoingServer> + </emailProvider> +</clientConfig> + diff --git a/www/mail.shore.co.il/.well-known/mta-sts.txt b/www/mail.shore.co.il/.well-known/mta-sts.txt new file mode 100644 index 0000000..d81ad3b --- /dev/null +++ b/www/mail.shore.co.il/.well-known/mta-sts.txt @@ -0,0 +1,4 @@ +version: STSv1 +mode: testing +mx: smtp.shore.co.il +max_age: 86400 diff --git a/www/www.shore.co.il/google88c23a5c89fa3cb3.html b/www/www.shore.co.il/google88c23a5c89fa3cb3.html new file mode 100644 index 0000000..ceace0b --- /dev/null +++ b/www/www.shore.co.il/google88c23a5c89fa3cb3.html @@ -0,0 +1 @@ +google-site-verification: google88c23a5c89fa3cb3.html \ No newline at end of file diff --git a/www/www.shore.co.il/robots.txt b/www/www.shore.co.il/robots.txt new file mode 100644 index 0000000..5a6f1a9 --- /dev/null +++ b/www/www.shore.co.il/robots.txt @@ -0,0 +1,3 @@ +User-agent: * +Crawl-delay: 3600 +Host: www.shore.co.il -- GitLab