My system is connected to a college hostel LAN. Internet is provided through the Cyberoam system. Thus, there is a cap on the maximum transfer speed for internet. I had an idea since months to exploit virtual interfaces to get more out of it. For eg, parallel downloads all at the max transfer speed and browsing simultaneously without being affected by those downloads. I didn’t find any favourable ways to achieve this until last couple of days when I came across various pieces which I could put together to get it done.
The whole idea is to create a virtual ethernet interface (which is connected to the LAN) using
ip aliasing and route selected traffic through that interface in a simple way. We will be using a proxy server to bind connections to that ip alias as it is much more simpler to configure any application to use a particular proxy server than to set their outgoing interface.
Although I will considering only virtual interfaces in the tutorial, the same technique can be applied to actual multiple interfaces as well. Also, note that there are tons of ways one might want to configure the behaviour. This is another reason why I will be using a proxy server.
Setting up the virtual interface
The network I am connected to is
192.168.124.0/255.255.252.0. Thus accordingly, create a virtual interface with ip
$ sudo ifconfig eth0:1 192.168.124.122 netmask 255.255.252.0 broadcast 192.168.127.255
eth0:1 is the new virtual interface. It can be anything like
eth0:25. Also you can make a lot of them.
Testing it out
Just make a curl request to a destination using
$ curl --interface "192.168.124.122" 192.168.125.63:8000
192.168.125.63 is my
eth0 address and I am just making a curl request to my http server to check the source ip is indeed the aliased one. You can make request to anything reachable to the network.
I do all my downloading through scripts which use curl or wget, so I can theoretically modify them to use
--interface, but it is too much work and I need most applications to be able to work this way. Thus, enter proxy.
Setting up the proxy server
We will be using squid to create our proxy server mainly because it supports
tcp_outgoing_interface directive which lets us select outgoing interface using squid acl rules. That way, it will be easier when number of virtual interfaces we wish to use increases.
squid from your distribution repository. Edit
http_port 3128 http_access allow localhost dns_v4_first on tcp_outgoing_address 192.168.124.122
For the sake of simplicity, I have kept the configuration minimal. The proxy runs at port 3128, and access is allowed to localhost. There is a lot that can be done with squid, so I will highly recommend going through the squid documentation and tutorials around the internet.
dns_v4_first on is used to make sure squid uses ipv4 first when contacting servers and peers. Befire this, I spend couple days wondering why I couldn’t make HTTPS connections. After frustrating troubleshooting with logs, wireshark, curl, and whatnot, this directive solved my problem. Most systems will be fine without this directive, so it can be removed.
tcp_outgoing_address 192.168.124.122 binds all outgoing connections to the aliased ip, which was our goal to begin with. This simply applies this to all the outgoing connections through the server. You may, use it to do more powerful filtering. Go though the tcp_outgoing_address documentation.
Start the squid daemon with (depending on your distribution)
$ sudo systemctl start squid
Using the proxy
All the work is done. Just use the http proxy
localhost:3128 for your application. Most applications respect the environment variables for proxy. So if you want a terminal session to launch programs which connect to the network using the second ip, do the following
export http_proxy=http://localhost:3128/ export https_proxy=$http_proxy export ftp_proxy=$http_proxy export rsync_proxy=$http_proxy export no_proxy="localhost,127.0.0.1"
For browsing you may set the proxy for firefox directly through the settings. For chrome/chromium, use
Extending to more than two interfaces
You just need to use
tcp_outgoing_address according to some parameter like port or ip. You will need to make a different port for each extra interface and write a
tcp_outgoing_address for each port.
Feedback, Problems, or any Alternative or better way? Throw them up on the comments.