diff --git a/scripts/nginx/README.md b/scripts/nginx/README.md index 20f6077..2e563eb 100644 --- a/scripts/nginx/README.md +++ b/scripts/nginx/README.md @@ -20,10 +20,29 @@ Feel free to check out the `restream.conf` file and tune it to your liking. The build script doesn't litter your system with random junk. When you're done you can just wipe the `./nginx` folder. -## Merging with your existing nginx +## Reverse proxying from existing nginx If you don't wanna bother merging the config, you can just use your existing -nginx to reverse-proxy to this one. +nginx to reverse-proxy to this one. It'd look something like this: + +``` + your server + ---------------------------------- + | | +viewer --|--> main nginx --> this nginx --|--> upstream + | w/ SSL | + ---------------------------------- +``` + +You can just do something like this: + +``` +location / { + proxy_pass http://127.0.0.1:8080/; +} +``` + +## Merging with your existing nginx If you want to merge it with an existing nginx config, you can copy these directives to the `http` block: @@ -41,3 +60,26 @@ you do the reverse proxy, set `proxy_cache` back to `restream_cache`. Feel free to tweak the parameters to fit your needs, but generally the values in `restream.conf` should just work alright for caching live streams. + +## Setting this up on a remote server + +The convenience script `remote_setup.sh` can be used to ssh into a fresh remote +server, install nginx there, configure the upstream and set up SSL. This should +work on a fresh Ubuntu 20.04 server. + +Run the script: + +``` +./remote_setup.sh \ + --domain relay1.stream.example.org \ + --upstream-server https://restream.dev:443 \ + --acme-email your.email@example.org \ + --target-server root@relay1.stream.example.org +``` + +**Important note**: you _must_ specify the protocol (`https://`) and the port +(`:443`) for the `--upstream-server` flag. + +Once the script is done, your server should be accessible from +`https://relay1.stream.example.org` and proxying all requests to +`https://restream.dev`. diff --git a/scripts/nginx/remote_setup.sh b/scripts/nginx/remote_setup.sh new file mode 100755 index 0000000..416eb9f --- /dev/null +++ b/scripts/nginx/remote_setup.sh @@ -0,0 +1,255 @@ +#!/bin/bash + +positional_args=() + +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 + ;; + --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 + ;; + -*|--*) + 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 --upstream-server --acme-email --target-server " + 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 --domain $domain --upstream-server $upstream_server --upstream-proto $upstream_proto --acme-email $acme_email --is-in-target" + + # 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..." +apt-get update && \ +apt-get upgrade -y && \ +apt-get install -y nginx socat + +echo "Downloading acme.sh..." +wget -O - https://get.acme.sh | sh -s email=$acme_email + +echo "Issuing certificate..." +~/.acme.sh/acme.sh --issue -d $domain -w /var/www/html +~/.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 < /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 ~ \.(m3u8|mpd)\$ { + proxy_cache_valid 200 302 1s; + proxy_ssl_server_name on; + proxy_pass $upstream_server; + } + + location / { + proxy_ssl_server_name on; + proxy_pass $upstream_server; + } + } +} +EOF + +nginx -t +systemctl reload nginx + +# sysctl settings +echo "Configuring sysctl" +cat < /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 < /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 < /etc/systemd/system.conf +[Manager] +DefaultLimitNOFILE=1048576 +DefaultLimitNPROC=1048576 +DefaultLimitMEMLOCK=infinity +EOF + +# Done! +reboot diff --git a/scripts/nginx/restream.conf b/scripts/nginx/restream.conf index f476880..4c1e247 100644 --- a/scripts/nginx/restream.conf +++ b/scripts/nginx/restream.conf @@ -31,7 +31,7 @@ http { # TODO: Update cache path to your cache directory proxy_cache_path # cache directory (e.g. /var/cache/nginx/proxy_cache) - ./cache + cache use_temp_path=off # the name of the cache, if you change this # you have to update the proxy_cache directive below