Scenario / Questions
I have a machine with several interfaces that I can configure as I want, for instance:
- eth1: 192.168.1.1
- eth2: 192.168.2.2
I would like to forward all the traffic sent to one of these local addresses through the other interface. For instance, all requests to an iperf, ftp, http server at 192.168.1.1 should be not just routed internally, but forwarded through eth2 (and the external network will take care of re-routing the packet to eth1).
I tried and looked at several commands, like iptables, ip route, etc… but nothing worked.
The closest behavior I could get was done with:
ip route change to 192.168.1.1/24 dev eth2
which send all 192.168.1.x on eth2, except for 192.168.1.1 which is still routed internally.
May be I could then do NAT forwarding of all traffic directed to fake 192.168.1.2 on eth1, rerouted to 192.168.1.1 internally? I am actually struggling with iptables, but it is too tough for me.
The goal of this setup is to do interface driver testing without using two PCs.
I am using Linux, but if you know how to do that with Windows, I’ll buy it!
The external network is just a crossover cable between eth1 and eth2.
Let’s say I have an http server on my machine.
Now I want to access this server from the same machine, but I want to force the TCP/IP traffic to go through this eth1/eth2 cable. How should I configure my interfaces for this?
Find below all possible solutions or suggestions for the above questions..
I expanded on caladona’s answer since I could not see response packets. For this example:
- On my local PC I have NIC’s on different subnets, 192.168.1/24, 192.168.2/24
- There is an external router/PC that has access to both subnets.
- I want to send bi-directional traffic over the NICs on the local PC.
- The configuration requires two unused IP addresses for each subnet.
Local PC iptable routes are set to SNAT and DNAT outgoing traffic to the ‘fake’ IP.
iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source 192.168.2.100 iptables -t nat -A PREROUTING -d 192.168.1.100 -i eth0 -j DNAT --to-destination 192.168.1.1 iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.100 iptables -t nat -A PREROUTING -d 192.168.2.100 -i eth1 -j DNAT --to-destination 192.168.2.1
The rules do the following:
- Rewrite 192.168.2.1 source to 192.168.2.100 on outgoing packets
- Rewrite 192.168.1.100 destination to 192.168.1.1 on incoming packets
- Rewrite 192.168.1.1 source to 192.168.1.100 on outgoing packets
- Rewrite 192.168.2.100 destination to 192.168.2.1 on incoming packets
To summarize, the local system now can talk to a ‘virtual’ machine with addresses 192.168.1.100 and 192.168.2.100.
Next you have to force your local PC to use the external router to reach your fake IP. You do this by creating a direct route to the IP’s through via the router. You want to make sure that you force the packets onto the opposite of the destination subnet.
ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP
Finally to make this all work, the external router needs to know how to reach the faked IPs on your local PC. You can do thins by turning on proxy ARPs on for your system.
echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
With this setup, you can now treat the fake IPs as a real system on your local PC. Sending data to .1 subnet will force packets out the .2 interface. Sending data to the .2 subnet will force packets out the .1 interface.
ping 192.168.1.100 ping 192.168.2.100
I successfully used the following on Linux to test throughput on a new dual-port 10Gbps card in “loopback” mode, that is, one port plugged directly into the other. This is all just a bit of voodoo just to force packets out the wire, but if you don’t, Linux will just short-circuit the traffic through the kernel (hence the OP’s question). In Casey’s answer above, I’m not sure if it was really necessary to have an external router or not above, but the following is completely self-contained. The two interfaces are eth2 and eth3.
Give IPs to the interfaces, and put them on separate networks:
ifconfig eth2 10.50.0.1/24 ifconfig eth3 10.50.1.1/24
Next we’ll set up a double NAT scenario: two new fake networks used to reach the other. On the way out, source NAT to your fake network. On the way in, fix the destination. And vice versa for the other network:
# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1 iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1 # nat inbound 10.60.0.1 -> 10.50.0.1 iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1 # nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1 iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1 # nat inbound 10.60.1.1 -> 10.50.1.1 iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1
Now tell the system how to get to each fake network, and prepopulate the arp entries (be sure to substitute your MAC addresses, don’t use mine):
ip route add 10.60.1.1 dev eth2 arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address ip route add 10.60.0.1 dev eth3 arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address
This fools Linux enough to actually put packets onto the wire. For example:
goes out eth2, the source IP 10.50.0.1 gets NATted to 10.60.0.1, and as it comes into eth3 the destination 10.60.1.1 gets NATted to 10.50.1.1. And the reply takes a similar journey.
Now use iperf to test throughput. Bind to the correct IPs, and be certain which IP you’re contacting (the other end’s fake address):
# server ./iperf -B 10.50.1.1 -s # client: your destination is the other end's fake address ./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10
Make sure traffic is really going out to the wire:
tcpdump -nn -i eth2 -c 500
You can also watch /proc/interrupts just to be absolutely sure the card is being used:
while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done
Anyhow, I found this post searching for how to do this, thanks for the Q&A guys, and hope this helps anyone else finding this post in the future.
As always – I’m a little late – but nowadays one could use network namespaces to isolate the interfaces and prevent any local forwarding (and fiddling with iptables :)).
Create namespaces (all done with required permissions, e.g. as root):
ip netns add ns_server ip netns add ns_client
Note that the interfaces status / config must now be accessed within
the context of the assigned namespace – so they won’t appear if you run a naked ip link as this is run in the context of the default namespace.
Running a command within a namespace can be done using
ip netns exec <namespace-name> <command>
Now assign namespaces to interfaces, apply config and set interfaces up:
ip link set eth1 netns ns_server ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24 ip netns exec ns_server ip link set dev eth1 up ip link set eth2 netns ns_client ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24 ip netns exec ns_client ip link set dev eth2 up
Now you can execute the applications within the namespace – for the iperf server run
ip netns exec ns_server iperf -s -B 192.168.1.1
and the client:
ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2
The traffic will now be send via the physical interfaces as the whole networkstack, interface, routing … is isolated by the namespaces so the kernel is not able to match the addresses used within the traffic with local (available) interfaces.
If you are done with your experiments simply delete the namespaces:
ip netns del <namespace-name>
The interfaces will be reassigned to the default namespace and all configuration done within the namespace disappears (e.g. no need to delete assigned IP addresses).
Ok, I finally succeeded in setting up my config.
The idea is to use another fake address, to force the route of this fake address to the interface 2 , then to translate the fake address with the real address 2 with NAT/iptables.
My set up is actually made of one router I can telnet between IF1 (interface 1) and IF2
In my set up, FAKE_ADDR and IF1_ADDR are on the same subnet.
ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0 ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0 iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR route add $FAKE_ADDR gw $ROUTER_ADDR
And on the router:
route add $FAKE_ADDR gw $IF2_ADDR
If I send something to FAKE_ADDR, pkt is forwarded through IF1 to the router, forwarded again to IF2, then FAKE_IP is replaced by IF2_ADDR. The packet is processed by the server, the result is send back to IF1_ADDR, from IF2_ADDR which is replaced by FAKE_ADDR.
May be it is possible to use a simpler configuration with just one crossover cable, but as I didnot tried I prefer to give my working solution.
The answer given above by Thomas Tannhäuser was spot on!
I had a similar situation: a single machine with two enet interfaces. My plan was to use one interface as a server (receiver) and the other as a client (sender). Each interface would be attached to the router and iperf would drive the traffic through the router to measure throughput, PPS, delay, etc.
Unfortunately, the iptables approach was non-intuitive and fraught with issues. After a few frustrating hours, I abandoned this plan of attack. Inspired by Thomas’s suggestion, I did a little homework on Linux IP Namespaces and began to appreciate the simplicity and elegance of this solution.
Below is a list of the exact commands that I used to configure my Fedora FC26 to serve in this capacity. The two interfaces are enp1s0 and enp3s0. The router has two interfaces with addresses 192.168.2.112 and 172.16.16.2. Each FC26 ENET connector is directly cabled to the corresponding router interface.
# How to configure the IP Namespaces ip netns add iperf-server ip netns add iperf-client ip link set enp1s0 netns iperf-server ip link set enp3s0 netns iperf-client ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20 ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24 ip netns exec iperf-client ip link set dev enp3s0 up ip netns exec iperf-server ip link set dev enp1s0 up ip netns exec iperf-server route add default gw 192.168.2.112 ip netns exec iperf-client route add default gw 172.16.16.1 # Test the interfaces and network using ping ip netns exec iperf-client ping -c1 172.16.16.1 ip netns exec iperf-server ping -c1 192.168.2.112 ip netns exec iperf-server ping -c1 172.16.16.2 ip netns exec iperf-client ping -c1 192.168.2.139 # Start Iperf Server for UDP test ip netns exec iperf-server iperf -u -s # Run Client against Iperf server for UDP test ip netns exec iperf-client iperf -u -c 192.168.2.139
It sounds like you want to turn your linux box into a router/bridge/gateway/firewall type box. The following resources may be what you are looking for:
Update based upon further information:
I don’t think you are going to be able to do what you want. The OS is always going to look at its internal routing table and ‘see’ both IP addresses locally. It will then route the traffic within the OS and never put it on the wire. You will need a second machine or two virtual machines (check out Xen).
A lot of stuff to go through here, so I can’t totally guarantee my accuracy, but the original question seems to be looking for what’s known as “send to self” technique. Linked search shows what I think is the best maintained kernel patch as top link + discussions and patches with other approaches on various mailing lists, esp. LKML.
I think one should also look at network namespaces, done with iproute2’s “ip netns”. This also takes some extra interface and routing magic, so might not even be less complex than the massive iptables hoopla in the other answers.
Comments definitely welcome if anyone found something useful with these – the how, the what, the where about your implementation.
Check this article. Here the detailed steps is mentioned for enabling internet access to a virtualbox vm using NAT forwarding.
here is how i got it working for IPV6
assigned static ips
/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 /sbin/ifconfig eth3 inet6 add 2001:db8::2/127
set up host only routes to “FAKE” addresses
ip -6 route add 2001:db8::2/128 dev eth1 metric 1 ip -6 route add 2001:db8::1/128 dev eth3 metric 1
populated the Neighbor table …like the arp
ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address
added the ip6tables entries
ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1 ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1 ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2 ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2
Kubernetes Free Online Tutorial, Kubernetes Beginner Tutorial
DevOps Free Online Tutorial, DevOps Beginner Tutorial
Ansible Free Online Tutorial, Ansible Beginner Tutorial
Docker Free Online Tutorial, Docker Beginner Tutorial
Openstack Free Online Tutorial, Openstack Beginner Tutorial
Disclaimer: This has been sourced from a third party syndicated feed through internet. We are not responsibility or liability for its dependability, trustworthiness, reliability and data of the text. We reserves the sole right to alter, delete or remove (without notice) the content in its absolute discretion for any reason whatsoever.