Setting Up OpenVPN Service on Ubuntu
This article introduces how to set up OpenVPN service on an Ubuntu system.
First, let me describe my local environment:
- Operating System: Ubuntu-18.04-LTS
- Internal IP: 192.168.1.110
- External IP: 14.153.76.91
- OpenVPN Version: 2.4.4
Installing OpenVPN
First, install some dependencies, including openssl and lzo, where lzo is used to compress communication data to speed up transmission.
sudo apt-get install openssl libssl-dev
sudo apt-get install lzop
Install OpenVPN and easy-rsa
sudo apt-get install openvpn
sudo apt-get install easy-rsa
Creating Certificates and Keys
After installing easy-rsa
, we can start creating the keys required for the OpenVPN service.
Modify and Initialize Environment Variables
sudo su
cd /usr/share/easy-rsa/
vim vars
# Modify registration information, such as company address, company name, department name, etc.
export KEY_COUNTRY="CN"
export KEY_PROVINCE="GuangDong"
export KEY_CITY="ShenZhen"
export KEY_ORG="XJXH"
export KEY_EMAIL="rock@xjxh.io"
export KEY_OU="FuckItWhatever"
export KEY_NAME="EasyRSA"
# Make environment variables effective
source ./vars
# Add openssl configuration file
cp openssl-1.0.0.cnf openssl.cnf
Create Keys
# Clear all certificate-related files in the keys directory
# The certificates and keys generated by the following steps are in the /usr/share/easy-rsa/keys directory
./clean-all
# Generate root certificate ca.crt and root key ca.key (just press Enter throughout)
./build-ca
# Generate certificate and private key for the server, --batch means to keep default settings without confirmation
./build-key-server --batch server
# Generate certificate and private key for the client
./build-key --batch client
# Create Diffie-Hellman key, which will generate the dh2048.pem file (the generation process is slow, do not interrupt it)
./build-dh
# Generate ta.key file (to prevent DDoS attacks, UDP floods, and other malicious attacks)
openvpn --genkey --secret keys/ta.key
Create Server Configuration File (server.conf)
First, create a keys directory in the OpenVPN configuration directory
sudo mkdir -p /etc/openvpn/keys
Then, copy the required OpenVPN certificates and keys to the newly created keys directory
cp /usr/share/easy-rsa/keys/{ca.crt,server.{crt,key},dh2048.pem,ta.key} /etc/openvpn/keys/
Copy a server configuration file template server.conf
to /etc/openvpn/
gzip -d /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/
Edit server.conf
# Service port
port 1194
# Transmission protocol used
proto tcp
# Routing mode, use dev tap for bridge mode
dev tun
# Certificate path
ca keys/ca.crt
cert keys/server.crt
key keys/server.key
dh keys/dh2048.pem
# Default virtual LAN segment, ensure it does not conflict with the actual LAN
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
# 192.168.1.0 is the LAN segment where my OpenVPN server is located
# If your LAN is different, modify it accordingly
push "route 192.168.1.0 255.255.255.0"
# If clients connect to the VPN using the same certificate and key, this option must be enabled
duplicate-cn
# If tls-auth is set here, the client must also set it, and it must correspond to the server, server is 0, client is 1
;tls-auth keys/ta.key 0 # This file is secret
;key-direction 0
# Number of clients to allow
max-clients 100
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
log-append /var/log/openvpn/openvpn.log
verb 3
# If TCP transmission is configured above, this should be commented out to avoid conflicts
;explicit-exit-notify 1
# Here configure support for username and password login, which can replace login using keys and certificates
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
# This is very important, if you enable this option, you only need to log in with username and password
# If you comment out this option, you must use Username + Password + Certificate to log in successfully, all are required.
;verify-client-cert none
username-as-common-name
script-security 3
If you have configured login using username and password, you need to create a login verification script vim /etc/openvpn/checkpsw.sh
#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>
#
# This script will authenticate OpenVPN users against
# a plain text file. The passfile should simply contain
# one row per user with the username first followed by
# one or more space(s) or tab(s) and then the password.
PASSFILE="/etc/openvpn/psw-file"
LOG_FILE="/etc/openvpn/openvpn-password.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`
###########################################################
if [ ! -r "${PASSFILE}" ]; then
echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}
exit 1
fi
CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`
if [ "${CORRECT_PASSWORD}" = "" ]; then
echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
fi
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
exit 0
fi
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
Then you also need to create a password file vim /etc/openvpn/psw-file
, with one user per line, separated by spaces:
user1 pass1
user2 pass2
user3 pass3
The server configuration is now complete.
Configuring Kernel and Firewall, Starting the Server
Step 1, enable routing forwarding
sed -i '/net.ipv4.ip_forward/s/0/1/' /etc/sysctl.conf
sed -i '/net.ipv4.ip_forward/s/#//' /etc/sysctl.conf
sysctl -p
Step 2, configure
iptables
iptables -I INPUT -p tcp --dport 1194 -m comment --comment "openvpn" -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
Then we save the iptables settings and load them automatically at boot. This can be quickly achieved using iptables-persistent
sudo apt-get install iptables-persistent
# Save rules
sudo service netfilter-persistent save
Next time you boot, you will see that the iptables
rules have been loaded automatically
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:openvpn /* openvpn */
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Disable ufw firewall
ufw disable
Step 3, start OpenVPN service
/etc/init.d/openvpn start
# Set to start on boot
systemctl enable openvpn@server
Creating Client Configuration File client.ovpn (for client software use)
First, copy a client.conf
template and name it client.ovpn
mkdir ~/openvpn-client
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/openvpn-client/client.ovpn
Then modify client.ovpn, vim /etc/openvpn/client.ovpn
client
# Set the same as the server here
dev tun
proto tcp
# OpenVPN server IP and port
remote 14.153.76.90 1194
resolv-retry infinite
nobind
persist-key
persist-tun
# Set certificates and keys here
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server
# If the server uses tls-auth, enable it here as well
;tls-auth ta.key 1
comp-lzo
verb 3
# Path to the file storing username and password, so you don't need to enter them manually when connecting
auth-user-pass pass.txt
After modifying the client configuration file, you also need to copy the certificate files to the ~/openvpn-client
folder:
cp /ect/openvpn/keys/ca.crt ~/openvpn-client
cp /usr/share/easy-rsa/keys/client.crt ~/openvpn-client
cp /usr/share/easy-rsa/keys/client.key ~/openvpn-client
Then you need to create a pass.txt
file in the openvpn-client
directory, with the username on the first line and the password on the second line:
user1
pass1