Share via


Aktivieren von automatischem HTTPS mit Caddy in einem Sidecar-Container

In diesem Artikel wird beschrieben, wie Caddy als Sidecar-Container in einer Containergruppe, die als Reverseproxy fungiert, verwendet werden kann, um einen automatisch verwalteten HTTPS-Endpunkt für Ihre Anwendung bereitzustellen.

Caddy ist ein leistungsstarker, unternehmensfähiger Open Source Webserver mit automatisch in Go geschriebenem HTTPS und stellt eine Alternative zu Nginx dar.

Die Automatisierung von Zertifikaten ist möglich, da Caddy die ACMEv2-API (RFC 8555) unterstützt, die mit Let's Encrypt interagiert, um Zertifikate auszustellen.

In diesem Beispiel wird nur der Caddy-Container für die Ports 80/TCP und 443/TCP verfügbar gemacht. Die Anwendung hinter dem Reverseproxy bleibt privat. Die Netzwerkkommunikation zwischen Caddy und Ihrer Anwendung erfolgt über Localhost.

Hinweis

Dies steht im Gegensatz zu der aus Docker Compose bekannten containergruppeninternen Kommunikation, bei der Container über ihren Namen referenziert werden können.

Im Beispiel wird die zum Konfigurieren des Reverseproxys erforderliche Caddyfile aus einer Dateifreigabe, die in einem Azure Storage-Konto gehostet wird, eingebunden.

Hinweis

Bei Produktionsbereitstellungen möchten die meisten Benutzer ein Baking der Caddyfile in ein benutzerdefiniertes Docker-Image auf Basis von Caddy ausführen. Auf diese Weise müssen keine Dateien in den Container eingebunden werden.

Voraussetzungen

  • Verwenden Sie die Bash-Umgebung in Azure Cloud Shell. Weitere Informationen finden Sie unter Schnellstart für Bash in Azure Cloud Shell.

  • Wenn Sie CLI-Referenzbefehle lieber lokal ausführen, installieren Sie die Azure CLI. Wenn Sie Windows oder macOS ausführen, sollten Sie die Azure CLI in einem Docker-Container ausführen. Weitere Informationen finden Sie unter Ausführen der Azure CLI in einem Docker-Container.

    • Wenn Sie eine lokale Installation verwenden, melden Sie sich mithilfe des Befehls az login bei der Azure CLI an. Führen Sie die in Ihrem Terminal angezeigten Schritte aus, um den Authentifizierungsprozess abzuschließen. Informationen zu anderen Anmeldeoptionen finden Sie unter Anmelden mit der Azure CLI.

    • Installieren Sie die Azure CLI-Erweiterung beim ersten Einsatz, wenn Sie dazu aufgefordert werden. Weitere Informationen zu Erweiterungen finden Sie unter Verwenden von Erweiterungen mit der Azure CLI.

    • Führen Sie az version aus, um die installierte Version und die abhängigen Bibliotheken zu ermitteln. Führen Sie az upgrade aus, um das Upgrade auf die aktuelle Version durchzuführen.

  • Für diesen Artikel ist mindestens Version 2.0.55 der Azure CLI erforderlich. Bei Verwendung von Azure Cloud Shell ist die aktuelle Version bereits installiert.

Vorbereiten der Caddyfile

Erstellen Sie eine Datei namens „Caddyfile“, und fügen Sie die folgende Konfiguration ein. Diese Konfiguration erstellt eine Reverseproxykonfiguration, die auf Ihren Anwendungscontainer, der auf 5000/TCP lauscht, verweist.

my-app.westeurope.azurecontainer.io {
    reverse_proxy http://localhost:5000
}

Es ist wichtig zu beachten, dass die Konfiguration auf einen Domänennamen und nicht auf eine IP-Adresse verweist. Caddy muss über diese URL erreichbar sein, um den vom ACME-Protokoll erforderlichen Herausforderungsschritt auszuführen und ein Zertifikat erfolgreich von Let's Encrypt abzurufen.

Hinweis

Für die Produktionsbereitstellung möchten Benutzer möglicherweise einen von ihnen kontrollierten Domänennamen verwenden, z. B. api.company.com und einen CNAME-Eintrag erstellen, der z. B. auf my-app.westeurope.azurecontainer.io verweist. Wenn ja, muss sichergestellt werden, dass anstelle des von Azure zugewiesenen Namens (z. B. *.westeurope.azurecontainer.io) der benutzerdefinierte Domänenname in der Caddyfile verwendet wird. Außerdem muss in der weiter unten in diesem Beispiel beschriebenen ACI YAML-Konfiguration auf den benutzerdefinierten Domänenname verwiesen werden.

Vorbereiten des Speicherkontos

Speicherkonto erstellen

az storage account create \
  --name <storage-account> \
  --resource-group <resource-group> \
  --location westeurope

Speichern Ihrer Verbindungszeichenfolge in einer Umgebungsvariable

AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string --name <storage-account> --resource-group <resource-group> --output tsv)

Erstellen Sie die Dateifreigaben, die zum Speichern des Containerzustands und der Caddykonfiguration erforderlich sind.

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>

Rufen Sie die Speicherkontoschlüssel ab, und notieren Sie sich diese zur späteren Verwendung.

az storage account keys list -g <resource-group> -n <storage-account>

Bereitstellen einer Containergruppe

Erstellen einer YAML-Datei

Erstellen Sie eine Datei namens „ci-my-app.yaml“, und fügen Sie die folgenden Inhalte ein. Stellen Sie sicher, dass Sie <account-key> durch einen der zuvor empfangenen Zugriffsschlüssel und <storage-account> entsprechend ersetzen.

Diese YAML-Datei definiert zwei Container, reverse-proxy und my-app. Der reverse-proxy-Container bindet die drei zuvor erstellten Dateifreigaben ein. Die Konfiguration macht auch Port 80/TCP und 443/TCP des reverse-proxy-Containers verfügbar. Die Kommunikation zwischen beiden Containern erfolgt nur über Localhost.

Hinweis

Es ist wichtig zu beachten, dass der dnsNameLabel-Schlüssel den öffentlichen DNS-Namen definiert, unter dem die Containerinstanzgruppe erreichbar ist. Er muss mit dem in der Caddyfile definierten FQDN übereinstimmen.

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>"

Bereitstellen der Containergruppe

Erstellen Sie mit dem Befehl az group create eine Ressourcengruppe:

az group create --name <resource-group> --location westeurope

Stellen Sie die Containergruppe mit dem Befehl az container create bereit, und geben Sie die YAML-Datei als Argument weiter.

az container create --resource-group <resource-group> --file ci-my-app.yaml

Anzeigen des Bereitstellungsstatus

Um den Bereitstellungsstatus anzuzeigen, verwenden Sie den folgenden Befehl az container show:

az container show --resource-group <resource-group> --name ci-my-app --output table

Überprüfen der TLS-Verbindung

Bevor Sie überprüfen, ob alles geklappt hat, geben Sie der Containergruppe etwas Zeit, um vollständig zu starten und damit Caddy ein Zertifikat anfordern kann.

OpenSSL

Zu diesem Zweck können Sie den s_client-Unterbefehl von OpenSSL verwenden.

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

Navigieren Sie zu https://my-app.westeurope.azurecontainer.io und überprüfen Sie das Zertifikat, indem Sie auf das Schloss neben der URL klicken.

Screenshot mit hervorgehobenem Schloss neben der URL zum überprüfen des Zertifikats.

Um die Zertifikatdetails anzuzeigen, klicken Sie auf „Verbindung ist sicher“, gefolgt von „Zertifikat ist gültig“.

Screenshot des von Let‘s Encrypt ausgestellten Zertifikats

Nächste Schritte