Linux based VM as a vless gateway

Associate
Joined
30 Dec 2025
Posts
7
Location
Moscow
Hello! Need some help - planning to build VM (Linux based) as a vless-client to make possible divert traffic from my home devices such as TV, smartphones, notebook to another country (to avoid censorship). Is there any ready-made decision to build such VM? For example, it should have 1 LAN port to connect it to my home switch (192.168.10.0.24) and 1 tun interface as a vless-client. Thank you for your advices.
 
A lot will be determined by who your VPN provider is, if they support something like Wireguard then a simple Ubuntu Server as a VM would work. You could set up WG as a client, stick a NAT rule on it and then any devices you want to hit the "wider" web you would use the VM as their gateway and bob's your uncle.

However that assumes that your upstream network will allow the VPN traffic, in honesty if it does then it's far easier to install a client on each device rather than having to add complexity within your network to do this.
 
In addition to the above, you could procure a router that supports VPN. Something based on OpenWRT is about as good as it gets. This gives you the ability to route all of your traffic via a VPN with little effort and removes the need to run the VM.
 
A lot will be determined by who your VPN provider is, if they support something like Wireguard then a simple Ubuntu Server as a VM would work. You could set up WG as a client, stick a NAT rule on it and then any devices you want to hit the "wider" web you would use the VM as their gateway and bob's your uncle.

However that assumes that your upstream network will allow the VPN traffic, in honesty if it does then it's far easier to install a client on each device rather than having to add complexity within your network to do this.
Oh, all these steps already in the past. Since december all the VPN protocols blocked by Russian government (except vless+tcp+reailty). This censorship is worst than in Iran... So I need to try Linux machine as a vless client and some software to convert packets from home devices to socks (advanced NAT in other words).
 
In addition to the above, you could procure a router that supports VPN. Something based on OpenWRT is about as good as it gets. This gives you the ability to route all of your traffic via a VPN with little effort and removes the need to run the VM.
Yes, I heard about OpenWRT but I have no such router at this moment. May be I can build virtual OpenWRT (VMware guest) to test firstly?
 
Have a look at MikroTik CHR.
RouterOS is the most versatile router operating system you will come across. CHR is free and if you register your CHR as free then you are not limited to 1Mb on interfaces. Very easy to virtualise, very resource light.
 
I tried to build it like this:
- get sources of BadVPN from github ;
- compile and install BadVPN sudo cmake /usr/src/badvpn-1.999.130/ -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1;
- create a new tun network interface sudo ip tuntap add dev tun0 mode tun user my_user_name;
- add an IP-address to this tun interface sudo ip a add 10.0.0.1/24 dev tun0 and bring it up sudo ip link set dev tun0 up;
Finally, run BadVPN:
badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.0.0.2 --netif-netmask 255.255.255.0 --socks-server-addr 192.168.10.107:10808
Already have working proxy 192.168.10.107 port 10808 (socks5). So I need to add route to start tunneling the data sent to tun0:
sudo ip r a default via 10.0.0.2 metric 10
Let's see route table:
route -v:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 10 0 0 tun0
default _gateway 0.0.0.0 UG 100 0 0 ens32
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32
_gateway 0.0.0.0 255.255.255.255 UH 100 0 0 ens32
Now I can check IP-address:
curl https://myip.wtf/json
{
"Your***ngIPAddress": "my_real_IP",
"Your***ngLocation": "London, ENG, United Kingdom",
"Your**ngHostname": "my_real_IP",
"Your***ngISP": "Kamatera Inc",
"Your***ngTorExit": false,
"Your***ngCity": "London",
"Your***ngCountry": "United Kingdom",
"Your***ngCountryCode": "GB"
}
That's it! But the most important thing remains: how can I now turn this virtual machine into a full-fledged gateway for other devices? I already set net.ipv4.ip_forward = 1 (/etc/sysctl.conf) but I can't use this VM (192.168.10.149) as a gate in same network (192.168.10.0/24). Should I setup masquerade to forward traffic to tun0?
 
Last edited by a moderator:
Your devices in 192.168.0.0/24 need to use the VM address as their gateway. You need to add an interface to the VM that is assigned an IP in the 192.168.0.0/24 subnet.

What is 192.168.10.0/24? If you can post your network topology and subnetting that would be helpful.

Your devices need a next hop that can use local connectivity (same subnet/layer 2) to route their traffic beyond that subnet. Your VM then needs IP forwarding (which you have enabled) and some sort of NAT configuration to get those packets out to the VPN and back to the devices.
 
Your devices in 192.168.0.0/24 need to use the VM address as their gateway. You need to add an interface to the VM that is assigned an IP in the 192.168.0.0/24 subnet.

What is 192.168.10.0/24? If you can post your network topology and subnetting that would be helpful.

Your devices need a next hop that can use local connectivity (same subnet/layer 2) to route their traffic beyond that subnet. Your VM then needs IP forwarding (which you have enabled) and some sort of NAT configuration to get those packets out to the VPN and back to the devices.
Yes, my VM have such interface - IP-address is 192.168.10.149. So if I understood you correctly I should add something like this in /etc/iptables/rules.v4:
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

Right?
 
Yes, my VM have such interface - IP-address is 192.168.10.149. So if I understood you correctly I should add something like this in /etc/iptables/rules.v4:
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

Right?
Sorry, no idea where I was getting 192.168.0.0/24 from. Must've been tired that day.

Yes, you enable NAT, then set the gateway of your devices as 192.168.10.149. Once configured, your devices will forward packets to the VM, which should then route traffic down the VPN tunnel.
 
Sorry, no idea where I was getting 192.168.0.0/24 from. Must've been tired that day.

Yes, you enable NAT, then set the gateway of your devices as 192.168.10.149. Once configured, your devices will forward packets to the VM, which should then route traffic down the VPN tunnel.
Things are getting even more interesting – I managed to achieve the desired result a couple of times, but for some reason it only takes about three minutes. I'll go over it step by step:
sudo ip tuntap add dev tun0 mode tun user username; //creating tun-interface
- sudo ip a add 10.0.0.1/24 dev tun0; //assigning 10.0.0.1 to it
- sudo ip link set dev tun0 up; //starting tun0
- sudo ifconfig; //checking is active
- badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.0.0.2 --netif-netmask 255.255.255.0 --socks-server-addr 192.168.10.107:10808; //connecting to socks5 server
- ping 10.0.0.2 //checking data exchange
- sudo ip r a default via 10.0.0.2 metric 10; //route adding
- sudo ip r del default via 0.0.0.0 dev ens32 //removing default route through ens32 (optional)
- route -v //route table check
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 10 0 0 tun0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32
192.168.10.1 0.0.0.0 255.255.255.255 UH 100 0 0 ens32
- curl https://myip.wtf/json //check it works through tunnel
{
"YourIPAddress": "my_real_IP",
"YourLocation": "London, ENG, United Kingdom",
"YourHostname": "my_real_IP",
"YourISP": "Kamatera Inc",
"YourTorExit": false,
"YourCity": "London",
"YourCountry": "United Kingdom",
"YourCountryCode": "GB"
}
Now all that remains is masquerade:
- sudo iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o tun0 -j MASQUERADE
checking:
sudo iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain POSTROUTING (policy ACCEPT 241 packets, 15273 bytes)
pkts bytes target prot opt in out source destination
461 60995 MASQUERADE 0 -- * tun0 192.168.10.0/24 0.0.0.0/0

I point to the new gateway address 192.168.10.149 and DNS 8.8.8.8 – everything starts working, packets are flowing, and then after 3-5 minutes everything stops. On Ubuntu, nothing seems to be down. What could this be? I thought I configured everything correctly, didn't I?
 
Things are getting even more interesting – I managed to achieve the desired result a couple of times, but for some reason it only takes about three minutes. I'll go over it step by step:
sudo ip tuntap add dev tun0 mode tun user username; //creating tun-interface
- sudo ip a add 10.0.0.1/24 dev tun0; //assigning 10.0.0.1 to it
- sudo ip link set dev tun0 up; //starting tun0
- sudo ifconfig; //checking is active
- badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.0.0.2 --netif-netmask 255.255.255.0 --socks-server-addr 192.168.10.107:10808; //connecting to socks5 server
- ping 10.0.0.2 //checking data exchange
- sudo ip r a default via 10.0.0.2 metric 10; //route adding
- sudo ip r del default via 0.0.0.0 dev ens32 //removing default route through ens32 (optional)
- route -v //route table check
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 10 0 0 tun0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens32
192.168.10.1 0.0.0.0 255.255.255.255 UH 100 0 0 ens32
- curl https://myip.wtf/json //check it works through tunnel
{
"YourIPAddress": "my_real_IP",
"YourLocation": "London, ENG, United Kingdom",
"YourHostname": "my_real_IP",
"YourISP": "Kamatera Inc",
"YourTorExit": false,
"YourCity": "London",
"YourCountry": "United Kingdom",
"YourCountryCode": "GB"
}
Now all that remains is masquerade:
- sudo iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o tun0 -j MASQUERADE
checking:
sudo iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain POSTROUTING (policy ACCEPT 241 packets, 15273 bytes)
pkts bytes target prot opt in out source destination
461 60995 MASQUERADE 0 -- * tun0 192.168.10.0/24 0.0.0.0/0

I point to the new gateway address 192.168.10.149 and DNS 8.8.8.8 – everything starts working, packets are flowing, and then after 3-5 minutes everything stops. On Ubuntu, nothing seems to be down. What could this be? I thought I configured everything correctly, didn't I?
It sounds like you have a bit of troubleshooting to do. Check that your VPN doesn't require some kind of keep-alive mechanism to remain active.
 
It sounds like you have a bit of troubleshooting to do. Check that your VPN doesn't require some kind of keep-alive mechanism to remain active.
I am using v2rayN as a proxy and it works without any problems if i connect from any device (192.168.10.107:10808). So this is only problem with masquerade - how to check do I need aditional mechanism for a maintaining connection? May be I should ping some IP-address constantly - 8.8.8.8 for example?
 
Back
Top Bottom