abiosoft / caddy-docker

Docker container for Caddy
https://hub.docker.com/r/abiosoft/caddy/
MIT License
768 stars 315 forks source link

Client IP always logged as Docker network gateway 172.18.0.1 #142

Closed qdm12 closed 5 years ago

qdm12 commented 5 years ago

Hi there !

I have the problem that the only client IP Caddy would log is 172.18.0.1 - my Docker network gateway. Is there any way to access the client IP address without without fully exposing Caddy on the host with --net=host?

Thank you !

abiosoft commented 5 years ago

Are you using Caddy directly or as a reverse proxy? Also, can you share contents or snippets of your Caddyfile?

qdm12 commented 5 years ago

My Docker Compose looks like:

version: '3'
services:
  caddy:
    image: abiosoft/caddy-docker
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
    network_mode: bridge
    volumes:
      - ./Caddyfile:/etc/Caddyfile:ro
      - ./caddy:/root/.caddy
      - ./static:/srv:ro

My Caddyfile:

https://mydomain.com {
    tls quentin.mcgaw@gmail.com
    log
    root /srv/website
}

I have tried accessing it with my phone using the mobile network or with a VPN but it still gives me the Docker network gateway 172.18.0.1 as client ip which is not useful for the Caddy built-in logs or ipfilter. Maybe an issue in the Caddy program? For example, I recently wrote a simple Golang container which detects your public IP address successfully even when running in Docker virtual networks.

Thanks !

abiosoft commented 5 years ago

I only get this behaviour when I'm accessing the container from the same host machine. From my experience, a container running on a publicly accessible network always reports the right address when accessed externally.

The value is gotten from {remote} from placeholders.

What behaviour were you expecting, and do you mind giving examples?

qdm12 commented 5 years ago

For example, someone from outside (genuinely from outside, probably a bot...) tried to access mydomain.com and the log is:

2018/09/21 04:01:37 [INFO] blog.mydomain.com - No such site at :80 (Remote: 172.18.0.1, Referer: http://mydomain.com/)
2018/09/21 04:01:37 [INFO] test.mydomain.com - No such site at :80 (Remote: 172.18.0.1, Referer: http://mydomain.com/)
2018/09/21 04:01:37 [INFO] wp.mydomain.com - No such site at :80 (Remote: 172.18.0.1, Referer: http://mydomain.com/)

So I have no way to know what this attacker IP address is. I have also tried with the {remote} Caddy placeholder but it will always ever give 172.18.0.1

qdm12 commented 5 years ago

I have also tried the realip plugin with:

realip {
    from 172.18.0.1/32
}

but it still does not solve the issue. The issue however appears to be a Docker networking issue which is still unsolved, in which the external IP address is lost through the Docker network gateway. The only viable solution is to run the container with --net=host or network_mode=host for Docker Compose.

What I am planning is to run a Linux virtual machine with the Caddy container running in the host network in order not to affect the other docker containers I currently have running. Closing as this is a Docker issue, not an issue with this repository.

devzsolt commented 5 years ago

@qdm12 could you please link here the related Docker issue? I face the same problem.

qdm12 commented 5 years ago

Hi there,

It works great on Docker 18.06 on an Ubuntu server. I had Docker 17.09 previously on a Synology NAS and it would fail. It is very likely an issue related to updating Docker, or maybe to the OS handling iptables in a bad way. So the issue is not related to Caddy at all.

devzsolt commented 5 years ago

That's weird because I'm using Docker version 18.06.1-ce on Ubuntu and all I see in Caddy logs that (Remote: 10.255.0.2, Referer: ) for each item. AFAIK this IP is the gateway in Docker Swarm Mode, right? I just checked and the custom network I'm using has overlay driver. Can that be the problem here?

qdm12 commented 5 years ago

I'm not using Swarm so I don't know. But you could try with a container I made qmcgaw/port-checker which logs the xforwardfor, remoteaddr and xrealip. It's quicker for testing purposes.

It's a Docker issue on how it handles TCP packets, maybe because of Swarm. You could also try disabling the Docker userland proxy

devzsolt commented 5 years ago

Yeah looks like a Docker Swarm bug (or lack of a basic functionality): https://github.com/moby/moby/issues/25526 and as it turned out everything works fine without Swarm mode using the legacy(?) docker-compose deployment. Thanks again!