Can't get the real client IP to make use of GeoBlock
kowalcj0 opened this issue · comments
Hi,
I tried quite a few different setups but for some reason traefik
can't get the real IP address of the client.
As a result GeoBlock
is not able to block any incoming requests because all requests are treated as local traffic.
Here's an excerpt from traefik's log:
INFO: GeoBlock: 2023/04/29 18:23:32 Local ip allowed: 172.18.0.1
I'd be really thankful for indicating how to make treafik
to get the real client IP so GeoBlock
can do its job :)
Discovering Client IP
To check the client IP address on the host (rpi) I ran tcpdump
with simple filter and the client IP was correct, e.g: 76.121.115.131
:
portainer@portainer:~ $ sudo tcpdump -i eth0 -n 'port 80 or port 443'
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
18:24:57.534844 IP 76.121.115.131.25587 > 192.168.2.100.443: Flags [S], ...
18:24:57.534966 IP 192.168.2.100.443 > 76.121.115.131.25587: Flags [S.], ...
...
When I ran the same tcpdump
filter inside the traefik
container,
then the IP address of the client was set to the proxy
network gateway 172.18.0.1
:
/ # apk add tcpdump
/ # tcpdump -i eth0 -n 'port 80 or port 443'
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
18:23:32.228121 IP 172.18.0.1.39766 > 172.18.0.2.443: Flags [S], ...
18:23:32.228271 IP 172.18.0.2.443 > 172.18.0.1.39766: Flags [S.], ...
...
The proxy
netwok was created with docker network create proxy
.
proxy
network details:
docker inspect proxy
[
{
"Name": "proxy",
"Id": "40429cbcf263dcdb61fd0d23c50deecc8da3d6cacbb7a495813760277f0d1068",
"Created": "2022-12-26T02:10:00.194178609Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"bfccdc8b4723920da92c3d6287a52c457457908bcf477d17b6776ad8ea77967e": {
"Name": "traefik",
"EndpointID": "7a632d50e2dab564156a2806eb6559c6f412ea47beaf2b4c6c71c71a2ca75cb6",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"c945edaea58a0331b8ff51b311c637303cfabc510192e10e8f28e6e7222e523a": {
"Name": "portainer",
"EndpointID": "044905b30cb22f1b841a03f8da6f41916807404f0a1cc6e7ae5ac72e8d4c3370",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
Setup
- RaspberryPi 3
- OS: Raspberry Pi OS 64-bit Debian GNU/Linux 11 (bullseye)
- Kernel: 6.1.21-v8+
- Docker: 23.0.4
- Docker Compose: v2.17.2
- traefik v2.10
- GeoBlock v0.2.5
- Portainer 2.18.1
- Cloudflare + Let's Encrypt
Config files
docker-compose.yml
version: '3'
networks:
proxy:
external: true
services:
traefik:
image: "traefik:v2.10"
container_name: "traefik"
restart: always
security_opt:
- "no-new-privileges:true"
ports:
# use host mode to get the client IP https://dockerswarm.rocks/traefik/#getting-the-client-ip
- target: 8080
published: 8080
mode: host
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
cap_add:
- NET_BIND_SERVICE
networks:
proxy:
aliases:
- traefik
env_file:
- .env
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /run/user/1000/docker.sock:/var/run/docker.sock:ro
- /home/portainer/container_configs/traefik/acme/acme.json:/acme.json
- /home/portainer/container_configs/traefik/config/traefik.yml:/traefik.yml:ro
- /home/portainer/container_configs/traefik/config/config.yml:/config.yml:ro
- /home/portainer/container_configs/traefik/letsencrypt:/letsencrypt
- /home/portainer/container_configs/traefik/ssl_certs:/ssl-certs
traefik.yml
global:
checkNewVersion: true
sendAnonymousUsage: false
log:
level: DEBUG
api:
insecure: true
dashboard: true
experimental:
plugins:
GeoBlock:
moduleName: "github.com/PascalMinder/geoblock"
version: "v0.2.5"
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
http:
middlewares:
- default-headers@file
- my-GeoBlock@file
tls:
certResolver: cloudflare
domains:
- main: somedomain.com
sans:
- "*.somedomain.com"
# Allow communication with upstream service behind a self-signed cert
serversTransport:
insecureSkipVerify: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false # Default is true
file:
filename: /config.yml
certificatesResolvers:
cloudflare:
acme:
email: email@somedomain.com
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
config.yml
http:
routers:
srv:
entryPoints:
- websecure
rule: "Host(`srv.somedomain.com`)"
tls:
certResolver: cloudflare
service: srv
services:
srv:
loadBalancer:
servers:
- url: "https://192.168.2.38:55500"
passHostHeader: true
middlewares:
my-GeoBlock:
plugin:
GeoBlock:
allowLocalRequests: true
logLocalRequests: true
logAllowedRequests: true
logApiRequests: true
api: "https://get.geojs.io/v1/ip/country/{ip}"
apiTimeoutMs: 1750
cacheSize: 1000
forceMonthlyUpdate: true
allowUnknownCountries: false
unknownCountryApiResponse: "nil"
countries:
- CH
https-redirect:
redirectScheme:
scheme: https
default-headers:
headers:
frameDeny: true
#sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
# disable Referer header
referrerPolicy: false
Thanks
I’m not sure how I can help you. I guess there must be a configuration error.