From c7c6e56a1e96828e47e176835a942422dd9889c0 Mon Sep 17 00:00:00 2001 From: Egor Savkin Date: Wed, 19 Jun 2024 15:33:22 +0800 Subject: [PATCH] Document intl node set up Uses strongswan and GRE for mail connection, iptables for port forwarding to the smtp, nginx for website and webhook service, with static files getting uploaded from nixbld Signed-off-by: Egor Savkin --- m-labs-intl/60-tunnels.yaml | 18 +++++++ m-labs-intl/gretun.service | 14 ++++++ m-labs-intl/gretun.sh | 10 ++++ m-labs-intl/gretun_down.sh | 10 ++++ m-labs-intl/m-labs-intl.com | 81 ++++++++++++++++++++++++++++++ m-labs-intl/m-labs.hk.conf | 34 +++++++++++++ m-labs-intl/mail.secret | 0 m-labs-intl/nginx.conf | 65 ++++++++++++++++++++++++ m-labs-intl/rfq.service | 12 +++++ m-labs-intl/runrfq.sh | 14 ++++++ m-labs-intl/setup.md | 99 +++++++++++++++++++++++++++++++++++++ 11 files changed, 357 insertions(+) create mode 100644 m-labs-intl/60-tunnels.yaml create mode 100644 m-labs-intl/gretun.service create mode 100755 m-labs-intl/gretun.sh create mode 100755 m-labs-intl/gretun_down.sh create mode 100644 m-labs-intl/m-labs-intl.com create mode 100644 m-labs-intl/m-labs.hk.conf create mode 100644 m-labs-intl/mail.secret create mode 100644 m-labs-intl/nginx.conf create mode 100644 m-labs-intl/rfq.service create mode 100644 m-labs-intl/runrfq.sh create mode 100644 m-labs-intl/setup.md diff --git a/m-labs-intl/60-tunnels.yaml b/m-labs-intl/60-tunnels.yaml new file mode 100644 index 0000000..ce8594e --- /dev/null +++ b/m-labs-intl/60-tunnels.yaml @@ -0,0 +1,18 @@ +network: + version: 2 + renderer: networkd + ethernets: + eth0: + addresses: + - 5.78.86.156/32 + - 2a01:4ff:1f0:83de::2/64 + - 2a01:4ff:1f0:83de::3/64 + - 2a01:4ff:1f0:83de::4/64 + tunnels: + gre1: + mode: gre + local: 5.78.86.156 + remote: 94.190.212.123 + addresses: + - 10.47.3.0/31 + diff --git a/m-labs-intl/gretun.service b/m-labs-intl/gretun.service new file mode 100644 index 0000000..0576dc2 --- /dev/null +++ b/m-labs-intl/gretun.service @@ -0,0 +1,14 @@ +[Unit] +Description=GRE tunnel to the main host +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/root/gretun.sh +ExecStop=/root/gretun_down.sh +Restart=on-failure +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/m-labs-intl/gretun.sh b/m-labs-intl/gretun.sh new file mode 100755 index 0000000..8bb0882 --- /dev/null +++ b/m-labs-intl/gretun.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +/usr/sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 25 -j DNAT --to-destination 10.47.3.1:25 +/usr/sbin/iptables -A FORWARD -p tcp -d 10.47.3.1/31 --dport 25 -j ACCEPT + +/usr/sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 587 -j DNAT --to-destination 10.47.3.1:587 +/usr/sbin/iptables -A FORWARD -p tcp -d 10.47.3.1/31 --dport 587 -j ACCEPT + +/usr/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT +/usr/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE diff --git a/m-labs-intl/gretun_down.sh b/m-labs-intl/gretun_down.sh new file mode 100755 index 0000000..b968a12 --- /dev/null +++ b/m-labs-intl/gretun_down.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +/usr/sbin/iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 25 -j DNAT --to-destination 10.47.3.1:25 +/usr/sbin/iptables -D FORWARD -p tcp -d 10.47.3.1/31 --dport 25 -j ACCEPT + +/usr/sbin/iptables -t nat -D PREROUTING -p tcp -i eth0 --dport 587 -j DNAT --to-destination 10.47.3.1:587 +/usr/sbin/iptables -D FORWARD -p tcp -d 10.47.3.1/31 --dport 587 -j ACCEPT + +/usr/sbin/iptables -D FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT +/usr/sbin/iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE diff --git a/m-labs-intl/m-labs-intl.com b/m-labs-intl/m-labs-intl.com new file mode 100644 index 0000000..7e76e8c --- /dev/null +++ b/m-labs-intl/m-labs-intl.com @@ -0,0 +1,81 @@ +upstream rfq_server { + server 127.0.0.1:5000; +} + +server { + limit_conn addr 5; + + root /var/www/m-labs-intl.com/html; + index index.html index.htm index.nginx-debian.html; + + server_name m-labs-intl.com; + + location / { + try_files $uri $uri/ =404; + } + + listen [::]:443 ssl ipv6only=on; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/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 +} + +server { + server_name www.m-labs-intl.com; + return 301 https://m-labs-intl.com$request_uri; + + listen [::]:443 ssl; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/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 +} + +server { + server_name hooks.m-labs-intl.com; + limit_conn addr 5; + + location /rfq { + proxy_pass http://rfq_server/rfq; + 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_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 30; + proxy_connect_timeout 30; + proxy_send_timeout 30; + } + + location / { + return 418; + } + + listen [::]:443 ssl; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/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 +} + +server { + limit_conn addr 5; + if ($host = m-labs-intl.com) { + return 301 https://$host$request_uri; + } # managed by Certbot + + + if ($host = www.m-labs-intl.com) { + return 301 https://m-labs-intl.com$request_uri; + } # managed by Certbot + + + listen 80; + listen [::]:80; + + server_name m-labs-intl.com www.m-labs-intl.com hooks.m-labs-intl.com; + return 301 https://$host$request_uri; +} \ No newline at end of file diff --git a/m-labs-intl/m-labs.hk.conf b/m-labs-intl/m-labs.hk.conf new file mode 100644 index 0000000..ba2a34a --- /dev/null +++ b/m-labs-intl/m-labs.hk.conf @@ -0,0 +1,34 @@ + + +connections { + m_labs { + version = 2 + encap = no + mobike = no + send_certreq = no + proposals = aes128gcm128-sha256-prfsha256-curve25519,aes128gcm128-sha256-prfsha256-ecp256 + local_addrs = 5.78.86.156 + remote_addrs = 94.190.212.123 + local { + auth = pubkey + id = fqdn:m-labs-intl.com + pubkeys = m-labs-intl.com + } + remote { + auth = pubkey + id = fqdn:m-labs.hk + pubkeys = m-labs.hk + } + children { + con1 { + mode = transport + ah_proposals = sha256-curve25519,sha256-ecp256 + esp_proposals = + local_ts = 5.78.86.156[gre] + remote_ts = 94.190.212.123[gre] + start_action = start + close_action = none + } + } + } +} \ No newline at end of file diff --git a/m-labs-intl/mail.secret b/m-labs-intl/mail.secret new file mode 100644 index 0000000..e69de29 diff --git a/m-labs-intl/nginx.conf b/m-labs-intl/nginx.conf new file mode 100644 index 0000000..9e0d8b8 --- /dev/null +++ b/m-labs-intl/nginx.conf @@ -0,0 +1,65 @@ +user www-data; +worker_processes auto; +pid /run/nginx.pid; +error_log /var/log/nginx/error.log; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + types_hash_max_size 2048; + # server_tokens off; + + server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + # Rate limiting + limit_conn_zone $binary_remote_addr zone=addr:10m; + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + + ## + # Gzip Settings + ## + + gzip on; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} + diff --git a/m-labs-intl/rfq.service b/m-labs-intl/rfq.service new file mode 100644 index 0000000..79b6858 --- /dev/null +++ b/m-labs-intl/rfq.service @@ -0,0 +1,12 @@ +[Unit] +Description=RFQ service +After=network.target + +[Service] +Type=simple +User=rfqserver +ExecStart=/home/rfqserver/runrfq.sh +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/m-labs-intl/runrfq.sh b/m-labs-intl/runrfq.sh new file mode 100644 index 0000000..c728d38 --- /dev/null +++ b/m-labs-intl/runrfq.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +export FLASK_DEBUG=0 +export FLASK_MAIL_SERVER=mail.m-labs.hk +export FLASK_MAIL_PORT=465 +export FLASK_MAIL_USE_SSL=True +export FLASK_MAIL_USERNAME=sysop-intl@m-labs-intl.com +export FLASK_MAIL_PASSWORD_FILE=/home/rfqserver/mail.secret +export FLASK_MAIL_RECIPIENT=sales@m-labs.hk +export FLASK_MAIL_SENDER=sysop-intl@m-labs-intl.com + +cd /home/rfqserver/web2019/server +source venv/bin/activate +python3 -m flask --app rfq run --port=5000 \ No newline at end of file diff --git a/m-labs-intl/setup.md b/m-labs-intl/setup.md new file mode 100644 index 0000000..7923aa1 --- /dev/null +++ b/m-labs-intl/setup.md @@ -0,0 +1,99 @@ +# Setup m-labs-intl.com server + +```shell +# Install required packages +apt install git nginx-full python3 python3.12-venv python3-pip iptables ufw \ + strongswan strongswan-swanctl strongswan-pki strongswan-libcharon +snap install --classic certbot +ln -s /snap/bin/certbot /usr/bin/certbot + +# Set up networks (includes GRE) +cp 60-tunnels.yaml /etc/netplan/ +netplan apply + +# set up IPsec-AH connection +cp m-labs.hk.conf /etc/swanctl/conf.d/ +echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf +sysctl -p +cp m-labs.hk /etc/swanctl/pubkey/m-labs.hk # get pubkey from nixbld +pki --gen --type rsa --size 4096 --outform pem > /etc/swanctl/private/m-labs-intl.com +pki --pub --in /etc/swanctl/private/m-labs-intl.com --outform pem > /etc/swanctl/pubkey/m-labs-intl.com +cp /etc/swanctl/pubkey/m-labs-intl.com m-labs-intl.com # add it to the nixbld +systemctl enable strongswan --now +systemctl restart strongswan + +# Set up website +cp m-labs-intl.com /etc/nginx/sites-available/ +cp nginx.conf /etc/nginx/ +ln -s /etc/nginx/sites-available/m-labs-intl.com /etc/nginx/sites-enabled/ +systemctl enable nginx --now +service nginx restart + +# Issue SSL certificate - website only, the mail is on the HK side +certbot --nginx +service nginx restart + +# Create a user for automatic website deployment from nixbld +useradd -m zolaupd +mkdir -p /var/www/m-labs-intl.com/html +chown -R zolaupd /var/www/m-labs-intl.com/ +sudo -u zolaupd sh -c ' + cd /home/zolaupd; + mkdir /home/zolaupd/.ssh; + echo -n "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP1OJJM8g/1ffxDjN31XKEfGmrYaW03lwpyTa1UGWqVx + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF6R6XK0IiuAKxVKvSABm4m9bfOlvfJcMvTpjenuXUPv" > /home/zolaupd/.ssh/authorized_keys + chmod 700 .ssh/ + chmod 600 .ssh/authorized_keys + ' + +# Create a user for RFQ hooks service +useradd -m rfqserver +cp runrfq.sh /home/rfqserver/ +cp mail.secret /home/rfqserver/ +chown rfqserver /home/rfqserver/runrfq.sh +chmod +x /home/rfqserver/runrfq.sh +chown rfqserver /home/rfqserver/mail.secret + +sudo -u rfqserver sh -c ' + cd /home/rfqserver; + git clone https://git.m-labs.hk/M-Labs/web2019.git; + cd web2019; + python3 -m venv ./venv; + source venv/bin/activate; + pip install -r requirements.txt; +' +cp rfq.service /etc/systemd/system/ + +# Automate port forwarding rules creation +cp gretun.sh /root/gretun.sh +cp gretun_down.sh /root/gretun_down.sh +chmod u+x /root/gretun.sh +chmod u+x /root/gretun_down.sh +cp gretun.service /etc/systemd/system/ + +# Enable custom services +systemctl daemon-reload +systemctl enable rfq.service --now +systemctl enable gretun.service --now + +# Setup basic firewall rules +ufw default deny +ufw default allow outgoing + +ufw allow from 94.190.212.123 +ufw allow from 2001:470:f891:1::/64 +ufw allow from 202.77.7.238 +ufw allow from 2001:470:18:390::2 +ufw allow "Nginx HTTP" +ufw allow "Nginx HTTPS" +ufw limit OpenSSH +ufw allow 25/tcp +ufw allow 587/tcp +ufw limit 500,4500/udp + +ufw route allow in on gre1 out on eth0 +ufw allow from 10.47.3.0/31 + +ufw show added +ufw enable +``` \ No newline at end of file