328 lines
8.9 KiB
Bash
Executable File
328 lines
8.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
positional_args=()
|
|
original_args="${@@Q}"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--domain)
|
|
domain="$2"
|
|
shift # past argument
|
|
shift # past value
|
|
;;
|
|
--upstream-server)
|
|
upstream_server="$2"
|
|
shift # past argument
|
|
shift # past value
|
|
;;
|
|
--upstream-base)
|
|
upstream_base="$2"
|
|
shift # past argument
|
|
shift # past value
|
|
;;
|
|
--target-server)
|
|
target_server="$2"
|
|
shift # past argument
|
|
shift # past value
|
|
;;
|
|
--acme-email)
|
|
acme_email="$2"
|
|
shift # past argument
|
|
shift # past value
|
|
;;
|
|
--is-in-target)
|
|
is_in_target=1
|
|
shift # past argument
|
|
;;
|
|
--pass-header)
|
|
pass_headers="$pass_headers
|
|
proxy_set_header $2 '$3';"
|
|
shift # past argument
|
|
shift # past value
|
|
shift # past value
|
|
;;
|
|
-*|--*)
|
|
echo "Unknown option $1"
|
|
exit 1
|
|
;;
|
|
*)
|
|
positional_args+=("$1") # save positional arg
|
|
shift # past argument
|
|
;;
|
|
esac
|
|
done
|
|
|
|
set -- "${positional_args[@]}" # restore positional parameters
|
|
|
|
# check if self is in target server
|
|
if [ -z "$is_in_target" ]; then
|
|
# we're still in the user's pc
|
|
# make sure we have all the required arguments
|
|
if [ -z "$domain" ] \
|
|
|| [ -z "$upstream_server" ] \
|
|
|| [ -z "$acme_email" ] \
|
|
|| [ -z "$target_server" ]; then
|
|
echo "Usage: $0 --domain <domain> --upstream-server <https://domain:port> --upstream-base </some/path/> --acme-email <your.email@domain.co> --target-server <user@host> [--pass-header Header Value]"
|
|
exit 1
|
|
fi
|
|
|
|
target_filename=$(mktemp -u)
|
|
|
|
echo "Copying self to target server..."
|
|
scp $0 $target_server:$target_filename
|
|
|
|
echo "Executing setup script on target server..."
|
|
ssh $target_server "$target_filename --is-in-target $original_args"
|
|
|
|
# exit
|
|
exit 0
|
|
fi
|
|
|
|
# we're now on the target server
|
|
# make sure we're root
|
|
if [ "$(id -u)" != "0" ]; then
|
|
echo "This script must be run as root"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Installing dependencies..."
|
|
cat <<EOF > /etc/apt/sources.list.d/nginx.list
|
|
deb https://nginx.org/packages/ubuntu/ focal nginx
|
|
deb-src https://nginx.org/packages/ubuntu/ focal nginx
|
|
EOF
|
|
|
|
while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do
|
|
echo "Waiting for dpkg lock to be free..."
|
|
sleep 0.5
|
|
done
|
|
|
|
|
|
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
|
|
apt-get update && \
|
|
apt-get upgrade -y && \
|
|
apt-get install -y nginx socat
|
|
|
|
# Fix firewall
|
|
if command -v ufw >/dev/null 2>&1; then
|
|
echo "Adding firewall rules..."
|
|
ufw allow http
|
|
ufw allow https
|
|
fi
|
|
|
|
echo "Downloading acme.sh..."
|
|
wget -O - https://get.acme.sh | sh -s email=$acme_email
|
|
|
|
echo "Issuing certificate..."
|
|
systemctl stop nginx
|
|
~/.acme.sh/acme.sh --issue -d $domain --server letsencrypt --standalone
|
|
systemctl start nginx
|
|
~/.acme.sh/acme.sh --install-cert -d $domain \
|
|
--cert-file /etc/nginx/ssl.crt \
|
|
--key-file /etc/nginx/ssl.key \
|
|
--fullchain-file /etc/nginx/ssl.pem \
|
|
--reloadcmd "systemctl reload nginx"
|
|
|
|
# create directories
|
|
mkdir -p /var/cache/nginx/proxy_cache
|
|
|
|
# create the nginx config file
|
|
echo "Setting up nginx"
|
|
cat <<EOF > /etc/nginx/cors.conf
|
|
proxy_hide_header 'Access-Control-Allow-Origin';
|
|
proxy_hide_header 'Access-Control-Allow-Methods';
|
|
proxy_hide_header 'Access-Control-Allow-Headers';
|
|
proxy_hide_header 'Access-Control-Expose-Headers';
|
|
|
|
if (\$request_method = 'OPTIONS') {
|
|
add_header 'Access-Control-Allow-Origin' '*';
|
|
add_header 'Access-Control-Allow-Methods' 'HEAD, GET, POST, OPTIONS';
|
|
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
|
add_header 'Access-Control-Max-Age' 1728000;
|
|
add_header 'Content-Type' 'text/plain; charset=utf-8';
|
|
add_header 'Content-Length' 0;
|
|
return 204;
|
|
}
|
|
if (\$request_method = 'POST') {
|
|
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, POST, OPTIONS' always;
|
|
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
|
|
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
}
|
|
if (\$request_method = 'GET') {
|
|
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, POST, OPTIONS' always;
|
|
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
|
|
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
}
|
|
if (\$request_method = 'HEAD') {
|
|
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, POST, OPTIONS' always;
|
|
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
|
|
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
|
}
|
|
EOF
|
|
cat <<EOF > /etc/nginx/nginx.conf
|
|
user www-data;
|
|
worker_processes auto;
|
|
pid /run/nginx.pid;
|
|
include /etc/nginx/modules-enabled/*.conf;
|
|
|
|
events {
|
|
worker_connections 1048576;
|
|
multi_accept on;
|
|
use epoll;
|
|
}
|
|
|
|
http {
|
|
# Basic settings
|
|
sendfile on;
|
|
tcp_nopush on;
|
|
tcp_nodelay on;
|
|
server_tokens off;
|
|
keepalive_timeout 300s;
|
|
types_hash_max_size 2048;
|
|
|
|
include /etc/nginx/mime.types;
|
|
default_type application/octet-stream;
|
|
|
|
# SSL settings
|
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
|
|
ssl_prefer_server_ciphers on;
|
|
|
|
# Logging Settings
|
|
access_log /var/log/nginx/access.log;
|
|
error_log /var/log/nginx/error.log;
|
|
|
|
# DNS resolver
|
|
resolver 1.1.1.1 8.8.8.8 valid=300s ipv6=off;
|
|
resolver_timeout 10s;
|
|
|
|
# Proxy cache
|
|
proxy_cache_path
|
|
/var/cache/nginx/proxy_cache
|
|
levels=1:2
|
|
keys_zone=restream_cache:10m
|
|
inactive=10m
|
|
max_size=20g;
|
|
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name $domain;
|
|
|
|
return 301 https://\$server_name\$request_uri;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl;
|
|
listen [::]:443 ssl;
|
|
server_name $domain;
|
|
|
|
# SSL settings
|
|
ssl_certificate /etc/nginx/ssl.crt;
|
|
ssl_certificate_key /etc/nginx/ssl.key;
|
|
|
|
proxy_redirect off;
|
|
proxy_http_version 1.1;
|
|
proxy_read_timeout 10s;
|
|
proxy_send_timeout 10s;
|
|
proxy_connect_timeout 10s;
|
|
proxy_cache restream_cache;
|
|
proxy_cache_methods GET HEAD;
|
|
proxy_cache_key \$uri;
|
|
proxy_cache_valid 200 302 5m;
|
|
proxy_cache_valid 404 3s;
|
|
proxy_cache_lock on;
|
|
proxy_cache_lock_age 5s;
|
|
proxy_cache_lock_timeout 1h;
|
|
proxy_ignore_headers Cache-Control;
|
|
proxy_ignore_headers Set-Cookie;
|
|
|
|
add_header X-Edge-Cache-Status \$upstream_cache_status;
|
|
|
|
location / {
|
|
include /etc/nginx/cors.conf;
|
|
$pass_headers
|
|
proxy_ssl_server_name on;
|
|
rewrite ^(.*)$ $upstream_base\$1 break;
|
|
proxy_pass $upstream_server;
|
|
|
|
location ~ \.(m3u8|mpd)$ {
|
|
include /etc/nginx/cors.conf;
|
|
rewrite ^(.*)$ $upstream_base\$1 break;
|
|
proxy_cache_valid any 1s;
|
|
proxy_pass $upstream_server;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
|
|
nginx -t
|
|
systemctl reload nginx
|
|
|
|
# sysctl settings
|
|
echo "Configuring sysctl"
|
|
cat <<EOF > /etc/sysctl.d/999-perf.conf
|
|
fs.file-max=1048576
|
|
fs.inotify.max_user_instances=1048576
|
|
fs.inotify.max_user_watches=1048576
|
|
fs.nr_open=1048576
|
|
net.core.default_qdisc=fq
|
|
net.core.netdev_max_backlog=1048576
|
|
net.core.rmem_max=16777216
|
|
net.core.somaxconn=65535
|
|
net.core.wmem_max=16777216
|
|
net.ipv4.ip_local_port_range=1024 65535
|
|
net.ipv4.netfilter.ip_conntrack_max=1048576
|
|
net.ipv4.tcp_fin_timeout=5
|
|
net.ipv4.tcp_max_orphans=1048576
|
|
net.ipv4.tcp_max_syn_backlog=20480
|
|
net.ipv4.tcp_max_tw_buckets=400000
|
|
net.ipv4.tcp_no_metrics_save=1
|
|
net.ipv4.tcp_rmem=4096 87380 16777216
|
|
net.ipv4.tcp_slow_start_after_idle=0
|
|
net.ipv4.tcp_synack_retries=2
|
|
net.ipv4.tcp_syn_retries=2
|
|
net.ipv4.tcp_tw_reuse=1
|
|
net.ipv4.tcp_wmem=4096 65535 16777216
|
|
net.nf_conntrack_max=1048576
|
|
vm.max_map_count=1048576
|
|
vm.min_free_kbytes=65535
|
|
vm.overcommit_memory=1
|
|
vm.swappiness=0
|
|
vm.vfs_cache_pressure=50
|
|
EOF
|
|
sysctl --system
|
|
|
|
# limits.conf settings
|
|
cat <<EOF > /etc/security/limits.d/999-perf.conf
|
|
* soft nofile 1048576
|
|
* hard nofile 1048576
|
|
root soft nofile 1048576
|
|
root hard nofile 1048576
|
|
* soft nproc 1048576
|
|
* hard nproc 1048576
|
|
root soft nproc 1048576
|
|
root hard nproc 1048576
|
|
* soft memlock unlimited
|
|
* hard memlock unlimited
|
|
root soft memlock unlimited
|
|
root hard memlock unlimited
|
|
* soft core 0
|
|
* hard core 0
|
|
root soft core 0
|
|
root hard core 0
|
|
EOF
|
|
|
|
# systemd limits
|
|
cat <<EOF > /etc/systemd/system.conf
|
|
[Manager]
|
|
DefaultLimitNOFILE=1048576
|
|
DefaultLimitNPROC=1048576
|
|
DefaultLimitMEMLOCK=infinity
|
|
EOF
|
|
|
|
# Done!
|
|
reboot
|