// DevOps

Redirecting All Container Traffic via SOCKS Proxy Using tun2socks

Published on 2026-09-22

Sometimes you need to route all outgoing traffic from a specific container through a proxy server. This can be useful for anonymity, bypassing geoblocks, or testing network configurations. In this article we’ll look at how to set up such a system using the tun2socks utility and iptables rules, and how to manage the process with systemd.


What is tun2socks?

tun2socks is a powerful tool that allows you to redirect network traffic destined for a TUN device through a SOCKS proxy. It creates a virtual network interface (a TUN device), and all traffic on that interface is tunneled over a SOCKS connection. This is especially handy when application-level proxying is impossible or undesirable.


Installing tun2socks

First we need to install tun2socks. We’ll use prebuilt binaries from GitHub.

  1. Go to the tun2socks releases page: https://github.com/xjasonlyu/tun2socks/releases

  2. Choose the latest stable version (as of September 2026 — v2.7.0 dated 12.07.2026) and download the archive for your architecture. Archives are provided as .zip files, e.g. tun2socks-linux-amd64.zip for 64-bit Linux systems; there is a single executable inside.

  3. Unpack the archive and move the executable into a system path, for example /usr/local/bin/:

    bash
    # Example for linux-amd64; when a new version is released replace v2.7.0
    wget https://github.com/xjasonlyu/tun2socks/releases/download/v2.7.0/tun2socks-linux-amd64.zip
    unzip tun2socks-linux-amd64.zip
    sudo install -m 0755 tun2socks-linux-amd64 /usr/local/bin/tun2socks

    Make sure the path to the binary in your script matches the actual one. In our example it is /usr/local/bin/tun2socks.


Traffic redirection script

Now let’s look at a script that automates creating the TUN device, setting up iptables, and launching tun2socks.

Important note: For proper operation with systemd, we’ll slightly modify the script so that tun2socks is started in the background and the script can exit while systemd manages the tun2socks process.

bash
#!/bin/bash
set -euo pipefail

# Configuration
TUN_DEV="tun0" # Name of the TUN device
TUN_ADDR="10.0.0.2/24" # IP address for the TUN device
FWMARK="100" # Mark for traffic
ROUTE_TABLE="100" # Routing table number
CONTAINER_IP="172.29.172.2" # IP address of your container whose traffic should be redirected
SOCKS_PROXY="socks5://username:password@xxx.xxx.xxx.xx:yyyyy" # SOCKS5 proxy address (with authentication)
TUN2SOCKS_BIN="/usr/local/bin/tun2socks" # Path to the tun2socks executable

# Path to the PID file that will be used by systemd
PID_FILE="/var/run/tun2socks.pid"

# Cleanup function to remove rules
cleanup() {
    echo "[INFO] Cleaning up old routes and iptables..."
    # Remove rules in the reverse order of creation
    iptables -t nat -D POSTROUTING -o "$TUN_DEV" -j MASQUERADE 2>/dev/null || true
    iptables -t mangle -D PREROUTING -s "$CONTAINER_IP" -p tcp -j MARK --set-mark "$FWMARK" 2>/dev/null || true

    ip route flush table "$ROUTE_TABLE" 2>/dev/null || true
    ip rule del fwmark "$FWMARK" table "$ROUTE_TABLE" priority "$FWMARK" 2>/dev/null || true

    ip link set "$TUN_DEV" down 2>/dev/null || true
    ip tuntap del dev "$TUN_DEV" mode tun 2>/dev/null || true

    # Remove PID file
    rm -f "$PID_FILE" 2>/dev/null || true
}

# Check command-line arguments
if [ "$#" -eq 1 ] && [ "$1" == "cleanup_only" ]; then
    cleanup
    echo "[INFO] Cleanup completed."
    exit 0
fi

# Call cleanup at start to ensure a clean state, unless in cleanup_only mode
cleanup

echo "[INFO] Creating $TUN_DEV..."
ip tuntap add dev "$TUN_DEV" mode tun
ip addr add "$TUN_ADDR" dev "$TUN_DEV"
ip link set "$TUN_DEV" up

echo "[INFO] Setting up ip rule and iptables..."
ip rule add fwmark "$FWMARK" table "$ROUTE_TABLE" priority "$FWMARK"
ip route replace default dev "$TUN_DEV" table "$ROUTE_TABLE"

iptables -t mangle -A PREROUTING -s "$CONTAINER_IP" -p tcp -j MARK --set-mark "$FWMARK"
iptables -t nat -A POSTROUTING -o "$TUN_DEV" -j MASQUERADE

echo "[INFO] Starting tun2socks..."
"$TUN2SOCKS_BIN" \
  --device "$TUN_DEV" \
  --proxy "$SOCKS_PROXY" \
  --loglevel info &

# Save tun2socks PID for systemd
echo $! > "$PID_FILE"

echo "[INFO] Setup complete. tun2socks is running."

Script breakdown

Let’s examine what each part of the script does in more detail:

Configuration

At the top of the script the key variables are defined:

  • TUN_DEV: Name of the virtual network interface (e.g. tun0).
  • TUN_ADDR: IP address and subnet mask to assign to TUN_DEV. This address will be used as the gateway for the container.
  • FWMARK: Arbitrary numeric mark that will be used to mark packets for redirection.
  • ROUTE_TABLE: Number of the custom routing table where marked traffic will be directed.
  • CONTAINER_IP: Critical parameter! This is the IP address of your container whose traffic you want to redirect. You will need to find it out.
  • SOCKS_PROXY: Full address of your SOCKS5 proxy, including protocol, username, password, and port.
  • PID_FILE: Path to the file where the PID of the tun2socks process will be written for systemd tracking.

cleanup function

The cleanup() function removes all previously created iptables rules, routes, and the TUN device itself. This is important to ensure a “clean” state before each new setup and when stopping the service. It also removes the PID file.

Startup and cleanup logic

The script checks its command-line arguments. If run with the cleanup_only argument, it only executes the cleanup function and exits. Otherwise, it first cleans previous settings and then creates new ones.

Creating the TUN device

  • ip tuntap add dev "$TUN_DEV" mode tun: Creates a new TUN interface with the specified name.
  • ip addr add "$TUN_ADDR" dev "$TUN_DEV": Assigns the IP address to the created TUN interface.
  • ip link set "$TUN_DEV" up: Brings the TUN interface up.

Setting up ip rule and iptables

This is the heart of the redirection mechanism:

  • ip rule add fwmark "$FWMARK" table "$ROUTE_TABLE" priority "$FWMARK": Adds a routing rule that says: “any packet with mark FWMARK should be handled using routing table ROUTE_TABLE”. The priority set to FWMARK ensures this rule is considered before others.

  • ip route replace default dev "$TUN_DEV" table "$ROUTE_TABLE": In our special routing table ROUTE_TABLE we set the default route to point to our TUN device. This means all traffic entering this table will be routed via TUN_DEV.

  • iptables -t mangle -A PREROUTING -s "$CONTAINER_IP" -p tcp -j MARK --set-mark "$FWMARK": This iptables rule in the PREROUTING chain (which processes packets before they go through routing) in the mangle table (used for packet alteration) says: “if a TCP packet originates from CONTAINER_IP, mark it with FWMARK”. This is how we identify traffic to be redirected.

Important: in this scheme only TCP goes through the proxy. The rule matches -p tcp, so UDP traffic from the container, including DNS queries, will go out via the main gateway directly. tun2socks can handle UDP as well, but the SOCKS5 server must support UDP ASSOCIATE, and you need to add UDP to the rule. If it’s important that DNS not bypass the proxy, either mark UDP too, or configure the container to use a DNS server accessible via the proxy over TCP.

  • iptables -t nat -A POSTROUTING -o "$TUN_DEV" -j MASQUERADE: This rule in the nat table’s POSTROUTING chain (processed just before packets are sent out) performs masquerading (SNAT), i.e., it rewrites the source IP of outgoing packets leaving via TUN_DEV to the IP address associated with TUN_DEV. This is necessary for the proxy to work correctly.

Starting tun2socks

  • "$TUN2SOCKS_BIN" --device "$TUN_DEV" --proxy "$SOCKS_PROXY" --loglevel info &: Starts tun2socks itself. It binds to the created TUN_DEV and uses the specified SOCKS_PROXY to forward traffic arriving on TUN_DEV. The & runs it in the background; --loglevel info sets the log verbosity (debug is useful for troubleshooting). tun2socks does not have --nohup or --log-level flags — it will not start with them.

  • echo $! > "$PID_FILE": Saves the PID of the process just started in the background so systemd can track it.


How to use (with systemd)

Now that the script is ready, we can integrate it with systemd for easy management.

  1. Save the script: create a file, e.g. /usr/local/bin/tun2socks_redirect.sh, and paste the modified script into it.

    bash
    sudo nano /usr/local/bin/tun2socks_redirect.sh
  2. Make it executable:

    bash
    sudo chmod +x /usr/local/bin/tun2socks_redirect.sh
  3. Determine the container IP address: if you use Docker, you can get the container IP by running docker inspect <container_name> | grep "IPAddress".

  4. Update CONTAINER_IP and SOCKS_PROXY: be sure to change the CONTAINER_IP and SOCKS_PROXY values in /usr/local/bin/tun2socks_redirect.sh to your own.


Creating the Systemd unit file

Create a systemd unit file for our service.

  1. Create the file /etc/systemd/system/tun2socks-redirect.service:

    bash
    sudo nano /etc/systemd/system/tun2socks-redirect.service
  2. Paste the following content:

    ini
    [Unit]
    Description=Tun2socks Traffic Redirection Service
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=forking
    # We use Type=forking because our script starts tun2socks in the background
    # and then exits; the tun2socks process remains running as part of the service.
    # PIDFile is used to track the tun2socks PID.
    PIDFile=/var/run/tun2socks.pid
    ExecStartPre=/usr/local/bin/tun2socks_redirect.sh
    # ExecStart is the command that systemd will track.
    # Since our script starts tun2socks in the background, systemd will track it via PIDFile.
    ExecStart=/bin/true
    # ExecStopPost runs after the service is stopped, to clean up
    ExecStopPost=/usr/local/bin/tun2socks_redirect.sh cleanup_only
    # User=root - the script requires root privileges
    User=root
    Restart=on-failure
    RestartSec=5s
    
    [Install]
    WantedBy=multi-user.target

Notes on the unit file:

  • [Unit]:
    • Description: Short description of the service.
    • After=network-online.target: The service will start after the network is fully configured.
    • Wants=network-online.target: Declares a soft dependency on network-online.target.
  • [Service]:
    • Type=forking: Tells systemd that the main service process will fork a child (our tun2socks), and the parent (the script) will exit. systemd will use PIDFile to track the real service process.
    • PIDFile=/var/run/tun2socks.pid: Path to the file where our script writes the PID of the started tun2socks. This is critical for Type=forking.
    • ExecStartPre=/usr/local/bin/tun2socks_redirect.sh: Command executed before the main service start. Here our script sets up the TUN device and iptables rules and starts tun2socks in the background.
    • ExecStart=/bin/true: Since tun2socks is already started by our ExecStartPre script and systemd tracks it via PIDFile, we don’t need to run anything else in ExecStart. /bin/true simply exits successfully.
    • ExecStopPost=/usr/local/bin/tun2socks_redirect.sh cleanup_only: Command run after the service stops. When called with cleanup_only, the script only performs cleanup of rules.
    • User=root: Service must run as root because it changes network settings and iptables rules.
    • Restart=on-failure: If the service exits with an error, systemd will try to restart it.
    • RestartSec=5s: Delay before attempting restart.
  • [Install]:
    • WantedBy=multi-user.target: The service will be started during boot in multi-user mode.

Enabling and starting the Systemd service

After creating the unit file and adjusting the script:

  1. Reload the systemd daemon:

    bash
    sudo systemctl daemon-reload
  2. Enable the service to start at boot:

    bash
    sudo systemctl enable tun2socks-redirect.service
  3. Start the service:

    bash
    sudo systemctl start tun2socks-redirect.service
  4. Check the service status:

    bash
    sudo systemctl status tun2socks-redirect.service

    You should see the service as active (active (running)).

  5. Check logs:

    bash
    journalctl -u tun2socks-redirect.service -f

    This will help you monitor output from the script and tun2socks.

Now your service will automatically start at boot and attempt to maintain tun2socks and routing rules. To stop the service use sudo systemctl stop tun2socks-redirect.service, and it will automatically clean up rules. To restart - sudo systemctl restart tun2socks-redirect.service.


Conclusion

We have configured a system that redirects all TCP traffic from a specified container through a SOCKS proxy server. If you need to route all system traffic through the proxy instead of a single container, see the article “Redirecting all system traffic through a SOCKS5 proxy using tun2socks”. This method provides flexibility and control over network traffic routing through external proxy services, and integrating with systemd greatly improves reliability and manageability.

I hope this article was helpful! If you have questions or suggestions, feel free to leave comments.

// Reviews

Related reviews

I needed to get n8n, Redis, and the database working. I had hired another contractor before and everything kept breaking. I hired Mikhail, and the next day everything was working quickly, like clockwork!

There was a task to get n8n, redis and the database working. I had previously ordered from another contractor, it kept breaking all the time. Ordered from Mikhail, the next day everything started working fast, like …

christ_media

n8n installation on your VPS server. Configuration of n8n, Docker, AI, Telegram

2025-09-24 · ★ 5/5

Experienced buyer

Quick solution — I highly recommend Mikhail as a contractor! I tried to build a similar configuration myself and even followed AI advice, which ended up costing a lot of time and money (due to server downtime). So my advice: hire professionals — it's cheaper =) Thanks to Mikhail for his professionalism.

Quick fix for the problem, I recommend Mikhail as a contractor to everyone! I tried to assemble a similar configuration myself and following advice from neural networks, which resulted in a lot of wasted effort and …

ladohinpy

n8n installation on your VPS server. Configuration of n8n, Docker, AI, Telegram.

2025-08-25 · ★ 5/5

// Contact

Need help?

Get in touch with me and I'll help solve the problem

I reply within one business day (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirm that you are not a bot.

Write and get a quick reply