Is it possible to map 1:1 port range iptable DNAT rules - iptables

I want the following rules to forward tcp packets
from 127.0.0.1:32770 to 172.17.0.36:1000
and forward packets from 127.0.0.1:32771 to 172.17.0.36:10001
and forward packets from 127.0.0.1:32772 to 172.17.0.36:10002
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 32770:32771 -j DNAT --to-destination 172.17.0.36:1000-1002
But currently it can forward all packets from 127.0.0.1:32770-32771 to any one of 172.17.0.36:1000-1002

I've struggled a lot to find this and finally found a solution that absolutely works, the command in your case would be:
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 32770:32771 -j DNAT --to-destination 172.17.0.36:1000-1002/32770
Here, 32770 is the base-port, and the mapping will start from there, for example:
32770 -> 172.17.0.36:1000
32771 -> 172.17.0.36:1001
Now, let's say the incoming range and outgoing range are not equal:
iptables -t nat -I PREROUTING -p tcp --dport 30000:30199 -j DNAT --to 10.1.1.1:40000-40099/30000
In the above case, the DNAT mapping will round itself like this:
30000 -> 10.1.1.1:40000
30001 -> 10.1.1.1:40001
...
30099 -> 10.1.1.1:40099
30100 -> 10.1.1.1:40000
30101 -> 10.1.1.1:40001
...
30199 -> 10.1.1.1:40099
The support for base-port based 1:1 port mapping in DNAT was added in 2018.
Please refer below link:
http://git.netfilter.org/iptables/commit/?id=36976c4b54061b0147d56892ac9d402dae3069df
I have seen this working in Linux kernel 4.19 and above.

Related

SSH tunnel <--> iptables NAT port forwarding - HOWTO?

I need to set up access to the HTTP(S) servers on devices like KVMs and PDUs on a private network (192.168.0.0/24). I must get through an isolated network (10.0.0.0/8) limited to ports 22 and 443. I have a dual-NIC Linux server inside the network that serves as a gateway to the private network. See diagram Here:
Network Diagram
I need to use a forward SSH tunnel to get to the Linux gateway, then use iptables NAT to route HTTP(s) traffic to the web frontends on the devices.
I've observed with both tcpdump and iptables trace that the inbound HTTP(s) request through the SSH tunnel shows up on interface lo , not eth1 as one might expect.
This has led me to come up with the following nat and filter rules:
*nat
-A PREROUTING -i lo -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.0.100:80
-A PREROUTING -i lo -p tcp -m tcp --dport 8081 -j DNAT --to-destination 192.168.0.101:443
-A POSTROUTING -d 10.0.0.0/8 -o lo -j SNAT --to-source <10.gateway_IP>
COMMIT
*filter
:INPUT ACCEPT [37234:5557621]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [26648:27864039]
-A FORWARD -d 192.168.0.0/24 -p tcp -m tcp --dport 80 -j ACCEPT
-A FORWARD -d 192.168.0.0/24 -p tcp -m tcp --dport 443 -j ACCEPT
COMMIT
So, when I set up the tunnel with:
ssh -L 8080:<gateway>:8080 <user>:#<gateway>
Then making sure on the gateway:
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
and then execute http://localhost:8080,
The packets make it out of the tunnel onto the gateway, out of interface lo, but iptables doesn't seem to forward it to the destination in the PREROUTING rule. stderr from the tunnel returns "Connection refused."
What am I missing?

iptables port forward rule to route traffic from WireGuard TUN interface to eth0

I am using WireGuard (WG) as a VPN and only routing certain port based traffic over it. On the ingress side of the tunnel the traffic first hits eth0 then goes on to the WG TUN interface, wg0, so the following rule works for forwarding on ingress:
-A PREROUTING -d 192.#.#.# -i eth0 -p tcp -m tcp --dport 7054 -j DNAT --to-destination 10.#.#.#:7054
However I can not get traffic routed from TUN interface to eth0 on the egress side of the tunnel with the following rule, I think due to the "tunnel" being virtual and the traffic first must cross eth0 so PREROUTING is not valid??? I am not sure how to think about the TUN interface with regards to the routing sequence, i.e. is this still PREROUTEING or POSTROUTING or somewhere in the middle?
-A PREROUTING -d 10.#.#.# -i wg0 -p tcp -m tcp --dport 7054 -j DNAT --to-destination 192.#.#.#:7054
I tried the following to see if PREROUTING would then work for the wg0 interface but it did not. I also tried this with POSTROUTING, but not the solution.
iptables -t raw -A PREROUTING -i eth0 -j NOTRACK

Port forwarding on NAT using KVM/QEMU

I'm using NAT mode for guest networking. I need my machines to be accessible from outside the guest. I've set up iptables to port forward a specific port on host to port 22 on guest, but this does not seem to work.
I added this rules:
# Port Forwardings
-A PREROUTING -i eth0 -p tcp --dport 9867 -j DNAT --to-destination 192.168.122.136:22
# Forward traffic through eth0 - Change to match you out-interface
-A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
When I ssh 192.168.122.136 from host it works perfectly, however when I try ssh 192.168.122.136 -p 9867 it shows ssh: connect to host 192.168.122.1 port 9867: Connection refused
I've enabled port forwarding on /etc/ufw/sysctl.conf
using iptables -t nat -L shows that the rule is set up on iptable
DNAT tcp -- anywhere anywhere tcp dpt:9867 to:192.168.122.136:22
Found my answer here. basicly I changed the above to
# connections from outside
iptables -t nat -A PREROUTING -p tcp --dport 9867 -j DNAT --to 192.168.122.136:22
# for local connection
iptables -t nat -A OUTPUT -p tcp --dport 9867 -j DNAT --to 192.168.122.136:22
# Masquerade local subnet
iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -j MASQUERADE
iptables -A FORWARD -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i virbr0 -o eth0 -j ACCEPT
iptables -A FORWARD -i virbr0 -o lo -j ACCEPT

IPTables forward traffic without hiding source IP

I am trying to setup a cloud server as a gateway, which forwards all traffic to my second cloud server. The problem is that the destination server (2nd cloud) only sees the IP address of the first cloud server.
Is it possible to keep the source IP so it would show the IP address of the one connecting to the first cloud server. I have tried removing MASQUERADE, but the connection between cloud #1 -> cloud #2 did not work properly anymore.
-A FORWARD -p tcp -m tcp --dport 25565 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 25565 -j DNAT --to-destination DESTINATIONIP:PORT
-A POSTROUTING -j MASQUERADE
It works with this setup, but does not show the source IP. Have you got any idea on how to not hide the IP that is connecting to the first cloud server?
Thanks
cloud 1 and 2 need to be in same network, a VPN is fine
on cloud1:
-A FORWARD -p tcp -m tcp --dport 25565 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 25565 -j DNAT --to-destination DESTINATIONIP:PORT
-A POSTROUTING -j MASQUERADE
on cloud2, we mark the desired packet with 1, eth0 is the default gateway:
iptables -t mangle -A OUTPUT -o eth0 -p tcp --sport 25565 -j MARK --set-mark 1
you need to manipulate the routing table on cloud2:
edit /etc/iproute2/rt_tables, add the line
1 http
here the manipulation, tun0 is the vpn interface on cloud2:
ip route add default via ip_vpn_cloud1 dev tun0 table http
ip rule add from all fwmark 1 table http
be sure that net.ipv4.conf.all.rp_filter and net.ipv4.conf.default.rp_filter are set to 1 in /etc/sysctl.conf
With -A POSTROUTING -j MASQUERADE all outgoing forwarded packets will have the source IP of the corresponding outgoing interface.
You should be more specific on the packets you masquerade/SNAT.

iptable rule on OpenWRT for all remaining ports

Ok, I'm working with an OpenWRT router. I have the following iptable rules:
iptables -t nat -I prerouting_rule -m mac --mac-source $2 -p tcp --dport 80 -j DNAT --to-destination $3:80;
iptables -t nat -I prerouting_rule -m mac --mac-source $2 -p tcp --dport 443 -j DNAT --to-destination $3:80;
These rules effectively redirect traffic on ports 80 and 443 to a specific destination ip address for a specific requesting MAC address.
I'd like to add another rule (or set of rules if necessary) that will drop traffic on all other ports for this specific MAC without breaking these 2 rules.
My version of iptables is: v1.4.10
Any pointers would be greatly appreciated!
EV
iptables -t nat -A prerouting_rule -m mac --mac-source $2 -j DROP
generally: use -A instead -I, append is more "human"
edit:
you should filter out pacakages in the filter tables ;)
iptables -A FORWARD -m mac --mac-source $2 --dport 80 -j ACCEPT
iptables -A FORWARD -m mac --mac-source $2 --dport 443 -j ACCEPT
iptables -A FORWARD -m mac --mac-source $2 -j DROP
i forgot that not all tables can do anything...