How to Install and configure VPN-server (OpenVPN) in CentOS/RHEL 7

Содержание


OpenVPN is a free implementation of the technology of virtual private network (VPN) with open source software to create encrypted channels, point-to-point or server-to-client between computers. It allows you to establish connections between computers behind a NAT firewall, without having to change their settings.

 

Connect the EPEL repository

To install OpenVPN – connect the EPEL repository (Extra Packages for Enterprise Linux):

$ yum -y install epel-release

 

Install OpenVPN

$ yum -y install openvpn

 

Setting up OpenVPN in simplest way

First of all bring OpenVPN to working condition, and then add the “features”. We need the private key, the certificate and the CA certificate. How to create them, you can read in this article.

$ cp /usr/share/doc/openvpn-*/sample/sample-config-files/server.conf /etc/openvpn
$ chcon -u system_u /etc/openvpn/server.conf
$ nano -w /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca /etc/pki/tls/certs/sub.class1.server.ca.pem
cert /etc/pki/tls/certs/vpn.example.com.crt
key /etc/pki/tls/private/vpn.example.com.key
dh dh2048.pem
server 10.8.0.0 255.255.255.0
push "route 10.8.0.0 255.255.255.0"
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
# Username and Password authentication.
client-cert-not-required
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn

$ nano -w /etc/pam.d/openvpn
auth	required	pam_unix.so shadow nodelay
account	required	pam_unix.so
$ chcon -u system_u /etc/pam.d/openvpn
$ touch /var/log/openvpn-status.log
$ restorecon -v /var/log/openvpn-status.log

$ openssl dhparam -out /etc/openvpn/dh2048.pem 2048
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
...

Some OpenVPN clients do not know how to work over UDP, as for example the OpenVPN client to MikroTik routers, in this case, you want to write a proto udp instead of a string proto tcp. Authorization in the configuration file we included for users. That is to connect the client’s preferences, you will need to specify the username and password of an existing user.
 

Setting up the firewall

$ firewall-cmd --permanent --zone=public --add-service=openvpn
$ firewall-cmd --permanent --zone=public --add-port=1194/tcp
$ firewall-cmd --reload

The first line will connect to OpenVPN server via UDP, TCP is the second.
 

Trial run OpenVPN server

Now, let’s run the OpenVPN server and try to connect to it:

$ cd /etc/openvpn
$ openvpn server.conf
Sat Nov 22 22:00:23 2014 OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Feb 14 2014
Sat Nov 22 22:00:23 2014 PLUGIN_INIT: POST /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so '[/usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so] [openvpn]' intercepted=PLUGIN_AUTH_USER_PASS_VERIFY 
Sat Nov 22 22:00:23 2014 Diffie-Hellman initialized with 2048 bit key
Sat Nov 22 22:00:23 2014 WARNING: POTENTIALLY DANGEROUS OPTION --client-cert-not-required may accept clients which do not present a certificate
Sat Nov 22 22:00:23 2014 Socket Buffers: R=[212992->131072] S=[212992->131072]
Sat Nov 22 22:00:23 2014 ROUTE_GATEWAY 192.168.0.1/255.255.255.0 IFACE=eth0 HWADDR=00:16:3e:00:00:dc
Sat Nov 22 22:00:23 2014 TUN/TAP device tun0 opened
Sat Nov 22 22:00:23 2014 TUN/TAP TX queue length set to 100
Sat Nov 22 22:00:23 2014 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Sat Nov 22 22:00:23 2014 /usr/sbin/ip link set dev tun0 up mtu 1500
Sat Nov 22 22:00:23 2014 /usr/sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
Sat Nov 22 22:00:23 2014 /usr/sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Sat Nov 22 22:00:23 2014 GID set to nobody
Sat Nov 22 22:00:23 2014 UID set to nobody
Sat Nov 22 22:00:23 2014 UDPv4 link local (bound): [undef]
Sat Nov 22 22:00:23 2014 UDPv4 link remote: [undef]
Sat Nov 22 22:00:23 2014 MULTI: multi_init called, r=256 v=256
Sat Nov 22 22:00:23 2014 IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Sat Nov 22 22:00:23 2014 IFCONFIG POOL LIST
Sat Nov 22 22:00:23 2014 Initialization Sequence Completed

 

OpenVPN client on CentOS 7

$ cp /usr/share/doc/openvpn-*/sample/sample-config-files/client.conf /etc/openvpn
$ chcon -u system_u /etc/openvpn/client.conf
$ nano -w /etc/openvpn/client.conf
client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
;user nobody
;group nobody
persist-key
persist-tun
status /var/log/openvpn-status.log
ca /etc/pki/tls/certs/ca-bundle.crt
;cert client.crt
;key client.key
;ns-cert-type server
comp-lzo
verb 3
auth-user-pass credentials.txt

$ nano -w /etc/openvpn/credentials.txt
username
password
$ chmod 0600 /etc/openvpn/credentials.txt
$ chcon -u system_u /etc/openvpn/credentials.txt
$ touch /var/log/openvpn-status.log
$ restorecon -v /var/log/openvpn-status.log
$ cd /etc/openvpn
$ openvpn client.conf
Sat Nov 22 22:57:37 2014 OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Feb 14 2014
Sat Nov 22 22:57:37 2014 WARNING: No server certificate verification method has been enabled.  See http://openvpn.net/howto.html#mitm for more info.
Sat Nov 22 22:57:37 2014 Socket Buffers: R=[212992->131072] S=[212992->131072]
Sat Nov 22 22:57:37 2014 NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
Sat Nov 22 22:57:37 2014 UDPv4 link local: [undef]
Sat Nov 22 22:57:37 2014 UDPv4 link remote: [AF_INET]192.168.0.1:1194
Sat Nov 22 22:57:38 2014 TLS: Initial packet from [AF_INET]192.168.0.1:1194, sid=0dc4cf7c d2ea1086
Sat Nov 22 22:57:38 2014 VERIFY OK: depth=2, C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
Sat Nov 22 22:57:38 2014 VERIFY OK: depth=1, C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Class 1 Primary Intermediate Server CA
Sat Nov 22 22:57:38 2014 VERIFY OK: depth=0, C=RU, CN=vpn.example.com, emailAddress=hostmaster@example.com
Sat Nov 22 22:57:38 2014 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Nov 22 22:57:38 2014 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Nov 22 22:57:38 2014 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Nov 22 22:57:38 2014 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Nov 22 22:57:38 2014 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 2048 bit RSA
Sat Nov 22 22:57:38 2014 [vpn.example.com] Peer Connection Initiated with [AF_INET]192.168.0.1:1194
Sat Nov 22 22:57:40 2014 SENT CONTROL [vpn.example.com]: 'PUSH_REQUEST' (status=1)
Sat Nov 22 22:57:40 2014 PUSH: Received control message: 'PUSH_REPLY,route 10.8.0.0 255.255.255.0,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.14 10.8.0.13'
Sat Nov 22 22:57:40 2014 OPTIONS IMPORT: timers and/or timeouts modified
Sat Nov 22 22:57:40 2014 OPTIONS IMPORT: --ifconfig/up options modified
Sat Nov 22 22:57:40 2014 OPTIONS IMPORT: route options modified
Sat Nov 22 22:57:40 2014 ROUTE_GATEWAY 192.168.255.1/255.255.255.0 IFACE=ens160 HWADDR=00:50:56:02:02:01
Sat Nov 22 22:57:40 2014 TUN/TAP device tun0 opened
Sat Nov 22 22:57:40 2014 TUN/TAP TX queue length set to 100
Sat Nov 22 22:57:40 2014 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Sat Nov 22 22:57:40 2014 /usr/sbin/ip link set dev tun0 up mtu 1500
Sat Nov 22 22:57:40 2014 /usr/sbin/ip addr add dev tun0 local 10.8.0.14 peer 10.8.0.13
Sat Nov 22 22:57:40 2014 /usr/sbin/ip route add 10.8.0.0/24 via 10.8.0.13
Sat Nov 22 22:57:40 2014 /usr/sbin/ip route add 10.8.0.1/32 via 10.8.0.13
Sat Nov 22 22:57:40 2014 Initialization Sequence Completed

In the client config I have a string: ca /etc/pki/tls/certs/ca-bundle.crt it means to validate the server SSL certificate I use system trusted root certificates. If you have a server is OpenVPN – a self-signed certificate, then the client side, you must copy the CA certificate and specify it in the configuration file of the client, in the ca.
And the string “user” nobody “and group” nobody “we you commented out, because if they leave, then after the VPN connection is established, the client OpenVPN does not have enough rights to” get rid of “. He will leave the DNS server and routes changed.

After a successful connection, log on the server we have seen the following:

Sat Nov 22 23:02:52 2014 192.168.255.100:45852 TLS: Initial packet from [AF_INET]192.168.255.100:45852, sid=ea90195b 352f0a5b
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 PLUGIN_CALL: POST /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so/PLUGIN_AUTH_USER_PASS_VERIFY status=0
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 TLS: Username/Password authentication succeeded for username 'root' 
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 [] Peer Connection Initiated with [AF_INET]192.168.255.100:45852
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 MULTI_sva: pool returned IPv4=10.8.0.22, IPv6=(Not enabled)
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 MULTI: Learn: 10.8.0.22 -> 192.168.0.100:45852
Sat Nov 22 23:02:53 2014 192.168.255.100:45852 MULTI: primary virtual IP for 192.168.0.100:45852: 10.8.0.22
Sat Nov 22 23:02:55 2014 192.168.255.100:45852 PUSH: Received control message: 'PUSH_REQUEST'
Sat Nov 22 23:02:55 2014 192.168.255.100:45852 send_push_reply(): safe_cap=940
Sat Nov 22 23:02:55 2014 192.168.255.100:45852 SENT CONTROL [UNDEF]: 'PUSH_REPLY,route 10.8.0.0 255.255.255.0,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.22 10.8.0.21' (status=1)

Keep in mind, if the client’s config register string auth-nocache authorization by login and password, then login with the password rekonnekta can be read from a file, and you will need to enter in the console.
The client connected to the server, the client-side try to ping the IP address of the server:

$ ping 10.8.0.1 -c 4
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=55.1 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=56.3 ms
64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=62.0 ms
64 bytes from 10.8.0.1: icmp_seq=4 ttl=64 time=58.2 ms

--- 10.8.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 55.178/57.961/62.078/2.622 ms

As we can see, everything is pinged. Then configure both client and server are correct. But it is better not to use settings, such as on the client side, in a file, we have system user name and password in clear text. This can be used for a short time, only during initial configuration.
 

Configuring masquerading on the server side

To clients in the world through our VPN server-side, we must configure the masquerading and forwarding the client’s default route on (keep in mind, it is desirable to send a DNS server). To do this, do the following:

$ firewall-cmd --permanent --zone=trusted --add-interface=tun0
$ firewall-cmd --permanent --zone=trusted --add-masquerade
$ firewall-cmd --reload
$ nano -w /etc/openvpn/server.conf
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 10.8.0.1"

$ cd /etc/openvpn
$ openvpn server.conf

Keep in mind, what linux client with default settings does not modify their DNS server when connecting to the OpenVPN to change it, do the following on the client:

$ mkdir /etc/openvpn/scripts/
$ restorecon -v /etc/openvpn/scripts/
$ cp -p /usr/share/doc/openvpn-*/contrib/pull-resolv-conf/client.{up,down} /etc/openvpn/scripts/
$ chmod a+x /etc/openvpn/scripts/client.{up,down}
$ restorecon -v /etc/openvpn/scripts/client.{up,down}
$ nano -w /etc/openvpn/client.conf
up /etc/openvpn/scripts/client.up
down /etc/openvpn/scripts/client.down
script-security 2

But, just keep in mind that if you are pushing the external address of the OpenVPN server as DNS, appeal to it will go with the external address of the client. But if pushing the internal IP address of the OpenVPN server, there might be a problem that the local DNS server is listening to port 53 on this address. If an address appears in the system after the local DNS server is already running, you must run the systemctl reload named-chroot.service to the DNS server binded to appear in the IP system. To automate this, do the following on the server:

$ nano -w /etc/openvpn/scripts/named-reload.sh
#!/bin/sh
/usr/bin/systemctl reload named-chroot.service

$ chmod a+x /etc/openvpn/scripts/named-reload.sh
$ restorecon -v /etc/openvpn/scripts/named-reload.sh
$ nano -w /etc/openvpn/server.conf
;user nobody
;group nobody
up /etc/openvpn/scripts/named-reload.sh                    
down /etc/openvpn/scripts/named-reload.sh                    
script-security 2

 

Configure auto-start OpenVPN

That’s how we run the OpenVPN is good only for the tests. Prepare to launch OpenVPN:

$ systemctl enable openvpn@server.service
ln -s '/usr/lib/systemd/system/openvpn@.service' '/etc/systemd/system/multi-user.target.wants/openvpn@server.service'

Handle server means that you use the configuration file with the name server.conf to the /etc/openvpn directory, in the case of a client, you need to run the following command:

$ systemctl enable openvpn@client.service
ln -s '/usr/lib/systemd/system/openvpn@.service' '/etc/systemd/system/multi-user.target.wants/openvpn@client.service'

In general, you can run multiple OpenVPN services on one machine, the main thing that had different configuration files, and to not use the same ports and IP addresses.
Let’s try to run the OpenVPN server:

$ systemctl start openvpn@server.service
Job for openvpn@server.service failed. See 'systemctl status openvpn@server.service' and 'journalctl -xn' for details.

As you can see, the service does not start. Let’s see why:

$ systemctl status openvpn@server.service
openvpn@server.service - OpenVPN Robust And Highly Flexible Tunneling Application On server
   Loaded: loaded (/usr/lib/systemd/system/openvpn@.service; enabled)
   Active: failed (Result: exit-code) since Sun 2014-11-23 02:00:54 MSK; 8s ago
  Process: 20948 ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/%i.pid --cd /etc/openvpn/ --config %i.conf (code=exited, status=1/FAILURE)

Nov 23 02:00:54 example.com openvpn[20948]: do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Nov 23 02:00:54 example.com openvpn[20948]: /usr/sbin/ip link set dev tun0 up mtu 1500
Nov 23 02:00:54 example.com openvpn[20948]: /usr/sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
Nov 23 02:00:54 example.com openvpn[20948]: /etc/openvpn/scripts/named-reload.sh tun0 1500 1542 10.8.0.1 10.8.0.2 init
Nov 23 02:00:54 example.com openvpn[20948]: /etc/openvpn/scripts/named-reload.sh: line 2: /usr/bin/systemctl: Permission denied
Nov 23 02:00:54 example.com openvpn[20948]: WARNING: Failed running command (--up/--down): external program exited with error status: 126
Nov 23 02:00:54 example.com openvpn[20948]: Exiting due to fatal error
Nov 23 02:00:54 example.com systemd[1]: openvpn@server.service: control process exited, code=exited status=1
Nov 23 02:00:54 example.com systemd[1]: Failed to start OpenVPN Robust And Highly Flexible Tunneling Application On server.
Nov 23 02:00:54 example.com systemd[1]: Unit openvpn@server.service entered failed state.

Okey, interesting. Take a look at the SELinux log:

$ cat /var/log/audit/audit.log | grep AVC
type=AVC msg=audit(1416697254.641:18838): avc:  denied  { execute } for  pid=20955 comm="named-reload.sh" name="systemctl" dev="dm-1" ino=33597892 scontext=system_u:system_r:openvpn_t:s0 tcontext=system_u:object_r:systemd_systemctl_exec_t:s0 tclass=file
type=AVC msg=audit(1416697254.641:18839): avc:  denied  { getattr } for  pid=20955 comm="named-reload.sh" path="/usr/bin/systemctl" dev="dm-1" ino=33597892 scontext=system_u:system_r:openvpn_t:s0 tcontext=system_u:object_r:systemd_systemctl_exec_t:s0 tclass=file
type=AVC msg=audit(1416697254.641:18840): avc:  denied  { getattr } for  pid=20955 comm="named-reload.sh" path="/usr/bin/systemctl" dev="dm-1" ino=33597892 scontext=system_u:system_r:openvpn_t:s0 tcontext=system_u:object_r:systemd_systemctl_exec_t:s0 tclass=file

Cool. Lack of OpenVPN’a to run the script. Give him these rights and try to start the service again:

$ setsebool -P openvpn_run_unconfined on
$ systemctl start openvpn@server.service
$ systemctl status openvpn@server.service
openvpn@server.service - OpenVPN Robust And Highly Flexible Tunneling Application On server
   Loaded: loaded (/usr/lib/systemd/system/openvpn@.service; enabled)
   Active: active (running) since Sun 2014-11-23 03:44:12 MSK; 3s ago
  Process: 22125 ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/%i.pid --cd /etc/openvpn/ --config %i.conf (code=exited, status=0/SUCCESS)
 Main PID: 22140 (openvpn)
   CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
           ├─22126 /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/server.pid --cd /etc/openvpn/ --config server.conf
           └─22140 /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/server.pid --cd /etc/openvpn/ --config server.conf

Nov 23 03:44:12 example.com openvpn[22125]: /etc/openvpn/scripts/named-reload.sh tun0 1500 1542 10.8.0.1 10.8.0.2 init
Nov 23 03:44:12 example.com openvpn[22125]: /usr/sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Nov 23 03:44:12 example.com openvpn[22140]: UDPv4 link local (bound): [undef]
Nov 23 03:44:12 example.com openvpn[22140]: UDPv4 link remote: [undef]
Nov 23 03:44:12 example.com openvpn[22140]: MULTI: multi_init called, r=256 v=256
Nov 23 03:44:12 example.com openvpn[22140]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Nov 23 03:44:12 example.com openvpn[22140]: IFCONFIG POOL LIST
Nov 23 03:44:12 example.com openvpn[22140]: Initialization Sequence Completed
Nov 23 03:44:12 example.com systemd[1]: Started OpenVPN Robust And Highly Flexible Tunneling Application On server.

Now the service has started successfully.
 
A little later I’ll enhance the post describing the work of OpenVPN with certificates.

Comments

  1. chcon -v –type=openvpn_exec_t /etc/openvpn/scripts/named-reload.sh

    So you dont have to let openvpn run unconfined.

  2. josefchmelJosef
    21.12.2015 - 17:50

    Thank you for great article!

  3. On CentOs7,
    chcon -v –type=openvpn_exec_t /etc/openvpn/scripts/named-reload.sh wont work
    need to modify it to
    chcon -vt openvpn_exec_t /etc/openvpn/scripts/named-reload.sh

  4. I have done everything in this article, but i am able to connect from internal network but cant connect from outside network, and also I dont have internet connectivity once i connect through VPN.

    Any help will be appriciated,

    Thanks in advance

    • $ firewall-cmd –permanent –zone=trusted –add-interface=tun0
      $ firewall-cmd –permanent –zone=trusted –add-masquerade
      $ firewall-cmd –reload
      May be this commands will help?

  5. Hello Wakko,

    Thanks for the quick reply,

    I have added the firewall and masquerade and also port forwarding on sysctl.conf.
    There is no effect, still no internet on the client side

    [root@centos7server-s3 ~]# firewall-cmd –zone=public –list-all
    public (default, active)
    interfaces: eth0 eth1
    sources:
    services: dhcpv6-client openvpn ssh
    ports: 1194/tcp
    masquerade: no
    forward-ports:
    icmp-blocks:
    rich rules:

    [root@centos7server-s3 ~]# firewall-cmd –zone=trusted –list-all
    trusted (active)
    interfaces: tun0
    sources:
    services:
    ports:
    masquerade: yes
    forward-ports:
    icmp-blocks:
    rich rules:

    [root@centos7server-s3 ~]# sysctl -p
    net.ipv4.ip_forward = 1

  6. Hi there,

    I have my servers at location-A(different country), and I want to configure the server here

    I want to access the vm’s under the server at Location-A (different country) from Location-B (different country)

    I was configuring the Openvpn to access my servers at location-A from Location-B

    Any help or suggestion will be very helpful.

    Thanks in advance

Leave a Reply