From specific source IP to specific destination IP with ip route or ip tables – A server stack is the collection of software that forms the operational infrastructure on a given machine. In a computing context, a stack is an ordered pile. A server stack is one type of solution stack — an ordered selection of software that makes it possible to complete a particular task. Like in this post about From specific source IP to specific destination IP with ip route or ip tables was one problem in server stack that need for a solution. Below are some tips in manage your linux server when you find problem about linux, networking, iptables, iproute, .
I’ve already created different IP aliases, (each with a different virtual Mac Address too) this way on my shell:
ip link add link eth0 address 00:11:11:11:11:11 eth0.1 type macvlan ifconfig eth0.1 172.17.1.15/21 up
I have used eth0.1 instead of eth0:1 because otherwise, it does not work the macvlan. I know that the IP alias are written as: eth0:1, though.
It is set a speed throttling to 10Mbps per IP (or Mac Addr, I do not know yet) and I am studying its bypassing for a well intentioned project.
What I want now is to set a specific destination for each IP alias in order to study the router’s speed throttling. It should now have 10Mbps per IP/connection.
I need now the eth0.1 to be the source to access: URL(speedtest1Web).
And the eth0.2 the source to access: URL(speedtest2Web).
I have tried:
iptables -t nat -A POSTROUTING -p tcp -s 172.17.1.15 -o eth0.1 -j SNAT --to-source xxx.xxx.xxx.xxx
iptables -t nat -I POSTROUTING -o eth0 -d xxx.xxx.xxx.xxx/32 -s 10.255.0.127 -j SNAT --to-source 172.17.1.15
where xxx.xxx.xxx.xxx = speedtest1Web
Is it correct the “-o eth0”? Or should I write “-o eth0.1”?
I have been trying many similar commands with no success or at least I continue having 10Mbps for all the connections instead of 10Mbps per connection (what it is supposed now with the IP aliasing).
You don’t need usage of macvlan in your case.
- Assign addresses on single interface. Aliases are deprecated way to have multiple addresses on same interface. You need macvlan only if you want have various mac addresses for various ip addresses, but it complicates the configuration of routing.
l1:~# ip link set up dev eth0 l1:~# ip address add 172.17.1.14/21 dev eth0 l1:~# ip address add 172.17.1.15/21 dev eth0 l1:~# ip address add 172.17.1.16/21 dev eth0
- Verify list of addresses on the
l1:~# ip -4 a ls dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 172.17.0.14/21 scope global eth0 valid_lft forever preferred_lft forever inet 172.17.0.15/21 scope global secondary eth0 valid_lft forever preferred_lft forever inet 172.17.0.16/21 scope global secondary eth0 valid_lft forever preferred_lft forever
- Add the default route and the default source address, then verify configuration:
l1:~# ip route add 0/0 via 172.17.0.1 src 172.17.0.14 l1:~# ip route list default via 172.17.0.1 dev eth0 src 172.17.0.14 172.17.0.0/21 dev eth0 proto kernel scope link src 172.17.0.14
- You have two ways to use the secondary addresses for specific destination. You can add the route to a particular destination with specifying src attribute:
172.17.0.15 as source address for
l1:~# ip route add 192.168.10.2 via 172.17.0.1 src 172.17.0.15
172.17.0.16 as source address for
l1:~# ip r add 192.168.11.2 via 172.17.0.1 src 172.17.0.16
Verify the routing table:
l1:~# ip r ls default via 172.17.0.1 dev eth0 src 172.17.0.14 172.17.0.0/21 dev eth0 proto kernel scope link src 172.17.0.14 192.168.10.2 via 172.17.0.1 dev eth0 src 172.17.0.15 192.168.11.2 via 172.17.0.1 dev eth0 src 172.17.0.16
Also you can check the actual routes for a specific destination with
ip route get command:
l1:~# ip route get 192.168.10.2 192.168.10.2 via 172.17.0.1 dev eth0 src 172.17.0.15 uid 0 cache
There is a short version of same command:
l1:~# ip r g 192.168.11.2 192.168.11.2 via 172.17.0.1 dev eth0 src 172.17.0.16 uid 0 cache
Check the results with
tcpdump. Ping the hosts and check the output of tcpdump in an other console. You can use the wireshark instead tcpdump.:
l1:~# tcpdump -ni eth0 'icmp' tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 10:21:07.972535 IP 172.17.0.14 > 172.17.0.1: ICMP echo request, id 23048, seq 0, length 64 10:21:07.974416 IP 172.17.0.1 > 172.17.0.14: ICMP echo reply, id 23048, seq 0, length 64 10:21:15.391709 IP 172.17.0.15 > 192.168.10.2: ICMP echo request, id 23304, seq 0, length 64 10:21:15.393515 IP 192.168.10.2 > 172.17.0.15: ICMP echo reply, id 23304, seq 0, length 64 10:21:18.207461 IP 172.17.0.16 > 192.168.11.2: ICMP echo request, id 23560, seq 0, length 64 10:21:18.209391 IP 192.168.11.2 > 172.17.0.16: ICMP echo reply, id 23560, seq 0, length 64
- Other way is usage the
SNATtarget in the iptables. But if you have the hundreds of similar rules, it may impact the performance.
l1:~# iptables -t nat -A POSTROUTING -o eth0 --dst 192.168.10.2 -j SNAT --to-source 172.17.0.15 l1:~# iptables -t nat -A POSTROUTING -o eth0 --dst 192.168.11.2 -j SNAT --to-source 172.17.0.16
Better use the
iptables-apply to safe configure the iptables. Verification is the same as in the route case – with
tcpdump. Also, you can check the rule counters to sure those rules work.
l1:~# iptables-save -c -t nat # Generated by iptables-save v1.6.2 on Wed May 15 10:31:26 2019 *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [4:336] :POSTROUTING ACCEPT [0:0] [2:168] -A POSTROUTING -d 192.168.10.2/32 -o eth0 -j SNAT --to-source 172.17.0.15 [2:168] -A POSTROUTING -d 192.168.11.2/32 -o eth0 -j SNAT --to-source 172.17.0.16 COMMIT # Completed on Wed May 15 10:31:26 2019
- There is the third way to use the specific source. In some applications you can specify the source in a configuration file or with command line arguments. For
l1:~# ping -c 2 -I 172.17.0.15 192.168.11.2 PING 192.168.11.2 (192.168.11.2) from 172.17.0.15: 56 data bytes 64 bytes from 192.168.11.2: seq=0 ttl=63 time=2.348 ms 64 bytes from 192.168.11.2: seq=1 ttl=63 time=1.270 ms --- 192.168.11.2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 1.270/1.809/2.348 ms
l1:~# tcpdump -ni eth0 'icmp' tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 10:37:08.724723 IP 172.17.0.15 > 192.168.11.2: ICMP echo request, id 37384, seq 0, length 64 10:37:08.726805 IP 192.168.11.2 > 172.17.0.15: ICMP echo reply, id 37384, seq 0, length 64 10:37:09.724985 IP 172.17.0.15 > 192.168.11.2: ICMP echo request, id 37384, seq 1, length 64 10:37:09.726084 IP 192.168.11.2 > 172.17.0.15: ICMP echo reply, id 37384, seq 1, length 64
- Also, you should know, what neither
iptablesknow nothing about domain-names and can use only ip address of destination. Iptables can resolve domain-name at rule creation, but ip address in it won’t being updated magically. There are some tricks to avoid this limitation:
- Fix the ip address associated with domain-name. You can use the
/etc/hostsfile to do it. This way suitable for quick tests and DNS records with long TTL.
- Most flexible way: usage of
iptables. In this case
dnsmasqresolves the domain-names and stores its ip addresses into
ipsetlists. You can use these lists in the
- Fix the ip address associated with domain-name. You can use the