NeuroAgent

Setting Up Kill Switch for Linux with VLESS Nekoray

Complete guide to setting up Kill Switch for Linux with VLESS via Nekoray. Protect your traffic when switching between VPN profiles with different IPs and ports. Learn how!

How to set up a Kill Switch for Linux Firewall with VLESS (Nekoray) and various VPN profiles (different IPs and ports)?

Hello respected experts!

Situation:

  • Linux machine running VLESS VPN through the Nekoray client
  • I have multiple VPN profiles with different IPs and ports for connection
  • Task: Set up a Kill Switch so that when switching between VPN profiles, I don’t have to reconfigure the firewall and traffic doesn’t bypass the VPN

I’m not a strong networking person, but it seems that the solution might be to route traffic to the virtual interface that Nekoray creates in “TUN” mode (visible with the ip a command).

However, questions arise:

  • What will happen if Nekoray fails, the interfaces remain, and traffic goes around the failed VPN?
  • What other possible failures could occur that are difficult to foresee?
  • If I hard-bind the Kill Switch to an IP or port, then I’ll have to reconfigure the firewall for each VPN profile switch.

Please advise on how to properly implement a Kill Switch in this situation?

Wishing everyone well!

NeuroAgent

Setting Up a Kill Switch for Linux Firewall with VLESS (Nekoray) and Various VPN Profiles

To configure a Kill Switch for Linux Firewall with VLESS (Nekoray) and various VPN profiles, you need to create rules that block all traffic except for traffic through the virtual TUN interface created by Nekoray, regardless of the VPN server’s IP address or port.

Contents


Understanding TUN Interface and Kill Switch

When Nekoray operates in TUN mode, it creates a virtual network interface (usually named tun0 or similar). All traffic in this mode is routed through this interface, allowing control over network flows at the Linux kernel level.

Important: The TUN interface is only created when the VPN connection is active. If Nekoray crashes, this interface will disappear, automatically terminating the VPN connection.

Benefits of the TUN interface approach:

  • Independent of specific VPN server IP addresses or ports
  • Works with any number of VPN profiles
  • Automatically adapts to connection changes

Potential issues:

  • If Nekoray hangs without properly closing interfaces
  • When the TUN driver itself fails
  • When conflicts with other network services occur

Basic Kill Switch Setup with iptables

To set up a Kill Switch, you’ll need root privileges. Here’s a step-by-step guide:

1. Determine the TUN interface name

bash
ip a

You’ll see something like:

4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0

2. Configure basic iptables rules

bash
# Reset existing rules (be careful!)
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X

# Default policy - block all traffic
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# Allow local traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Allow traffic through TUN interface
iptables -A OUTPUT -o tun0 -j ACCEPT
iptables -A INPUT -i tun0 -j ACCEPT

# Allow establishment of new connections
iptables -A OUTPUT -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

3. Make rules persistent

For Debian/Ubuntu:

bash
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

For CentOS/RHEL:

bash
service iptables save

Working with Multiple VPN Profiles

Since your Kill Switch is based on the TUN interface rather than specific IP addresses, it will automatically work with any number of VPN profiles.

Dynamic Configuration for Different VPNs

If you encounter issues determining the TUN interface name, you can use a more universal approach:

bash
#!/bin/bash

# Script for dynamic Kill Switch
VPN_INTERFACE=$(ip a | grep -o 'tun[0-9]\+' | head -1)

if [ -n "$VPN_INTERFACE" ]; then
    # Allow traffic only through VPN interface
    iptables -P OUTPUT DROP
    iptables -A OUTPUT -o "$VPN_INTERFACE" -j ACCEPT
    iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    
    echo "Kill Switch activated for interface: $VPN_INTERFACE"
else
    echo "VPN interface not found! Traffic blocked."
    iptables -P OUTPUT DROP
fi

Save this script as /usr/local/bin/vpn-killswitch and make it executable:

bash
chmod +x /usr/local/bin/vpn-killswitch

Integration with Nekoray

You can run this script each time you connect to a VPN through Nekoray. To do this:

  1. Open Nekoray
  2. Select the desired profile
  3. Click “Connect”
  4. In a separate terminal, run the script

Monitoring and Automatic Rule Management

Script for Monitoring VPN Connection

bash
#!/bin/bash

# Monitor VPN connection and automatic Kill Switch
VPN_INTERFACE="tun0"
CHECK_INTERVAL=5

while true; do
    if ip a show "$VPN_INTERFACE" up &>/dev/null; then
        # VPN connected, allow traffic through interface
        iptables -P OUTPUT DROP
        iptables -A OUTPUT -o "$VPN_INTERFACE" -j ACCEPT
        iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
        echo "VPN active, traffic routed through $VPN_INTERFACE"
    else
        # VPN disconnected, block all traffic
        iptables -P OUTPUT DROP
        echo "VPN disconnected, all traffic blocked!"
    fi
    sleep "$CHECK_INTERVAL"
done

Run this script in the background:

bash
nohup /usr/local/bin/vpn-monitor > /var/log/vpn-monitor.log 2>&1 &

Disabling the Kill Switch

To safely disable the Kill Switch:

bash
# Allow all traffic
iptables -P ACCEPT

# Stop monitoring
pkill -f vpn-monitor

Handling Failures and Edge Cases

Scenario 1: Nekoray hangs without properly closing interfaces

In this case, the TUN interface will remain active, but the VPN connection may be non-functional.

Solution:

bash
#!/bin/bash

# Check VPN activity by pinging DNS server
VPN_INTERFACE="tun0"
DNS_SERVER="8.8.8.8"

if ip a show "$VPN_INTERFACE" up &>/dev/null; then
    if ping -c 1 -W 2 -I "$VPN_INTERFACE" "$DNS_SERVER" &>/dev/null; then
        echo "VPN is active and working"
    else
        echo "VPN interface is active, but connection is not working!"
        # Block traffic
        iptables -P OUTPUT DROP
    fi
else
    echo "VPN interface not detected"
    iptables -P OUTPUT DROP
fi

Scenario 2: Conflicts with Other Network Services

If you have other network services running (DHCP, DNS, etc.), they may require network access.

Solution:

bash
# Allow DNS requests (for domain resolution)
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT

# Allow NTP time synchronization
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT

# Allow access to internal networks (if needed)
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
iptables -A OUTPUT -d 10.0.0.0/8 -j ACCEPT
iptables -A OUTPUT -d 172.16.0.0/12 -j ACCEPT

Alternative Solutions with UFW

If you prefer to use UFW (Uncomplicated Firewall), you can set up a Kill Switch as follows:

bash
# Install UFW if not installed
sudo apt install ufw

# Allow all traffic through TUN interface
sudo ufw allow in on tun0
sudo ufw allow out on tun0

# Allow local traffic
sudo ufw allow from any to any

# Allow established connections
sudo ufw allow out from any to any established

# Set default policy to block
sudo ufw default deny incoming
sudo ufw default deny outgoing

# Enable UFW
sudo ufw enable

For monitoring with UFW, you can use the same approach but with ufw commands:

bash
#!/bin/bash

VPN_INTERFACE="tun0"

while true; do
    if ip a show "$VPN_INTERFACE" up &>/dev/null; then
        # VPN active, allow traffic
        sudo ufw default deny outgoing
        sudo ufw allow out on "$VPN_INTERFACE"
        sudo ufw allow out from any to any established
    else
        # VPN disconnected, block all traffic
        sudo ufw default deny outgoing
    fi
    sleep 5
done

Recommendations and Best Practices

1. Testing the Kill Switch

Before regular use, thoroughly test your settings:

bash
# Block all traffic
iptables -P OUTPUT DROP

# Try to access the internet
ping 8.8.8.8  # Should be blocked

# Connect to VPN via Nekoray
# Start Kill Switch monitoring
/usr/local/bin/vpn-monitor &

# Check internet access
ping 8.8.8.8  # Should be allowed

2. Automatic Startup on Boot

Add the monitoring script to autostart:

bash
# Create a systemd service
sudo nano /etc/systemd/system/vpn-killswitch.service

File contents:

ini
[Unit]
Description=VPN Kill Switch Monitor
After=network.target

[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/vpn-monitor
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable the service:

bash
sudo systemctl daemon-reload
sudo systemctl enable vpn-killswitch
sudo systemctl start vpn-killswitch

3. Creating a Restore Point

Before making changes to firewall rules, create a backup:

bash
# Save current rules
iptables-save > /root/iptables-backup-$(date +%Y%m%d-%H%M%S).rules

# To restore
iptables-restore < /root/iptables-backup-20240115-1430.rules

4. Status Monitoring

Regularly check the Kill Switch status:

bash
#!/bin/bash

# Script to check Kill Switch status
check_killswitch() {
    VPN_INTERFACE=$(ip a | grep -o 'tun[0-9]\+' | head -1)
    
    if [ -z "$VPN_INTERFACE" ]; then
        echo "⚠️  VPN interface not found!"
        echo "📊 Traffic status:"
        iptables -L OUTPUT -n -v | grep -E "(ACCEPT|DROP)"
        return 1
    fi
    
    if ping -c 1 -W 2 -I "$VPN_INTERFACE" 8.8.8.8 &>/dev/null; then
        echo "✅ VPN active: $VPN_INTERFACE"
        echo "📊 Traffic status:"
        iptables -L OUTPUT -n -v | grep -E "(ACCEPT|DROP)"
        return 0
    else
        echo "❌ VPN interface $VPN_INTERFACE found, but connection is not working!"
        echo "📊 Traffic status:"
        iptables -L OUTPUT -n -v | grep -E "(ACCEPT|DROP)"
        return 1
    fi
}

check_killswitch

Conclusion

Setting up a Kill Switch for Linux with VLESS (Nekoray) and various VPN profiles requires attention to detail but is quite achievable. Key points:

  1. Base your rules on the TUN interface rather than specific IP addresses
  2. Use monitoring for automatic rule management when VPN connections change
  3. Test regularly and create restore points
  4. Consider edge cases such as Nekoray hanging or network interface failures
  5. Use systemd for automatic Kill Switch startup on system boot

This approach will provide reliable protection against traffic leaks when switching between different VPN profiles with different IP addresses and ports.

Sources

  1. How To Create A VPN Killswitch Using Iptables on Linux - Detailed guide to creating a Kill Switch with iptables
  2. Tun mode killswitch · Issue #1605 · MatsuriDayo/nekoray - Discussion of Kill Switch issues in Nekoray
  3. How to Build a VPN Kill Switch with IPTables and UFW - Alternative methods for implementing a Kill Switch
  4. NekoRay split tunneling - Information about TUN mode in Nekoray
  5. VPN Kill Switch for Linux and macOS Clients - Guide to setting up a Kill Switch for VPN clients