Certbot i OVH
Posted on Mon 12 December 2022 in Linux, Wirtualizacja • 4 min read
Odnawianie certyfikatów Letsencrypt na hostach schowanych za firewallem może być przyjemne trzeba to zrobić raz i porządnie.
Dlaczego w ogóle istnieje ten problem i czego dotyczy? W moim przypadku najczęściej serwerów pocztowych, które nie tylko znajdują się firewallem ale na które nie mogę dynamicznie przekierować portów 80 i 443, aby odpowiedzieć na żądanie z Letsencrypt.
Ale po co przekierowywać te porty? Bo wystawianie nowego certyfikatu to proces składający się z kilku etapów w których wymieniana jest informacja między hostem, a serwerem Letsencrypt (LE). Komunikacja odbywa się przez porty 80 i 443.
W skrócie: w pewnym momencie serwer LE chce "pogadać" z serwerem HTTP na hoście na który wskazuje rekord DNS domeny, dla której wystawiamy nowy certyfikat (lub go odnawiamy), żeby przekonać się, że mamy do tego prawo. A prawo mamy jeśli jesteśmy adminem tego serwera.
No, ale co zrobić jeśli na firewallu porty 80 i 443 już są przekierowane na innego hosta?
Jeśli domena utrzymywana jest u dostawcy obsługiwanego modułem Certbota, sprawę mamy załatwioną bo innym sposobem autoryzacji jest udowodnienie, że mamy prawo do ustawiania rekordów DNS dla tej domeny.
Jeśli DNS obsługiwany jest przez OVH to problem rozwiązuje moduł do Certbota o nazwie: certbot-dns-ovh. Metoda jest prosta, najpierw modułowi zezwalamy na dostęp do API w OVH, dzięki temu może on dopisywać i usuwać rekordy w DNS. Rekordy te służą poświadczeniu, że my to rzeczywiście my i że mamy prawo poprosić o nowy certyfikat.
Instalujemy certbota (źródłem niech będzie SNAP, "paczkowany" bywa zbyt stary).
Tu instaluję na Debianie 10 (buster), inne distra mają podobnie.
Najpierw snap i certbot:
sudo apt update sudo apt install snapd sudo snap install core sudo snap refresh core sudo apt remove certbot sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/bin/certbot
Kontener w Proxmoxie ma inaczej
W kontenerze na Proxmoxie powyższa instalacja nie powiedzie się, można kombinować z ustawieniami 'fuse':
Snap requires a bit more work. There may soon be a 'fuse' flag for the features option, but fuse can be dangerous. For now you have to do this:- For unprivileged containers:1) Put this in /etc/pve/lxc/$vmid.conf:Code:
... features: mount=fuse,nesting=1 lxc.mount.entry = /dev/fuse dev/fuse none bind,create=file 0 02) Inside the container: `apt install squashfuse`- For privileged containers, also add:Code:
... # EDIT: # We need to allow apparmor administration, by default mac_admin is dropped for privileged containers. # Note that you do not want this for un-trusted containers... lxc.cap.drop = lxc.cap.drop = mac_override sys_time sys_module sys_rawioAlternatively to squashfuse, privileged containers could use loop devices, but I wouldn't recommend it...Note that enabling `fuse` in a container does not play well with backups, or anything that causes an `lxc-freeze` command to be executed on the container, as this can cause deadlocks in the kernel.https://forum.proxmox.com/threads/ubuntu-snaps-inside-lxc-container-on-proxmox.36463/#post-230060
Ale wolę szybsze i bezpieczniejsze rozwiązanie czyli instalacja za pomocą PIP:
sudo apt-get remove certbot sudo apt update sudo apt install python3 python3-venv libaugeas0 sudo python3 -m venv /opt/certbot/ sudo /opt/certbot/bin/pip install --upgrade pip sudo /opt/certbot/bin/pip install certbot certbot sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot
Moduł Node do OVH
zainstalujmy go w /opt:
cd /opt sudo git clone https://github.com/mcdado/certbot-dns-ovh.git cd certbot-dns-ovh
Moduł używa Node.js więc pierwszym krokiem jest zainstalowanie Node na naszym serwerze. Najlepszym sposobem jest ominięcie instalacji z paczek i użycie NVM, a to ponieważ Node podlega szybkim zmianom, wkrótce więc może okazać się, że jest nieaktualny.
NVM to Node Version Manager, nazwa wyjaśnia wszystko. Instalacja jest trywialna:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
Następnie instalacja samego Node:
nvm install node
Domyślne instalowana jest najnowsza wersja, inne można wyświetlić tą komendą:
nvm list-remote
Mamy Node, pora zrobić resztę pracy, po której będzie można zapomnieć o ręcznym odnawianiu certyfikatów.
OVH: Appkey i AppSecret
Wchodzimy na ten adres: https://eu.api.ovh.com/createApp/
Teraz następuje kolejny krok autoryzacji aplikacji, w konsoli, nadal w katalogu /opt/certbot-dns-ovh odpalamy:
node bin/authorize.js --endpoint=ovh-eu --app_key=yourappkey --app_secret=yourappsecret Jeśli wystąpi błąd mówiący o braku modułu "dotenv" należy go zainstalować: .. code:: html npm install dotenv
Oczywiście w miejsce "yourappkey" i "yourappsecret" podstawiamy App Key i App Secret z poprzedniego kroku.
W konsoli pojawia się odpowiedź, mniej więcej taka: { validationUrl: 'https://eu.api.ovh.com/auth/?credentialToken=jed…', consumerKey: '69X…', state: 'pendingValidation' }
Zapamiętujemy klucz klienta (consumerKey). Kopiujemy URL do przeglądarki i zatwierdzamy dostęp do API, wybieramy też przez jaki czas dane te będą ważne. Sam wybrałem, że w nieskończoność bo... tak.
Znajdujący się w katalogu: /opt/certbot-dns-ovh plik .env.example kopiujemy do .env:
cd /opt/certbot-dns-ovh cp .env.example .env
Edytujemy .env, wstawiając odpowiednie wartości uzyskane we wcześniejszych krokach:
OVH_ENDPOINT="ovh-eu" OVH_APP_KEY="tutaj klucz czyli App Key" OVH_APP_SECRET="tu sekret App Secret" OVH_CUSTOMER_KEY="klucz kienta czyli consumerKey wyświetlony w konsoli" DNS_TIMEOUT="tu możemy zwiększyć czas oczekiwania z domyślnych 60 sekund"
Przedostatni krok to uzyskanie certyfikatu, jeśli się powiedzie to mamy potwierdzenie, że nic nie spapraliśmy:
sudo certbot certonly --manual --preferred-challenges=dns --manual-auth-hook '/opt/certbot-dns-ovh/bin/create-record.js' --manual-cleanup-hook '/opt/certbot-dns-ovh/bin/delete-record.js' -d mojadomena.pl -d www.mojadomena.pl
Odnawianie: cron i systemd
Jeśli się udało to za pomocą komendy:
sudo crontab -e
edytujemy crontaba i wstawiamy na końcu linijkę:
@weekly certbot renew --quiet
czyli jako root uruchamiamy:
crontab -e
i wklejamy powyższą linijkę.
W nowych "linuksach" crontab nie zawsze działa, zamieszczam więc poniżej wersję dla systemd.
Plik: /etc/systemd/system/certbot-renewal.service:
[Unit] Description=Certbot Renewal [Service] ExecStart=/usr/bin/certbot renew
Plik: /etc/systemd/system/certbot-renewal.timer (odpala certbot-renewal co tydzień):
[Unit] Description=Timer for Certbot Renewal [Timer] OnBootSec=300 OnUnitActiveSec=1w [Install] WantedBy=multi-user.target
I jeszcze plik: /etc/letsencrypt/renewal-hooks/post/00-restart-mail.sh, któremy należy nadać bit uruchomienia:
#!/bin/bash systemctl restart postfix systemctl restart dovecot.service
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/00-restart-mail.sh
Po skopiowaniu powyższych plików należy odświeżyć konfigurację systemd:
systemctl daemon-reload
No i zostaje uruchomienie serwisu:
systemctl start certbot-renewal.timer systemctl enable certbot-renewal.timer
Aby sprawdzić czy timer działa:
systemctl status certbot-renewal.timer
Jak to się dzieje, że po tych zabiegach Cerbot już "wie" jak odnawiać certyfikaty?
Potrafi to, bo w katalogu /etc/letsencrypt/renewal powstaje plik z konfiguracją. Nosi on nazwę domeny z końcówką .conf. Czyli w przypadku domeny mojadomena.pl będzie to:
/etc/letsencrypt/renewal/mojadomena.pl.conf
Zajrzyj do środka do zrozumiesz.