Posts Tagged ‘Linux router’

Linux answers to ARP who-is on the wrong network interface

Friday, April 14th, 2017

Assume a server has two network interfaces as follows:

  • eth0 :
  • eth1 :

Let’s assume these interfaces reside on the different VLANs. Lets assume they were connected incorrectly, in such a way that eth0 is connected to VLAN 10, which servers and eth1 is connected to VLAN 2, which serves

You would expect that queries by other hosts on VLAN 2 (which is connected to eth1, but serves!) would not get responses from the server. You are wrong.

Linux will answer who-is queries on VLAN 2, replying with eth1’s MAC address to queries for IP address.

This example is a simple example, but it can get ugly if your eth0 mimics a different network, and you want the server to be disconnected. I have had to “forge” a network setup on a different VLAN, mimicking the original network and subnet. However – a “backdoor” I have opened (on an additional NIC) between the mimicking server and the original server on a different IP class (a private one) resulted in the mimicking server answering to ARP queries, causing the clients to attempt connecting to the mimicking server instead of the production server. The clients could not complete the TCP handcheck because the mimicking server attempted to contact them via eth0, which was on the fake network, and did not actually reach anywhere.

This was a more complex example, however – the result is the same – the response on the “wrong” network interface to ARP who-is queries might hijack data which should be delivered elsewhere.

There is a solution! You need to setup the sysctl parameter arp_ignore  to either of the following values. The parameter is hidden in /proc/sys/net/ipv4/conf/<NIC>/arp_ignore

The parameters documentation is as follows:

arp_ignore – INTEGER
Define different modes for sending replies in response to received ARP requests that resolve local target IP addresses:
0 – (default): reply for any local target IP address, configured on any interface
1 – reply only if the target IP address is local address configured on the incoming interface
2 – reply only if the target IP address is local address configured on the incoming interface and both with the sender’s IP address are part from same subnet on this interface
3 – do not reply for local addresses configured with scope host, only resolutions for global and link addresses are replied

The value “1” or “2” would do the trick in such cases.

Work around ISP QoS limitations

Friday, May 29th, 2009

ISPs which enforce QoS limitations suddenly, without alerting the customer, are abusing their force. QoS limitation is not a bad thing, from the ISP’s point of view, but changing the customer deal without notifying him seems to me to be unfair.

This is a recipe for a QoS workaround.


  • One fast Internet connection which is not used to its full capacity
  • Defined target service provider. I use Giganews as an NNTP, which is the fastest method of obtaining content today. You should have the service list of IPs. Luckily, Giganews use only two IP addresses
  • One “evil” ISP which enforces QoS for external targets
  • One server in the ISP’s hosting farm, which has no speed or transfer limitations, and is probably not bound by the ISP’s QoS
  • For a better looking dish – some graphing solution, such as Cacti or MRTG


  • Setup OpenVPN Server on the hosted server
  • Setup OpenVPN Client on your NNTP/Other service client (your desktop, your Linux router, etc) – This can also be a Windows machine, but configuration varies a bit.
  • Define, in your OpenVPN client.conf line(s) which look like this:

route <SERVICE_IP>

route <SERVICE_IP2>

  • If this is a router machine, activate NAT on it. Of course – remember to set this rule to work after reboot too!

iptables -t nat -A POSTROUTING -o tun+ -j MASQUERADE

  • For your good feeling, try to pickup data from before and after, and compare.
  • Start the OpenVPN Service on the server, on the client, and restart your NNTP/Other service downloads.
  • Serve with a smile 🙂

The result dish is both tasty and good looking! see below:


A word of warning – OpenVPN is a VPN tool. As such, it uses encryption and varios methods which are very secure. This means that for high througput, such as mine (about 10Mb/s) you will see the impact on the router/workstation’s CPU. Under virtualization, I get about 2% additional system CPU utilization from a 2x3GHz Xeon CPU. For older router devices this could result in an overworked router. I am so glad I got rid of my old P2 350MHz router in favor of the virtualized one.

Linux as a WAN router

Friday, June 16th, 2006

I will discuss the issue of placing a Linux machine as a router, and some special cases where things might play a bit different.

The most common scenario is of placing the Linux as some sort of PPP or DHCP-via-cables router. It might look like this:

In this picture, the Linux machine actually recieves, via PPP, a single Internet IP, and it is required to masquerade all outbound traffic as being sourced by it.

In such a case, a line similar to this would be in place:

iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE

It would create MASQUERADE NAT on the external IP address, and will result in a fully working connection from the LAN outside and back (other parameters should be set, like ip_forwarding, and FORWARD IPTables rules, but this is the general idea, IPTables-wise).

Not long ago I have discoverd the true reason for the IPTables rule:

iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to-source $EXT_IP

For most common cases, it would behave just like the MASQUERADE rule. All outbound traffic would be rebuilt, with $EXT_IP as its source.

However, here is a case where routing poses some problem:

In this case, my Linux router did not actually have the internet IP address. The Linux router has the Transport IP, it has the LAN IP on the other side, but it is required to behave as if it has the Internet IP (or part of the pool, at least) defined. In this drawing, you cannot see where the Internet IP comes in.

After some games, I have found a solution for this specific problem, the IPTables line above:

iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to-source $EXT_IP

The server doesn’t have to "hold" the $EXT_IP – as its ISP-side routed knows where to route transportation for this IP address, and routes it outbound without any NAT, we require that all outbound traffic, which is on the Transport IPs, will contain the headers with the $EXT_IP in it. That way, servers on the internet understand the source of the communication and can reply.

Without this line, all outbound traffic never get answered.

So it works, and it works correcly, but when setting up OpenVPN, I’ve had lot of TLS problems.

Clarification – OpenVPN uses UDP by default, and the initial TLS negotiation kept on failing.

After some thought, it seems like this: Incomming TLS communication is directed to the public IP Address ($EXT_IP), which is not an IP address the Linux router knows as its own. Therefore he ignores it. The solution is this following IPTables directive:

iptables -t nat -A PREROUTING -d $EXT_IP -j DNAT –to $TRANSPORT_IP

This line directs all inbound traffic directed at $EXT_IP to the Transport IP address, which in turn, completes the header-rewrite cycle of the router. Not only all outbound traffic’s header is rewritten to "sourced at $EXT_IP", but also all inbound traffic directed at the router is redirected (more logically than physically, but leave it at that) to the Transport interface. A full cycle.