On the Docker Swarm cluster, I set up a Traefik container as a reverse proxy and tried to operate it with a configuration that distributes content with a node container, but I was in trouble because I could not get REMOTE_ADDR.
Make a note of what to do in that case.
Docker version: 19.03.12
The original docker-compose.yml file is:
version: '3.4'
services:
socket-proxy:
image: tecnativa/docker-socket-proxy
networks:
- internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- SERVICES=1
- TASKS=1
- NETWORKS=1
- LOGSPOUT=ignore
deploy:
placement:
constraints:
- node.hostname == manager
traefik:
image: traefik:1.7-alpine
command:
- "--logLevel=error"
- "--entryPoints=Name:http Address::80 Redirect.EntryPoint:https"
- "--entryPoints=Name:https Address::443 TLS"
- "--defaultentrypoints=http,https"
- "--web"
- "--web.address=:8080"
- "--acme"
- "--acme.storage=certs.json"
- "--acme.entrypoint=https"
- "--acme.httpchallenge.entrypoint=http"
- "--acme.onHostRule=true"
- "[email protected]"
- "--docker"
- "--docker.endpoint=tcp://socket-proxy:2375"
- "--docker.swarmMode"
- "--docker.watch"
ports:
- 80:80
- 443:443
networks:
- internal
- overlay
volumes:
- ./certs/certs.json:/certs.json
deploy:
placement:
constraints:
- node.hostname == web
restart_policy:
condition: on-failure
web:
image: hoge/fuga:dev
networks:
- overlay
deploy:
replicas: 1
placement:
constraints:
- node.hostname == web
labels:
- "traefik.enable=true"
- "traefik.backend=web"
- "traefik.frontend.rule=Host:sample.com"
- "traefik.frontend.entryPoints=https"
- "traefik.frontend.passHostHeader=true"
- "traefik.docker.network=overlay"
- "traefik.protocol=http"
- "traefik.port=3000"
networks:
overlay:
external: true
internal:
internal: true
Although it is not the main subject of this time, in the above setting, "docker-socket-proxy" is used to allocate the endpoint of Traefik to another container. Generally, Traefik is executed on the manager node and docker.sock is specified as the endpoint, but if a security hole is found in Traefik, there is a risk that the entire cluster will be hijacked. .. By using docker-socket-proxy, you can execute Traefik on the worker node, and by narrowing down the authority with docker-socket-proxy, you can operate with enhanced security.
I have been operating a certain site before and have suffered from malicious access, so I definitely want to keep REMOTE_ADDR as a log, but I can not get it anyway.
Traefik should send the header information etc. to the backend as it is if you specify "traefik.frontend.passHostHeader = true" in each container. User-Agent etc. can be acquired correctly, so it seems that this setting is alive.
After a lot of research, I found information on overseas bulletin boards that the Docker Swarm overlay network does not seem to carry REMOTE_ADDR. And, in the case of Nginx, there was also a solution to mount the port in host mode.
So, I rewrote the port setting of Traefik as follows.
ports:
- mode: host
protocol: tcp
published: 80
target: 80
- mode: host
protocol: tcp
published: 443
target: 443
After testing, I was able to get REMOTE_HOST safely.
I think that Nginx etc. can solve it with the same correspondence. If you have any problems with the same problem, please try it.
Recommended Posts