Skip to content

Instantly share code, notes, and snippets.

@pedrolamas
Created August 18, 2020 19:32
Show Gist options
  • Save pedrolamas/db809a2b9112166da4a2dbf8e3a72ae9 to your computer and use it in GitHub Desktop.
Save pedrolamas/db809a2b9112166da4a2dbf8e3a72ae9 to your computer and use it in GitHub Desktop.
Script to fix Docker iptables on Synology NAS
#!/bin/bash
currentAttempt=0
totalAttempts=10
delay=15
while [ $currentAttempt -lt $totalAttempts ]
do
currentAttempt=$(( $currentAttempt + 1 ))
echo "Attempt $currentAttempt of $totalAttempts..."
result=$(iptables-save)
if [[ $result =~ "-A DOCKER -i docker0 -j RETURN" ]]; then
echo "Docker rules found! Modifying..."
iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL ! --dst 127.0.0.0/8 -j DOCKER
echo "Done!"
break
fi
echo "Docker rules not found! Sleeping for $delay seconds..."
sleep $delay
done
@ben-ba
Copy link

ben-ba commented Mar 13, 2023

@domigi
Thats the way a reverse proxy work.

@domigi
Copy link

domigi commented Mar 13, 2023

@ben-ba Not sure if we're talking about the same idea.
In my nextcloud container it seems to only see the XFF IP if it's an external/public IP.
For example here two request:

Client Proxy Service Request appears to be from
10.0.0.2 172.16.0.2 172.30.1.2 172.16.0.2
42.199.8.17 172.16.0.2 172.30.1.2 42.199.8.17

(My local LAN is 10.0.0.0/24)

What I would like to achieve: In the example above the first request should also appear to be from 10.0.0.2 and not how it currently is 172.16.0.2.

@arsenio7
Copy link

arsenio7 commented Apr 7, 2023

@domigi Thats the way a reverse proxy work.

in this case, it's not a reverse proxy issue. This happens within the NAT mechanism of the firewall of the Synology box (OSI layer 3), a reverse proxy would be an app getting the incoming connections and forwarding 'em, i.e. a HTTP rev-proxy (OSI layer 7)

@petrosmm
Copy link

this works for a synology 1621+ DSM 7... kudos!

@scrapix
Copy link

scrapix commented Jul 9, 2023

@Maypul
Thank you lots! This helped me to get the actual IPs in traefik and stopped crowdsec to block all connections!

@SK-StYleZ
Copy link

I've testen iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER and it worked for me => saw the "real" ip in the traefik access log.
After a reboot i've promted the same command, but this time it didn't work. I am getting the internal docker ip's in the traefik access log.
recreated the containers but still no "real" ip's ...
what do i miss?

@Hoaxr
Copy link

Hoaxr commented Sep 7, 2023

FINNALY! Been searching so long for this and now it works! Thanks

@Paul-B
Copy link

Paul-B commented Sep 19, 2023

I've been wasting so much time this week getting NGINX reverse proxy manager to work properly on Synology. If you want IP-whitelisting then being aware of actual outside IP's is essential and I just could not get it to work. Got headaches from macvlan in Docker and still it did not work. Thank you!

Is this problem unique to Synology?
The rule that I applied is the first suggestion by Pedro:
sudo iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
sudo iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL ! --dst 127.0.0.0/8 -j DOCKER

However I have a few thoughts.

The first one is security.
It seems that this is a bit of a brute force method that risks exposing other ports of other containers to the network. An attacker would have to break through the port forwarding of my router which does seem like an unlikely event. Then the solution by @Maypul to only script the ports that you are actually going to use sounds like smart paranoia.

The second thought I have is about complexity.
After a while there are so many tweaks to a system that without proper documentation to self (or others) somebody else or even myself is never going to figure out what or why these tweaks were done in case of a system reset or rebuild. Thus, it might be a smart move to install the docker containers that need to be aware of the outside IP to another system like a Raspberry Pi that runs somewhere in the network in more or less default config and that is dedicated to these tasks. That way it becomes clear what the purpose of that machine is and why it is setup the way that it is.

Anyway, just my thoughts but I'm curious about comments.

@mat926
Copy link

mat926 commented Oct 8, 2023

This doesn't work when trying to access the container from a reverse proxy

@Jabb0
Copy link

Jabb0 commented Nov 30, 2023

Awesome @Maypul thank you!

The change bypassing the synology firewall is understandable and the default docker behaviour.

Other rules added to the FORWARD chain, either manually, or by another iptables-based firewall, are evaluated after the DOCKER-USER and DOCKER chains. This means that if you publish a port through Docker, this port gets published no matter what rules your firewall has configured

https://docs.docker.com/network/packet-filtering-firewalls/#add-iptables-policies-before-dockers-rules

It should only affect ports that you published with docker.

I have my home network on eth0 and another network on eth1. For this reason I only want to accept connections from eth0.

adding the -i eth0 flag does the trick.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 53 -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -m addrtype --dst-type LOCAL -j DOCKER

@JVT038
Copy link

JVT038 commented Mar 27, 2024

None of these iptables rules have worked for me :(

I'm using a DS918+ and running DSM 7.2.

When I run the iptables script, the X-Forwarded-For IP address becomes the address of my router for some reason. So I don't get the client IP, but the IP of my router.

Does anyone know a fix? I've also tried disabling userland-proxy in the docker daemon, but that didn't work either. Or maybe I did something wrong.

@Aurel004
Copy link

@ben-ba Not sure if we're talking about the same idea. In my nextcloud container it seems to only see the XFF IP if it's an external/public IP. For example here two request:

Client Proxy Service Request appears to be from
10.0.0.2 172.16.0.2 172.30.1.2 172.16.0.2
42.199.8.17 172.16.0.2 172.30.1.2 42.199.8.17
(My local LAN is 10.0.0.0/24)

What I would like to achieve: In the example above the first request should also appear to be from 10.0.0.2 and not how it currently is 172.16.0.2.

Have you got any fix on this ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment