IQ-Openvpn or Openvpn with distributed routing
Every day more and more people find out what a VPN is and start using it, but often everyone is faced with such a problem that by turning on VPN we get access to blocked resources, but at the same time we lose access to resources that block our access from other locations for one reason or another. For this reason, you have to constantly turn off the VPN. In this mana, I will tell you how to raise your VPN service, which will allow you to access all resources on the Internet without disconnecting from the VPN server.
To create, we need two VPN1 and VPN2 servers.
VPN1 should ideally be in the same country as the user for two reasons:
1. To speed up the signal and minimize delays
2. Many resources prohibit access from other locations
VPN2 may be located in a country where there are no restrictions that need to be bypassed. The closer to the user’s location it will be, the better for the same first reason above.
For further understanding of what and where to “stick” let’s define the server data:
VPN1:
IP1 – 11.11.11.11
ip1_gateway – 11.11.11.1
IP_VPN1 – 192.168.11.1
ip_gateway_vpn1 – 192.168.11.1
VPN2:
IP2 – 12.12.12.12
ip2_gateway – 12.12.12.1
IP_VPN2 – 192.168.12.1
ip_gateway_vpn2 – 192.168.12.1
On the VPN1 server, we connect users with all traffic redirected, and on the VPN2 server, we connect the VPN1 server with a “local” connection. “Local” connection – a connection in which only a tunnel is created between servers and certain traffic goes into it, and all traffic by default goes around the tunnel.
Let’s start configuring the VPN1 server.
First, install the necessary utilities:
apt update && apt upgrade
apt install sudo vim shorewall curl wget openvpn dnsutils -y
Enable packet forwarding on the server. We find the line and bring it to the following form:
vim /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
cd /etc/shorewall/
Next, we need to take the templates of the necessary files so as not to write them from scratch:
cp /usr/share/doc/shorewall/examples/two-interfaces/{interfaces,policy,rules,snat,zones} /etc/shorewall/
cp /usr/share/shorewall/configfiles/{tunnels,routes} /etc/shorewall/
mkdir {local,routes.d}
Now we bring patterns to our situation. On the VPN1 server, we will have three interfaces:
ens3 – physical interface with external static IP,
tun1u – vpn1.server virtual interface,
tun2u – vpn2.client virtual interface.
The VPN1 server is in the ru zone, so let’s call it that, and VPN2 is in the nl zone:
vim zones
fw firewall
net ipv4
ru ipv4
nl ipv4
Pay attention to the interface names!
vim interfaces
net ens3 dhcp,tcpflags,nosmurfs,routefilter,logmartians,sourceroute=0
ru tun1u optional,tcpflags,nosmurfs,routefilter,logmartians
nl tun2u optional,tcpflags,nosmurfs,routefilter,logmartians
In the following file, we write the settings for forwarding VPN traffic, where we specify our protocol and port of the vpn server:
vim tunnels
openvpnserver:udp:11443 net 0.0.0.0/0
We need to enable masquerading, for this we remove the default settings in the snat file and write our own with the substitution of our subnets:
vim snat
MASQUERADE 192.168.11.0/24 ens3
MASQUERADE 192.168.11.0/24 tun2u
vim policy
$FW net ACCEPT
$FW ru ACCEPT
$FW nl ACCEPT
ru $FW ACCEPT
ru net ACCEPT
ru nl ACCEPT
net all DROP $LOG_LEVEL
# THE FOLOWING POLICY MUST BE LAST
all all REJECT $LOG_LEVEL
vim rules
?SECTION ALL
?SECTION ESTABLISHED
?SECTION RELATED
?SECTION INVALID
?SECTION UNTRACKED
?SECTION NEW
# Don't allow connection pickup from the net
#
Invalid(DROP) net all tcp
#
# Accept DNS connections from the firewall to the network
#
DNS(ACCEPT) $FW net
#
# Accept SSH connections from the local network for administration
#
SSH(ACCEPT) net $FW
SSH(ACCEPT) nl $FW
SSH(ACCEPT) ru $FW
SSH(ACCEPT) $FW net
SSH(ACCEPT) $FW nl
SSH(ACCEPT) $FW ru
#
# Allow Ping from the local network
#
Ping(ACCEPT) nl $FW
Ping(ACCEPT) ru $FW
#
# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
#
Ping(DROP) net $FW
ACCEPT $FW nl icmp
ACCEPT $FW ru icmp
ACCEPT $FW net icmp
Set up a vpn server, run it. We also restart shorewall:
systemctl restart shorewall
systemctl enable shorewall
We can issue a user certificate with the turnover of all traffic and check the performance. You can check on the website https://2ip.ru Or on the one you like best. If the connection went well, we saw the IP of the server on the site, then we did everything right.
Let’s start configuring VPN2.
First, install the necessary utilities:
apt update && apt upgrade
apt install sudo vim shorewall curl wget openvpn dnsutils -y
Enable packet forwarding on the server. We find the line and bring it to the following form:
vim /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
cd /etc/shorewall/
Next, we need to take the templates of the necessary files so as not to write them from scratch:
cp /usr/share/doc/shorewall/examples/two-interfaces/{interfaces,policy,rules,snat,zones} /etc/shorewall/
cp /usr/share/shorewall/configfiles/tunnels /etc/shorewall/
Now we bring patterns to our situation. On the VPN2 server, we will have two interfaces:
ens3 – physical interface with external static IP,
tun2u – vpn2.server virtual interface.
The VPN2 server is located in the nl zone, so let’s call it that:
vim zones
fw firewall
net ipv4
nl ipv4
Pay attention to the names of interfaces!
vim interfaces
net ens3 dhcp,tcpflags,nosmurfs,routefilter,logmartians,sourceroute=0
nl tun2u optional,tcpflags,nosmurfs,routefilter,logmartians
In the following file, we specify the settings for forwarding VPN traffic, where we specify our protocol and port of the vpn server:
vim tunnels
openvpnserver:udp:12443 net 0.0.0.0/0
Next, we need to enable masquerading, for this we remove the default settings in the next file and write our own with the substitution of our subnets:
vim snat
MASQUERADE 192.168.0.0/16 ens3
vim policy
$FW net ACCEPT
$FW nl ACCEPT
nl net ACCEPT
net all DROP $LOG_LEVEL
# THE FOLOWING POLICY MUST BE LAST
all all REJECT $LOG_LEVEL
vim rules
?SECTION ALL
?SECTION ESTABLISHED
?SECTION RELATED
?SECTION INVALID
?SECTION UNTRACKED
?SECTION NEW
# Don't allow connection pickup from the net
#
Invalid(DROP) net all tcp
#
# Accept DNS connections from the firewall to the network
#
DNS(ACCEPT) $FW net
#
# Accept SSH connections from the local network for administration
#
SSH(ACCEPT) net $FW
SSH(ACCEPT) nl $FW
SSH(ACCEPT) $FW net
SSH(ACCEPT) $FW nl
#
# Allow Ping from the local network
#
Ping(ACCEPT) nl $FW
Ping(ACCEPT) nl nl
#
# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
#
Ping(DROP) net $FW
ACCEPT $FW nl icmp
ACCEPT $FW net icmp
Set up a vpn server, run it. We also restart shorewall
systemctl restart shorewall
systemctl enable shorewall
Now we can create a user certificate, but without wrapping all traffic in vpn, which will only create a tunnel between VPN1 server and VPN2, local. We send the certificate to the VPN1 server, turn it on and add it to startup.
Now we are starting to do what everything was started for. We need to configure traffic routing by zones (yes, we only make two servers, but more can be done). The first thing we need to do is create a list of location addresses.
Difficult, boring, but fun
For this we go to website and choose for which country (the country where we are located).
We get a list of networks with start and end addresses, and in this form we cannot use them, we need to bring them to the following form xx.xx.xx.xx/xx, and for this we need to correctly calculate the mask of each network from the table. You can manually count on a piece of paper or in your mind, or you can go here and calculate using the network calculator. You need to be very careful when recalculating, because the mistakes made can lead to the fact that the traffic will not be redirected the way we want or the system will not start at all.
And so, we count the networks and immediately write them to the /etc/shorewall/local/ru file on the VPN1 server in a column in the form:
xx.xx.xx.xx/xx
xx.xxx.xx.xx/xx
etc.
The work is quite large, especially if the country is large)
Simple and boring
I’m going to the same websitebut a little further, select the country and CIDR format and download the archive with the list of addresses in the format we need, however, the list contains the first extra lines, delete them and save them to the /etc/shorewall/local/ru file on the VPN1 server.
Finished? Go ahead. Now we need to make sure that the address data in the required format gets into the configuration file, plus enable traffic forwarding to VPN2, for this we need to create a script (you don’t need to panic, I wrote everything a long time ago, we just need to copy and paste, substituting our values):
cd /etc/shorewall/
vim auto.sh
#!/bin/bash
input=local/ru
output=routes.d/ru
localnet="<ip1_gateway>"
interface=ens3
tun2=tun2u
ip2="<IP2>"
ip_gateway_vpn2="<ip_gateway_vpn2>"
echo "#provider dest gateway device" > $output
echo "#provider dest gateway device
main 0.0.0.0/0 $ip_gateway_vpn2 $tun2
main $ip2 $localnet $interface #connect nl
main 195.201.201.32 $localnet $interface #check 2ip.ru
INCLUDE /etc/shorewall/routes.d/ru" > routes
while IFS= read -r network
do
echo "main $network $localnet $interface" >> $output
done < $input
Important note
This scheme will only work if the client also connects from the same zone as the VPN1 server, otherwise there will be no access to the server. However, if you want to give a friend from Turkey a certificate to your vpn, then you need to take his IP address and add it to the routes file:
vim /etc/shorewall/routes
...
main <IP_of_friend> <localnet> <interface>
...
Now we make the file executable:
chmod +x auto.sh
Run the script and restart shorewall:
./auto.sh
shorewall restart
Now we have almost everything ready, first we will check the work. We are connected to vpn and we go to check. Let’s go to the site 2ip.ru and we see the address of VPN1, since we have registered the forwarding of packets to this site through VPN1. Now let’s go to the site. 2ip.ua or any other, but which is definitely not in the ru zone (in the example, I did it for it) and we see the VPN2 address. If everything is so, then congratulations, if not, then it’s worth checking everything again step by step.
The last step remains on the VPN1 server, unless of course we want to do everything manually every time after a reboot (at which access via ssh will be closed). We need to configure the shorewall autoload condition. To do this, we edit the /usr/lib/systemd/system/shorewall.service file and change the line “After=network-online.target” to “After=openvpn@cli002008.service”, where cli002008 is the name of my certificate:
vim /usr/lib/systemd/system/shorewall.service
problem place
On the latest version of debian, shorewall does not want to start after openvpn, which we indicated above. I have not figured out the problem yet, if someone has an answer, then write in the comments. While I will offer another solution, run via cron:
crontab -e
...
@reboot sleep 10; systemctl restart shorewall
...
Now everything is ready!
I took servers here, you can buy “eternal server”. Still using servers Herethis hosting has a wide variety of locations at affordable prices.
You can set up automatic data updates. A file with addresses will be downloaded through cron and written to shorewall, but this method is paid. You need to buy a subscription and get a link and a token for downloading in the following format:
curl -o firewall.gz ‘https://dl.ip2location.com/v1/firewall?token=mOdUlMdh0nK9Oap3iHaJxFrX0koqVahHX9Е9gfZhP9nURa126U4xnS9vKlbU3gry&country=RU|BY&format=cidr‘
Advertising
To make life easier, I offer my own script for creating a vpn server and client certificates. Everyone welcome to LS.
Thanks for the help
Thanks for the editorial [Дарью](https://www.linkedin.com/in/).