Archiwa tagu: systemd

Logo projektu Let's Encypt i firmy OVH

SSL/TLS z Let’s Encrypt dla domen w OVH.

Let’s Encrypt ma plugin dla OVH, skorzystamy więc z niego w poniższym tutorialu. Opisuje w nim krok po kroku jak skonfigurować automatyczne generowanie i odświeżanie certyfikatów z wykorzystaniem dns-01 challenge.

Instrukcja ta ma zastosowanie tylko gdy Twoja domena hostowana jest przez OVH, wykorzystywać bowiem będziemy API tej firmy.

Pokazane rozwiązanie pozwala na generowanie certyfikatów dla pojedynczych domen, oraz wildcardów.

Żeby było jeszcze ciekawiej, skorzystamy z oficjalnego obrazu certbot/dns-ovh, także tutorial ten można zastosować praktycznie na każdym linuxie z dockerem lub podmanem. No i przy okazji jest szansa, że będzie przez jakiś czas aktualny. 😉

1. Generowanie credentiali w OVH

Na stronie https://api.ovh.com/createToken/ musimy wypełnić formularz w celu wygenerowania danych używanych później do tworzenia i kasowania wpisów dns. Zgodnie z dokumentacją pluginu certbot-dns-ovh, by móc potwierdzić bycie właścicielem domeny na potrzeby uzyskania certyfikatu Let’s Encrypt, będziemy potrzebować dostępu do następujących metod udostępnionych przez API OVH:

  • GET /domain/zone/*
  • PUT /domain/zone/*
  • POST /domain/zone/*
  • DELETE /domain/zone/*

Tak wygląda formularz, który wypełniłem dla swojego rozwiązania:

OVH API, Creating API Keys for your script

Klikamy na 'Create keys’, jeżeli macie skonfigurowane 2FA OVH poprosi o zatwierdzenie akcji, a rezulatem będzie tabelka zawierająca:

  1. Script name
  2. Script Description
  3. Application Key
  4. Application Secret
  5. Consumer Key

Notujemy z boku te wartości, będą za chwilkę potrzebne.

2. Konfiguracja certbota

Kolejny krok polega na stworzeniu pliku zawierającego dane pozwalające na autentykację w api OVH. Muszą się w nim znaleźć cztery kluczowe informacje – dns_ovh_endpoint, dns_ovh_application_key, dns_ovh_application_secret, dns_ovh_consumer_key.

Ja założyłem ten plik w /etc/certbot/ovh-secrets.conf. Pamiętajcie, że raczej nie chcecie, żeby ktoś mógł tworzyć, czy kasować subdomeny w waszym imieniu, także zabezpieczcie ten pliczek. Powiedzmy, że wystarczy chmod 0600 /etc/certbot/ovh-secrets.conf.

Przykładowy plik konfiguracyjny:

dns_ovh_endpoint = ovh-eu
dns_ovh_application_key = 7rPawafweAJYWNvhH
dns_ovh_application_secret = 4SFtGD012npocan90nc0qkTWBflirSEf8oo
dns_ovh_consumer_key = Et3lLNe2fthx3MeMFaHe3ssoS71qQZHZ
Jeżeli przygotowujesz konfigurację dla infrastruktury zarządzanej przez OVH w Ameryce Północnej, parametr dns_ovh_endpoint powinien mieć wartość ovh-ca. 

3. Katalogi, uprawnienia, selinux

Przygotuj potrzebne do działania katalogi i ustaw odpowiednie uprawnienia. W tym tutorialu przyjmuję, że certbot będzie uruchamiany jako root i chcemy trzymać certyfikaty w głównej strukturze systemu (/etc, /var).

mkdir /etc/letsencrypt /var/lib/letsencrypt /var/log/letsencrypt
chmod 0700 /etc/letsencrypt /var/lib/letsencrypt /var/log/letsencrypt

3.1 SELinux?

Na Fedorze SELinux zablokował mi certbota przy próbie zapisu do powyższych katalogów. Jako, że będzie do nich pisać tylko ta aplikacja, ustawiłem/dodałem im kontekst container_file_t.

# semanage fcontext -a -t container_file_t '/etc/letsencrypt'
# restorecon -v /etc/letsencrypt/
# semanage fcontext -a -t container_var_lib_t /var/lib/letsencrypt
# restorecon -v /var/lib/letsencrypt
# semanage fcontext -a -t container_file_t /var/log/letsencrypt
# restorecon -v /var/log/letsencrypt

3.2 Logrotate

Jak można się domyślić po tym, że zakładamy dedykowany katalog w /var/log, będziemy zbierać logi. Logi zbyt długo trzymane to zło, także dodaj sobie do katalogu /etc/logrotate.d pliczek certbot, którego zawartość to:


Dzięki temu będziemy trzymać logi przez 60 dni, no i log będzie 'łamany’ codziennie. Co oczywiste chcemy też starsze logi pakować, a użyjemy do tego komendy xz.

4. Pierwsze uruchomienie

Podman czy Docker?

To zależy… Ja pracuję na Fedorze, lubię podmana i w tutorialu będę używał komendy podman.

Co gdy używasz Dockera?
Składnia jest identyczna, także zamień słówko podman na docker i wszystko będzie działać bez problemu. 🙂

podman run \
 --rm \
 --name letsencrypt \
 -v /etc/certbot/ovh-secrets.conf:/ovh-secrets.conf \
 -v /etc/letsencrypt:/etc/letsencrypt \
 -v /var/lib/letsencrypt:/var/lib/letsencrypt \
 -v /var/log/letsencrypt:/var/log/letsencrypt \ 
 certbot/dns-ovh:latest certonly \
   --non-interactive \
   --agree-tos -m twój@email.pl \ 
   --dns-ovh
   --dns-ovh-credentials /ovh-secrets.conf \
   --dns-ovh-propagation-seconds 10 \
   -d example.com -d *.example.com -d innadomena.pl

Ło panie, a dłuższej tej komendy się nie dało? Przeanalizujmy linia po linii co tu się dzieje:

  1. podman run – uruchom kontener (możesz zmienić na docker run, jeżeli używasz dockera)
  2. –rm – posprzątaj po zakończeniu życia kontenera
  3. –name letsencrypt – kontener ma się nazywać letsencrypt
  4. -v ścieżka_na_serwerze:ścieżka_w_kontenerze – te pliki i katalogi z serwera będą dostępne w kontenerze. Tam gdzie sobie zażyczyliśmy.
  5. certbot/dns-ovh:latest certonly – uruchamiamy najnowszą wersję kontenera dns-ovh. To w nim zainstalowany jest certbot, wraz z naszym pluginem do ovh. Instruujemy certbota, że ma działać w trybie 'certonly’.
  6. –non-interactive – nie chcemy być zbyt rozmowni i odpowiadać na pytania
  7. –agree-tos -m twój@email.pl – zgadzamy się na licencję i podajemy swojego maila, żeby Let’s Encrypt wiedziało z kim gadać na temat domen, którym wystawi certyfikat. W praktyce mail jest używany do powiadomienia, że certyfikat niedługo wygaśnie.
  8. –dns-ovh – odpal challenge dns01 z wykorzystaniem pluginu dns-ovh
  9. –dns-ovh-credentials /ovh-secrets.conf – plugin musi wiedzieć jak się zalogować do OVH, także pokazujemy mu gdzie leży przygotowany przez nas config.
  10. –dns-ovh-propagation-seconds 10 – halt! Dajmy ovh 10 sekund, żeby się zdążyła dodać domena.
  11. -d, -d, -d, -d itd. – Lista domen dla których chcemy dostać certyfikaty.

Przykładowy log:

# podman run --rm --name letsencrypt -v /etc/certbot/ovh-secrets.conf:/ovh-secrets.conf -v /etc/letsencrypt:/etc/letsencrypt -v /var/lib/letsencrypt:/var/lib/letsencrypt certbot/dns-ovh:latest certonly --agree-tos -m mój@email.pl  --dns-ovh --dns-ovh-credentials /ovh-secrets.conf --dns-ovh-propagation-seconds 10 -d example.com -d *.example.com

Requesting a certificate for example.com and example.com
Waiting 10 seconds for DNS changes to propagate

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2021-10-28.
These files will be updated when the certificate renews.

NEXT STEPS:
- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

5. Mamy certyfikat, co dalej?

Zapewne po coś ten certyfikat był ci potrzebny. Apache httpd? Nginx? Haproxy? W tym tutorialu nic o nich nie będzie, ale tak. To są programy w których możesz użyć uzyskane właśnie certy.

5.1 Odnawianie

Po przeczytaniu loga na 100% (jak nie na 100000!) rzuciła ci się w oczy informacja, że certyfikaty trzeba odnawiać, i są raczej dość krótko ważne. Co z tym zrobić?

Stwórz sobie pliczek /usr/local/bin/certbot_renew.sh (albo o innej nazwie!) i nadaj mu prawa do wykonywania (chmod +x /usr/local/bin/certbot_renew.sh).
Do środka wrzuć wywołanie certbota w trybie 'renew’, oczywiście w stylu dns-ovh. Żeby mieć pewność, że korzystam z najnowszej wersji kontenera dns-ovh, dorzuciłem jeszcze podman pull na początku:


Odpalamy testowo:

# vi /usr/local/bin/certbot_renew.sh
# chmod +x /usr/local/bin/certbot_renew.sh
# /usr/local/bin/certbot_renew.sh
Trying to pull docker.io/certbot/dns-ovh:latest...
Getting image source signatures
...
Copying blob 0b99e4c5dcd1 [--------------------------------------] 0.0b / 0.0b
Copying config be6f9c73b8 done  
Writing manifest to image destination
Storing signatures
be6f9c73b8127bdd5983728deba3644efffb6826ff4d9be6757b2cf60c4aef5f

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certificate not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certificates are not due for renewal yet:
  /etc/letsencrypt/live/example.com/fullchain.pem expires on 2021-10-28 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Saving debug log to /var/log/letsencrypt/letsencrypt.log

5.2 systemd service i timer

Mamy już działający skrypcik, który gdy będzie czas odnowi certyfikaty. Wypadałoby teraz go uruchamiać cyklicznie. Cron jest trochę passe, także treningowo zróbmy to przy użyciu systemd.

Stwórz plik /etc/systemd/system/certbot_renew.service:


Następnie timer, który będzie go uruchamiać (/etc/systemd/system/certbot_renew.timer):


Pozostaje nam już tylko przeładować ustawienia i włączyć timer:

# systemctl daemon-reload
# systemctl enable certbot_renew.timer 
Created symlink /etc/systemd/system/timers.target.wants/certbot_renew.timer → /etc/systemd/system/certbot_renew.timer.

Podsumowanie i aftercare Let’s Encrypt + OVH

Raz zdefiniowany proces odświeżania certyfikatów powinien być bezobsługowy, pamiętajmy jednak, że dobrze jest czasem zajrzeć do logów:

  • journalctl -u certbot_renew.service
  • cat /var/log/letsencrypt/letsencrypt.log

No i na szczęście Let’s encrypt jest o tyle miłe, że w razie czego ostrzeże mailowo, gdy odnowienie certa nie wykona się o czasie.

Ustawienie strefy czasowej (systemd).

W paczce systemd możemy znaleźć narzędzie do zarządzania ustawieniami czasu w Linuksie. Narzędzie pokazuje obecny status, pozwala też w prosty status ustawić TZ.

Weryfikacja:

$ timedatectl
Local time: Sat 2020-05-23 15:39:25 CEST
Universal time: Sat 2020-05-23 13:39:25 UTC
RTC time: Sat 2020-05-23 13:39:25
Time zone: Europe/Paris (CEST, +0200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

Chcę, żeby serwer pracował zgodnie z czasem polskim. Komenda 'timedatectl list-timezones’ pozwala znaleźć odpowiadającą nam strefę czasową, czyli w tym przypadku 'Europe/Warsaw’.


No to ustawiamy i weryfikujemy:

$ sudo timedatectl set-timezone 'Europe/Warsaw'
$ timedatectl
Local time: Sat 2020-05-23 15:41:38 CEST
Universal time: Sat 2020-05-23 13:41:38 UTC
RTC time: Sat 2020-05-23 13:41:38
Time zone: Europe/Warsaw (CEST, +0200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

Chcesz automatycznie synchronizować czas na swoim serwerze? Rzuć okiem na artykuł opisujący jak skonfigurować ntp z użyciem serwisu systemd-timesyncd.

Synchro czasu ntp Linux (systemd)

Kolejny już wpis o synchronizacji czasu ntp. O dziwo pozmieniało się od 2014 roku, kiedy cały dumny opisałem jak w sposób nieprzesadzony synchronizować czas na Linuxach. 😉

Ktoś mądrzejszy ode mnie wdrożył to o czym pisałem – debilizmem jest stawianie serwera ntpd, jeżeli nasz Linux ma być tylko klientem. Wdrożył w systemd, także dystrybucje które go używają, powinny mieć to rozwiązanie out of box (na pewno mają Fedora, Arch i HypriotOS).

No to po kolei. Sprawdzamy czy faktycznie posiadamy taki serwis:

[szydell@laPtak ~]$ systemctl status systemd-timesyncd.service
● systemd-timesyncd.service - Network Time Synchronization
Loaded: loaded (/usr/lib/systemd/system/systemd-timesyncd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:systemd-timesyncd.service(8)

Jest. Sprawdzamy czy nasz system nie korzysta już czasem z jakiegoś dostawcy czasu. Jeżeli korzysta, to wyłączamy.

Chronyd (Fedora):

$ sudo systemctl status chronyd
● chronyd.service - NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2020-05-22 12:39:12 CEST; 59min ago
...

$ sudo systemctl disable chronyd.service --now
Removed /etc/systemd/system/multi-user.target.wants/chronyd.service.

Ntpd (HypriotOS/Debian):

$ sudo systemctl status ntp
● ntp.service - Network Time Service
Loaded: loaded (/lib/systemd/system/ntp.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-05-12 09:17:07 UTC; 1 weeks 3 days ago
...

$ sudo systemctl disable ntp --now
Synchronizing state of ntp.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable ntp
Removed /etc/systemd/system/multi-user.target.wants/ntp.service.

$ sudo apt purge ntp
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following packages will be REMOVED:
ntp*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 1,848 kB disk space will be freed.
Do you want to continue? [Y/n]
(Reading database … 28459 files and directories currently installed.)
Removing ntp (1:4.2.8p12+dfsg-4) …
Processing triggers for man-db (2.8.5-2) …
(Reading database … 28404 files and directories currently installed.)
Purging configuration files for ntp (1:4.2.8p12+dfsg-4) …
Processing triggers for systemd (241-7~deb10u3+rpi1) …

Konfiguracja serwisu systemd-timesyncd leży w pliku /etc/systemd/timesyncd.conf.
Ustaw NTP i FallbackNTP. Resztę parametrów można skasować. Wartości domyślne są ok.

Przykładowy config (główne serwery ntp z polski. Awaryjne z zasobów Fedory i Debiana):

# cat systemd/timesyncd.conf
[Time]
NTP=0.pl.pool.ntp.org 1.pl.pool.ntp.org 2.pl.pool.ntp.org 3.pl.pool.ntp.org
FallbackNTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org 2.fedora.pool.ntp.org 3.fedora.pool.ntp.org 0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org

Uruchomienie:

[szydell@laPtak ~]$ sudo systemctl enable systemd-timesyncd.service --now
Created symlink /etc/systemd/system/dbus-org.freedesktop.timesync1.service → /usr/lib/systemd/system/systemd-timesyncd.service.
Created symlink /etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service → /usr/lib/systemd/system/systemd-timesyncd.service.

[szydell@laPtak ~]$ sudo timedatectl set-ntp true

Efekty zmian można szybko zweryfikować:

[szydell@laPtak ~]$ timedatectl
Local time: pią 2020-05-22 14:48:08 CEST
Universal time: pią 2020-05-22 12:48:08 UTC
RTC time: pią 2020-05-22 12:48:08
Time zone: Europe/Warsaw (CEST, +0200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

[szydell@laPtak ~]$ timedatectl timesync-status
Server: 162.159.200.123 (0.pl.pool.ntp.org)
Poll interval: 1min 4s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 3
Reference: A490853
Precision: 1us (-25)
Root distance: 11.786ms (max: 5s)
Offset: +2.133ms
Delay: 12.974ms
Jitter: 0
Packet count: 1
Frequency: -13,327ppm

RHEL 7: zmiana hasła roota

Metoda działa na Red Hat Enterprise Linux 7 oraz Centos 7.

  • W trakcie startu systemu po wyświetleniu menu gruba zatrzymujemy go (strzałka w górę np.). Wybieramy z listy kernel, który chcemy użyć (zapewne będzie to pierwsza linia od góry).
  • Wciskamy 'e’
  • Znajdujemy linię, która zaczyna się od 'linux16′
  • Za słowem 'quiet’ lub przed 'LANG’ dodajemy wpis 'rd.break’
  • Wciskamy CTRL-X
  • Powinien wystartować goły system, z promptem #
  • # mount -o remount,rw /sysroot
  • # chroot /sysroot
  • # passwd – wpisujemy nowe hasło
  • # touch /.autorelabel – wymuszamy odtworzenie kontekstów SELinuxa przy starcie
  • exit, exit

Koniec.