{"id":227,"date":"2024-03-13T05:46:46","date_gmt":"2024-03-13T05:46:46","guid":{"rendered":"https:\/\/blog.devops955.com\/swain\/?p=227"},"modified":"2024-03-14T06:31:55","modified_gmt":"2024-03-14T06:31:55","slug":"how-to-build-an-openvpn-server","status":"publish","type":"post","link":"https:\/\/blog.devops955.com\/swain\/2024\/03\/13\/how-to-build-an-openvpn-server\/","title":{"rendered":"How to Build an OpenVPN Server"},"content":{"rendered":"<blockquote>\n<p>Estimated reading time: 8 minutes<\/p>\n<\/blockquote>\n<h1>What is OpenVPN<\/h1>\n<h2>Introduction<\/h2>\n<p><strong>OpenVPN<\/strong> 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.<\/p>\n<h2>Working Mechanism<\/h2>\n<p>The working principle and data encryption of OpenVPN are basically similar to HTTPS:<\/p>\n<ol>\n<li>\n<p><strong>Connection Establishment:<\/strong><br \/>\nOpenVPN usually uses <strong>certificates<\/strong> or <strong>pre-shared keys<\/strong> for authentication to ensure that the parties connecting are legitimate. Once authentication is successful, the parties can begin to establish a secure communication tunnel.<\/p>\n<\/li>\n<li>\n<p><strong>Tunnel Establishment:<\/strong><br \/>\nOpenVPN uses the <strong>SSL\/TLS<\/strong> 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.<\/p>\n<\/li>\n<li>\n<p><strong>Data Transfer:<\/strong><br \/>\nOnce the tunnel is established, all data within the tunnel will be encrypted. OpenVPN uses advanced encryption algorithms such as <strong>AES (Advanced Encryption Standard)<\/strong> to encrypt data. Only the recipient with the correct key can decrypt and read the data. OpenVPN also uses <strong>Message Authentication Codes (MACs)<\/strong> to verify the integrity of the data to prevent tampering.<\/p>\n<\/li>\n<\/ol>\n<h1>OpenVPN Deployment<\/h1>\n<p>The following steps are to deploy OpenVPN on CentOS 7, using certificates for authentication.<\/p>\n<h2>Install OpenVPN<\/h2>\n<ol>\n<li>Install openvpn\n<pre><code class=\"language-bash\">yum install openvpn<\/code><\/pre>\n<p>After installation, the default path is <code>\/etc\/openvpn<\/code>. Modify using the sample configuration provided. Check OpenVPN-related files with <code>rpm -ql openvpn<\/code>, usually under <code>\/usr\/share\/doc\/openvpn-2.4.11<\/code> directory, copy the <code>server.conf<\/code> configuration file from the sample directory to \/etc\/openvpn.<\/p>\n<\/li>\n<\/ol>\n<h2>Install easy-rsa and Self-signed Certificates<\/h2>\n<ol>\n<li>\n<p>Install easy-rsa<\/p>\n<pre><code class=\"language-bash\">yum install easy-rsa<\/code><\/pre>\n<p>Similarly, find the example configuration vars.sample and copy it to <code>\/etc\/openvpn\/easy-rsa\/vars<\/code>, and modify the vars file. Copy easyrsa and the configuration folder x509-types to <code>\/etc\/openvpn\/easy-rsa\/vars<\/code> for convenient configuration.<\/p>\n<\/li>\n<li>\n<p>Configure Certificates<br \/>\n<code>vim vars<\/code> In the example, configurations are commented out; you can directly move to the end to add configurations:<\/p>\n<pre><code class=\"language-bash\">set_var EASYRSA_REQ_COUNTRY     &quot;Country Code&quot;  # e.g., CN\nset_var EASYRSA_REQ_PROVINCE    &quot;Province Name&quot;  # e.g., Sichuan\nset_var EASYRSA_REQ_CITY        &quot;City Name&quot;  # e.g., Chengdu\nset_var EASYRSA_REQ_ORG         &quot;Organization Name&quot;  # Any name, company or individual\nset_var EASYRSA_REQ_EMAIL       &quot;email@example.com&quot;  # Any email\nset_var EASYRSA_REQ_OU          &quot;OpenVPN Server&quot;  # Any name, company or individual\nset_var EASYRSA_KEY_SIZE        2048  # Default 2048, recommended 1024 or higher\nset_var EASYRSA_ALGO            rsa  # Default rsa, can choose ecdsa, etc.\nset_var EASYRSA_CA_EXPIRE      36500  # Expiry time, in days, set according to actual needs\nset_var EASYRSA_CERT_EXPIRE    36500<\/code><\/pre>\n<\/li>\n<li>\n<p>Generate Self-signed Certificates<br \/>\nNavigate to <code>cd \/etc\/openvpn\/easy-rsa\/<\/code> directory, run easyrsa to create a CA self-signed certificate:<\/p>\n<pre><code class=\"language-bash\">.\/easyrsa init-pki \n.\/easyrsa build-ca  # Enter password (needed for signing later), fill in organization name\n.\/easyrsa build-server-full server nopass  # Generate server certificate \n.\/easyrsa gen-dh  # Generate pem\nopenvpn --genkey --secret ta.key  # Generate key<\/code><\/pre>\n<\/li>\n<li>\n<p>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):<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"language-bash\">cp pki\/ca.crt \/etc\/openvpn\/server\/\ncp pki\/private\/server.key \/etc\/openvpn\/server\/\ncp pki\/issued\/server.crt \/etc\/openvpn\/server\/\ncp pki\/dh.pem \/etc\/openvpn\/server\/\ncp ta.key \/etc\/openvpn\/server\/<\/code><\/pre>\n<h2>Configure OpenVPN<\/h2>\n<ol>\n<li>Configure the OpenVPN file <code>vim \/etc\/openvpn\/server.conf<\/code>, where <code>;<\/code> and <code>#<\/code> both serve as comment symbols, then configure according to your needs<\/li>\n<\/ol>\n<p>:<\/p>\n<pre><code class=\"language-ini\">local 0.0.0.0  # Change listening address\nport 8443  # Change listening port, need to configure firewall to allow\n;proto tcp  # Choose protocol, tcp or udp, as needed\nproto udp\ndev tun  # Network device mode, tun for virtual network card, tap requires bridging mode\n# Certificate information configuration, use the path where certificates were placed earlier\nca \/etc\/openvpn\/server\/ca.crt  \ncert \/etc\/openvpn\/server\/server.crt  \nkey \/etc\/openvpn\/server\/server.key  \ntls-auth \/etc\/openvpn\/server\/ta.key 0 \nserver 10.0.0.0 255.255.255.0  # Specify the subnet used by vpn\nifconfig-pool-persist ipp.txt  # Specify client IP binding as needed\npush &quot;route 172.16.1.0 255.255.255.0&quot;  # Push the internal network route needed for VPN access\npush &quot;dhcp-option DNS 8.8.8.8&quot;  # Push VPN&#039;s DNS to ensure correct internal network resolution\n# Enable logging, helpful for initial debugging, log level can be set higher for detailed output during debugging\nstatus openvpn-status.log  \nlog-append  openvpn.log\nverb 4 \nexplicit-exit-notify 1  # Notify when server disconnects, facilitating client reconnection\n# Certificate verification, if managing client certificates, needs to be enabled\ncrl-verify \/etc\/openvpn\/server\/crl.pem<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>Set up OpenVPN environment and boot startup<br \/>\nCopy the OpenVPN service to the system environment<br \/>\n<code>cp \/usr\/lib\/systemd\/system\/openvpn-server@.service \/usr\/lib\/systemd\/system\/openvpn@server.service<\/code><br \/>\nserver as the name of the server.conf configuration file, if it's changed, modify accordingly<br \/>\nEdit service configuration <code>vim \/usr\/lib\/systemd\/system\/openvpn@server.service<\/code><\/p>\n<pre><code class=\"language-bash\">ExecStart=\/usr\/sbin\/openvpn --status %t\/openvpn-server\/status-%i.log --status-version 2 --suppress-timestamps --config %i.conf<\/code><\/pre>\n<p>You can replace with the  <code>%i<\/code> with the configuration file name, and make sure all the paths are exist and correct.<br \/>\nAfter completion, add to startup and start the service:<\/p>\n<pre><code class=\"language-bash\">systemctl enable openvpn@server.service\nsystemctl start openvpn@server.service<\/code><\/pre>\n<\/li>\n<li>\n<p>Firewall and System Configuration<br \/>\nThe server <strong>iptables<\/strong> needs to allow the source address and port that needs access:<br \/>\nThe access path can be understood as: client --&gt; vpn --&gt; backend server<br \/>\nTherefore, the VPN server needs to configure forwarding requests from tun to the server's network card eth0 to access internal resources<br \/>\niptables addition:<\/p>\n<pre><code class=\"language-bash\">iptables -t nat -A POSTROUTING -s 10.0.0.0\/24 -o eth0 -j MASQUERADE<\/code><\/pre>\n<p>firewalld addition (add tun0 and eth0 to the zone):<\/p>\n<pre><code class=\"language-bash\">firewall-cmd --permanent --add-interface=tun0 --zone=public\nfirewall-cmd --permanent --add-masquerade --zone=public\nfirewall-cmd --reload<\/code><\/pre>\n<p>When configuring NAT, don't forget to enable kernel forwarding, otherwise, it cannot forward requests:<\/p>\n<pre><code class=\"language-bash\">cat \/proc\/sys\/net\/ipv4\/ip_forward\necho 1 &gt; \/proc\/sys\/net\/ipv4\/ip_forward<\/code><\/pre>\n<\/li>\n<li>\n<p>Some Possible Issues<br \/>\na. After starting, the CLI continuously prompts the following message<br \/>\nBroadcast message from root@Docker-test (Mon 2022-01-24 11:28:25 CST):<br \/>\nPassword entry required for 'Enter Private Key Password:' (PID 14218).<br \/>\nPlease enter password with the systemd-tty-ask-password-agent tool!<br \/>\nIf this occurs, run <code>systemd-tty-ask-password-agent<\/code> and then enter the password, or modify the OpenVPN service configuration to add:<\/p>\n<pre><code class=\"language-bash\">--askpass \/etc\/openvpn\/server\/passwd<\/code><\/pre>\n<p>Write the private key password in the <code>passwd<\/code> file, then restart the OpenVPN service<\/p>\n<\/li>\n<\/ol>\n<p>b. If starting the tun network card fails, check the openvpn log for a message like<br \/>\n<code>TCP\/UDP: Socket bind failed on local address [AF_INET]172.18.5.77:13579: Permission denied (errno=13) Exiting due to fatal error<\/code><br \/>\nDisable selinux, <code>setenforce 0<\/code> and modify the configuration <code>vim \/etc\/selinux\/config<\/code> to <code>disabled<\/code><\/p>\n<blockquote>\n<p>Note: Other issues can be investigated through the <code>openvpn log<\/code>.<\/p>\n<\/blockquote>\n<h2>Client Management<\/h2>\n<p>For businesses, there may be new hires or resignations, so certificate management is necessary.<\/p>\n<ol>\n<li>Client Certificate Creation<br \/>\nReturn to the easyrsa directory to create the client key<br \/>\n<code>.\/easyrsa build-client-full username<\/code><br \/>\nDuring this, first create a client password, then enter the server CA password for signing.<br \/>\nAfter the issuance is complete, export the server <strong>ca.crt<\/strong>, **<\/li>\n<\/ol>\n<p>ta.key<strong>, and <\/strong>client certificate and key** to the client for use. If unsure of the storage path after generation, use <code>.\/easyrsa show-cert username<\/code> or <code>.\/easyrsa show-ca<\/code> to check.<\/p>\n<ol start=\"2\">\n<li>Revoke User Certificate<br \/>\nUse easyrsa to revoke the user certificate:<\/p>\n<pre><code class=\"language-bash\">.\/easyrsa revoke username<\/code><\/pre>\n<p>Enter the server CA password for confirmation, then generate an updated crl file:<\/p>\n<pre><code class=\"language-bash\">.\/easyrsa gen-crl<\/code><\/pre>\n<p>After entering the CA password for confirmation, copy the generated crl.pem file to the OpenVPN configuration file directory:<\/p>\n<pre><code class=\"language-bash\">cp keys\/crl.pem \/etc\/openvpn\/server\/crl.pem  # Match the path with OpenVPN configuration<\/code><\/pre>\n<p>Restart the service after completion, subsequent revocations need to update the crl.pem and overwrite the original file to take effect.<\/p>\n<\/li>\n<\/ol>\n<h2>Client Configuration<\/h2>\n<p>The client configuration file is typically a <code>client.ovpn<\/code> file. Copy the server-generated certificates and keys to the client configuration file directory, then replace <code>ca<\/code>, <code>cert<\/code>, and <code>key<\/code> 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:<\/p>\n<pre><code class=\"language-ini\">client\ndev tun\nproto udp\nremote 1.1.1.1 8443  # Server IP and listening port\nresolv-retry infinite\nnobind\n\n# Certificate configuration\nca ca.crt\ncert client.crt\nkey client.key\ntls-auth ta.key 1<\/code><\/pre>\n<h1>Other Configurations<\/h1>\n<p>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:<\/p>\n<ol>\n<li>\n<p><strong>Set iptables rules for port mapping<\/strong>:<br \/>\nYou 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:<\/p>\n<pre><code class=\"language-bash\">iptables -t nat -A PREROUTING -p udp --dport 50000:60000 -j REDIRECT --to-ports 8443\niptables -A INPUT -p udp --dport 50000:60000 -j ACCEPT<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>Client Configuration<\/strong>:<br \/>\nClients need to set the OpenVPN connection port to one within the 50000 to 60000 range. In the client's configuration file (usually <code>client.ovpn<\/code>), modify the <code>remote<\/code> directive as follows:<\/p>\n<pre><code class=\"language-ini\">remote your-server-ip 50000 udp<\/code><\/pre>\n<p>Replace <code>50000<\/code> with any port between 50000 and 60000, as per actual circumstances.<br \/>\nAfter 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.<\/p>\n<\/li>\n<\/ol>\n<blockquote>\n<p>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.<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>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&#8230;<\/p>\n","protected":false},"author":3,"featured_media":229,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[4],"tags":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/openvpn.png","_links":{"self":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts\/227"}],"collection":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/comments?post=227"}],"version-history":[{"count":6,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts\/227\/revisions"}],"predecessor-version":[{"id":252,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts\/227\/revisions\/252"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/media\/229"}],"wp:attachment":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/media?parent=227"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/categories?post=227"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/tags?post=227"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}