Skip to content

Instantly share code, notes, and snippets.

@rikka0w0
Last active June 24, 2018 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rikka0w0/1df7360ec16c3101db48d055df7c7c8e to your computer and use it in GitHub Desktop.
Save rikka0w0/1df7360ec16c3101db48d055df7c7c8e to your computer and use it in GitHub Desktop.
ss-server with multiple network interface (is there a way to set the outgoing of a ss-server)

Please answer these questions before submitting your issue. Thanks!

(Please mention that if the issue you filed is solved, you may wish to close it by yourself. Thanks again.)

(PS, you can remove 3 lines above, including this one, before post your issue.)

What version of shadowsocks-libev are you using?

shadowsocks-libev 3.1.3

What operating system are you using?

Debian 9

What did you do?

Ok I think its better to introduce a little bit about the background before talking about my problem. My server has 2 independent physical ethernet interface and each has its own IP (one is enp11s0 192.168.0.9 static the other is eth0 192.168.2.2), both of them have internet access (through different ISP). What I would like to achieve is setting up a ss-server which forwards incoming shadowsocks traffics from client to eth0 192.168.2.2. =========End of background============== I have been someone suggested using the -i flag and -b flag, however with ss-server -s 0.0.0.0 -p 2324 -k Password -m chacha20 -u -i eth0, clients were unable to connect to the ss-server.

here is my route table:

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.0.1     0.0.0.0         UG    0      0        0 enp11s0
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 enp11s0
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

here is part of the log without -i

 2018-04-02 03:40:16 INFO: running from root user
 2018-04-02 03:40:19 INFO: accept a connection
 2018-04-02 03:40:19 INFO: connect to www.baidu.com:80
 2018-04-02 03:40:19 INFO: IPv6 resolv: valid domain but no data of requested type
 2018-04-02 03:40:19 INFO: successfully resolved www.baidu.com
 2018-04-02 03:40:19 INFO: remote connected
 2018-04-02 03:40:20 INFO: [udp] server receive a packet
 2018-04-02 03:40:20 INFO: [udp] cache miss: 114.114.114.114:53 <-> 124.190.81.xxx:50613
 2018-04-02 03:40:20 INFO: [udp] remote receive a packet

with -i(not working):

 2018-04-02 03:40:36 INFO: running from root user
 2018-04-02 03:40:39 INFO: accept a connection
 2018-04-02 03:40:39 INFO: connect to www.baidu.com:80
 2018-04-02 03:40:39 INFO: IPv6 resolv: valid domain but no data of requested type
 2018-04-02 03:40:39 INFO: successfully resolved www.baidu.com
 2018-04-02 03:40:44 INFO: accept a connection
 2018-04-02 03:40:44 INFO: connect to www.microsoft.com:80
 2018-04-02 03:40:44 INFO: successfully resolved www.microsoft.com
 2018-04-02 03:40:49 INFO: accept a connection
 2018-04-02 03:40:49 INFO: connect to www.yahoo.com:80
 2018-04-02 03:40:49 INFO: successfully resolved www.yahoo.com
 2018-04-02 03:40:54 INFO: accept a connection
 2018-04-02 03:40:54 INFO: connect to www.qq.com:80
 2018-04-02 03:40:54 INFO: successfully resolved www.qq.com
 2018-04-02 03:40:59 INFO: [udp] server receive a packet
 2018-04-02 03:40:59 INFO: [udp] cache miss: 114.114.114.114:53 <-> 124.190.81.QAQ:65184
 2018-04-02 03:41:02 INFO: [udp] server receive a packet
 2018-04-02 03:41:02 INFO: [udp] cache miss: 8.8.8.8:53 <-> 124.190.81.QAQ:65185
 2018-04-02 03:41:05 INFO: [udp] server receive a packet
 2018-04-02 03:41:05 INFO: [udp] cache miss: 208.67.222.222:53 <-> 124.190.81.QAQ:65186
 2018-04-02 03:41:08 INFO: [udp] server receive a packet
 2018-04-02 03:41:08 INFO: [udp] cache miss: 223.5.5.5:53 <-> 124.190.81.QAQ:65187
 2018-04-02 03:41:59 INFO: [udp] connection timeout
 2018-04-02 03:41:59 INFO: [udp] one connection freed
 2018-04-02 03:42:02 INFO: [udp] connection timeout
 2018-04-02 03:42:02 INFO: [udp] one connection freed
 2018-04-02 03:42:05 INFO: [udp] connection timeout
 2018-04-02 03:42:05 INFO: [udp] one connection freed
 2018-04-02 03:42:08 INFO: [udp] connection timeout
 2018-04-02 03:42:08 INFO: [udp] one connection freed

What did you expect to see?

A client would use ss-tap to connect to this ss server and access the internet as it any other devices with 192.168.2.xxx ip address.

What did you see instead?

If i remove "-i eth0" then clients are able to connect however their traffics still go through enp11s0 192.168.0.9

What is your config in detail (with all sensitive info masked)?

I started the server with ss-server -s 0.0.0.0 -p 2324 -k Password -m chacha20 -u -i eth0

So my question is, is there a way to set the outgoing network interface of ss-server? or ss-libev does not support this feature at this moment? Thanks in advance!

Solution

I think I should write a tutorial just in case if someone else encounters similar scenario. (Can this be merged to the wiki?) Title: Setting up a ss-server on a multi-interface Linux with outgoing traffic control If you have two internet-accessible interface, and you want to let all outgoing traffic go though one particular interface, here is the guide on how to do it. In this example we will setup a ss-server which accepts connection from both interface and send outgoing traffics only through eth0. For sake of simplicity, I assume both interface have static IP address. The /etc/network/interfaces can look something like this:


# The loopback network interface
auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet static
        address 192.168.2.2
        netmask 255.255.255.0
# We are going to add something here

# The primary network interface
allow-hotplug enp11s0
iface enp11s0 inet static
        address 192.168.0.9
        netmask 255.255.255.0
        gateway 192.168.0.1
        dns-nameservers 8.8.8.8 8.8.4.4

Where enp11s0 is the primary interface and eth0 is the additional interface. What we are going to do is to create a seperate route table for eth0, by adding the following script in section iface eth0 inet static:

# Create an additional route table for the second internet accessible interface
        post-up ip route add 192.168.2.0/24 dev eth0 table routetable2
        post-up ip route add default via 192.168.2.1 dev eth0 routetable2
        post-up ip rule add from 192.168.2.2/32 table routetable2
        post-up ip rule add to 192.168.2.2/32 table routetable2

# Clean up
        pre-down ip route del 192.168.2.0/24 dev eth0 table routetable2
        pre-down ip route del default via 192.168.2.1 dev eth0 table routetable2
        pre-down ip rule del from 192.168.2.2/32 table routetable2
        pre-down ip rule del to 192.168.2.2/32 table routetable2

During start-up, these commands create a second route table called routetable2, add default route and then set a rule so that any connection from/to 192.168.2.2 uses route table routetable2. Finally add a line 1 routetable2 to /etc/iproute2/rt_tables. To apply the change, either execute ifdown eth0 && ifup eth0 or reboot your system. Use curl icanhazip.com --interface eth0 to make sure that the interface is accessible. The rest will be easy, start ss-server with: ss-server -s 0.0.0.0 -p 2333-m chacha20 -k Password -b 192.168.2.2 -u, this will spawn a ss-server with UDP relay listing to all interfaces at port 2333, using chacha20 encryption and password is Password. All outgoing traffics will go through the interface eth0 with IP 192.168.2.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment