Kapsi, Let's Encrypt ja Ansible
Kapsin UKK:ssa oli varsin mainiot ohjeet siihen, miten Kapsilla voi ottaa käyttöön Let's Encrypt -palvelun varmentaman sertifikaatin.
Seurasin näitä ohjeita ja tein samalla Ansible playbookin ja roolin tiedostojen asentamista varten oikeille paikoilleen.
Ansible-projekti
Ansible-projektista tuli rakenteeltaan seuraavanlainen.
. ├── files │ ├── account.key │ ├── server.csr │ └── server.key ├── host_vars │ └── kapsi.fi.yml ├── production.ini ├── roles │ └── acme │ ├── files │ │ └── acme_tiny.py │ ├── tasks │ │ └── main.yml │ ├── templates │ │ └── acme-tiny.sh.j2 │ └── vars │ └── main.yml └── site.yml
files
-hakemistossa on
Let's Encryptiä varten generoitu avain (account.key
) ja
sivustoa varten generoitu avain WWW-palvelimelle (server.key
) sekä
certificate-signing-request (server.csr
).
Ne voi generoida edellä mainitun
ohjeen mukaisesti.
production.ini
on inventaario-tiedosto, jossa määritellään koneet,
joille asennuksia tehdään. Tässä määritellään kapsi.fi
acme_hosts
-ryhmään.
[acme_hosts] kapsi.fi
host_vars
-hakemistossa kapsi.fi.yml
-tiedostossa määritellään
kapsi.fi
-koneelle liittyviä asetuksia, kuten tässä tapauksessa
hakemisto, jonne sertifikaatin hakuun liittyvät tiedostot sijoitetaan, ja
sivuston domain muuttujaan site_name
. Esimerkiksi näin:
--- acme_dir: "~/acme" site_name: "tsk.iki.fi"
site.yml
on playbook, jossa määritellään,
että acme_hosts
-ryhmään kuuluvilla koneilla on acme
-rooli.
--- - name: Setup acme-tiny for retrieving Let's Encrypt certificate. hosts: acme_hosts roles: - acme
Acme-rooli
Acme-roolissa on files
-hakemistossa acme_tiny.py
,
joka on suoraan kopio
acme-tiny-GIT-repositorysta.
templates
-hakemistossa on shell-skripti, joka ajaa acme_tinyn
sopivilla parametreilla.
#!/bin/bash {{ acme_bin_dir }}/acme_tiny.py --account-key {{ acme_etc_dir }}/account.key --csr {{ acme_etc_dir }}/server.csr --acme-dir {{ site_www_dir }}/.well-known/acme-challenge/ > {{ site_ssl_dir }}/server.crt wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem -O {{ site_ssl_dir }}/ca.crt
Roolin käyttämät muuttujat on määritelty vars
-hakemiston
main.yml
-tiedostossa.
--- acme_dir: "~/acme" acme_etc_dir: "{{ acme_dir }}/etc" acme_bin_dir: "{{ acme_dir }}/bin" acme_log_dir: "{{ acme_dir }}/log" site_dir: "~/sites/{{ site_name }}" site_ssl_dir: "{{ site_dir }}/.ssl" site_www_dir: "{{ site_dir }}/www"
Lopuksi tasks
-hakemiston main.yml
-tiedostossa on varsinaiset
toimenpiteet tiedostojen asentamiseksi paikoilleen.
--- - name: Assert that variables are defined. assert: that: - acme_dir is defined - site_name is defined - site_dir is defined - name: Make acme directories. file: path={{ item }} state=directory mode=u+rwx,g-rwx,o-rwx with_items: - "{{ acme_dir }}" - "{{ acme_etc_dir }}" - "{{ acme_bin_dir }}" - "{{ acme_log_dir }}" - name: Copy acme binaries. copy: src={{ item }} dest={{ acme_bin_dir }}/ mode=u+x with_items: - acme_tiny.py - name: Template acme binaries. template: src=acme-tiny.sh.j2 dest={{ acme_bin_dir }}/acme-tiny-{{ site_name }}.sh mode=u+x - name: Copy acme data. copy: src={{ item }} dest={{ acme_etc_dir }}/ with_items: - account.key - server.csr - name: Make ssl directory. file: path={{ site_ssl_dir }} state=directory mode=700 - name: Copy server.key. copy: src=server.key dest={{ site_ssl_dir }}/ - name: Make well-known directory. file: path: "{{ site_www_dir }}/.well-known" state: directory mode: u+rwx,g+rx,o+rx - name: Make well-known/acme-challenge directory. file: path: "{{ site_www_dir }}/.well-known/acme-challenge" state: directory mode: u+rwx,g+rx,o+rx - name: Setup cron job to update certificate. cron: name: "Update {{ site_name }} certificate" hour: 0 minute: 0 day: 1 state: present job: "{{ acme_bin_dir }}/acme-tiny-{{ site_name }}.sh 2> {{ acme_log_dir }}/{{ site_name }}.log"
Playbookin ajo
Asennuksen saa tehtyä komennolla
ansible-playbook -i production.ini site.yml
Jonka jälkeen ansible tulostaa jotain seuraavankaltaista:
PLAY [Setup acme-tiny for retrieving Let's Encrypt certificate.] *************** TASK [setup] ******************************************************************* ok: [kapsi.fi] TASK [acme : Assert that variables are defined.] ******************************* ok: [kapsi.fi] TASK [acme : Make acme directories.] ******************************************* ok: [kapsi.fi] => (item=~/acme) ok: [kapsi.fi] => (item=~/acme/etc) ok: [kapsi.fi] => (item=~/acme/bin) ok: [kapsi.fi] => (item=~/acme/log) ...
Jos kaikki menee hyvin pitäisi viimeisellä rivillä lukea "failed=0".
Sertifikaattia ei vielä ole haettu,
vaan tämän jälkeen pitää kerran ajaa ~/acme/bin
-hakemistoon generoitu
acme-tiny-tsk.iki.fi.sh
-skripti.
Sertifikaatin uusimista varten ajamisen tekee cron.
Huomioita
Tämä toimi minun tilanteessa. Käytössä on vain yksi sivusto. En ole pohtinut vielä, mitä kohtia pitää muuttaa, jos sivustoja olisi useita.
Roolin on tarkoitus olla uudelleenkäytettävä, eli sen pitäisi toimia sellaisenaan muillekin sivustoille, jos vain asible-projektissa määrittelee tarvittavat muuttujat oikein.
Certificate-signing-requestin (server.csr
) voisi varmaankin generoida
automaattisesti jonkinlaista templatea käyttäen.
Sitä en kuitenkaan lähtenyt tähän vielä tuunaamaa,
koska request on samanlainen joka kerralle,
jos sivustoihin ei tule muutoksia.
Laittakaa kommenttia parannusehdotuksista tai vioista, niin katsotaan, saisiko tätä skriptiä täydennettyä.
Kommentit