1

The system has two different interfaces(like eth0 and tap0). I want to use two different selenium phantomjs browsers same time with both interfaces.

Is there any way to choose interface in selenium?

My system is Linux and I am using Python.

Unfortunately I couldn't find any suitable solutions in related topics.

The solution does not have to use directly a feature of phantomjs but also can use a linux or selenium feature/tool.

Yavuz
  • 1,257
  • 1
  • 16
  • 32
  • Possible duplicate of [Bind Phantomjs to a Network Interface](http://stackoverflow.com/questions/29932658/bind-phantomjs-to-a-network-interface) – Vaviloff Feb 08 '17 at 14:12
  • See also: https://github.com/ariya/phantomjs/issues/10269 – Vaviloff Feb 08 '17 at 14:13
  • 1
    Google-Fu is not strong in you. http://scraping.pro/change-webdrivers-ip-address/ Maybe that will help. – IamBatman Feb 08 '17 at 16:26
  • Thank you Google-Fu master. But I am not looking for defining proxy to selenium. I have already different IP addresses with different interfaces in my own PC. I need to use those interfaces not proxies. – Yavuz Feb 09 '17 at 10:42
  • Let the answer be generic for Google/Firefox (think PhantomJS is hardly used, and the question is aware we'd like a Selenium solution rather than browser specific if possible) – PascalVKooten Oct 08 '22 at 12:20
  • I'm not a linux or python guy. But I've been working with selenium c# and firfoxbrowser. there for us to access the browser through a particular network interface of particular IP address we derive the browser profile. And ForceBindIP allows to access the browser through particular interface. https://r1ch.net/projects/forcebindip – joekevinrayan96 Oct 15 '22 at 01:43

2 Answers2

2

You can use Linux network namespaces to create a namespace for each interface, then use "ip netns exec <command_and_args>" to run your Selenium processes with whatever namespace (interface) you desire.

Below is from a real working example with two interfaces...

eth0: 172.20.0.0/16
eth1: 172.21.0.0/16

To validate the test, I had two Apache httpd servers, one on each network...

eth0 httpd: 172.20.0.3
eth1 httpd: 172.21.0.3

This was on Alpine Linux... so I installed iproute2 to get ip netns...

/ # apk update
/ # apk add iproute2

The two namespaces I created were...

eth0 namespace: eth0ns # The 172.20.0.0/16 network.
eth1 namespace: eth1ns # The 172.21.0.0/16 network.

Remaining setup (adding namespaces, route in each namespace, see phantomjs tests further below)...

/ # ip netns add eth0ns
/ # ip netns add eth1ns
/ # ip link add link eth0 eth0ns netns eth0ns type ipvlan mode l2
/ # ip link add link eth1 eth1ns netns eth1ns type ipvlan mode l2
/ # ip -n eth0ns link set lo up
/ # ip -n eth0ns link set eth0ns up
/ # ip -n eth1ns link set lo up
/ # ip -n eth1ns link set eth1ns up

/ # ip addr
...
126: eth0@if127: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    ...
    inet 172.20.0.2/16 brd 172.20.255.255 scope global eth0
       valid_lft forever preferred_lft forever
128: eth1@if129: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    ...
    inet 172.21.0.2/16 brd 172.21.255.255 scope global eth1
       valid_lft forever preferred_lft forever

Add routes...

/ # ip -n eth0ns addr add 172.20.0.2/16 dev eth0ns
/ # ip -n eth0ns route add default via 172.20.0.1 dev eth0ns
/ # ip -n eth1ns addr add 172.21.0.2/16 dev eth1ns
/ # ip -n eth1ns route add default via 172.21.0.1 dev eth1ns

If you have issues adding routes, you can delete any existing ones first... for example...

/ # ip netns exec eth1ns route del default
/ # ip netns exec eth1ns route add default gw 172.21.0.1 eth1ns
/ # ip netns exec eth1ns route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.21.0.1      0.0.0.0         UG    0      0        0 eth1ns
172.21.0.0      *               255.255.0.0     U     0      0        0 eth1ns
/ #

Add DNS for each namespace. Note, 10.5.20.5 was my test DNS, and both networks were connected to outside world as well (see ping test below)...

/ # cat /etc/resolv.conf
# my dns
nameserver 10.5.20.5
#nameserver 127.0.0.11
options ndots:0

/ # cat /etc/netns/eth0ns/resolv.conf
# my dns
nameserver 10.5.20.5
#nameserver 127.0.0.11
options ndots:0

/ # cat /etc/netns/eth1ns/resolv.conf
# my dns
nameserver 10.5.20.5
#nameserver 127.0.0.11
options ndots:0

Traceroute test to show two different interfaces being used depending on namespace used with ip netns exec...

ip netns exec eth0ns <cmd> will cause cmd to use eth0.

ip netns exec eth1ns <cmd> will cause cmd to use eth1.

/ # ip netns exec eth0ns traceroute -m 1 google.com
traceroute to google.com (142.251.33.110), 1 hops max, 46 byte packets
 1  172.20.0.1 (172.20.0.1)  0.002 ms  0.002 ms  0.001 ms

/ # ip netns exec eth1ns traceroute -m 1 google.com
traceroute to google.com (142.251.33.110), 1 hops max, 46 byte packets
 1  172.21.0.1 (172.21.0.1)  0.003 ms  0.001 ms  0.002 ms

Ping tests:

Without any namespace, neither httpd server can be accessed...

/ # ping -w 2 172.20.0.3
PING 172.20.0.3 (172.20.0.3): 56 data bytes
--- 172.20.0.3 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

/ # ping -w 2 172.21.0.3
PING 172.21.0.3 (172.21.0.3): 56 data bytes
--- 172.21.0.3 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

172.20.0.0/16 network namespace, only its httpd server can be accessed...

/ # ip netns exec eth0ns ping -w 2 172.20.0.3
PING 172.20.0.3 (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.075 ms
64 bytes from 172.20.0.3: seq=1 ttl=64 time=0.070 ms
--- 172.20.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.070/0.072/0.075 ms

/ # ip netns exec eth0ns ping -w 2 172.21.0.3
PING 172.21.0.3 (172.21.0.3): 56 data bytes
--- 172.21.0.3 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

172.21.0.0/16 network namespace, only its httpd server can be accessed...

/ # ip netns exec eth1ns ping -w 2 172.21.0.3
PING 172.21.0.3 (172.21.0.3): 56 data bytes
64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.067 ms
64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.068 ms
--- 172.21.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.067/0.068 ms

/ # ip netns exec eth1ns ping -w 2 172.20.0.3
PING 172.20.0.3 (172.20.0.3): 56 data bytes
--- 172.20.0.3 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
/ #

Curl test, remember that 172.20.0.3 is on one network and 172.21.0.3 on the other, so below you see 4 tests, pass/fail to show each process can only access its respective network's httpd server...

/ # ip netns exec eth0ns curl -m 3 http://172.20.0.3
<html><body><h1>It works!</h1></body></html>
/ # ip netns exec eth0ns curl -m 3 http://172.21.0.3
curl: (28) Connection timed out after 3001 milliseconds // expected, different network.

/ # ip netns exec eth1ns curl -m 3 http://172.21.0.3
<html><body><h1>It works!</h1></body></html>
/ # ip netns exec eth1ns curl -m 3 http://172.20.0.3
curl: (28) Connection timed out after 3002 milliseconds // expected, different network.
/ #

Install phantomjs and perform a similar tests.

/ # #Install phantomjs

/ # cat show_content.js
var webPage = require('webpage');
var system = require('system');
var page = webPage.create();

page.settings.resourceTimeout = 5000
page.onResourceTimeout = function(e) {
  console.log(e.errorCode);
  console.log(e.errorString);
  console.log(e.url);
  phantom.exit(1);
};

page.open(system.args[1], function (status) {
  var content = page.content;
  console.log('Content: ' + content);
  phantom.exit();
});

/ # ip netns exec eth0ns phantomjs show_content.js http://172.20.0.3
...
Content: <html><head></head><body><h1>It works!</h1>
</body></html>

/ # ip netns exec eth0ns phantomjs show_content.js http://172.21.0.3
...
408
Network timeout on resource.
http://172.21.0.3/

/ # ip netns exec eth1ns phantomjs show_content.js http://172.21.0.3
...
Content: <html><head></head><body><h1>It works!</h1>
</body></html>

/ # ip netns exec eth1ns phantomjs show_content.js http://172.20.0.3
...
408
Network timeout on resource.
http://172.20.0.3/
/ #

If not obvious, after getting your network namespaces setup, you use the ip netns exec <ns> <cmd> command to run a process having access only to that namespace's interface...

ip netns exec eth0ns <cmd> to run a process using eth0 172.20.0.0/16

ip netns exec eth1ns <cmd> to run a process using eth1 172.21.0.0/16

Ashley
  • 575
  • 5
  • 12
1

the route Selenium goes is configured by the OS (usually the default Gateway). In Linux you can create traffic exceptions and stuff with the "IPtables". Not a solution but maybe a starting point. Good luck :)

Lamphish
  • 11
  • 2