├── csite.conf ├── LICENSE ├── README.md ├── site.conf └── csite2.conf /csite.conf: -------------------------------------------------------------------------------- 1 | # NOTES: 2 | # - Replace DOMAIN with the actual domain 3 | 4 | # don't send the nginx version number in error pages and Server header 5 | server_tokens off; 6 | 7 | # when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header, 8 | # to disable content-type sniffing on some browsers. 9 | # https://www.owasp.org/index.php/List_of_useful_HTTP_headers 10 | # currently suppoorted in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx 11 | # http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx 12 | # 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020 13 | add_header X-Content-Type-Options nosniff; 14 | 15 | server { 16 | listen 80; 17 | listen [::]:80; 18 | server_name DOMAIN; 19 | 20 | location / { 21 | proxy_pass http://api; 22 | } 23 | } 24 | 25 | upstream api { 26 | server 127.0.0.1:3000; 27 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mike van Rossum 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # New webserver 2 | 3 | Scripts and config files to quickly start a new webserver that has: 4 | 5 | - ufw 6 | - letsenscrypt ssl cert 7 | - Diffie-Hellman parameters 8 | - nginx with ssl properly configured 9 | - docker 10 | - postgres via docker 11 | 12 | Assumes you are logged in as root. 13 | 14 | # nodejs 15 | 16 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash 17 | export NVM_DIR="$HOME/.nvm" 18 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm 19 | [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion 20 | nvm install 22.9.0 21 | 22 | # UFW 23 | 24 | ufw default deny incoming 25 | ufw default allow outgoing 26 | ufw allow 22 # ssh 27 | ufw allow 443 # https 28 | ufw allow 80 # http 29 | # allow port from specific IP 30 | # ufw allow from 1.1.1.1 to any port 22 31 | # allow port from specific interface 32 | # ufw allow in on eth0 to any port 80 33 | ufw enable 34 | 35 | # Nginx 36 | 37 | apt-get install nginx # todo: nginx official repo 38 | openssl dhparam -out /etc/nginx/dhparam.pem 2048 # Diffie-Hellman parameters 39 | cd /etc/nginx/conf.d 40 | wget https://raw.githubusercontent.com/askmike/new-webserver/master/site.conf 41 | # edit nginx conf with your site and api 42 | service nginx configtest 43 | service nginx restart 44 | 45 | # Nginx /w certbot 46 | 47 | sudo apt-get update 48 | sudo apt-get install -y nginx certbot python3-certbot-nginx 49 | sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048 # Diffie-Hellman parameters 50 | cd /etc/nginx/conf.d 51 | sudo wget https://raw.githubusercontent.com/askmike/new-webserver/master/csite.conf 52 | # edit nginx conf with your domain 53 | sudo service nginx configtest 54 | sudo service nginx restart 55 | sudo certbot --nginx -d domain 56 | [email] 57 | y 58 | n 59 | wget https://raw.githubusercontent.com/askmike/new-webserver/master/csite2.conf 60 | sudo rm csite.conf 61 | sudo mv csite2.conf site.conf 62 | # edit nginx conf with your site and api 63 | sudo service nginx configtest 64 | sudo service nginx restart 65 | sudo crontab -e 66 | # add txt: 67 | 0 12 * * * /usr/bin/certbot renew --quiet 68 | 69 | # Build tools 70 | 71 | apt-get install python python3 make build-essential 72 | 73 | # docker 74 | 75 | apt-get update 76 | apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 77 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 78 | # apt-key fingerprint 0EBFCD88 79 | add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ 80 | $(lsb_release -cs) \ 81 | stable" 82 | apt-get update 83 | apt-get install docker-ce docker-ce-cli containerd.io 84 | 85 | ## docker postgres 86 | 87 | cd ~ 88 | mkdir postgresdata 89 | docker run --rm --name pg-docker -e POSTGRES_PASSWORD=YOUR-PW -d -p 5432:5432 -v $HOME/postgresdata:/var/lib/postgresql/data postgres 90 | docker ps 91 | -------------------------------------------------------------------------------- /site.conf: -------------------------------------------------------------------------------- 1 | # NOTES: 2 | # - Replace DOMAIN with the actual domain 3 | # - Replace PORT with the port the api/webservice is running on 4 | # based on: https://gist.github.com/plentz/6737338 5 | 6 | # don't send the nginx version number in error pages and Server header 7 | server_tokens off; 8 | 9 | # when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header, 10 | # to disable content-type sniffing on some browsers. 11 | # https://www.owasp.org/index.php/List_of_useful_HTTP_headers 12 | # currently suppoorted in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx 13 | # http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx 14 | # 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020 15 | add_header X-Content-Type-Options nosniff; 16 | 17 | server { 18 | listen 80; 19 | listen [::]:80; 20 | server_name DOMAIN; 21 | return 301 https://$host$request_uri; 22 | } 23 | 24 | upstream api { 25 | server 127.0.0.1:PORT; 26 | } 27 | 28 | server { 29 | listen 443 ssl http2; 30 | listen [::]:443 ssl http2; 31 | server_name DOMAIN; 32 | 33 | gzip on; 34 | gzip_comp_level 9; 35 | gzip_types application/json; 36 | 37 | # enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner) 38 | # http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ 39 | resolver 8.8.8.8 8.8.4.4; 40 | ssl_stapling on; 41 | ssl_stapling_verify on; 42 | ssl_trusted_certificate /lego/.lego/certificates/DOMAIN.crt; 43 | 44 | ssl_certificate /lego/.lego/certificates/DOMAIN.crt; 45 | ssl_certificate_key /lego/.lego/certificates/DOMAIN.key; 46 | 47 | # enable session resumption to improve https performance 48 | # http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html 49 | ssl_session_cache shared:SSL:50m; 50 | ssl_session_timeout 1d; 51 | ssl_session_tickets off; 52 | 53 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits 54 | ssl_dhparam /etc/nginx/dhparam.pem; 55 | 56 | # enables server-side protection from BEAST attacks 57 | # http://blog.ivanristic.com/2013/09/is-beast-still-a-threat.html 58 | ssl_prefer_server_ciphers on; 59 | # disable SSLv3(enabled by default since nginx 0.8.19) since it's less secure then TLS http://en.wikipedia.org/wiki/Secure_Sockets_Layer#SSL_3.0 60 | ssl_protocols TLSv1.2 TLSv1.3; 61 | # ciphers chosen for forward secrecy and compatibility 62 | # http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html 63 | ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; 64 | 65 | # config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security 66 | # to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping 67 | # also https://hstspreload.org/ 68 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; 69 | 70 | # if: 71 | # - you want lego while nginx is running 72 | # - you have basic auth on root 73 | 74 | #location /.well-known/acme-challenge/ { 75 | # auth_basic off; 76 | #} 77 | 78 | 79 | # if you have root upstreamed but want to lego 80 | # root /var/www/d; 81 | #location /.well-known/acme-challenge/ { 82 | # try_files $uri $uri/ $request_uri $uri$is_args$args =404; 83 | #} 84 | 85 | location / { 86 | proxy_pass http://api; 87 | } 88 | } -------------------------------------------------------------------------------- /csite2.conf: -------------------------------------------------------------------------------- 1 | # NOTES: 2 | # - Replace DOMAIN with the actual domain 3 | # - Replace PORT with the port the api/webservice is running on 4 | # based on: https://gist.github.com/plentz/6737338 5 | 6 | # don't send the nginx version number in error pages and Server header 7 | server_tokens off; 8 | 9 | # when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header, 10 | # to disable content-type sniffing on some browsers. 11 | # https://www.owasp.org/index.php/List_of_useful_HTTP_headers 12 | # currently suppoorted in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx 13 | # http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx 14 | # 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020 15 | add_header X-Content-Type-Options nosniff; 16 | 17 | server { 18 | listen 80; 19 | listen [::]:80; 20 | server_name DOMAIN; 21 | return 301 https://$host$request_uri; 22 | } 23 | 24 | upstream api { 25 | server 127.0.0.1:PORT; 26 | } 27 | 28 | server { 29 | listen 443 ssl http2; 30 | listen [::]:443 ssl http2; 31 | server_name DOMAIN; 32 | 33 | gzip on; 34 | gzip_comp_level 9; 35 | gzip_types application/json; 36 | 37 | # enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner) 38 | # http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ 39 | resolver 8.8.8.8 8.8.4.4; 40 | ssl_stapling on; 41 | ssl_stapling_verify on; 42 | ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem; 43 | 44 | ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem; 45 | ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem; 46 | 47 | # enable session resumption to improve https performance 48 | # http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html 49 | ssl_session_cache shared:SSL:50m; 50 | ssl_session_timeout 1d; 51 | ssl_session_tickets off; 52 | 53 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits 54 | ssl_dhparam /etc/nginx/dhparam.pem; 55 | 56 | # enables server-side protection from BEAST attacks 57 | # http://blog.ivanristic.com/2013/09/is-beast-still-a-threat.html 58 | ssl_prefer_server_ciphers on; 59 | # disable SSLv3(enabled by default since nginx 0.8.19) since it's less secure then TLS http://en.wikipedia.org/wiki/Secure_Sockets_Layer#SSL_3.0 60 | ssl_protocols TLSv1.2 TLSv1.3; 61 | # ciphers chosen for forward secrecy and compatibility 62 | # http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html 63 | ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; 64 | 65 | # config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security 66 | # to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping 67 | # also https://hstspreload.org/ 68 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; 69 | 70 | # if: 71 | # - you want lego while nginx is running 72 | # - you have basic auth on root 73 | 74 | #location /.well-known/acme-challenge/ { 75 | # auth_basic off; 76 | #} 77 | 78 | 79 | # if you have root upstreamed but want to lego 80 | # root /var/www/d; 81 | #location /.well-known/acme-challenge/ { 82 | # try_files $uri $uri/ $request_uri $uri$is_args$args =404; 83 | #} 84 | 85 | location / { 86 | proxy_pass http://api; 87 | } 88 | } --------------------------------------------------------------------------------