W drodze do automatyzacji wydawania SSL

Dość często musimy pracować z certyfikatami SSL. Przypomnijmy sobie proces tworzenia i instalacji certyfikatu (w ogólnym przypadku dla większości).

 

  • Znaleźć dostawcę (stronę, na której można kupić SSL).
  • Wygenerować CSR.
  • Wysłać go do dostawcy.
  • Potwierdzić posiadanie domeny.
  • Otrzymać certyfikat.
  • Przekształcić certyfikat w potrzebną formę (opcjonalnie). Na przykład, z pem do PKCS #12.
  • Zainstalować certyfikat na serwerze WWW.

 

Relatywnie szybko, niezłożone i zrozumiałe. Ta opcja jest całkiem odpowiednia, jeśli mamy maksymalnie kilka projektów. A jeśli ich jest więcej i mają co najmniej trzy środowiska? Klasyczne dev — staging — production. W takim przypadku warto pomyśleć o automatyzacji tego procesu. Proponuję, aby zagłębić się w problem i znaleźć rozwiązanie, które w przyszłości zminimalizuje czasochłonność tworzenia i utrzymania certyfikatów. W artykule znajduje się analiza problemu oraz krótkie instrukcje powtarzania.

 

Przedtem muszę zaznaczyć: podstawowa specjalizacja naszej firmy to .net, a więc IIS i inne związane z tym aspekty. Dlatego też klient ACME i wszystkie działania dla niego będą opisane z perspektywy użycia Windows.

 

Dla kogo to jest aktualne oraz niektóre dane początkowe

Firma K w osobie autora. URL (dla przykładu): company.tld

 

Projekt X — jeden z naszych projektów, w którego realizacji doszedłem do wniosku, że trzeba dążyć do maksymalnej oszczędności czasu przy pracy z certyfikatami. Ten projekt ma cztery środowiska: dev, test, staging i production. Dev i test znajdują się po naszej stronie, staging i production po stronie klienta.

 

Cechą charakterystyczną projektu jest to, że ma on wiele modułów, które są dostępne jako subdomeny.

 

Czyli, mamy następujący obraz:

 

Dev
Test
Staging
Production

projectX.dev.company.tld
projectX.test.company.tld
staging.projectX.tld
projectX.tld

module1.projectX.dev.company.tld
module1.projectX.test.company.tld
module1.staging.projectX.tld
module1.projectX.tld

module2.projectX.dev.company.tld
module2.projectX.test.company.tld
module2.staging.projectX.tld
module2.projectX.tld




moduleN.projectX.dev.company.tld
moduleN.projectX.test.company.tld
moduleN.staging.projectX.tld
moduleN.projectX.tld

 

Do produkcji używany jest zakupiony certyfikat wildcard, więc nie ma co do tego wątpliwości. Pokrywa on jednak tylko pierwszy poziom poddomeny. Oznacza to, że jeśli istnieje certyfikat dla *.projectX.tld — będzie on działać dla staging.projectX.tld, ale już dla module1.staging.projectX.tld nie zadziała. A nie chcę wydawać pieniędzy na osobny certyfikat.

 

I to tylko na przykładzie jednego projektu jednej firmy. Projektów, oczywiście, jest więcej.

 

Powody, dla których wszyscy powinni zająć się rozwiązaniem tego problemu, wyglądają mniej więcej tak:

 

  • Stosunkowo niedawno Google zaproponował skrócenie maksymalnego okresu ważności certyfikatów SSL. Ze wszystkimi tego konsekwencjami.
  • Ułatwić proces wydawania i zarządzania SSL certyfikatami dla wewnętrznych potrzeb projektów i firmy jako całości.
  • Centralne przechowywanie rekordów certyfikatów, które częściowo rozwiązuje problem potwierdzania domeny za pomocą DNS oraz późniejszej automatyzacji aktualizacji, a także wzmacnia zaufanie klienta. W końcu, większe zaufanie budzi CNAME na serwerze firmy partnera wykonawcy, niż na zewnętrznym zasobie.
  • No i wreszcie, w takim przypadku powiedzenie „lepiej mieć niż nie mieć” pasuje idealnie.

 

Wybór dostawcy SSL oraz kroki przygotowawcze

 

Z dostępnych opcji bezpłatnych certyfikatów SSL rozważane były cloudflare i letsencrypt. DNS dla tego (i niektórych innych projektów) jest zlokalizowany na cloudflare, ale nie jestem zwolennikiem korzystania z ich certyfikatów. Dlatego postanowiono użyć letsencrypt.
Aby stworzyć certyfikat wildcard SSL należy potwierdzić posiadanie domeny. Procedura ta wymaga utworzenia pewnego rekordu DNS (TXT lub CNAME), a następnie jego weryfikacji przy wydawaniu certyfikatu. W systemie Linux istnieje narzędzie — certbot, które pozwala częściowo (lub całkowicie dla niektórych dostawców DNS) zautomatyzować ten proces. Dla systemu Windows z znalezionych i sprawdzonych opcji klientów ACME zatrzymałem się na WinACME.

 

A rekord dla domeny jest już utworzony, przechodzimy do stworzenia certyfikatu:

 

W drodze do automatyzacji wydawania SSL

 

Interesuje nas ostatni wynik, a mianowicie — dostępne opcje potwierdzenia posiadania domeny do wydania certyfikatu wildcard:

 

  1. Ręczne tworzenie rekordów DNS (automatyczna aktualizacja nie jest obsługiwana)
  2. Tworzenie rekordów DNS za pomocą serwera acme-dns (więcej informacji można znaleźć tutaj.
  3. Tworzenie rekordów DNS za pomocą własnego skryptu (analog wtyczki cloudflare dla certbot).

 

Na pierwszy rzut oka trzeci punkt wydaje się odpowiedni, ale co jeśli dostawca DNS nie wspiera tej funkcjonalności? A potrzebujemy przypadku ogólnego. A przypadek ogólny to rekordy CNAME, które wszyscy wspierają. Dlatego zatrzymujemy się na punkcie 2 i przechodzimy do konfiguracji swojego serwera ACME-DNS.

 

Konfiguracja serwera ACME-DNS i proces wydawania certyfikatu

 

Na przykład stworzyłem domenę 2nd.pp.ua i w dalszej części będę jej używać.

 

Obowiązkowym wymaganiem dla poprawnego działania serwera jest stworzenie rekordów NS i A dla jego domeny. I pierwszy nieprzyjemny moment, z którym się spotkałem, to że cloudflare (przynajmniej w trybie bezpłatnym) nie pozwala jednocześnie stworzyć rekordów NS i A dla tego samego hosta. Nie żeby to było problemem, ale w bind jest to możliwe. Support odpowiedział, że ich panel tego nie umożliwia. Nie szkodzi, stworzymy dwa rekordy:

 

acmens.2nd.pp.ua. IN A 35.237.128.147
acme.2nd.pp.ua. IN NS acmens.2nd.pp.ua.

 

Na tym etapie nasz host powinien rozwiązywać acmens.2nd.pp.ua.

 

$ ping acmens.2nd.pp.ua
PING acmens.2nd.pp.ua (35.237.128.147) 56(84) bajtów danych

 

Natomiast acme.2nd.pp.ua nie będzie się rozwiązywać, ponieważ serwer DNS, który go obsługuje, jeszcze nie został uruchomiony.

 

Rekordy zostały stworzone, przechodzimy do konfiguracji i uruchomienia serwera ACME-DNS. Będzie on działać na ubuntu server w docker kontenerze, ale można go uruchomić wszędzie tam, gdzie jest golang. Windows również się nada, ale ja wolę serwery Linux.

 

Tworzymy potrzebne katalogi i pliki:

 

$ mkdir config
$ mkdir data
$ touch config/config.cfg

 

Skorzystamy z vim, waszego ulubionego edytora tekstu i wstawimy do config.cfg przykład konfiguracji.

 

Dla skutecznej pracy wystarczy dostosować sekcje general i api:

 

[general]
listen = "0.0.0.0:53"
protocol = "both"
domain = "acme.2nd.pp.ua"
nsname = "acmens.2nd.pp.ua" 
nsadmin = "admin.2nd.pp.ua" 
records = 
    "acme.2nd.pp.ua. A 35.237.128.147",
    "acme.2nd.pp.ua. NS acmens.2nd.pp.ua.",                                                                                                                                                                                                  ]
...
[api]
...
tls = "letsencrypt"
…

 

Również, na życzenie, stworzymy plik docker-compose w głównym katalogu usługi:

 

version: '3.7'
services:
  acmedns:
    image: joohoi/acme-dns:latest
    ports:
      - "443:443"
      - "53:53"
      - "53:53/udp"
      - "80:80"
    volumes:
      - ./config:/etc/acme-dns:ro
      - ./data:/var/lib/acme-dns

 

Gotowe. Można uruchamiać.

 

$ docker-compose up -d

 

Na tym etapie powinien zacząć się rozwiązywać host acme.2nd.pp.ua, a na https://acme.2nd.pp.ua

 

$ ping acme.2nd.pp.ua
PING acme.2nd.pp.ua (35.237.128.147) 56(84) bajtów danych.

$ curl https://acme.2nd.pp.ua
404 page not found

 

Jeśli to się nie pojawiło — docker logs -f w pomoc, dobro, logi są całkiem czytelne.

 

Możemy przystąpić do tworzenia certyfikatu. Otwórz PowerShell jako administrator i uruchom winacme. Interesują nas opcje:

 

  • M: Utwórz nowy certyfikat (wszystkie opcje)
  • 2: Ręczne wprowadzenie
  • 2: [dns-01] Utwórz rekordy weryfikacyjne z acme-dns (https://github.com/joohoi/acme-dns)
  • Na pytanie o link do serwera ACME-DNS wprowadzamy w odpowiedzi URL utworzonego serwera (https). URL serwera acme-dns: https://acme.2nd.pp.ua

 

Klient zwraca rekord, który należy dodać do istniejącego serwera DNS (procedura jednorazowa):

 

[INFO] Tworzenie nowej rejestracji acme-dns dla domeny 1nd.pp.ua

Domena:              1nd.pp.ua
Rekord:               _acme-challenge.1nd.pp.ua
Typ:                   CNAME
Zawartość:              c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.
Uwaga:                   Niektóre panele kontroli DNS automatycznie dodają końcową kropkę.
                           Tylko jedna jest wymagana.

 

W drodze do automatyzacji wydawania SSL

 

Tworzymy potrzebny rekord i upewniamy się, że został poprawnie utworzony:

 

W drodze do automatyzacji wydawania SSL

 

$ dig CNAME _acme-challenge.1nd.pp.ua +short
c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.

 

Potwierdzamy, że utworzyliśmy wymagany rekord w winacme i kontynuujemy proces tworzenia certyfikatu:

 

W drodze do automatyzacji wydawania SSL

 

Jak używać certbota jako klienta opisano tutaj.

 

Na tym proces tworzenia certyfikatu zakończony, można go zainstalować na serwerze WWW i używać. Jeśli podczas tworzenia certyfikatu utworzysz również zadanie w harmonogramie, to w przyszłości proces aktualizacji certyfikatu będzie przebiegał automatycznie.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster