HTTPS
In this page, the web servers get a certificate from Let's Encrypt and serve the site over HTTPS. Let's Encrypt connects to your domain on port 80 to check it, so the DNS record of each domain must point to its web server.
Open port 443
In both inventories, add port 443 to tcp_ports of the group web:
vars:
tcp_ports: [22, 80, 443]Get the certificate
In recipes/nginx/recipe.yaml, install certbot with nginx:
- name: Install nginx and certbot
pkg:
name: [nginx, certbot, python3-certbot-nginx]Add a certbot step before Configure the site:
- name: Get the TLS certificate
certbot:
name: !expr vars.domain
domains: !expr vars.domain
email: !tpl webmaster@{{ .vars.domain }}
deploy_hook: systemctl reload nginxThe step gets a certificate for the domain. It comes before the site
config, because the config names the certificate files. certbot renews
the certificate on its own, and deploy_hook reloads nginx after each
new certificate.
Serve HTTPS
Change recipes/nginx/templates/site.tmpl:
server {
listen 80;
listen [::]:80;
server_name {{ .vars.domain }};
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name {{ .vars.domain }};
root /var/www/{{ .vars.domain }};
ssl_certificate /etc/letsencrypt/live/{{ .vars.domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ .vars.domain }}/privkey.pem;
}Port 80 now redirects to HTTPS, and port 443 serves the site.
Plan and apply
winch plan site --inventory stagingstaging1.example.com
base
~ Allow the open ports; drop the rest: firewall
add tcp 22, 80, 443
remove tcp 22, 80
load the rules
web
nginx
+ Install nginx and certbot: pkg nginx, certbot, python3-certbot-nginx
refresh the package index
install certbot, python3-certbot-nginx
also install python3-openssl, python3-josepy, python3-pytz, python3-rfc3339, python3-acme, python3-configargparse, python3-parsedatetime, python3-certbot, libicu76, python3-pyparsing, python3-icu
+ Get the TLS certificate: certbot staging.example.com
domains staging.example.com
authenticator nginx
deploy_hook systemctl reload nginx
~ Configure the site: file /etc/nginx/sites-enabled/staging.example.com
@@ -2,5 +2,15 @@
listen 80;
listen [::]:80;
server_name staging.example.com;
+ return 301 https://$host$request_uri;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ server_name staging.example.com;
root /var/www/staging.example.com;
+
+ ssl_certificate /etc/letsencrypt/live/staging.example.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/staging.example.com/privkey.pem;
}
validate: nginx -t
! handler nginx.reload
1 host: 1 to change, 0 unchanged, 0 unknown
plan 4b0778e7e01560bcApply it:
winch apply site --inventory stagingApply these changes? [y/N] y
staging1.example.com: base: ~ Allow the open ports; drop the rest: firewall
staging1.example.com: nginx: + Install nginx and certbot: pkg nginx, certbot, python3-certbot-nginx
staging1.example.com: nginx: + Get the TLS certificate: certbot staging.example.com
staging1.example.com: nginx: ~ Configure the site: file /etc/nginx/sites-enabled/staging.example.com
staging1.example.com: nginx: ~ handler nginx.reload: Reload nginx: service nginx
1 host: 1 changed, 0 unchangedOpen https://staging.example.com/ in a browser. To check the
redirect from the server:
winch exec web --inventory staging -- "curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://localhost/"staging1.example.com
301 https://localhost/When staging works, apply production.
What you built
example/
winch.yaml
inventories/
production.yaml
staging.yaml
pipelines/
site.yaml
recipes/
nginx/
recipe.yaml
templates/index.html.tmpl
templates/site.tmplA web server with a firewall and HTTPS, a database server with a firewall, and a staging server to test each change first.
The Reference has the details of every module, and of topics such as handlers and templates.