Automatische HTTPS met Caddy inschakelen in een sidecar-container
In dit artikel wordt beschreven hoe Caddy kan worden gebruikt als sidecarcontainer in een containergroep en als een omgekeerde proxy kan fungeren om een automatisch beheerd HTTPS-eindpunt voor uw toepassing te bieden.
Caddy is een krachtige opensource-webserver die klaar is voor ondernemingen met automatische HTTPS die in Go is geschreven en een alternatief voor Nginx vertegenwoordigt.
De automatisering van certificaten is mogelijk omdat Caddy de ACMEv2-API (RFC 8555) ondersteunt die communiceert met Let's Encrypt om certificaten uit te geven.
In dit voorbeeld wordt alleen de Caddy-container weergegeven op poorten 80/TCP en 443/TCP. De toepassing achter de omgekeerde proxy blijft privé. De netwerkcommunicatie tussen Caddy en uw toepassing vindt plaats via localhost.
Notitie
Dit staat in tegenstelling tot de communicatie binnen de containergroep die bekend is van docker compose, waar naar containers kan worden verwezen op naam.
In het voorbeeld wordt de Caddyfile, die is vereist voor het configureren van de omgekeerde proxy, gekoppeld aan een bestandsshare die wordt gehost in een Azure Storage-account.
Notitie
Voor productie-implementaties willen de meeste gebruikers de Caddyfile in een aangepaste Docker-installatiekopieën bakken op basis van caddy. Op deze manier hoeft u geen bestanden in de container te koppelen.
Vereisten
Gebruik de Bash-omgeving in Azure Cloud Shell. Zie quickstart voor Bash in Azure Cloud Shell voor meer informatie.
Installeer de Azure CLI, indien gewenst, om CLI-referentieopdrachten uit te voeren. Als u in Windows of macOS werkt, kunt u Azure CLI uitvoeren in een Docker-container. Zie De Azure CLI uitvoeren in een Docker-container voor meer informatie.
Als u een lokale installatie gebruikt, meldt u zich aan bij Azure CLI met behulp van de opdracht az login. Volg de stappen die worden weergegeven in de terminal, om het verificatieproces te voltooien. Raadpleeg Aanmelden bij Azure CLI voor aanvullende aanmeldingsopties.
Installeer de Azure CLI-extensie bij het eerste gebruik, wanneer u hierom wordt gevraagd. Raadpleeg Extensies gebruiken met Azure CLI voor meer informatie over extensies.
Voer az version uit om de geïnstalleerde versie en afhankelijke bibliotheken te vinden. Voer az upgrade uit om te upgraden naar de nieuwste versie.
- Voor dit artikel is versie 2.0.55 of hoger van de Azure CLI vereist. Als u Azure Cloud Shell gebruikt, is de nieuwste versie al geïnstalleerd.
De Caddyfile voorbereiden
Maak een bestand met de naam Caddyfile
en plak de volgende configuratie. Met deze configuratie maakt u een omgekeerde proxyconfiguratie, die verwijst naar uw toepassingscontainer die luistert op 5000/TCP.
my-app.westeurope.azurecontainer.io {
reverse_proxy http://localhost:5000
}
Het is belangrijk om te weten dat de configuratie verwijst naar een domeinnaam in plaats van een IP-adres. Caddy moet bereikbaar zijn via deze URL om de uitdagingsstap uit te voeren die is vereist voor het ACME-protocol en om een certificaat op te halen uit Let's Encrypt.
Notitie
Voor productie-implementatie willen gebruikers mogelijk een domeinnaam gebruiken die ze beheren, bijvoorbeeld api.company.com
en een CNAME-record maken die verwijst naar bijvoorbeeld my-app.westeurope.azurecontainer.io
. Zo ja, dan moet worden gegarandeerd dat de aangepaste domeinnaam ook wordt gebruikt in de Caddyfile, in plaats van de naam die is toegewezen door Azure (bijvoorbeeld *.westeurope.azurecontainer.io
). Verder moet naar de aangepaste domeinnaam worden verwezen in de ACI YAML-configuratie die verderop in dit voorbeeld wordt beschreven.
Opslagaccount voorbereiden
Een opslagaccount maken
az storage account create \
--name <storage-account> \
--resource-group <resource-group> \
--location westeurope
De verbindingsreeks opslaan in een omgevingsvariabele
AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string --name <storage-account> --resource-group <resource-group> --output tsv)
Maak de bestandsshares die nodig zijn om de containerstatus en caddyconfiguratie op te slaan.
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>
Haal de sleutels van het opslagaccount op en noteer deze voor later gebruik
az storage account keys list -g <resource-group> -n <storage-account>
Containergroep implementeren
YAML-bestand maken
Maak een bestand met de naam ci-my-app.yaml
en plak de volgende inhoud. Zorg ervoor dat u een van de eerder ontvangen <storage-account>
toegangssleutels vervangt <account-key>
door een van de toegangssleutels.
Dit YAML-bestand definieert twee containers reverse-proxy
en my-app
. De reverse-proxy
container koppelt de drie eerder gemaakte bestandsshares. De configuratie maakt ook poort 80/TCP en 443/TCP van de reverse-proxy
container beschikbaar. De communicatie tussen beide containers vindt alleen plaats op localhost.
Notitie
Het is belangrijk om te weten dat de dnsNameLabel
sleutel de openbare DNS-naam definieert, waaronder de containerinstantiegroep bereikbaar is, deze moet overeenkomen met de FQDN die is gedefinieerd in de 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>"
De containergroep implementeren
Maak een resourcegroep met de opdracht az group create :
az group create --name <resource-group> --location westeurope
Implementeer de containergroep met de opdracht az container create , waarbij het YAML-bestand als argument wordt doorgegeven.
az container create --resource-group <resource-group> --file ci-my-app.yaml
De implementatiestatus weergeven
Gebruik de volgende opdracht az container show om de status van de implementatie weer te geven:
az container show --resource-group <resource-group> --name ci-my-app --output table
TLS-verbinding controleren
Voordat u controleert of alles goed is gegaan, geeft u de containergroep enige tijd om volledig te starten en voor Caddy om een certificaat aan te vragen.
OpenSSL
Hiervoor kunnen we de s_client
subopdracht van OpenSSL gebruiken.
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
Chrome-browser
Navigeer naar https://my-app.westeurope.azurecontainer.io
het certificaat en controleer het door op de hangslot naast de URL te klikken.
Als u de certificaatdetails wilt zien, selecteert u 'Verbinding is veilig' gevolgd door 'certificaat is geldig'.