Proxy-managed TLS

This topic describes how to deploy a Swarm service wherein the proxy manages the TLS connection. Using proxy-managed TLS entails that the traffic between the proxy and the Swarm service is not secure, so you should only use this option if you trust that no one can monitor traffic inside the services that run in your datacenter.

To deploy a Swarm service with proxy-managed TLS:

  1. Obtain a private key and certificate for the TLS connection. The Common Name (CN) in the certificate must match the name where your service will be available. Generate a self-signed certificate for app.example.org:

    openssl req \
    -new \
    -newkey rsa:4096 \
    -days 3650 \
    -nodes \
    -x509 \
    -subj "/C=US/ST=CA/L=SF/O=Docker-demo/CN=app.example.org" \
    -keyout app.example.org.key \
    -out app.example.org.cert
    
  2. Create the following docker-compose.yml file:

    version: "3.2"
    
    services:
      demo:
        image: mirantiseng/docker-demo
        deploy:
          replicas: 1
          labels:
            com.docker.lb.hosts: app.example.org
            com.docker.lb.network: demo-network
            com.docker.lb.port: 8080
            com.docker.lb.ssl_cert: demo_app.example.org.cert
            com.docker.lb.ssl_key: demo_app.example.org.key
        environment:
          METADATA: proxy-handles-tls
        networks:
          - demo-network
    
    networks:
      demo-network:
        driver: overlay
    secrets:
      app.example.org.cert:
        file: ./app.example.org.cert
      app.example.org.key:
        file: ./app.example.org.key
    

    The demo service has labels specifying that the proxy service routes app.example.org traffic to this service. All traffic between the service and proxy occurs using the demo-network network. The service has labels that specify the Docker secrets used on the proxy service for terminating the TLS connection.

    The private key and certificate are stored as Docker secrets, and thus you can readily scale the number of replicas used for running the proxy service, with MKE distributing the secrets to the replicas.

  3. Download and configure the client bundle and deploy the service:

    docker stack deploy --compose-file docker-compose.yml demo
    
  4. Test that everything works correctly by updating your /etc/hosts file to map app.example.org to the IP address of an MKE node.

  5. Optional. In a production deployment, create a DNS entry so that users can access the service using the domain name of your choice. After creating the DNS entry, access your service at https://<hostname>:<https-port>.

    • hostname is the name you specified with the com.docker.lb.hosts. label.

    • https-port is the port you configured in the MKE settings.

    Because this example uses self-signed certificates, client tools such as browsers display a warning that the connection is insecure.

  6. Optional. Test that everything works using the CLI:

    curl --insecure \
    --resolve <hostname>:<https-port>:<mke-ip-address> \
    https://<hostname>:<https-port>/ping
    

    Example output:

    {"instance":"f537436efb04","version":"0.1","request_id":"5a6a0488b20a73801aa89940b6f8c5d2"}
    

    The proxy uses SNI to determine where to route traffic, and thus you must verify that you are using a version of curl that includes the SNI header with insecure requests. Otherwise, curl displays the following error:

    Server aborted the SSL handshake
    

Note

There is no way to update expired certificates using the proxy-managed TLS method. You must create a new secret and then update the corresponding service.