Service delivery consists of more than just HTTP reverse proxies and SSL termination. This post will explore exposing a TCP service within a cluster as well as limiting access to said service. It’s written specifically for TraefikEE users but easily adapted to CE.
We’ll be working with the following components:
- Proxy stacks
- Static configuration
- Dynamic configuration
- Docker stacks
If you want your service to access the source IP of incoming connections you’ll need to enable host networking. You can skip this step if you don’t have the source IP requirement. Open up your
proxies.yaml file and configure the ports section as shown below, the service we’re adding will use port 1234. You will have to allow port 1234 to any network filters/firewalls.
For more details on host networking see this post by Sebastián Ramírez.
services: proxies: image: traefik/traefikee:v2.6.0 deploy: ... networks: ... ports: - target: 80 published: 80 protocol: tcp mode: host - target: 443 published: 443 protocol: tcp mode: host - target: 1234 published: 1234 protocol: tcp mode: host
If you’ve switched to host networking you’ll have to redeploy the proxy service via
docker stack deploy -c proxies.yaml traefikee.
Next up we’ll add the pertinent details to our static configuration. Specifically, the entrypoint.
entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" # Example tcp service running on port 1234 tcp_1234: address: ":1234/tcp"
Our dynamic configuration is used to define the ipwhitelist middleware that our tcp service will use. This is a list of IPs/networks you wish to allow.
tcp: middlewares: internal-restricted: ipwhitelist: sourcerange: - "220.127.116.11" - "18.104.22.168" - "22.214.171.124" - "126.96.36.199" - "188.8.131.52"
Apply our static and dynamic configuration files
teectl apply --file="static.yaml" teectl apply --file="dynamicweb.yaml"
The remaining step is to add the Traefik labels to our docker stack. In this example, the tcp service running inside the container is also using port 1234. If that differs then you can change the loadbalancer port on the last line.
tcpservice: image: yourimage:3 networks: - traefikee_ingress - dev_env deploy: labels: - "traefik.enable=true" - "traefik.docker.network=traefikee_ingress" - "traefik.tcp.routers.tcp_1234.entrypoints=tcp_1234" - "traefik.tcp.routers.tcp_1234.service=tcp_1234" - "traefik.tcp.routers.tcp_1234.tls=false" - "traefik.tcp.routers.tcp_1234.tls.passthrough=true" - "traefik.tcp.routers.tcp_1234.rule=HostSNI(`*`)" - "traefik.tcp.routers.tcp_1234.middlewares=internal-restricted@traefikee" - "traefik.tcp.services.tcp_1234.loadbalancer.server.port=1234"
Save your changes and redeploy the stack. The Traefik dashboard should now display the tcp router and your service should be accessible from the addresses listed in the ipwhitelist.