Włączanie automatycznego protokołu HTTPS za pomocą narzędzia Caddy w kontenerze przyczepki
W tym artykule opisano, jak caddy może być używany jako kontener przyczepki w grupie kontenerów i pełnić rolę zwrotnego serwera proxy w celu zapewnienia automatycznie zarządzanego punktu końcowego HTTPS dla aplikacji.
Caddy to zaawansowany, gotowy do użycia w przedsiębiorstwie serwer internetowy typu open source z automatycznym protokołem HTTPS napisanym w języku Go i stanowi alternatywę dla serwera Nginx.
Automatyzacja certyfikatów jest możliwa, ponieważ program Caddy obsługuje interfejs API ACMEv2 (RFC 8555), który współdziała z usługą Let's Encrypt w celu wystawiania certyfikatów.
W tym przykładzie tylko kontener Caddy jest uwidoczniony na portach 80/TCP i 443/TCP. Aplikacja za zwrotnym serwerem proxy pozostaje prywatna. Komunikacja sieciowa między programem Caddy a aplikacją odbywa się za pośrednictwem hosta lokalnego.
Uwaga
Jest to przeciwieństwo komunikacji wewnątrz grupy kontenerów znanej z narzędzia docker compose, gdzie kontenery mogą być przywoływanych według nazwy.
Przykład instaluje plik Caddyfile, który jest wymagany do skonfigurowania zwrotnego serwera proxy z udziału plików hostowanego na koncie usługi Azure Storage.
Uwaga
W przypadku wdrożeń produkcyjnych większość użytkowników chce umieścić plik Caddyfile w niestandardowym obrazie platformy Docker opartym na caddy. W ten sposób nie ma potrzeby instalowania plików w kontenerze.
Wymagania wstępne
Użyj środowiska powłoki Bash w usłudze Azure Cloud Shell. Aby uzyskać więcej informacji, zobacz Szybki start dotyczący powłoki Bash w usłudze Azure Cloud Shell.
Jeśli wolisz uruchamiać polecenia referencyjne interfejsu wiersza polecenia lokalnie, zainstaluj interfejs wiersza polecenia platformy Azure. Jeśli korzystasz z systemu Windows lub macOS, rozważ uruchomienie interfejsu wiersza polecenia platformy Azure w kontenerze Docker. Aby uzyskać więcej informacji, zobacz Jak uruchomić interfejs wiersza polecenia platformy Azure w kontenerze platformy Docker.
Jeśli korzystasz z instalacji lokalnej, zaloguj się do interfejsu wiersza polecenia platformy Azure za pomocą polecenia az login. Aby ukończyć proces uwierzytelniania, wykonaj kroki wyświetlane w terminalu. Aby uzyskać inne opcje logowania, zobacz Logowanie się przy użyciu interfejsu wiersza polecenia platformy Azure.
Po wyświetleniu monitu zainstaluj rozszerzenie interfejsu wiersza polecenia platformy Azure podczas pierwszego użycia. Aby uzyskać więcej informacji na temat rozszerzeń, zobacz Korzystanie z rozszerzeń w interfejsie wiersza polecenia platformy Azure.
Uruchom polecenie az version, aby znaleźć zainstalowane wersje i biblioteki zależne. Aby uaktualnić do najnowszej wersji, uruchom polecenie az upgrade.
- Ten artykuł wymaga wersji 2.0.55 lub nowszej interfejsu wiersza polecenia platformy Azure. W przypadku korzystania z usługi Azure Cloud Shell najnowsza wersja jest już zainstalowana.
Przygotowywanie pliku Caddyfile
Utwórz plik o nazwie Caddyfile
i wklej następującą konfigurację. Ta konfiguracja tworzy konfigurację zwrotnego serwera proxy wskazującą kontener aplikacji nasłuchujący na 5000/TCP.
my-app.westeurope.azurecontainer.io {
reverse_proxy http://localhost:5000
}
Należy pamiętać, że konfiguracja odwołuje się do nazwy domeny zamiast adresu IP. Program Caddy musi być osiągalny przez ten adres URL, aby wykonać krok wyzwania wymagany przez protokół ACME i pomyślnie pobrać certyfikat z usługi Let's Encrypt.
Uwaga
W przypadku wdrożenia produkcyjnego użytkownicy mogą chcieć użyć nazwy domeny, którą kontrolują, npapi.company.com
. i utworzyć rekord CNAME wskazujący na przykład . my-app.westeurope.azurecontainer.io
Jeśli tak, należy się upewnić, że niestandardowa nazwa domeny jest również używana w pliku Caddyfile zamiast nazwy przypisanej przez platformę Azure (np. *.westeurope.azurecontainer.io
). Ponadto nazwa domeny niestandardowej musi zostać odwołana w konfiguracji YAML usługi ACI opisanej w dalszej części tego przykładu.
Przygotowywanie konta magazynu
Tworzenie konta magazynu
az storage account create \
--name <storage-account> \
--resource-group <resource-group> \
--location westeurope
Przechowywanie parametry połączenia do zmiennej środowiskowej
AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string --name <storage-account> --resource-group <resource-group> --output tsv)
Utwórz udziały plików wymagane do przechowywania stanu kontenera i konfiguracji caddy.
az storage share create \
--name proxy-caddyfile \
--account-name <storage-account>
az storage share create \
--name proxy-config \
--account-name <storage-account>
az storage share create \
--name proxy-data \
--account-name <storage-account>
Pobieranie kluczy konta magazynu i zanotowanie do późniejszego użycia
az storage account keys list -g <resource-group> -n <storage-account>
Wdrażanie grupy kontenerów
Tworzenie pliku YAML
Utwórz plik o nazwie ci-my-app.yaml
i wklej następującą zawartość. Upewnij się, że zastąp element <account-key>
jednym z wcześniej odebranych kluczy dostępu i <storage-account>
odpowiednio.
Ten plik YAML definiuje dwa kontenery reverse-proxy
i my-app
. Kontener reverse-proxy
instaluje trzy wcześniej utworzone udziały plików. Konfiguracja uwidacznia również port 80/TCP i 443/TCP kontenera reverse-proxy
. Komunikacja między obydwoma kontenerami odbywa się tylko na hoście lokalnym.
Uwaga
Należy pamiętać, że dnsNameLabel
klucz definiuje publiczną nazwę DNS, w ramach której grupa wystąpień kontenera będzie osiągalna, musi być zgodna z nazwą FQDN zdefiniowaną w Caddyfile
name: ci-my-app
apiVersion: "2021-10-01"
location: westeurope
properties:
containers:
- name: reverse-proxy
properties:
image: caddy:2.6
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
resources:
requests:
memoryInGB: 1.0
cpu: 1.0
limits:
memoryInGB: 1.0
cpu: 1.0
volumeMounts:
- name: proxy-caddyfile
mountPath: /etc/caddy
- name: proxy-data
mountPath: /data
- name: proxy-config
mountPath: /config
- name: my-app
properties:
image: mcr.microsoft.com/azuredocs/aci-helloworld
ports:
- port: 5000
protocol: TCP
environmentVariables:
- name: PORT
value: 5000
resources:
requests:
memoryInGB: 1.0
cpu: 1.0
limits:
memoryInGB: 1.0
cpu: 1.0
ipAddress:
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
type: Public
dnsNameLabel: my-app
osType: Linux
volumes:
- name: proxy-caddyfile
azureFile:
shareName: proxy-caddyfile
storageAccountName: "<storage-account>"
storageAccountKey: "<account-key>"
- name: proxy-data
azureFile:
shareName: proxy-data
storageAccountName: "<storage-account>"
storageAccountKey: "<account-key>"
- name: proxy-config
azureFile:
shareName: proxy-config
storageAccountName: "<storage-account>"
storageAccountKey: "<account-key>"
Wdrażanie grupy kontenerów
Utwórz grupę zasobów za pomocą polecenia az group create :
az group create --name <resource-group> --location westeurope
Wdróż grupę kontenerów za pomocą polecenia az container create , przekazując plik YAML jako argument.
az container create --resource-group <resource-group> --file ci-my-app.yaml
Wyświetlanie stanu wdrożenia
Aby wyświetlić stan wdrożenia, użyj następującego polecenia az container show :
az container show --resource-group <resource-group> --name ci-my-app --output table
Weryfikowanie połączenia TLS
Przed sprawdzeniem, czy wszystko poszło dobrze, daj grupie kontenerów trochę czasu na pełne uruchomienie i, aby Caddy zażądał certyfikatu.
OpenSSL
W tym celu możemy użyć s_client
podpolecenia biblioteki OpenSSL.
echo "Q" | openssl s_client -connect my-app.westeurope.azurecontainer.io:443
CONNECTED(00000188)
---
Certificate chain
0 s:CN = my-app.westeurope.azurecontainer.io
i:C = US, O = Let's Encrypt, CN = R3
1 s:C = US, O = Let's Encrypt, CN = R3
i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEgTCCA2mgAwIBAgISAxxidSnpH4vVuCZk9UNG/pd2MA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMzA0MDYxODAzMzNaFw0yMzA3MDUxODAzMzJaMC4xLDAqBgNVBAMT
I215LWFwcC53ZXN0ZXVyb3BlLmF6dXJlY29udGFpbmVyLmlvMFkwEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAEaaN/wGyFcimM+1O4WzbFgO6vIlXxXqp9vgmLZHpFrNwV
aO8JbaB7hE+M5EAg34LDY80RyHgY+Ff4vTh2Z96rVqOCAl4wggJaMA4GA1UdDwEB
/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/
BAIwADAdBgNVHQ4EFgQUoL5DP+4PWiyE79hL5o+v8uymHdAwHwYDVR0jBBgwFoAU
FC6zF7dYVsuuUAlA5h+vnYsUwsYwVQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzAB
hhVodHRwOi8vcjMuby5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5p
LmxlbmNyLm9yZy8wLgYDVR0RBCcwJYIjbXktYXBwLndlc3RldXJvcGUuYXp1cmVj
b250YWluZXIuaW8wTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMBAQEw
KDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEEBgor
BgEEAdZ5AgQCBIH1BIHyAPAAdgC3Pvsk35xNunXyOcW6WPRsXfxCz3qfNcSeHQmB
Je20mQAAAYdX8+CQAAAEAwBHMEUCIQC9Ztqd3DXoJhOIHBW+P7ketGrKlVA6nPZl
9CiOrn6t8gIgXHcrbBqItemndRMv+UJ3DaBfTkYOqECecOJCgLhSYNUAdgDoPtDa
PvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAYdX8+CAAAAEAwBHMEUCIBJ1
24z44vKFUOLCi1a7ymVuWErkmLb/GtysvcxILaj0AiEAr49hyKfen4BbSTwC8Fg4
/LgZnn2F3uHI+9p+ZMO9xTAwDQYJKoZIhvcNAQELBQADggEBACqxa21eiW3JrZwk
FHgpd6SxhUeecrYXxFNva1Y6G//q2qCmGeKK3GK+ZGPqDtcoASH5t5ghV4dIT4WU
auVDLFVywXzR8PT6QUu3W8QxU+W7406twBf23qMIgrF8PIWhStI5mn1uCpeqlnf5
HpRaj2f5/5n19pcCZcrRx94G9qhPYdMzuy4mZRhxXRqrpIsabqX3DC2ld8dszCvD
pkV61iuARgm3MIQz1yL/x5Bn4nywjnhYZA4KFktC0Ti55cPRh1mkzGQAsYQDdWrq
dVav+U9dOLQ4Sq4suaDmzDzApr+hpQSJhwgRN16+tLMyZ6INAU2JWKDxiyDTdOuH
jz456og=
-----END CERTIFICATE-----
subject=CN = my-app.westeurope.azurecontainer.io
issuer=C = US, O = Let's Encrypt, CN = R3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 4208 bytes and written 401 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 20 (unable to get local issuer certificate)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_128_GCM_SHA256
Session-ID: 85F1A4290F99A0DD28C8CB21EF4269E7016CC5D23485080999A8548057729B24
Session-ID-ctx:
Resumption PSK: 752D438C19A5DBDBF10781F863D5E5D9A8859230968A9EAFFF7BBA86937D004F
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 604800 (seconds)
TLS session ticket:
0000 - 2f 25 98 90 9d 46 9b 01-03 78 db bd 4d 64 b3 a6 /%...F...x..Md..
0010 - 52 c0 7a 8a b6 3d b8 4b-c0 d7 fc 04 e8 63 d4 bb R.z..=.K.....c..
0020 - 15 b3 25 b7 be 64 3d 30-2b d7 dc 7a 1a d1 22 63 ..%..d=0+..z.."c
0030 - 42 30 90 65 6b b5 e1 83-a3 6c 76 c8 f6 ae e9 31 B0.ek....lv....1
0040 - 45 91 33 57 8e 9f 4b 6a-2e 2c 9b f9 87 5f 71 1d E.3W..Kj.,..._q.
0050 - 5a 84 59 50 17 31 1f 62-2b 0e 1e e5 70 03 d9 e9 Z.YP.1.b+...p...
0060 - 50 1c 5d 1f a4 3c 8a 0e-f4 c5 7d ce 9e 5c 98 de P.]..<....}..\..
0070 - e5 .
Start Time: 1680808973
Timeout : 7200 (sec)
Verify return code: 20 (unable to get local issuer certificate)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
Przeglądarka Chrome
Przejdź do https://my-app.westeurope.azurecontainer.io
i zweryfikuj certyfikat, klikając kłódkę obok adresu URL.
Aby wyświetlić szczegóły certyfikatu, wybierz pozycję "Połączenie jest bezpieczne", a następnie "certyfikat jest prawidłowy".