DEV Community

Cover image for Local port forwarding using shadowsocks-rust + openvpn over shadowsocks
Mehdi mFat
Mehdi mFat

Posted on

5

Local port forwarding using shadowsocks-rust + openvpn over shadowsocks

How to forward local port using shadowsocks

The purpose here is to forward local port 3080 to remote port 2.2.2.2:1194 (where an openvpn server is listening) using shadowsocks.

To do this we'll use shadowsocks-rust:

First we download the latest binaries for linux:

wget https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.16.1/shadowsocks-v1.16.1.x86_64-unknown-linux-gnu.tar.xz
Enter fullscreen mode Exit fullscreen mode

and extract the files:

mkdir shadowsocks
tar xvf shadowsocks-v1.16.1.x86_64-unknown-linux-gnu.tar.xz -C shadowsocks
Enter fullscreen mode Exit fullscreen mode

Now we cd into the folder and make the binaries executable and move them to /usr/local/bin:

cd shadowsocks/
chmod +x ss*
sudo mv ss* /usr/local/bin
Enter fullscreen mode Exit fullscreen mode

Verify installation using this command:

sslocal --version

Enter fullscreen mode Exit fullscreen mode

Now we are ready to create our local tunnel.

To do this we obviously need a shadowsocks server. There are many tutorials for setting up one. However here is how you can quickly set up a shadowsocks server on a debian/ubuntu VPS:

sudo apt install shadowsocks-libev simple-obfs

sudo nano /etc/shadowsocks-libev/config.json
Enter fullscreen mode Exit fullscreen mode

with the following content:

{
   "server": "0.0.0.0",
   "server_port": DESIRED PORT,
   "password": "DESIRED PASSWORD",
   "timeout": 300,
   "method": "chacha20-ietf-poly1305",
   "mode": "tcp_only",
   "dns":"1.1.1.1",
   "plugin":"obfs-server",
   "plugin_opts": "obfs=http;obfs-host=cloudfront.net",
   "fast_open": false
}
Enter fullscreen mode Exit fullscreen mode

*(Please note simple-obfs is obsolete and you should consider using a more secure pluging such as xray.)
*

sudo systemctl restart shadowsocks-libev.service

Enter fullscreen mode Exit fullscreen mode

Now back to our local system, we create a shadowsocks tunnel configuration file:

nano sstunnel.json

Enter fullscreen mode Exit fullscreen mode

and paste these lines. Make necessary adjustments based on your shadowsocks server configuration:

{
"locals": [
{
            "protocol": "tunnel",

            "local_address": "127.0.0.1",
            "local_port": 3080,
            "forward_address":"2.2.2.2",
            "forward_port": 1194,

}
],
            "server": "SHADOWSOCKS_SERVER_IP",
            "server_port": SHADOWSOCKS_SERVER_PORT,
            "password": "SHADOWSOCKS_SERVER_PASSWORD",
            "method": "chacha20-ietf-poly1305",
            "mode": "tcp_only",
            "plugin": "obfs-local",
            "plugin_opts": "obfs=http;obfs-host=cloudfront.net"

}
Enter fullscreen mode Exit fullscreen mode

This file tells shadowsocks to forward connections to 127.0.0.1:3080 to the remote port 2.2.2.2:1194 which is our openvpn server, for example.

Now we can run the tunnel:

/usr/local/bin/sslocal -c sstunnel.json
Enter fullscreen mode Exit fullscreen mode

This is the output on my system:

$ /usr/local/bin/sslocal -c sstest.json 
2023-09-09T02:08:53.356339957+03:30 INFO  shadowsocks local 1.16.1 build 2023-09-01T05:08:00.031376835+00:00
 2023-09-09 02:08:53 [simple-obfs] INFO: obfuscating enabled
 2023-09-09 02:08:53 [simple-obfs] INFO: obfuscation http method: GET
 2023-09-09 02:08:53 [simple-obfs] INFO: obfuscating hostname: cloudfront.net
 2023-09-09 02:08:53 [simple-obfs] INFO: tcp port reuse enabled
 2023-09-09 02:08:53 [simple-obfs] INFO: listening at 127.0.0.1:41681
2023-09-09T02:08:53.357713632+03:30 INFO  shadowsocks TCP tunnel listening on 127.0.0.1:3080
Enter fullscreen mode Exit fullscreen mode

As you can see the last line
TCP tunnel listening on 127.0.0.1:3080
shows sslocal is listening at port 3080.

How to connect to openvpn over shadowsocks

Now let's assume we have an client.ovpn file for connecting to our 2.2.2.2:1194 openvpn server.

We open the client.ovpn file and make two changes:

  1. We change remote line to 127.0.0.1 3080
  2. We also tell openvpn to route the shadowsocks server IP through default gateway, not through the vpn tunnel:
route SHADOWSOCKS_SERVER_IP 255.255.255.255 net_gateway

Enter fullscreen mode Exit fullscreen mode

This is how my openvpn client configuration looks now:

client
proto tcp-client
remote 127.0.0.1 3080
route SHADOWSOCKS_SERVER_IP 255.255.255.255 net_gateway
....
Enter fullscreen mode Exit fullscreen mode

The rest of the configuration file remains intact.

Now I can connect to openvpn using this command:

sudo openvpn --config client.ovpn

Enter fullscreen mode Exit fullscreen mode

P.S: instead of creating a shadowsocks tunnel configuration file we can also use the following command:

sslocal --protocol tunnel -b "127.0.0.1:3080" -f "2.2.2.2:1194"  --server-url "ss://...."
Enter fullscreen mode Exit fullscreen mode

or

/usr/local/bin/sslocal --protocol tunnel -b "127.0.0.1:3080" -f "2.2.2.2:1194" -s "SHADOWSOCKS_SERVER_IP:PORT" -m "chacha20-ietf-poly1305" -k "SHADOWSOCKS_SERVER_PASSWORD" --plugin "obfs-local" --plugin-opts "obfs=http;obfs-host=cloudfront.net"
Enter fullscreen mode Exit fullscreen mode

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay