redsocks + iptables behavior [closed] - linux

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
The following is the network topology of the test bed where I use redsocks and iptables to access youtube from LAN, provided that I have a ssh dynamic forwarding established between Linux and VPS:
|
outside | inside firewall
|
| LAN 192.168.1.0/24
| ----+--------------------+-----------
| |.2 | .3
+-----+ | +------+----+ +----+----+
| | | | | | |
Youtube <-->| VPS <============> Linux | | Windows |
| | | | | | |
+-----+ | +-----------+ +---------+
|
|
The Linux box and Windows box are on the same LAN inside the firewall, which blocks any access to say Youtube. The VPS is outside the firewall and it can access Youtube. From within the Linux box I can ssh -D to the VPS, making VPS acts as a SOCKS5 proxy.
To further make the SOCKS5 proxy "transparent" to the processes (e.g., browser) on the Linux box, I did the following:
run a SOCKS5 client software redsocks to talk with the SOCKS5 server, for handling the SOCKS5 protocols.
add some iptable rules, to direct youtube-bound traffic to redsocks process
This works fine for the Linux box itself:
echo 1 > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -F -t nat
/sbin/iptables -t nat -X REDSOCKS
/sbin/iptables -t nat -N REDSOCKS
/sbin/iptables -t nat -A OUTPUT -d $YOUTUBE -j REDSOCKS
/sbin/iptables -t nat -A REDSOCKS -p TCP -d $YOUTUBE -j REDIRECT --to-ports $REDSOCKS_PORT
/sbin/iptables -t nat -A REDSOCKS -p UDP -d $YOUTUBE -j REDIRECT --to-ports $REDSOCKS_PORT
/sbin/iptables -t nat -A REDSOCKS -p ICMP -d $YOUTUBE -j REDIRECT --to-ports $REDSOCKS_PORT
/sbin/iptables -t nat -A REDSOCKS -j RETURN
Now I want let Windows box also to access Youtube "transparently", with some software configuration. My idea is as the following:
Change the routing table on Windows machine such that all Youtube-bound traffic will be routed to the Linux box (192.168.1.2)
Setup iptables "somehow" to do SNAT for the Youtube-bound traffic from Windows
After some tests, I encountered the following problem:
the REDIRECT (or DNAT) target only applicable for PREROUTING/OUTPUT hooks (e.g., in the iptable settings for redsocks, the REDSOCKS chain is hooked on OUTPUT chain)
the SNAT (or MASQUERADE) target only applicable for POSTROUTING hook
What I want to do for the Windows machine is firstly SNAT and then REDIRECT, but as SNAT is happening on POSTROUTING hook, it seems it's too later (in the packet processing flow) to have it to be processed by PREROUTING/OUTPUT hooks...
Is there a way out here?
PS 1. I found a working solution (below in the reply from myself), although I don't really understand why it worked.
PS 2. I started looking into source code of redsocks, one thing I found so far is that redsocks use getsockopt(,SO_ORIGINAL_DST,) to obtain the destination address before DNAT. What's not clear to me is the following processing, and src/dst ip address of the return packet from redsocks. Don't know if there is an introduction about redsocks implementation...

I found a solution which does not require SNAT:
let redsocks listen on 192.168.1.2 instead of 127.0.0.1, by changing /etc/redsocks.conf
change REDIRECT --to-ports 12345 target in all rules in REDSOCKS chain to DNAT --to-destination 192.168.1.2:12345 target
add a rule in PREROUTING chain to handle "youtube-bound traffic from windows" by REDSOCKS chain: /sbin/iptables -t nat -A PREROUTING -d $youtube -s $win10 -j REDSOCKS
add a route entry on Windows to route youtube-bound traffic to 192.168.1.2
With some more learning and tests, I think I know why the new config works, and why the previous config does not work.
The first is the behavior of REDIRECT:
for locally oriented traffic, the new destination ip address after REDIRECT is 127.0.0.1
for external traffic, the new destination ip address after REDIRECT is NOT 127.0.0.1, but 192.168.1.2
That's why the previous config does not work, since in previous config, redsocks listen on 127.0.0.1, but iptables REDIRECTs to 192.168.1.2.
The new config let redsocks listen on 192.168.1.2 and explicitly use DNAT to change destination of both locally generated and external traffic to 192.168.1.2, so it works.
I also tested another config, almost the same as the 2nd config, but letting redsocks listen on 127.0.0.1, and use DNAT explicitly set destination ip to 127.0.0.1. This way, externally generated traffic will be directly to 127.0.0.1, which are regarded as martian packets by kernel. I also need to set /proc/sys/net/ipv4/conf/eth0/route_localnet to 1, then it works for windows machine.
At this point, to me, it seems every piece of information fit together :)

Related

IP tables TEE command changes source mac address

I am trying to forward/clone traffic from my host machine to my docker container using IPtables command.
I am able to receive traffic inside my container via iptables TEE command. However, this command changes the ethernet header by replacing SRC ethernet mac with host ethernet mac. I am interested in collecting this data for my project.
Is there any other way I can achieve this?
Commands used:
1. iptables -t mangle -I PREROUTING -i <host_interface_name>-p tcp -j TEE --gateway <container_ip>
2. iptables -t nat -A PREROUTING -p tcp -j DNAT --to-destination <container_ip:port>
IPtables operate at the network layer and route the packet from the host where the rules were added. Therefore, we cannot avoid update of the source mac. I've tried using TPROXY, FORWARD, ACCEPT. Found the documentation for this at https://ipset.netfilter.org/iptables-extensions.man.html#lbDU
Achieved my requirement using : Linux TC. Simple inbuild Linux Traffic Controller can be used for shaping traffic moving through your interfaces.
https://man7.org/linux/man-pages/man8/tc-mirred.8.html

Iptables: forward port from one host to another inside same bridged network

I have a network like this:
Internet <===> Modem/Router <---------> Switch
1.2.3.4 192.168.1.1/24 | | |
| | |
+-----+ | +------+
| | |
PC 2 | PC 3
192.168.1.3/24 | 192.168.1.4/24
|
PC 1
192.168.1.2/24
/|\
WLAN
/ | \
PC W1 PC W2 PC W3
192.168.1.X/24 (X>10)
Modem/Router act as DHCP server too. Any request sent on public IP 1.2.3.4 is redirected to 192.168.1.2 on internal network. Modem/Router belong to ISP and I can't access/configure it. PC 1 is a linux box: eth0 and wlan0 are bridged (enslaved to br0 with address 192.168.1.2); hostapd is running on PC 1 sharing internet connection with PC WX. I want to redirect connections to some ports on PC 1 toward PCs on the same net, eg:
1.2.3.4:2222 > 192.168.1.2:2222 -> 192.168.1.3:22
1.2.3.4:3333 > 192.168.1.2:3333 -> 192.168.1.4:25
I tried using iptables and enabling ip_forward
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -d 192.168.1.2 -p tcp --dport 2222 -j DNAT --to 192.168.1.3:22
iptables -t nat -A POSTROUTING -d 192.168.1.3 -p tcp --dport 22 -j SNAT --to-source 192.168.1.2
and so on for others ports, but it didn't work. I discovered that redirections toward any other PC connected via WLAN worked fine. It seems that, using iptables PREROUTING rule in conjunction with a bridge, once a packet has entered the bridge from one side (eth0), it can only flow to the other side (wlan0), but can't go out throw the same input interface. The arrangement described above worked fine when the bridge is disabled, but I dont't want to use PC 1 as a router but as AP only.
Can someone help me?
The rules you've suggested should work with a minor adjustment. Though it's not documented in iptables' man page, you must specify the protocol as the first argument to match, as follows:
iptables -t nat -A PREROUTING -p tcp -d 192.168.1.2 --dport 2222 -j DNAT --to 192.168.1.3:22
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.3 --dport 22 -j SNAT --to-source 192.168.1.2
Note that the second rule is not required since the first rule triggers iptables to take care of the responses automatically.
If it still doesn't work, try disabling iptables invocation while traversing the bridge via echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables and rebooting the machine.

Iptables forward over VPN

I'm conecting to a VPN in Windows to access a remote computer (Linux) with a static IP. From this remote computer I have access to different machines (database, svn, etc.).
I am trying to set up my remote computer to have access from my Windows machine to the database, the svn server, etc, because working on a remote connection is very slow.
So I tried the next lines in /etc/rc.local, but it doesn't work:
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables --table nat -A POSTROUTING -o eth0 -j MASQUERADE
/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp -d B1.B2.B3.B4 --dport 89 -j DNAT --to R1.R2.R3.R4:89
/sbin/iptables -A FORWARD -p tcp -d R1.R2.R3.R4 --dport 89 -j ACCEPT
Where B1.B2.B3.B4 is my remote database IP, 89 is the port we use to access the database, and R1.R2.R3.R4 is my remote machine IP.
What is wrong in this configuration?
Thanks.
Make sure ip_forward is enabled:
echo 1 > /proc/sys/net/ipv4/ip_forward
Also, you need to make sure the VPN pushes routes for B1.B2.B3.B4 to your Windows machine when connecting; if not, you'll have to add the routes yourself.
I think the MASQUERADE rule should be enough, but write it like this:
iptables -t nat -A POSTROUTING -s WINDOWS_BOX_VPN_IP -j MASQUERADE
But if you don't want to mess with iptables, you can use SSH to setup tunnels to your remote services, for example (you need some Windows SSH client that can create tunnels, I'm giving an example how to run this from a linux box):
ssh user#R1.R2.R3.R4 -L 8989:B1.B2.B3.B4:89
This will create a tunnel on localhost:8989 which will forward the connection to B1.B2.B3.B4:89 (look for "Local port forwarding", http://chamibuddhika.wordpress.com/2012/03/21/ssh-tunnelling-explained/ )
At the end I found Rinetd that allows TCP redirections with an easy configuration.
According to my question, the configuration I had to add in /etc/rinetd.conf is:
R1.R2.R3.R4 89 B1.B2.B3.B4 89
Then I run Rinetd:
/usr/sbin/rinetd
And that's all.
If you want to run it automatically everytime you restart your computer, you can add the command before in the file /etc/rc.local

iptables to forward port to another network [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I have a VDS running CentOS with two interfaces: eth0 and ham0. eth0 is my WAN interface and has external IP accessible from the Internet, and ham0 is an interface to a small VPN network (Logmein Hamachi).
There are three machines in the VPN network, one of them is a linux box at my home which runs Apache on port 80. This machine is behind ISP's NAT and cannot be seen from outside.
I want to create a rule on my VDS to forward connections to port 8081 coming from the Internet (eth0 interface) to this linux box inside my VPN network. Something like this:
[Internet] ---> [VDS server with public IP] ---> [Apache server inside VPN]
I used the following rules:
iptables -t nat -A PREROUTING -p tcp -d *external_ip* --dport 8081 -j DNAT --to *internal_ip*:80
iptables -A FORWARD -p tcp -d *internal_ip* --dport 80 -j ACCEPT
iptables -t nat -A POSTROUTING -p tcp --dst *internal_ip* -j LOG --log-level warning --log-prefix "[REQUEST_FORWARDED]"
But it does not work. I can see a "REQUEST_FORWARDED" message in /var/log/messages, but when I go to the http://my_eternal_ip:8081/ in my browser, it tries to connect to the host for a very long time, and then shows a message that server did not respond.
What can cause this problem?
I guess you need to make sure "/proc/sys/net/ipv4/ip_forward" has been enabled, if not
echo 1 > /proc/sys/net/ipv4/ip_forward
Above command can help you allow IP forwarding.
Hope this helpful to you.

Iptables or something to redirect IP in gateway (GNU/Linux)

Im writing a bash scripting to account traffic in my network server:
WAN:eth1 -> GNU/Linux Server:eth0 -> Users
The GNU/Linux server uses squid, bind, QoS, mysql, lighttpd.
After an IP exceed the established quota a new QoS rule is applied for that IP (user) too exist one "flag" to decide when is restored the IP counter to Zero.
Some IPs and subnets work without quotas, other gruop of ips/subnets work with new QoS after quota is exceeded, and now I wanna work with a third group with redirection after quota is exceeded.
When an IP exceed the established quota all http traffic must be redirected to host (lighttpd runing on GNU/Linux ) and DROP all other traffic generated for that IP. In webserver exist a webpage with: "You exceed your daily quote of traffic, please wait "x" hours or call to your provider to purchase an extra navigation package" or something like that.
Is possible using a chain, or how can I do that?.
The most topics that I found in Internet, are related to block all and create a new chain to let out to Internet (not work for me). And other redirect only IP by IP, but how can I create something that a "chain" and attach the IPs to must me redirected to can after restore that IPs easly?
Thanks for help and sorry for my poor English :S.
Are you looking for something like this?
iptables -t nat -A PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -I INPUT 1 -i lo -s 192.168.100.66 -j ACCEPT
iptables -I INPUT 2 -i eth1 -d 192.168.100.66 -j DROP
This will redirect packets from 192.168.100.66 on port 80 to the local webserver on the loopback interface, allow that conversation, then reject all other packets being routed to 192.168.100.66 on the WAN interface.
To restore the connection back to normal you will want to delete those firewall entries:
iptables -t nat -D PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -D INPUT -i lo -s 192.168.100.66 -j ACCEPT
iptables -D INPUT -i eth1 -d 192.168.100.66 -j DROP
Note that iptables itself (well, the xtables-addons extension set providing quota2) can already do the quota matching magic and you can (re)set the values through procfs, combined with REDIRECT as #resmon6 says:
-t nat -s user1addr -m quota2 --name user1 ! --quota 0 -j REDIRECT...
-t nat -s user2addr -m quota2 --name user2 ! --quota 0 -j REDIRECT...
The syntax is a arguably a little odd right now (0 is the initial value only and is independent from the runtime quota test involving the negational !. Noticing this just now, a patch may make it in to unroll this confusing syntax in the future).

Resources