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!
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
- Basic Kill Switch Setup with iptables
- Working with Multiple VPN Profiles
- Monitoring and Automatic Rule Management
- Handling Failures and Edge Cases
- Alternative Solutions with UFW
- Recommendations and Best Practices
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
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
# 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:
iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6
For CentOS/RHEL:
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:
#!/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:
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:
- Open Nekoray
- Select the desired profile
- Click “Connect”
- In a separate terminal, run the script
Monitoring and Automatic Rule Management
Script for Monitoring VPN Connection
#!/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:
nohup /usr/local/bin/vpn-monitor > /var/log/vpn-monitor.log 2>&1 &
Disabling the Kill Switch
To safely disable the Kill Switch:
# 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:
#!/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:
# 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:
# 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:
#!/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:
# 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:
# Create a systemd service
sudo nano /etc/systemd/system/vpn-killswitch.service
File contents:
[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:
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:
# 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:
#!/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:
- Base your rules on the TUN interface rather than specific IP addresses
- Use monitoring for automatic rule management when VPN connections change
- Test regularly and create restore points
- Consider edge cases such as Nekoray hanging or network interface failures
- 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
- How To Create A VPN Killswitch Using Iptables on Linux - Detailed guide to creating a Kill Switch with iptables
- Tun mode killswitch · Issue #1605 · MatsuriDayo/nekoray - Discussion of Kill Switch issues in Nekoray
- How to Build a VPN Kill Switch with IPTables and UFW - Alternative methods for implementing a Kill Switch
- NekoRay split tunneling - Information about TUN mode in Nekoray
- VPN Kill Switch for Linux and macOS Clients - Guide to setting up a Kill Switch for VPN clients