It happens that this installation was done on Fedora25 server with single NIC connected to a switch passing all VLANs as trunk. Then there will be NetworkManager and selinux stuff here.
I still not feel good with firewalld, then I am usually replacing it with iptables-services*rpm. Then here will be an iptables stuff also.
Prepare network, remove all unneccesary connections and define correct definitions. Hint: do this on console.
# nmcli connection delete "Wired connection 1" # nmcli connection add con-name INTERNET type vlan id 20 ifname INTERNET \ dev ens192 ipv4.method manual ipv4.addresses 15.15.15.15/24 ipv6.method ignore \ ipv4.gateway 15.15.15.1
I know that 15.15.15.15 belongs to HP, I will use it here only for example. Use your real IP address, mask and gateway information.
Configure firewall, make remote access possible. You can use this "SSH, MOSH backdoor access to your server" memo as reference.
It is important part to decide how to authenticate vpn connections. Thanks to PAM, you can choose almost any user authentication with OVPN. I've selected to use certificate based authentication without dealing with real users creation and password caring.
Read Making your own CA using openssl how to make your own CA and certificates. You can use any certificates, for example, get them from AD. You will need the following certificates before continue with OVPN configuration:
It is good idea to make your own CA only for OVPN usage, then you can fully control it.
Put all files at /etc/pki/CA/ (default place for CA on Fedora) or /etc/ssl/ (I likes this slightly more). Make all of them owned by root with 644 mode. The private unlocked key have to be 400 mode. Apply to them selinux policy:
# restorecon /etc/ssl/* # ls -lZ /etc/ssl/cacert.pem -rw-r--r--. 1 root root unconfined_u:object_r:cert_t:s0 424 Apr 23 15:51 /etc/ssl/cacert.pem
This type of configuration suits when OVPN server installed on office default gateway. Then there is no needs to add routes to remote addresses on every internal server.
Add internal interface and give it internal IP address:
# nmcli connection add con-name LAN type vlan id 30 ifname LAN \ dev ens192 ipv4.method manual ipv4.addresses 192.168.0.1/24 ipv6.method ignore
Configure NAT and firewall, this server will give internet access to internal LAN, not only VPN. Add additional services, if you want. Usually I adding caching DNS server, NTP server, DHCP server. Update firewall to allow desired protocols on relevant interfaces.
Copy example config file to /etc/openvpn/server/ and apply selinux policy:
# cp -v $(rpm -qd openvpn | grep /server.conf) /etc/openvpn/server/ # restorecon /etc/openvpn/server/server.conf # ls -lZ /etc/openvpn/server/server.conf -rw-r--r--. 1 root root unconfined_u:object_r:openvpn_etc_t:s0 621 Apr 23 16:24 /etc/openvpn/server/server.conf
Edit the example configuration file as you want. Mine resulting file looks as:
# egrep -v "^$|^#|^;" /etc/openvpn/server/server.conf port 11940 proto udp dev tun ca /etc/ssl/cacert.pem cert /etc/ssl/server.pem key /etc/ssl/unlocked_server_key.pem dh /etc/ssl/dh2048.pem tls-server server 100.99.1.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "route 192.168.0.0 255.255.255.0" keepalive 10 120 cipher AES-256-CBC compress lz4 push "compress lz4" user nobody group nobody persist-key persist-tun status openvpn-status.log verb 3 explicit-exit-notify 1
My OVPN server will listen UDP port 11940. Of course, you have to allow it in firewall ! But this is not enough. You should add it to selinux too:
# semanage port -a -t openvpn_port_t -p udp 11940
A DH file (/etc/ssl/dh2048.pem) should be created according to instructions in example file, a selinux policy should be applied to it:
# openssl dhparam -out /etc/ssl/dh2048.pem 2048 .. # restorecon /etc/ssl/dh2048.pem
Skip to "Starting server" part.
Bridge mode is most flexible VPN configuration. You should not play with any route tables, nor on server, neither on client side. A VPN client will get IP address from internal subnet and will work directly.
However, there is a lot of limitations in implementation. Bridge mode puts network interface in promiscous mode and if it is not allowed, the solution will not work. For example, this is not possible on any cloud provider. An existing solutions for VmWare guest to use promiscous mode for network interface caused many other problems to me, therefore I decide that bridge mode VPN do not suit for use in VmWare guest.
A LAN network interface that was simply defined in chapter above, should be configured in different way. Remove all internal interfaces (it was named LAN in previous example):
# nmcli connection delete LAN
Create bridge and assign IP to it, create VLAN interface then attach it to bridge:
# nmcli connection add con-name BR30 type bridge ifname BR30 \ ipv4.method manual ipv4.addresses 192.168.0.201/24 ipv6.method ignore # nmcli connection modify BR30 bridge.stp no # nmcli connection modify BR30 bridge.forward-delay 0 # nmcli connection add con-name V30 type vlan id 30 ifname V30 dev \ ens192 ipv4.method disabled ipv6.method ignore # nmcli connection modify V30 type bridge-slave master BR30
You have not have to assign any address at all. If you do not want OVPN server itself access or be accessible by this VLAN, then no IP required. But for the first time, it is good to assign any IP to check connectivity.
For some reason, nmcli does not write bridge parameters well in configuration file. Check it (/etc/sysconfig/network-scripts/ifcfg-BR30) and verify that:
STP=no DELAY=0
The virtual interface, created by OVPN will be attached to bridge using external script. You have to put this script to /etc/openvpn/scripts directory to fits selinux rules.
root:/etc/openvpn/scripts # cat add_to_BR.sh #!/bin/bash # # called by openvpn with parms: # cmd tap_dev tap_mtu link_mtu ifconfig_local_ip ifconfig_netmask [ init | restart ] BR=${BRIDGE:-BR30} echo " BR=$BR ; BRIDGE=$BRIDGE ;" | logger -t "add_to_BR.sh" /usr/bin/nmcli connection modify $BR bridge.forward-delay 0 /usr/sbin/ip link set $1 master $BR up root:/etc/openvpn/scripts # ls -lZ add_to_BR.sh -rwxr-xr-x. 1 root root unconfined_u:object_r:openvpn_unconfined_script_exec_t:s0 357 May 10 22:49 add_to_BR.sh
Make script executable and run "restorecon" on it.
It's time to write configuration file:
root:/etc/openvpn/server # cat bridgevpn.conf mode server tls-server # to change: max-clients 5 ifconfig-pool 192.168.0.241 192.168.0.249 255.255.255.0 port 11940 setenv BRIDGE BR30 verify-client-cert require ca /etc/ssl/cacert.pem cert /etc/ssl/server.pem key /etc/ssl/unlocked_server_key.pem dh /etc/ssl/dh2048.pem dev tap syslog verb 2 compress lz4 push "compress lz4" # bind address: local 15.15.15.15 proto udp script-security 2 # set using setenv var BRIDGE passed to script up /etc/openvpn/scripts/add_to_BR.sh user openvpn group openvpn
Do not forget to run "restorecon" on configuration file. The UDP listening port should be opened in firewall and enabled in selinux:
# semanage port -a -t openvpn_port_t -p udp 11940
Openvpn services are autogenerated services based on configuration files you've been created. Therefore, ask systemd to rescan files:
# systemctl daemon-reload # systemctl list-units | grep openvpnNow you can start it as usual.
Now you will need a user's certificate, we talked about in authentication chapter. Create user.ovpn using text editor:
client dev tun # <- use this for routed dev tap # <- use this for bridged proto udp remote 15.15.15.15 11940 persist-key cipher AES-256-CBC # <- should match server's definitions verb 2 compress lz4 auth-nocache <ca> -----BEGIN CERTIFICATE----- Copy-Paste here CA Certificate -----END CERTIFICATE----- </ca> <cert> -----BEGIN CERTIFICATE----- Copy-Paste here User Certificate -----END CERTIFICATE----- </cert> <key> -----BEGIN ENCRYPTED PRIVATE KEY----- Copy-Paste here User's encrypted key -----END ENCRYPTED PRIVATE KEY----- </key>