-
Star
(305)
You must be signed in to star a gist -
Fork
(103)
You must be signed in to fork a gist
-
-
Save mattiaslundberg/ba214a35060d3c8603e9b1ec8627d349 to your computer and use it in GitHub Desktop.
| Ansible playbook to setup HTTPS using Let's encrypt on nginx. | |
| The Ansible playbook installs everything needed to serve static files from a nginx server over HTTPS. | |
| The server pass A rating on [SSL Labs](https://www.ssllabs.com/). | |
| To use: | |
| 1. Install [Ansible](https://www.ansible.com/) | |
| 2. Setup an Ubuntu 16.04 server accessible over ssh | |
| 3. Create `/etc/ansible/hosts` according to template below and change example.com to your domain | |
| 4. Copy the rest of the files to an empty directory (`playbook.yml` in the root of that folder and the rest in the `templates` subfolder) | |
| 5. Run `ansible-playbook playbook.yml` | |
| 6. Copy your (static HTML) code to `/var/www/example.com` (`example.com` replaced with your domain) | |
| 7. Restart nginx (`systemctl restart nginx`) |
| [letsencrypt] | |
| example.com ansible_user=root [email protected] domain_name=example.com |
| --- | |
| - hosts: letsencrypt | |
| become: true | |
| gather_facts: no | |
| pre_tasks: | |
| - raw: apt-get install -y python-simplejson | |
| tasks: | |
| - name: Upgrade system | |
| apt: upgrade=dist update_cache=yes | |
| - name: Install nginx | |
| apt: name=nginx state=latest | |
| - name: install letsencrypt | |
| apt: name=letsencrypt state=latest | |
| - name: create letsencrypt directory | |
| file: name=/var/www/letsencrypt state=directory | |
| - name: Remove default nginx config | |
| file: name=/etc/nginx/sites-enabled/default state=absent | |
| - name: Install system nginx config | |
| template: | |
| src: templates/nginx.conf.j2 | |
| dest: /etc/nginx/nginx.conf | |
| - name: Install nginx site for letsencrypt requests | |
| template: | |
| src: templates/nginx-http.j2 | |
| dest: /etc/nginx/sites-enabled/http | |
| - name: Reload nginx to activate letsencrypt site | |
| service: name=nginx state=restarted | |
| - name: Create letsencrypt certificate | |
| shell: letsencrypt certonly -n --webroot -w /var/www/letsencrypt -m {{ letsencrypt_email }} --agree-tos -d {{ domain_name }} | |
| args: | |
| creates: /etc/letsencrypt/live/{{ domain_name }} | |
| - name: Generate dhparams | |
| shell: openssl dhparam -out /etc/nginx/dhparams.pem 2048 | |
| args: | |
| creates: /etc/nginx/dhparams.pem | |
| - name: Install nginx site for specified site | |
| template: | |
| src: templates/nginx-le.j2 | |
| dest: /etc/nginx/sites-enabled/le | |
| - name: Reload nginx to activate specified site | |
| service: name=nginx state=restarted | |
| - name: Add letsencrypt cronjob for cert renewal | |
| cron: | |
| name: letsencrypt_renewal | |
| special_time: weekly | |
| job: letsencrypt --renew certonly -n --webroot -w /var/www/letsencrypt -m {{ letsencrypt_email }} --agree-tos -d {{ domain_name }} && service nginx reload |
| server_tokens off; | |
| server { | |
| listen 80 default_server; | |
| server_name {{ domain_name }}; | |
| location /.well-known/acme-challenge { | |
| root /var/www/letsencrypt; | |
| try_files $uri $uri/ =404; | |
| } | |
| location / { | |
| rewrite ^ https://{{ domain_name }}$request_uri? permanent; | |
| } | |
| } | |
| add_header X-Frame-Options SAMEORIGIN; | |
| add_header X-Content-Type-Options nosniff; | |
| add_header X-XSS-Protection "1; mode=block"; | |
| add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google-analytics.com; img-src 'self' data: https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; font-src 'self'; frame-src 'none'; object-src 'none'"; | |
| # HTTPS server | |
| # | |
| server { | |
| listen 443 ssl default deferred; | |
| server_name {{ domain_name }}; | |
| ssl on; | |
| ssl_certificate /etc/letsencrypt/live/{{ domain_name }}/fullchain.pem; | |
| ssl_certificate_key /etc/letsencrypt/live/{{ domain_name }}/privkey.pem; | |
| ssl_trusted_certificate /etc/letsencrypt/live/{{ domain_name }}/fullchain.pem; | |
| ssl_session_cache shared:SSL:50m; | |
| ssl_session_timeout 5m; | |
| ssl_stapling on; | |
| ssl_stapling_verify on; | |
| ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
| ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; | |
| ssl_dhparam /etc/nginx/dhparams.pem; | |
| ssl_prefer_server_ciphers on; | |
| root /var/www/{{ domain_name }}; | |
| index index.html index.htm; | |
| location / { | |
| try_files $uri $uri/ =404; | |
| } | |
| } |
| user www-data; | |
| worker_processes 4; | |
| pid /run/nginx.pid; | |
| 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; | |
| gzip on; | |
| gzip_disable "msie6"; | |
| include /etc/nginx/conf.d/*.conf; | |
| include /etc/nginx/sites-enabled/*; | |
| } |
@diablozzq this is great. what if need to handle 2 sub domains
example: domain_name: aaa.example.com and domain_name_2: bbbb.example.com
@diablozzq this is great. what if need to handle 2 sub domains
example:
domain_name: aaa.example.comanddomain_name_2: bbbb.example.com
you can do like this: -d www.aname.com -d api.aname.com -d api2.aname.com
also you can use wildcard way
Thanks for this!
FYI, on my Ubuntu 16.04.6 server with certbot 0.27.0, I had to change the cronjob from
job: letsencrypt --renew certonly -n --webroot -w /var/www/letsencrypt -m {{ letsencrypt_email }} --agree-tos -d {{ domain_name }} && service nginx reload
to
job: letsencrypt --renew-by-default certonly -n --webroot -w /var/www/letsencrypt -m {{ letsencrypt_email }} --agree-tos -d {{ domain_name }} && service nginx reload
Thank you man! This saved me hours!
pre_tasks:
- raw: apt-get install -y python-simplejson
for Gentoo replace
pre_tasks:
- raw: emerge -v dev-python/simplejson
thanks man! amazing work.
Great stuff man, thanks a lot!
why u not using proxy nginx with buffer?
thanks for this! nowadays python-simplejson is python3-simplejson (tested on debian 11)
--renew-by-default
thanks for the tip
This is amazing. Worked without any major modifications on ubuntu 19.10 on a raspberry pi.
I did the following changes
My playbook: