📜 ⬆️ ⬇️

VPN bridge to local network

I read the habrahabr.ru/blogs/linux/67209 topic and decided to post here my article, which was previously visible only in the closed corporate Wiki.

Usually, when creating a VPN, a point-to-point connection to a server is used, or an ethernet tunnel with a server is installed, at which a specific subnet is assigned to the tunnel. The VPN server at the same time performs the functions of routing and filtering traffic to access the local network through a VPN.

This article discusses a different approach to creating a virtual network in which remote systems are connected to an already existing local subnet, and the VPN server acts as an Ethernet gateway. Using this approach, we still have the ability to filter traffic based on the connection method (for example, use different filters for the local network and for remote users), but eliminates the need to configure routing, and remote machines are connected directly to the local network, they see resources that can even use broadcast packets without any additional configuration. Through such a VPN, they display all computers on the local Windows network, all available XDMCP servers for XDMCP broadcast, etc.
')


Network structure and server setup


Suppose there is an office with a local network, an IP subnet 192.168.168.0/24 is used . We will include home users in this local network, that is, they will have an address from the same subnet. You need to make sure that they do not have this subnet “at home” and that no systems in the local network have addresses from the range that we will allocate to remote users.

Bridge support in the core


For the operation of such technology, we need some kernel drivers. This is a universal driver for virtual network interfaces tun , and an ethernet bridge bridge driver. You can include them in the kernel, or assemble modules:

     -> Networking
       -> Networking support (NET [= y])
         -> Networking options
           <*> 802.1d Ethenet Bridging (BRIDGE [= y])
     -> Device Drivers
       -> Network device support (NETDEVICES [= y])
         <*> Universal TUN / TAP device driver support (TUN [= y])

If they are assembled by modules, you must either enable automatic loading of modules in the kernel, or load them yourself before establishing a VPN connection.

Software


The server will require OpenVPN and utilities to service the bridge. In Gentoo, they are going as follows:

   emerge net-misc / bridge-utils net-misc / openvpn


When using> = sys-apps / baselayout-1.12.6, this is enough; for older versions, you need special utilities to maintain tun / tap devices:

   emerge sys-apps / usermode-utilities


Network configuration


Let eth2 be the interface to which the local network is connected, with the assigned address 192.168.168.254. Its setup looked like this:

   config_eth2 = ("192.168.168.254/24")


Since he will participate in the bridge, he does not need to assign addresses. Also, the newly created virtual interface tap0 participates in the bridge, which is also not assigned any address. The address that was used by eth2 is now assigned to bridge br0:

   config_eth2 = ("null")
  
   tuntap_tap0 = "tap"
   config_tap0 = ("null")
  
   depend_br0 () {
     need net.tap0 net.eth2
   }
  
   # specify existing interfaces, combining them into a bridge
   bridge_br0 = "eth2 tap0"
   # either, you can dynamically connect the newly emerging interfaces there
   # bridge_add_eth2 = "br0"
  
   config_br0 = ("192.168.168.254/24")


You also need to create configuration scripts for the specified interfaces:

   cd /etc/init.d
   ln -s net.lo net.eth2
   ln -s net.lo net.tap0
   ln -s net.lo net.br0


It is enough to automatically load only the interface br0. depend_br0 () will automatically raise all the rest necessary for its work:

   rc-update add net.br0 default
   /etc/init.d/net.eth2 stop
   /etc/init.d/net.br0 start


Creating OpenVPN keys


We will authenticate clients using OpenSSL RSA keys. To simplify the process, we prepared several init scripts for us:

   cd / usr / share / openvpn / easy-rsa /


There is a vars file in which we will enter general values:

   nano vars


At the bottom of this file we fill in our variables:

   export KEY_COUNTRY = "RU"
   export KEY_PROVINCE = "Voronezh oblast"
   export KEY_CITY = "Boguchar"
   export KEY_ORG = "OrganiZationnAme"
   export KEY_EMAIL = "root@oza.ru"


Load the variables from this file and build the CA (Certificate Authority):

   source ./vars
   ./clean-all
   ./build-ca


Server key


To generate a server key with the name office, use the following command:

   ./build-key-server office


The question “Common Name” must be answered with the server name (in our case, office). Two questions at the end of “Sign the certificate? [y / n] "and" 1 out of 1 certificate requests certified, commit? [y / n] ”answer“ y ”.

If necessary, you can create additional server keys. For example, these may be backup access servers to increase system reliability. They are created by the same command, before it you need to run source ./vars.

Diffie-Hellman options

There is nothing extra to do here, but you have to wait.

   ./build-dh


This file is needed only on the server.

Customer keys


Each client must give his key. For a client named client, the key is created by the command

   ./build-key client


The question about the “Common Name” is answered with the name of the client (in this case, client). We answer the two questions at the end.

The generated keys and certificates are passed to clients via a secure channel. If necessary, you can create more keys with the same command. Before its launch, it is necessary to load the environment - run source ./vars.

Setup and start of the OpenVPN service


To start, use the following server configuration (/etc/openvpn/openvpn.conf file):

   # This port is recommended by IANA for OpenVPN.  You can move to another port, but secrecy does not increase - it is still the first thing to admit that it is OpenPVN.
   port 1194
  
   # OpenVPN can use tcp and udp as the transport protocol, udp is preferable
   proto udp
  
   # The virtual interface that we included in the bridge is definitely of type tap (you cannot emulate Ethernet via tun)
   dev tap0
  
   # Root CA self signed certificate
   ca /etc/openvpn/keys/ca.crt
  
   # Certificate and server secret key.  crt must have modes 644, key - 600
   cert /etc/openvpn/keys/office.crt
   key /etc/openvpn/keys/office.key
  
   # File with Diffie-Hellman parameters.  If you have a different key length, correct the name :)
   dh /etc/openvpn/keys/dh1024.pem
  
   # Distribute addresses to remote clients in this subnet, from this range (note that the subnet is ALL, as in the network card config, and the range is part of the subnet)
   server-bridge 192.168.168.254 255.255.255.0 192.168.168.128 192.168.168.159
  
   # Allow clients to interact with each other (otherwise, only with the server and the network segment "behind the bridge")
   client-to-client
  
   # This will allow the client to give the same address, which was issued earlier, if not busy
   ifconfig-pool-persist /etc/openvpn/ipp.txt
  
   # If you do not want to send the DNS server address also via DHCP, you can remove the following line
   push "dhcp-option DNS 192.168.168.254"
  
   # Compression
   comp-lzo
   # Maximum number of clients - it makes sense to make less or equal to the number of addresses in the server-bridge range
   max-clients 32

   # Details on these keys - in the documentation OpenVPN
   keepalive 10 120

   # Do not reinitialize tun and do not re-read the key during reconnections;  if we work not as root, but as nobody, then we will not be allowed, therefore either all these options or none of them
   user nobody
   group nobody
   persist-key
   persist tun

   # Every minute OpenVPN resets the current state here (list of clients, routes, etc.)
   status /tmp/openvpn-status.log
  
   # Very noisy log, normal operation - verb 2
   verb 6
   log-append /var/log/openvpn.log


The office.key key must have mode 600 (access only to the owner). The office.crt and dh1024.pem files have mode 644 .

Filter setting



Since we use a bridge, there are several features of packet filtering. For example, not all passing packets can be IPv4 at all. To configure the operation of the bridge in the kernel, there are several parameters:

The variables of this group are stored in the files of the / proc / sys / net / bridge / directory. They can also be configured in /etc/sysctl.conf, then they all get the prefix "net.brigde."


For filtering packets passing through the bridge, physdev matching is used, which distinguishes from which port of the bridge the packet should go and from which port. We include it in the core:

 -> Networking
   -> Networking support (NET [= y])
     -> Networking options
       -> Network packet filtering framework (Netfilter) (NETFILTER [= y])
         -> Core Netfilter Configuration
           -> Netfilter Xtable support (required for ip_tables) (NETFILTER_XTABLES [= y])
             -> "physdev" match support (NETFILTER_XT_MATCH_PHYSDEV [= y])


In addition, the kernel configuration must allow the transfer of packets for iptables filtering, i.e. bridge-nf-call-iptables = 1 and bridge-nf-call-ip6tables = 1 (if you use IPv6).
Then you can use, for example, the following rules for filtering:

   iptables -A FORWARD -p tcp --dport 22 -m physdev --physdev-in eth1 --physdev-out eth0 -j ACCEPT

In more detail about setup of filtering between ports of a post it is possible to read in the article Building bridges with Linux

If you do not want to make any distinction between LAN users and bridged VPN users, you can simply turn off these settings in the kernel (they are enabled by default):

   echo "net.bridge.bridge-nf-call-iptables = 0" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-ip6tables = 0" >> /etc/sysctl.conf 


Customers


On the client, you need to create an OpenVPN configuration file with the following content:

   client
   nobind
   dev tap
   proto udp
   # Where to connect.  You can specify several remote options - the first available server will be used.  If there are several A-records for server.example.net, they are randomly selected between them.
   remote server.example.net 1194
   # Never give up, try to connect endlessly.
   resolv-retry infinite
   # Either all options together or none of them
   persist-key
   persist tun
   user nobody
   group nogroup
   comp-lzo
   ns-cert-type server
   ca ca.crt
   cert client.crt
   key client.key


If the server is connected through several providers, you can increase the network resilience to failures. To do this, the client needs to register several remote options, one per server, in the order of “first preferred”.

The file names specified in the parameters ca, cert and key are files transferred via a secure channel. The permissions of the key file must be set to 600.

Linux


A universal tun / tap driver is required in the kernel, or as a module, but loaded.

Gentoo

When you install net-misc / openvpn, the /etc/init.d/openvpn script is created. This script runs openvpn with the /etc/openvpn/openvpn.conf configuration file. However, we can support several OpenVPN configurations at the same time, if we make symlinks like /etc/init.d/openvpn.network-name -> /etc/init.d/openvpn - each such script runs OpenVPN with the configuration file / etc / openvpn /network-name.conf.

Accordingly, we put the above config there, create a symlink and put the scripts in a subdirectory in / etc / openvpn /. In the config, write the full path to the key and certificates. Make sure that the file names in the config do not overlap, in order to avoid unpleasant effects!

The start and stop of the network are done through the management of the /etc/openvpn.network-name service.

Windows


The configuration file is placed in the “C: \ Program Files \ OpenVPN \ config \” directory with a name like “office.ovpn”, the rest of the files - keys and certificates are also placed there. If we put them in a subdirectory (for example, we want to use several virtual networks and they all provided files with the same name ca.crt), we specify the full paths to the files.

To start networks, you can either start the OpenVPN service (then all the * .ovpn configurations found in the config \ will be launched), or individually - click on the .ovpn file with the right button and select "Run OpenVPN with this configuration".

Possible problems


You can check the availability of the server, if it is running on TCP, by using ordinary telnet.

Windows


No free virtual TAP adapter

 Wed Dec 31 10:43:51 2008 TCP connection established with 88.83.201.253:1194 
 Wed Dec 31 10:43:51 2008 TCPv4_CLIENT link local: [undef] 
 Wed Dec 31 10:43:51 2008 TCPv4_CLIENT link remote: 88.83.201.253:1194 
 Wed Dec 31 10:44:51 2008 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity) 
 Wed Dec 31 10:44:51 2008 TLS Error: TLS handshake failed 
 Wed Dec 31 10:44:51 2008 Fatal TLS error (check_tls_errors_co), restarting 
 Wed Dec 31 10:44:51 2008 SIGUSR1 [soft, tls-error] received, process restarting 
 Wed Dec 31 10:44:56 2008 IMPORTANT: OpenVPN's port number is now 1194, based on the official port number assignment by IANA.  OpenVPN 2.0-beta16 and earlier used 5000 as the default port. 
 Wed Dec 31 10:44:56 2008 Re-using SSL / TLS context 
 Wed Dec 31 10:44:56 2008 LZO compression initialized 
 Wed Dec 31 10:44:56 2008 Attempting to establish TCP connection with 88.83.201.253:1194 
 Wed Dec 31 10:44:56 2008 TCP connection established with 88.83.201.253:1194 
 Wed Dec 31 10:44:56 2008 TCPv4_CLIENT link local: [undef] 
 Wed Dec 31 10:44:56 2008 TCPv4_CLIENT link remote: 88.83.201.253:1194 
 Wed Dec 31 10:45:11 2008 [office] Peer Connection Initiated with 88.83.201.253:1194 
 Wed Dec 31 10:45:13 2008 All TAP-Win32 adapters on this system are currently in use. 
 Wed Dec 31 10:45:13 2008 Exiting 
 Press any key to continue ...

The OpenVPN log shows that the client successfully joined the server, logged in, but could not bind the virtual network to the virtual adapter. Most likely, some other processes have already installed all the TAP-Win32 adapters in the system. It could be OpenVPN itself, which hung and did not give up the adapter.

It is treated by rebooting or finding out what processes and killing them could be.

Links


When writing this article, the following sources were used:
  1. Gentoo Linux Wiki - OpenVPN Server for Ethenet Bridging with Server Certificates (There is a copy of this page at: http://www.gentoo-wiki.info/HOWTO_OpenVPN_Server_for_Ethernet_Bridging_with_Server_Certificates . Thank you hexes for the link!)
  2. Gentoo Linux Wiki - HOWTO OpenVPN Linux Server Windows Client
  3. OpenVPN Documentation - HOWTO
  4. Network protocols encyclopedia - sysctl options for IP stack
  5. Building bridges with Linux


PS Some sources have fallen. I will not remove links, but it is worth bearing in mind.

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


All Articles