# This script was used to build sequence.davidje13.com # It will install the sequence diagram code (and necessary environment) # and install an nginx proxy server. It will also use the "let's encrypt" # service to get SSH keys for the site. # Security updates will be applied automatically. Other updates can be # applied by running: # sudo apt-get update; # sudo apt-get dist-upgrade; # sudo shutdown -r now; # if needed # sudo apt-get autoremove; # The github code can be updated by running: # sudo /var/www/sequence/update.sh # The AWS configuration used: # EC2: # Community AMI: ami-0b91bd72, T2.micro, 8GB (only uses ~2GB but this is the minimum) # Use a security group which allows 80 (public), 443 (public) and 22 (your ip) # (assign elastic IP) # Route53: # A (1day) # A www. (1day) # A sequence. (1day) # CAA 0 issue "letsencrypt.org" (1day) # Once the EC2 & Route53 config is done, log in to the box and run this script. # Pass a single parameter: the main domain name (e.g. davidje13.com) # You can easily download this script to the box by running: # wget https://davidje13.github.io/SequenceDiagram/docs/ubuntu-nginx-installer.sh; # chmod 0744 ubuntu-nginx-installer.sh; # ./ubuntu-nginx-installer.sh # thanks, # https://gist.github.com/nrollr/9a39bb636a820fb97eec2ed85e473d38 # https://bjornjohansen.no/redirect-to-https-with-nginx # http://tumblr.intranation.com/post/766288369/using-nginx-reverse-proxy # https://certbot.eff.org/ # https://help.ubuntu.com/lts/serverguide/automatic-updates.html # https://cloud-images.ubuntu.com/locator/ec2/ # https://gist.github.com/alonisser/a2c19f5362c2091ac1e7 # https://www.freedesktop.org/software/systemd/man/systemd.service.html set -ex DOMAIN="$1"; if [[ -z "$DOMAIN" ]]; then echo "Must specify domain!"; exit 1; fi; echo 'iptables-persistent iptables-persistent/autosave_v4 boolean true' | sudo debconf-set-selections; echo 'iptables-persistent iptables-persistent/autosave_v6 boolean true' | sudo debconf-set-selections; sudo tee -a /etc/apt/apt.conf.d/20auto-upgrades <<'EOF' > /dev/null; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::AutocleanInterval "7"; EOF sudo tee -a /etc/apt/apt.conf.d/50unattended-upgrades <<'EOF' > /dev/null; Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; Unattended-Upgrade::Automatic-Reboot "true"; EOF sudo add-apt-repository ppa:certbot/certbot -y; sudo apt-get update; sudo apt-get dist-upgrade -y; sudo apt-get install -y \ iptables-persistent \ daemontools \ certbot \ nodejs \ npm \ nginx; sudo systemctl stop nginx; sudo useradd --system --user-group --password '' sequence-runner; sudo mkdir -p /var/www/http/.well-known/acme-challenge; sudo mkdir -p /var/www/https; git clone https://github.com/davidje13/SequenceDiagram.git; cd SequenceDiagram && npm install --production; cd - > /dev/null; sudo mv SequenceDiagram /var/www/sequence; sudo mkdir -p /var/www/sequence/logs; sudo tee /var/www/sequence/runner.sh <<'EOF' > /dev/null; #!/bin/bash BASEDIR="$(dirname "$0")"; PORT="$1"; mkdir -p "$BASEDIR/logs/log$PORT"; FONTDIR="$BASEDIR/fonts" \ "$BASEDIR/bin/server.js" "$PORT" 2>&1 \ > >(multilog n50 s1048576 "$BASEDIR/logs/log$PORT") & echo $! > "$BASEDIR/logs/pid$PORT"; EOF sudo tee /var/www/sequence/update.sh <<'EOF' > /dev/null; #!/bin/bash BASEDIR="$(dirname "$0")"; cd "$BASEDIR"; git pull; cd - > /dev/null; chmod -R g-w "$BASEDIR"; systemctl restart sequence8080.service; systemctl restart sequence8081.service; EOF sudo tee /var/www/https/index.htm < /dev/null; $DOMAIN Nothing to see here… try https://sequence.$DOMAIN/ instead for now. EOF sudo chmod 0544 /var/www/sequence/runner.sh; sudo chmod 0744 /var/www/sequence/update.sh; sudo chmod -R g-w /var/www/sequence; sudo chown -R root:sequence-runner /var/www/sequence; sudo chown -R sequence-runner:sequence-runner /var/www/sequence/logs; sudo chown sequence-runner:sequence-runner /var/www/sequence/runner.sh; sudo chown -R root:www-data /var/www/http; sudo chown -R root:www-data /var/www/https; openssl dhparam -out dhparam.pem 2048; sudo mv dhparam.pem /etc/nginx/dhparam.pem; sudo chmod 0600 /etc/nginx/dhparam.pem; sudo chown root:root /etc/nginx/dhparam.pem; sudo rm /etc/nginx/modules-enabled/50-mod-http-geoip.conf; sudo rm /etc/nginx/modules-enabled/50-mod-http-image-filter.conf; sudo rm /etc/nginx/modules-enabled/50-mod-http-xslt-filter.conf; sudo rm /etc/nginx/modules-enabled/50-mod-mail.conf; # should be mod-stream remaining sudo rm /etc/nginx/sites-enabled/default; sudo tee /etc/nginx/nginx.conf < /dev/null; user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } EOF sudo tee /etc/nginx/conf.d/custom.conf < /dev/null; server_tokens off; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; EOF sudo tee /etc/nginx/conf.d/mime.conf < /dev/null; types { application/javascript mjs; } EOF sudo tee /etc/nginx/sites-available/shared-ssl.inc < /dev/null; ssl on; ssl_session_cache shared:SSL:5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_dhparam /etc/nginx/dhparam.pem; ssl_certificate /etc/letsencrypt/live/all/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/all/privkey.pem; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/all/fullchain.pem; EOF sudo tee /etc/nginx/sites-available/http < /dev/null; server { listen 8000 default_server; listen [::]:8000 default_server; root /var/www/http; keepalive_requests 1; keepalive_timeout 0s; client_header_timeout 5s; client_body_timeout 5s; client_max_body_size 1; location / { access_log off; expires max; return 301 https://\$host\$request_uri; } location /.well-known/acme-challenge/ { } } EOF sudo tee /etc/nginx/sites-available/root < /dev/null; server { server_name $DOMAIN www.$DOMAIN; listen 8443 ssl http2; listen [::]:8443 ssl http2; # listen 8000 # listen [::]:8000 root /var/www/https; include /etc/nginx/sites-available/shared-ssl.inc; index index.htm index.html; client_header_timeout 5s; client_body_timeout 5s; client_max_body_size 1; gzip on; gzip_comp_level 4; gzip_types *; location /errors/ { internal; } error_page 404 /errors/404.htm; } EOF sudo tee /etc/nginx/sites-available/sequence < /dev/null; upstream sequence_backend { server 127.0.0.1:8080 max_conns=64; server 127.0.0.1:8081 max_conns=64; keepalive 16; } server { server_name sequence.$DOMAIN; listen 8443 ssl http2; listen [::]:8443 ssl http2; # listen 8000 # listen [::]:8000 include /etc/nginx/sites-available/shared-ssl.inc; client_header_timeout 5s; client_body_timeout 5s; client_max_body_size 1; access_log off; error_log off; merge_slashes off; location / { proxy_pass http://sequence_backend; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_redirect off; proxy_buffering off; proxy_connect_timeout 5s; proxy_read_timeout 10s; } } EOF sudo ln -s /etc/nginx/sites-available/http /etc/nginx/sites-enabled/http; sudo systemctl start nginx; sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000; sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443; sudo ip6tables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000; sudo ip6tables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443; sudo certbot certonly --agree-tos --register-unsafely-without-email --cert-name all --webroot \ -w /var/www/http \ -d "$DOMAIN" \ -d "www.$DOMAIN" \ -d "sequence.$DOMAIN"; make_sequence_service() { PORT="$1"; sudo tee "/lib/systemd/system/sequence$PORT.service" < /dev/null; [Unit] Description=Sequence Diagram Server $PORT After=network.target [Service] Type=forking PIDFile=/var/www/sequence/logs/pid$PORT User=sequence-runner ExecStart=/var/www/sequence/runner.sh $PORT KillMode=process KillSignal=SIGINT Restart=always [Install] WantedBy=multi-user.target EOF sudo chmod 0644 "/lib/systemd/system/sequence$PORT.service"; sudo systemctl enable "sequence$PORT.service"; } make_sequence_service 8080; make_sequence_service 8081; sudo systemctl start sequence8080.service; sudo systemctl start sequence8081.service; sudo ln -s /etc/nginx/sites-available/root /etc/nginx/sites-enabled/root; sudo ln -s /etc/nginx/sites-available/sequence /etc/nginx/sites-enabled/sequence; sudo nginx -s reload; sudo iptables-save | sudo tee /etc/iptables/rules.v4 > /dev/null; sudo ip6tables-save | sudo tee /etc/iptables/rules.v6 > /dev/null; sudo rm /etc/cron.d/certbot; sudo tee /etc/cron.daily/certbot-renew <<'EOF' > /dev/null; certbot renew -q --deploy-hook "nginx -s reload"; EOF sudo chmod 0755 /etc/cron.daily/certbot-renew;