Estimated reading time: 8 minutes
What is OpenVPN
Introduction
OpenVPN is an open-source Virtual Private Network (VPN) solution. It is a VPN solution based on the SSL/TLS protocol, which establishes an encrypted tunnel connection to implement remote access, secure communication, and privacy protection, preventing unauthorized intruders from stealing or peeking into the communication content. It is widely used in internal corporate networks, remote work, cross-regional connections, and personal privacy protection. For individuals or small businesses, OpenVPN is a simple, easy-to-use, and secure VPN solution. Next, we will specifically introduce the installation and configuration of OpenVPN.
Working Mechanism
The working principle and data encryption of OpenVPN are basically similar to HTTPS:
-
Connection Establishment:
OpenVPN usually uses certificates or pre-shared keys for authentication to ensure that the parties connecting are legitimate. Once authentication is successful, the parties can begin to establish a secure communication tunnel. -
Tunnel Establishment:
OpenVPN uses the SSL/TLS protocol to establish a secure communication tunnel. It can run over TCP or UDP protocols, usually using UDP to provide better performance. Once the connection is established, OpenVPN negotiates keys through TLS and ensures the integrity and security of communication. -
Data Transfer:
Once the tunnel is established, all data within the tunnel will be encrypted. OpenVPN uses advanced encryption algorithms such as AES (Advanced Encryption Standard) to encrypt data. Only the recipient with the correct key can decrypt and read the data. OpenVPN also uses Message Authentication Codes (MACs) to verify the integrity of the data to prevent tampering.
OpenVPN Deployment
The following steps are to deploy OpenVPN on CentOS 7, using certificates for authentication.
Install OpenVPN
- Install openvpn
yum install openvpn
After installation, the default path is
/etc/openvpn
. Modify using the sample configuration provided. Check OpenVPN-related files withrpm -ql openvpn
, usually under/usr/share/doc/openvpn-2.4.11
directory, copy theserver.conf
configuration file from the sample directory to /etc/openvpn.
Install easy-rsa and Self-signed Certificates
-
Install easy-rsa
yum install easy-rsa
Similarly, find the example configuration vars.sample and copy it to
/etc/openvpn/easy-rsa/vars
, and modify the vars file. Copy easyrsa and the configuration folder x509-types to/etc/openvpn/easy-rsa/vars
for convenient configuration. -
Configure Certificates
vim vars
In the example, configurations are commented out; you can directly move to the end to add configurations:set_var EASYRSA_REQ_COUNTRY "Country Code" # e.g., CN set_var EASYRSA_REQ_PROVINCE "Province Name" # e.g., Sichuan set_var EASYRSA_REQ_CITY "City Name" # e.g., Chengdu set_var EASYRSA_REQ_ORG "Organization Name" # Any name, company or individual set_var EASYRSA_REQ_EMAIL "email@example.com" # Any email set_var EASYRSA_REQ_OU "OpenVPN Server" # Any name, company or individual set_var EASYRSA_KEY_SIZE 2048 # Default 2048, recommended 1024 or higher set_var EASYRSA_ALGO rsa # Default rsa, can choose ecdsa, etc. set_var EASYRSA_CA_EXPIRE 36500 # Expiry time, in days, set according to actual needs set_var EASYRSA_CERT_EXPIRE 36500
-
Generate Self-signed Certificates
Navigate tocd /etc/openvpn/easy-rsa/
directory, run easyrsa to create a CA self-signed certificate:./easyrsa init-pki ./easyrsa build-ca # Enter password (needed for signing later), fill in organization name ./easyrsa build-server-full server nopass # Generate server certificate ./easyrsa gen-dh # Generate pem openvpn --genkey --secret ta.key # Generate key
-
Copy relevant certificates to the OpenVPN configuration directory for easy management, or just leave them in the current directory (the subsequent configuration will need file paths):
cp pki/ca.crt /etc/openvpn/server/
cp pki/private/server.key /etc/openvpn/server/
cp pki/issued/server.crt /etc/openvpn/server/
cp pki/dh.pem /etc/openvpn/server/
cp ta.key /etc/openvpn/server/
Configure OpenVPN
- Configure the OpenVPN file
vim /etc/openvpn/server.conf
, where;
and#
both serve as comment symbols, then configure according to your needs
:
local 0.0.0.0 # Change listening address
port 8443 # Change listening port, need to configure firewall to allow
;proto tcp # Choose protocol, tcp or udp, as needed
proto udp
dev tun # Network device mode, tun for virtual network card, tap requires bridging mode
# Certificate information configuration, use the path where certificates were placed earlier
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
tls-auth /etc/openvpn/server/ta.key 0
server 10.0.0.0 255.255.255.0 # Specify the subnet used by vpn
ifconfig-pool-persist ipp.txt # Specify client IP binding as needed
push "route 172.16.1.0 255.255.255.0" # Push the internal network route needed for VPN access
push "dhcp-option DNS 8.8.8.8" # Push VPN's DNS to ensure correct internal network resolution
# Enable logging, helpful for initial debugging, log level can be set higher for detailed output during debugging
status openvpn-status.log
log-append openvpn.log
verb 4
explicit-exit-notify 1 # Notify when server disconnects, facilitating client reconnection
# Certificate verification, if managing client certificates, needs to be enabled
crl-verify /etc/openvpn/server/crl.pem
-
Set up OpenVPN environment and boot startup
Copy the OpenVPN service to the system environment
cp /usr/lib/systemd/system/openvpn-server@.service /usr/lib/systemd/system/openvpn@server.service
server as the name of the server.conf configuration file, if it's changed, modify accordingly
Edit service configurationvim /usr/lib/systemd/system/openvpn@server.service
ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --config %i.conf
You can replace with the
%i
with the configuration file name, and make sure all the paths are exist and correct.
After completion, add to startup and start the service:systemctl enable openvpn@server.service systemctl start openvpn@server.service
-
Firewall and System Configuration
The server iptables needs to allow the source address and port that needs access:
The access path can be understood as: client --> vpn --> backend server
Therefore, the VPN server needs to configure forwarding requests from tun to the server's network card eth0 to access internal resources
iptables addition:iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
firewalld addition (add tun0 and eth0 to the zone):
firewall-cmd --permanent --add-interface=tun0 --zone=public firewall-cmd --permanent --add-masquerade --zone=public firewall-cmd --reload
When configuring NAT, don't forget to enable kernel forwarding, otherwise, it cannot forward requests:
cat /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/ip_forward
-
Some Possible Issues
a. After starting, the CLI continuously prompts the following message
Broadcast message from root@Docker-test (Mon 2022-01-24 11:28:25 CST):
Password entry required for 'Enter Private Key Password:' (PID 14218).
Please enter password with the systemd-tty-ask-password-agent tool!
If this occurs, runsystemd-tty-ask-password-agent
and then enter the password, or modify the OpenVPN service configuration to add:--askpass /etc/openvpn/server/passwd
Write the private key password in the
passwd
file, then restart the OpenVPN service
b. If starting the tun network card fails, check the openvpn log for a message like
TCP/UDP: Socket bind failed on local address [AF_INET]172.18.5.77:13579: Permission denied (errno=13) Exiting due to fatal error
Disable selinux, setenforce 0
and modify the configuration vim /etc/selinux/config
to disabled
Note: Other issues can be investigated through the
openvpn log
.
Client Management
For businesses, there may be new hires or resignations, so certificate management is necessary.
- Client Certificate Creation
Return to the easyrsa directory to create the client key
./easyrsa build-client-full username
During this, first create a client password, then enter the server CA password for signing.
After the issuance is complete, export the server ca.crt, **
ta.key, and client certificate and key** to the client for use. If unsure of the storage path after generation, use ./easyrsa show-cert username
or ./easyrsa show-ca
to check.
- Revoke User Certificate
Use easyrsa to revoke the user certificate:./easyrsa revoke username
Enter the server CA password for confirmation, then generate an updated crl file:
./easyrsa gen-crl
After entering the CA password for confirmation, copy the generated crl.pem file to the OpenVPN configuration file directory:
cp keys/crl.pem /etc/openvpn/server/crl.pem # Match the path with OpenVPN configuration
Restart the service after completion, subsequent revocations need to update the crl.pem and overwrite the original file to take effect.
Client Configuration
The client configuration file is typically a client.ovpn
file. Copy the server-generated certificates and keys to the client configuration file directory, then replace ca
, cert
, and key
in the configuration file with the server-generated certificates and keys. Modify the server IP address and port, and configure the method and protocol used, some examples are as follows:
client
dev tun
proto udp
remote 1.1.1.1 8443 # Server IP and listening port
resolv-retry infinite
nobind
# Certificate configuration
ca ca.crt
cert client.crt
key client.key
tls-auth ta.key 1
Other Configurations
If you want to set up port mapping on the OpenVPN server side, such as mapping UDP ports 50000-60000 to port 8443, then the server side won't need to change its port, and clients can connect to the VPN by modifying their port. You can use iptables for this setup. Here are the specific steps:
-
Set iptables rules for port mapping:
You need to add a rule that redirects all traffic arriving at your server's UDP ports 50000 to 60000 to port 8443. You can use the following command:iptables -t nat -A PREROUTING -p udp --dport 50000:60000 -j REDIRECT --to-ports 8443 iptables -A INPUT -p udp --dport 50000:60000 -j ACCEPT
-
Client Configuration:
Clients need to set the OpenVPN connection port to one within the 50000 to 60000 range. In the client's configuration file (usuallyclient.ovpn
), modify theremote
directive as follows:remote your-server-ip 50000 udp
Replace
50000
with any port between 50000 and 60000, as per actual circumstances.
After completing the above steps, clients will be able to connect to the OpenVPN server by accessing any UDP port between 50000 and 60000, thus hiding the server's real port.
This article is based on previous experiences and may contain outdated content. If you encounter any issues, feel free to leave a message and ask questions.