📜 ⬆️ ⬇️

How to keep 20 thousand VPN clients on servers for $ 5

A month ago, my friends and I made a free service to bypass site blockages in Ukraine Zaborona.Help . During this time, the service has become quite popular, the audience has grown to 20,000 users. The number of simultaneous connections at peak hours is ≈6,000 clients.

The main feature of our service is that through VPN traffic is only routed to blocked networks, other sites work directly. This does not affect the speed of the Internet and does not replace the IP address for other sites.

The article describes the details of setting up OpenVPN for a large number of clients on cheap VPS.
')

Our experience will be useful for those who are going to deploy a VPN for personal needs, and those who want to create a service with a large number of clients.

Hosting


At first, we used several servers in Europe from Scaleway, Linode, DigitalOcean providers. These were the cheapest VPS, for $ 3-5. Immediately, users began to complain that due to the European IP addresses, Yandex.Music and VK.com music is not available. We began to look for a suitable hosting in the CIS.

It turned out that domestic hosters, comparable in level of services to European ones, do not exist. Almost always, this is a low quality of services at a high price, a complicated order procedure, outdated technologies. During the search, we managed to create a list of the distinctive features of bad hosting.

Distinctive features of a poor hosting



Having tried several hosting sites, we almost despaired. It seemed that in Russia there simply wasn’t a normal hosting provider for our needs. I sent a letter to all the hosters that I could find on the hosting aggregator sites, in which I described our requirements, and asked for free to provide us with a site in exchange for advertising on our site.

Our requirements for VPS servers



About a dozen companies responded to our request, but almost all of them had signs of poor hosting and did not fit. As a result, we did find the ONLY hosting provider that satisfies all our needs.

It sounds strange, but I am ready to prove with conviction in the comments that 99% of domestic hosts are bullshit, not reaching the level of Europe. I will especially be glad to talk with representatives of large companies, such as MasterHost, REG.ru, 1GB.ru, Timeweb.

How we made friends with Veesp.com


A real discovery for us was the hoster Veesp.com with a data center in St. Petersburg. This is the only hoster who knew how to properly prepare IPv6. Network / 64 is allocated for each VPS server and / 56 upon request.

They have two lines of VPS tariffs. We use the “Storage 1” tariff, with unlimited traffic. The servers at this rate have an Intel Xeon X5650 processor. There is also a line of tariffs "Compute" , with an SSD drive, a powerful Intel Xeon E5v4 processor and DDR4 memory.

Tariff line Compute VPS provider Veesp.com
Tariff line Compute VPS provider Veesp.com

The control panel is comparable in convenience with DigitalOcean. There is even a payment through Bitcoin!

At the moment we have completely moved to the Veesp.com site and use six Storage 1 servers for OpenVPN. Music in VK and Yandex works again, users are happy.

IPv6


I really love IPv6. It allows you to get rid of heaps of unnecessary entities, such as NAT and port forwarding. For VPN, it is convenient because each client goes to the Internet with his real IP address. Unfortunately, many hosting providers and system administrators resist and dislike this protocol, because of this, it is incorrectly configured and used.

The most common mistake is to issue one IPv6 address per server.
Site slash64.net dedicated to this misconception.

Why do I need to allocate a minimum of / 64 for each end node



To give VPN clients IPv6 addresses directly without crutches, you need to have a separate routed network via the IPv6 address on the server, that is, the subnet from which you plan to distribute addresses to clients should not be assigned to the server interface, but should be routed through any address on the network interface of the server.

There are two common distribution options for routable networks.

The first option: one / 64 on the network interface, and / 56 routed through the first / 64. You can beat / 56 as you want, or assign the entire / 56 to the VPN interface.

The second option: one or several / 64 (or more) routed through a link-local-address.

Most hosters have a dedicated network ordered separately. Veesp.com issues a / 56 block to each server for free. Unfortunately, even advanced hosters, like DigitalOcean, do not provide such a service. Here is a list of hosters that provide this service version 6.ru/vps , from @rm.

NAT and Firewall


On servers, there are more than two hundred iptables rules, several for each range from the list of prohibited networks in Ukraine .

It is inconvenient to maintain a complex set of rules using the standard iptables-save and iptables-restore tools, because if one rule is changed, it will be necessary to edit hundreds of lines of the same type.

Simplify writing firewall rules with ferm


Ferm is a utility for managing complex iptables rules with its syntactic sugar. It allows you to create a readable iptables configuration, use variables, arrays and cycles, but does not limit you, unlike other add-ins over iptables: you can do absolutely everything, use all the features and modules of netfilter.

A simple example: we want to block incoming connections from several thousand networks on three eth0, eth1, eth2 network interfaces. Normally, you would have to write thousands of identical rules for each interface.

Here is how this problem is solved through ferm:

 @def $WAN_0 = eth0; @def $WAN_1 = eth1; @def $WAN_2 = eth2; @def $BLOCKED_NETWORKS = ( 123.123.123.123 234.234.234.234 .... ); chain INPUT { saddr $BLOCKED_NETWORKS of ($WAN_0 $WAN_1 $WAN_2) DROP; } 

As a result, a rule will be created for each address from $ BLOCKED_NETWORKS to each network interface. Such a record is easy to read and takes three times less lines. Its easier to edit.

In our case, iptables performs three functions: NAT for IPv4 connections, restricting access to other networks and load balancing between OpenVPN processes. Let us examine each task in detail.

NAT for IPv4 connections


Clients are given a "gray" IP address from the range 192.168. *. *, So it cannot be routed directly to the Internet. In order to release clients to IPv4 Internet, you must use network address translation (NAT) .

Your home WiFi router does the same thing. For each outgoing client connection, a translation is created in the server's memory, which stores information about who owns which connection. Despite the fact that this operation requires few server resources, with a huge number of connections (tens of thousands), this can become a resource-intensive task for a weak server.

This problem does not exist in IPv6, since each VPN client is given a real IP address that is directly routed to the Internet. The server needs only to transfer packets from one interface to another, without creating translations and storing information about each connection.

Restricting access to other networks


Any user can add the redirect-gateway option to the OpenVPN config and use our servers as the default route. It is necessary to close access to all networks except those blocked in Ukraine.

Load balancing between OpenVPN processes


The OpenVPN architecture is single-threaded, so one OpenVPN daemon process uses only one processor core. For better utilization of all processor cores, the number of processes should be equal to the number of cores on the server. Inter-process balancing is performed using the statistic module, which randomly redirects incoming connections to different internal ports.

Balancing between servers


We use the easiest balancing method — using multiple A-DNS records. All clients connect to the server through the domain name vpn.zaborona.help . This domain has six A-records that are sent to all servers. As a result, at the time of connection, the client selects a random server from the available ones. So the total number of connections is evenly distributed between all servers. The OpenVPN configuration on all servers is identical, except for the ranges of IPv6 addresses issued to clients.

image
DNS control panel. Balancing with multiple A-records. A small TTL value allows you to quickly remove addresses from the general list.

You can quickly see which IP addresses the domain resolves from around the world using the host-tracker.com service by selecting any of the tests, such as http or ping.

The result for the domain vpn.zaborona.help: www.host-tracker.com/InstantCheck/ResultComplete/ec0e5a90-ed56-e711-b124-0003ff7328cc

Recursive DNS resolvers


Many Ukrainian providers block DNS requests to forbidden domains, intercepting requests to third-party DNS servers, such as 8.8.8.8. Therefore, it is important that customers send DNS requests through a VPN tunnel, where the provider cannot modify them.
This is not so easy to do, because in new versions of Windows queries can go to all DNS servers in the system, and the one that responds faster will be used. The provider's DNS server is physically closer to the client, so it’s likely that the system will get the provider’s spoofed response faster, rather than the correct DNS answer inside the VPN, and the site will remain blocked.

To solve this problem, ValdikSS wrote a patch for OpenVPN that blocks DNS leaks in Windows . It uses the Windows Filtering Platform, a special layer of the Windows firewall that allows blocking requests to third-party DNS while OpenVPN is running.

Server deployment


In the comments to the previous article I was blamed for the fact that some stages that seemed obvious to me were not described. Here I will describe the complete set of commands for deploying the server fence.

Configs are maximally unified and can be deployed without changes on the server. This is convenient when using automatic deployment tools, such as Ansible.

The only unique data for each server is the IPv6 subnet, which is signed in the OpenVPN configuration file.

The servers use Ubuntu 16.04 LTS with kernel 4.4.0.

Package installation


The distribution repository contains an outdated version of OpenVPN 2.3, therefore we add the official project repositories with OpenVPN 2.4. All other packages are set from the standard delivery.

 wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg|apt-key add - echo "deb http://build.openvpn.net/debian/openvpn/release/2.4 xenial main" > /etc/apt/sources.list.d/openvpn-aptrepo.list apt update apt upgrade apt install openvpn dnsmasq ferm 

OpenVPN configuration


Since all servers are configured identically, we simply copy the configs along with the key files and certificates to the / etc / openvpn folder. No key / certificate generation is performed. The number of processes OpenVPN configures by the number of cores on the server, in our case 2. Each individual process has its own config: zaborona1.conf and zaborona2.conf.

To avoid confusion, I will call OpenVPN processes as demons, but essentially they are several separate servers running inside a single VPS.

List of files in /etc/openvpn

 /etc/openvpn/zaborona1.conf #    /etc/openvpn/zaborona2.conf #    /etc/openvpn/ccd/DEFAULT #          /etc/openvpn/ccd2/DEFAULT #          /etc/openvpn/logs #    /etc/openvpn/ca.crt #   /etc/openvpn/zaborona.help.crt #   /etc/openvpn/zaborona.help.key #   /etc/openvpn/dh2048.pem #   Diffie-Hellman  (  ) 

File Contents:

zaborona1.conf
 mode server #   ,   UDP ,   TCP       c,     UDP     keep-alive ,   NAT-    CGNAT. proto tcp #   L3,   ip .    L2 . dev-type tun #  tun-   dev zaborona1 #      /24,      /30. topology subnet #  "" ipv4-,  . server 192.168.224.0 255.255.252.0 #   ipv6-,  .    . server-ipv6 2a00:1838:32:200::/112 txqueuelen 250 keepalive 300 900 persist-tun persist-key cipher AES-128-CBC ncp-ciphers AES-128-GCM #user nobody duplicate-cn log logs/zaborona1.log status logs/status1.log 30 #      .         .       ,       . client-config-dir ccd ca ca.crt cert zaborona.help.crt key zaborona.help.key dh dh2048.pem 


zaborona2.conf
 mode server port 1195 proto tcp dev-type tun dev zaborona2 topology subnet server 192.168.228.0 255.255.252.0 server-ipv6 2a00:1838:32:280::/112 txqueuelen 250 keepalive 300 900 persist-tun persist-key cipher AES-128-CBC ncp-ciphers AES-128-GCM #user nobody duplicate-cn log logs/zaborona2.log status logs/status2.log 30 client-config-dir ccd2 ca ca.crt cert zaborona.help.crt key zaborona.help.key dh dh2048.pem 


ccd / DEFAULT
 push "dhcp-option DNS 192.168.224.1" push "dhcp-option DNS 74.82.42.42" # HE.net DNS push "route 74.82.42.42" # Route to HE.net DNS push "route 77.88.8.8" # Route to Yandex DNS push "dhcp-option DNS6 2001:4860:4860::8888" # Google IPv6 dns push "route-ipv6 2001:4860:4860::8888" push "dhcp-option DNS6 2001:4860:4860::8844" # Google IPv6 dns push "route-ipv6 2001:4860:4860::8844" #Persist TUN push "persist-tun" # Routes # Yandex network push "route 5.45.192.0 255.255.192.0" push "route 5.255.192.0 255.255.192.0" push "route 37.9.64.0 255.255.192.0" push "route 37.140.128.0 255.255.192.0" push "route 77.75.152.0 255.255.248.0" push "route 77.88.0.0 255.255.192.0" push "route 84.201.128.0 255.255.192.0" push "route 87.250.224.0 255.255.224.0" push "route 93.158.128.0 255.255.192.0" push "route 95.108.128.0 255.255.128.0" push "route 100.43.64.0 255.255.224.0" push "route 109.235.160.0 255.255.248.0" push "route 130.193.32.0 255.255.224.0" push "route 141.8.128.0 255.255.192.0" push "route 178.154.128.0 255.255.128.0" push "route 185.32.185.0 255.255.255.0" push "route 185.32.186.0 255.255.255.0" push "route 185.71.76.0 255.255.252.0" push "route 199.21.96.0 255.255.252.0" push "route 199.36.240.0 255.255.252.0" push "route 213.180.192.0 255.255.224.0" push "route-ipv6 2001:678:384::/48" push "route-ipv6 2620:10f:d000::/44" push "route-ipv6 2a02:6b8::/32" push "route-ipv6 2a02:5180::/32" # Mail.ru network push "route 5.61.16.0 255.255.248.0" push "route 5.61.232.0 255.255.248.0" push "route 79.137.157.0 255.255.255.0" push "route 79.137.183.0 255.255.255.0" push "route 94.100.176.0 255.255.240.0" push "route 95.163.32.0 255.255.224.0" push "route 95.163.248.0 255.255.248.0" push "route 128.140.168.0 255.255.248.0" push "route 178.22.88.0 255.255.248.0" push "route 178.237.16.0 255.255.240.0" push "route 185.5.136.0 255.255.252.0" push "route 185.16.148.0 255.255.252.0" push "route 185.16.244.0 255.255.252.0" push "route 188.93.56.0 255.255.248.0" push "route 194.186.63.0 255.255.255.0" push "route 195.211.20.0 255.255.252.0" push "route 195.211.128.0 255.255.252.0" push "route 195.218.168.0 255.255.255.0" push "route 208.87.92.0 255.255.252.0" push "route 217.20.144.0 255.255.240.0" push "route 217.69.128.0 255.255.240.0" push "route 185.6.244.0 255.255.252.0" push "route 185.30.176.0 255.255.252.0" push "route 195.218.190.0 255.255.254.0" push "route-ipv6 2a00:1148::/32" push "route-ipv6 2a00:a300::/32" push "route-ipv6 2a00:b4c0::/32" push "route-ipv6 2a04:4b40::/29" # VK.com network push "route 87.240.128.0 255.255.192.0" push "route 93.186.224.0 255.255.240.0" push "route 95.142.192.0 255.255.240.0" push "route 95.213.0.0 255.255.192.0" push "route 185.29.130.0 255.255.255.0" push "route 185.32.248.0 255.255.252.0" # Kaspersky network push "route 77.74.176.0 255.255.252.0" push "route 77.74.181.0 255.255.255.0" push "route 77.74.183.0 255.255.255.0" push "route 93.159.228.0 255.255.252.0" push "route 185.54.220.0 255.255.254.0" push "route 185.85.12.0 255.255.255.0" push "route 185.85.14.0 255.255.254.0" push "route 77.74.176.0 255.255.248.0" push "route 91.103.64.0 255.255.248.0" push "route 93.159.224.0 255.255.248.0" push "route-ipv6 2a03:2480::/33" # DrWeb push "route 178.248.232.183 255.255.255.255" push "route 178.248.233.94 255.255.255.255" push "route 195.88.252.0 255.255.254.0" 


ccd2 / DEFAULT
 push "dhcp-option DNS 192.168.228.1" push "dhcp-option DNS 74.82.42.42" # HE.net DNS push "route 74.82.42.42" # Route to HE.net DNS push "route 77.88.8.8" # Route to Yandex DNS push "dhcp-option DNS6 2001:4860:4860::8888" # Google ipv6 dns push "route-ipv6 2001:4860:4860::8888" push "dhcp-option DNS6 2001:4860:4860::8844" # Google ipv6 dns push "route-ipv6 2001:4860:4860::8844" #Persist TUN push "persist-tun" # Routes # Yandex network push "route 5.45.192.0 255.255.192.0" push "route 5.255.192.0 255.255.192.0" push "route 37.9.64.0 255.255.192.0" push "route 37.140.128.0 255.255.192.0" push "route 77.75.152.0 255.255.248.0" push "route 77.88.0.0 255.255.192.0" push "route 84.201.128.0 255.255.192.0" push "route 87.250.224.0 255.255.224.0" push "route 93.158.128.0 255.255.192.0" push "route 95.108.128.0 255.255.128.0" push "route 100.43.64.0 255.255.224.0" push "route 109.235.160.0 255.255.248.0" push "route 130.193.32.0 255.255.224.0" push "route 141.8.128.0 255.255.192.0" push "route 178.154.128.0 255.255.128.0" push "route 185.32.185.0 255.255.255.0" push "route 185.32.186.0 255.255.255.0" push "route 185.71.76.0 255.255.252.0" push "route 199.21.96.0 255.255.252.0" push "route 199.36.240.0 255.255.252.0" push "route 213.180.192.0 255.255.224.0" push "route-ipv6 2001:678:384::/48" push "route-ipv6 2620:10f:d000::/44" push "route-ipv6 2a02:6b8::/32" push "route-ipv6 2a02:5180::/32" # Mail.ru network push "route 5.61.16.0 255.255.248.0" push "route 5.61.232.0 255.255.248.0" push "route 79.137.157.0 255.255.255.0" push "route 79.137.183.0 255.255.255.0" push "route 94.100.176.0 255.255.240.0" push "route 95.163.32.0 255.255.224.0" push "route 95.163.248.0 255.255.248.0" push "route 128.140.168.0 255.255.248.0" push "route 178.22.88.0 255.255.248.0" push "route 178.237.16.0 255.255.240.0" push "route 185.5.136.0 255.255.252.0" push "route 185.16.148.0 255.255.252.0" push "route 185.16.244.0 255.255.252.0" push "route 188.93.56.0 255.255.248.0" push "route 194.186.63.0 255.255.255.0" push "route 195.211.20.0 255.255.252.0" push "route 195.211.128.0 255.255.252.0" push "route 195.218.168.0 255.255.255.0" push "route 208.87.92.0 255.255.252.0" push "route 217.20.144.0 255.255.240.0" push "route 217.69.128.0 255.255.240.0" push "route 185.6.244.0 255.255.252.0" push "route 185.30.176.0 255.255.252.0" push "route 195.218.190.0 255.255.254.0" push "route-ipv6 2a00:1148::/32" push "route-ipv6 2a00:a300::/32" push "route-ipv6 2a00:b4c0::/32" push "route-ipv6 2a04:4b40::/29" # VK.com network push "route 87.240.128.0 255.255.192.0" push "route 93.186.224.0 255.255.240.0" push "route 95.142.192.0 255.255.240.0" push "route 95.213.0.0 255.255.192.0" push "route 185.29.130.0 255.255.255.0" push "route 185.32.248.0 255.255.252.0" # Kaspersky network push "route 77.74.176.0 255.255.252.0" push "route 77.74.181.0 255.255.255.0" push "route 77.74.183.0 255.255.255.0" push "route 93.159.228.0 255.255.252.0" push "route 185.54.220.0 255.255.254.0" push "route 185.85.12.0 255.255.255.0" push "route 185.85.14.0 255.255.254.0" push "route 77.74.176.0 255.255.248.0" push "route 91.103.64.0 255.255.248.0" push "route 93.159.224.0 255.255.248.0" push "route-ipv6 2a03:2480::/33" # DrWeb push "route 178.248.232.183 255.255.255.255" push "route 178.248.233.94 255.255.255.255" push "route 195.88.252.0 255.255.254.0" 


Configs of different daemons differ only in the port number for incoming connections and the range of IP addresses issued to clients.

Change settings on the fly using client-config-dir


At first, we constantly edited the list of blocked networks, because of this we had to restart the OpenVPN daemons every time the configs changed. Because of this, the clients lost their connection to the server.

The solution to this problem was the client-config-dir option. It is used to assign individual settings to each user name. Since we all connect on behalf of one public client, the file is one for all < b> ccd / DEFAULT . The trick is that the file is re-read each time the client connects and does not require a server restart to apply the settings.

As a result, we can edit the server settings without disconnecting clients. and to get rid of the new settings, the user simply reconnects to the server. Since users sooner or later in any case are connected, the new settings are eventually applied to all clients.

Ferm


The firewall settings are identical on all servers, so we copy the /etc/ferm/ferm.conf file without changes. By default, after installation, the ferm package immediately activates the standard set of rules in which all connections are prohibited, except for SSH on port 22. So if your SSH server is on a different port, be careful not to block yourself.

/etc/ferm/ferm.conf
 #  tun-   OpenVPN. zaborona1, zaborona2    zaborona+. @def $VPN = ( zaborona+ ); #  ,    @def $WAN_4 = eth0; @def $WAN_6 = eth0; #  "" ,   @def $VPN_ADDR_4 = ( 192.168.224.0/22 192.168.228.0/22 ); @def $ALLOW_SSH = (  ,      SSH ); @def $ALLOWED_NETWORKS_V4 = (  ipv4-,    ); @def $ALLOWED_NETWORKS_V6 = (  ipv6-,    ); table filter { chain ZABORONA_V4 { daddr $ALLOWED_NETWORKS_V4 ACCEPT; } chain FORWARD { policy DROP; mod conntrack ctstate INVALID DROP; if $WAN_4 of $VPN mod conntrack ctstate (ESTABLISHED RELATED) ACCEPT; if $VPN of $WAN_4 jump ZABORONA_V4; } chain INPUT { saddr $ALLOW_SSH protocol tcp dport 22 ACCEPT; protocol tcp dport 22 REJECT reject-with icmp-port-unreachable; } } table nat { chain POSTROUTING { saddr $VPN_ADDR_4 of $WAN_4 MASQUERADE; } #    OpenVPN chain PREROUTING { interface $WAN_4 protocol tcp dport 1194 mod conntrack ctstate NEW mod statistic mode random probability 0.50000000000 REDIRECT to-ports 1195; } } # IPv6: domain ip6 { table filter { chain ZABORONA_V6 { daddr $ALLOWED_NETWORKS_V6 ACCEPT; } chain FORWARD { policy DROP; mod conntrack ctstate INVALID DROP; if $WAN_6 of $VPN mod conntrack ctstate (ESTABLISHED RELATED) ACCEPT; if $VPN of $WAN_6 jump ZABORONA_V6; } } } 


For comparison, here’s what the same set of rules obtained through iptables-save looks like:

iptables-save
 # Generated by iptables-save v1.6.0 on Fri Jun 23 19:44:10 2017 *filter :INPUT ACCEPT [54622:15244109] :FORWARD DROP [50:2520] :OUTPUT ACCEPT [59291:85277655] :ZABORONA_V4 - [0:0] -A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -m conntrack --ctstate INVALID -j DROP -A FORWARD -i eth0 -o zaborona+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i zaborona+ -o eth0 -j ZABORONA_V4 -A ZABORONA_V4 -d 87.240.128.0/18 -j ACCEPT -A ZABORONA_V4 -d 93.186.224.0/20 -j ACCEPT -A ZABORONA_V4 -d 95.142.192.0/20 -j ACCEPT -A ZABORONA_V4 -d 95.213.0.0/18 -j ACCEPT -A ZABORONA_V4 -d 185.29.130.0/24 -j ACCEPT -A ZABORONA_V4 -d 185.32.248.0/22 -j ACCEPT -A ZABORONA_V4 -d 5.45.192.0/18 -j ACCEPT -A ZABORONA_V4 -d 5.255.192.0/18 -j ACCEPT -A ZABORONA_V4 -d 37.9.64.0/18 -j ACCEPT -A ZABORONA_V4 -d 37.140.128.0/18 -j ACCEPT -A ZABORONA_V4 -d 77.75.152.0/21 -j ACCEPT -A ZABORONA_V4 -d 77.88.0.0/18 -j ACCEPT -A ZABORONA_V4 -d 84.201.128.0/18 -j ACCEPT -A ZABORONA_V4 -d 87.250.224.0/19 -j ACCEPT -A ZABORONA_V4 -d 93.158.128.0/18 -j ACCEPT -A ZABORONA_V4 -d 95.108.128.0/17 -j ACCEPT -A ZABORONA_V4 -d 100.43.64.0/19 -j ACCEPT -A ZABORONA_V4 -d 109.235.160.0/21 -j ACCEPT -A ZABORONA_V4 -d 130.193.32.0/19 -j ACCEPT -A ZABORONA_V4 -d 141.8.128.0/18 -j ACCEPT -A ZABORONA_V4 -d 178.154.128.0/17 -j ACCEPT -A ZABORONA_V4 -d 185.32.185.0/24 -j ACCEPT -A ZABORONA_V4 -d 185.32.186.0/24 -j ACCEPT -A ZABORONA_V4 -d 185.71.76.0/22 -j ACCEPT -A ZABORONA_V4 -d 199.21.96.0/22 -j ACCEPT -A ZABORONA_V4 -d 199.36.240.0/22 -j ACCEPT -A ZABORONA_V4 -d 213.180.192.0/19 -j ACCEPT -A ZABORONA_V4 -d 5.61.16.0/21 -j ACCEPT -A ZABORONA_V4 -d 5.61.232.0/21 -j ACCEPT -A ZABORONA_V4 -d 79.137.157.0/24 -j ACCEPT -A ZABORONA_V4 -d 79.137.183.0/24 -j ACCEPT -A ZABORONA_V4 -d 94.100.176.0/20 -j ACCEPT -A ZABORONA_V4 -d 95.163.32.0/19 -j ACCEPT -A ZABORONA_V4 -d 95.163.248.0/21 -j ACCEPT -A ZABORONA_V4 -d 128.140.168.0/21 -j ACCEPT -A ZABORONA_V4 -d 178.22.88.0/21 -j ACCEPT -A ZABORONA_V4 -d 178.237.16.0/20 -j ACCEPT -A ZABORONA_V4 -d 185.5.136.0/22 -j ACCEPT -A ZABORONA_V4 -d 185.16.148.0/22 -j ACCEPT -A ZABORONA_V4 -d 185.16.244.0/22 -j ACCEPT -A ZABORONA_V4 -d 188.93.56.0/21 -j ACCEPT -A ZABORONA_V4 -d 194.186.63.0/24 -j ACCEPT -A ZABORONA_V4 -d 195.211.20.0/22 -j ACCEPT -A ZABORONA_V4 -d 195.218.168.0/24 -j ACCEPT -A ZABORONA_V4 -d 217.20.144.0/20 -j ACCEPT -A ZABORONA_V4 -d 217.69.128.0/20 -j ACCEPT -A ZABORONA_V4 -d 195.211.128.0/22 -j ACCEPT -A ZABORONA_V4 -d 208.87.92.0/22 -j ACCEPT -A ZABORONA_V4 -d 77.74.176.0/22 -j ACCEPT -A ZABORONA_V4 -d 77.74.181.0/24 -j ACCEPT -A ZABORONA_V4 -d 77.74.183.0/24 -j ACCEPT -A ZABORONA_V4 -d 93.159.228.0/22 -j ACCEPT -A ZABORONA_V4 -d 185.54.220.0/23 -j ACCEPT -A ZABORONA_V4 -d 185.85.12.0/24 -j ACCEPT -A ZABORONA_V4 -d 185.85.14.0/23 -j ACCEPT -A ZABORONA_V4 -d 77.74.176.0/21 -j ACCEPT -A ZABORONA_V4 -d 91.103.64.0/21 -j ACCEPT -A ZABORONA_V4 -d 93.159.224.0/21 -j ACCEPT -A ZABORONA_V4 -d 8.8.8.8/32 -j ACCEPT -A ZABORONA_V4 -d 8.8.4.4/32 -j ACCEPT -A ZABORONA_V4 -d 74.82.42.42/32 -j ACCEPT -A ZABORONA_V4 -d 77.75.152.0/21 -j ACCEPT -A ZABORONA_V4 -d 185.71.72.0/21 -j ACCEPT -A ZABORONA_V4 -d 185.6.244.0/22 -j ACCEPT -A ZABORONA_V4 -d 185.30.176.0/22 -j ACCEPT -A ZABORONA_V4 -d 195.218.190.0/23 -j ACCEPT -A ZABORONA_V4 -d 195.88.252.0/23 -j ACCEPT -A ZABORONA_V4 -d 178.248.232.183/32 -j ACCEPT -A ZABORONA_V4 -d 178.248.233.94/32 -j ACCEPT COMMIT # Completed on Fri Jun 23 19:44:10 2017 # Generated by iptables-save v1.6.0 on Fri Jun 23 19:44:10 2017 *nat :PREROUTING ACCEPT [917:61256] :INPUT ACCEPT [430:26400] :OUTPUT ACCEPT [122:8320] :POSTROUTING ACCEPT [122:8320] -A PREROUTING -i eth0 -p tcp -m tcp --dport 1194 -m conntrack --ctstate NEW -m statistic --mode random --probability 0.50000000000 -j REDIRECT --to-ports 1195 -A POSTROUTING -s 192.168.224.0/22 -o eth0 -j MASQUERADE -A POSTROUTING -s 192.168.228.0/22 -o eth0 -j MASQUERADE COMMIT # Completed on Fri Jun 23 19:44:10 2017 


Balancing between demons fulfills this rule:

 -A PREROUTING -i eth0 -p tcp -m tcp --dport 1194 -m conntrack --ctstate NEW -m statistic --mode random --probability 0.50000000000 -j REDIRECT --to-ports 1195 

With a 50% chance of connecting to port 1194, they are redirected to port 1195. So, connections are evenly distributed between two OpenVPN processes. If there were more processes, it would be necessary to add additional rules to each process and change the probability of each rule to trigger.

Dnsmasq caching resolver


By default, dnsmasq accepts requests only from the local interface 127.0.0.1, so we resolve requests from VPN client addresses and set the size of the DNS cache.

/etc/dnsmasq.d/zaborona

 listen-address=127.0.0.1,192.168.224.1,192.168.228.1 cache-size=1000 

sysctl


The systctl.conf file with the kernel settings. It includes forwarding IP packets and other options for optimizing the system for a VPN server.

/etc/sysctl.conf
 #   ipv4  ipv6  net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 net.netfilter.nf_conntrack_max=65535 net.netfilter.nf_conntrack_generic_timeout = 600 net.netfilter.nf_conntrack_icmp_timeout = 30 net.netfilter.nf_conntrack_tcp_timeout_close = 10 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60 net.netfilter.nf_conntrack_tcp_timeout_established = 1800 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120 net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30 net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300 net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60 net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120 net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300 net.netfilter.nf_conntrack_udp_timeout = 60 net.netfilter.nf_conntrack_udp_timeout_stream = 180 net.ipv4.tcp_slow_start_after_idle = 0 net.ipv4.tcp_fastopen = 3 net.ipv4.tcp_rmem = 4096 262143 4194304 net.core.rmem_max = 4194304 net.core.rmem_default = 262143 net.ipv4.tcp_wmem = 4096 262143 4194304 net.core.wmem_max = 4194304 net.core.wmem_default = 262143 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 90 net.ipv4.tcp_keepalive_probes = 5 net.ipv4.tcp_congestion_control=bbr net.ipv6.conf.default.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0 net.ipv6.conf.default.accept_source_route = 0 net.ipv6.conf.all.use_tempaddr = 2 


Start services


After all services are configured, you can add their start to autoload.

Preliminarily, we increase the limit on the number of open file descriptors for OpenVPN processes, otherwise, with a large number of clients, we will exceed them and get the error Too many open files due to the large number of open sockets.

 systemctl edit openvpn@.service [Service] LimitNOFILE=8192 

 #   ,     . systemctl daemon-reload #         OpenVPN. systemctl enable --now openvpn@zaborona1 systemctl enable --now openvpn@zaborona2 #   dnsmasq  ferm.        . systemctl restart dnsmasq systemctl restart ferm 

To check the correctness of the settings, you can restart the server and make sure that all services are running.

Broken user OS


A significant proportion of users turned out to be outdated, broken OS. Very often, IPv6 support is broken in the system, for example, in many Windows 7 builds “from Vasyan with rutracker,” where automatic system updates are disabled. We started a Wiki on Github, to which users can add instructions on their own. It describes solutions to some common problems.

Here are the most typical cases of user environment curve:

Windows xp


Despite the fact that support for this OC ended EIGHT years ago, it is still used. It does not work a lot of modern programs, web browsers, as well as the latest version of OpenVPN 2.4. This topic is devoted to a separate article in our Wiki .

Windows 7


Many users have disabled automatic Windows updates. For some reason, in such a configuration on Windows 7 IPv6 often breaks. When connecting to the OpenVPN logs, this error appears:

  NETSH: C:\WINDOWS\system32\netsh.exe interface ipv6 set address interface=32 2a00:1838:30:7280::1149 store=active ERROR: netsh command failed: returned error code 1 

The cause of this anomaly could not be found out. But Microsoft has a special utility for this case - IPv6 Re-enabler . Download link below with the caption "Re-enable IPv6 on nontunnel interfaces and on IPv6 tunnel interfaces"

Android 4.4 and others


Each vendor breaks the VPN framework in Android in its own way. Many Android builds have problems that cannot be explained, for example, they often complain that when a VPN is connected, DNS queries are executed for a few seconds. In Android 4.4, the VPN is completely broken .

Microtik


RouterOS has support for OpenVPN. Unfortunately, it often does not work, than it works. An article devoted to the problem Mikrotik .

We refused to break our servers to make them compatible with the Mikrotik bugs, and suggested that users write bug reports to Miktorik. As a result, several fixes were released in the version of RouterOS 6.40rc24.

 What's new in 6.40rc24 (2017-Jun-20 09:38): *) ovpn - added support for topology subnet for IP mode; *) ovpn - added support for "push-continuation"; *) ovpn - fixed duplicate default gateway presence when receiving extra routes; 

Although according to users, the problem has not been completely solved. I advise all interested parties to continue sending bug reports to Mikrotik until the problem is completely resolved.

Source: https://habr.com/ru/post/331178/


All Articles