{"id":446,"date":"2025-04-17T10:54:18","date_gmt":"2025-04-17T10:54:18","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=446"},"modified":"2025-04-17T10:54:18","modified_gmt":"2025-04-17T10:54:18","slug":"setup-pritunl-vpn-on-ec2","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=446","title":{"rendered":"How to Setup Pritunl VPN on AWS EC2 (Step by Step Guide)"},"content":{"rendered":"<p>In this step-by-step guide, you will learn to setup a self-hosted Pritunl VPN in an AWS EC2 instance.<\/p>\n<p>By the end of this guide, you will learn:<\/p>\n<ol>\n<li>How to install and configure Pritunl<\/li>\n<li>How to create and set up VPN users (clients)<\/li>\n<li>How to connect and authenticate users using a VPN client app<\/li>\n<li>How to configure split tunneling to route only AWS traffic through the VPN<\/li>\n<\/ol>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">Pritunl is a free, open-source VPN (Virtual Private Network) server that helps you create secure client to site self-hosted VPN solution.<\/div>\n<\/div>\n<p>Before we dive in to the setup, lets understand the Pritunl VPN workflow.<\/p>\n<h2 id=\"pritunl-vpn-workflow\">Pritunl VPN Workflow<\/h2>\n<p>The following diagram shows the traffic flow to access AWS private resources using the Pritunl VPN server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/11\/pritunl.png\" class=\"kg-image\" alt=\"Pritunl VPN Architecture &amp; Workflow\" loading=\"lazy\" width=\"1560\" height=\"1924\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/11\/pritunl.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/11\/pritunl.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/11\/pritunl.png 1560w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Here is how it works.<\/p>\n<ol>\n<li>The user first establishes a VPN tunnel to the Pritunl server residing in the AWS public subnet using the Pritunl VPN client.<\/li>\n<li>Once authenticated, a secure, encrypted tunnel gets created over the internet from the local workstation to the pritunl VPN server.<\/li>\n<li>When the user tries to access any AWS private resources from the networks configured in Pritunl, the connection from the local workstation reaches the VPN server over an encrypted tunnel, and then the traffic gets decrypted to reach the AWS private resources.<\/li>\n<\/ol>\n<h2 id=\"set-up-pritunl-vpn-on-ec2-instance\">Set up Pritunl VPN on EC2 instance<\/h2>\n<p>For setting up the Pritunl, I am choosing an Ubuntu based t3 medium instance.<\/p>\n<p>A t3.medium instance type, can handle <strong>almost 250 client connections<\/strong> and provides a decent performance.<\/p>\n<p>Also, Pritunl requires a MongoDB database to store the user data and VPN configuration.<\/p>\n<p>In this setup, we are installing MongoDB on the same EC2 instance. For production HA setups, it is better to keep the Database in a dedicated instance.<\/p>\n<p>Lets get started with the setup.<\/p>\n<h3 id=\"step-1-create-an-ec2-instance\">Step 1: Create an EC2 Instance <\/h3>\n<p>Go to the AWS EC2 dashboard and spin up a new EC2 instance with the following configuration.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-75.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"1512\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-75.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-75.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/04\/image-75.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-75.png 2182w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Select the <code>Instance type<\/code> as t3.medium instance type and select the key pairs.<\/p>\n<p>If you don&#8217;t have an existing key, create a new one for the server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-76.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1067\" height=\"470\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-76.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-76.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-76.png 1067w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h3 id=\"step-2-choosing-vpc\">Step 2: Choosing VPC<\/h3>\n<p>I am choosing the default VPC for this setup.<\/p>\n<p>If you are using a custom VPC, make sure the selected subnet is a public subnets the <code>Auto-assign public IP<\/code> option is enabled.<\/p>\n<p>Also, I am selecting the default security group. I will add some rules for access in the latter part of the configuration. You can choose to create a new security group as per your requirements.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-77.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1071\" height=\"710\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-77.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-77.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-77.png 1071w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>After configuring everything, click the <code>Launch instance<\/code> to create the EC2 instance.<\/p>\n<p>After configuring everything, click the Launch instance to create the EC2 instance.<\/p>\n<p>It will take a few minutes to up the server, then you can use the ec2 instance connect or SSH into the instance from the local machine using the pem key.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\u26a0\ufe0f<\/div>\n<div class=\"kg-callout-text\">Make sure the attached security group has enabled port 22 for the SSH access.<\/div>\n<\/div>\n<p>For now, I\u2019m using the web terminal in the browser to connect to the instance.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-81.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"778\" height=\"277\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-81.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-81.png 778w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>I am using the ec2 instance connect option.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-82.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1017\" height=\"708\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-82.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-82.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-82.png 1017w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h3 id=\"step-3-add-pritunl-openvpn-and-mongodb-repositories\">Step 3: Add Pritunl, OpenVPN and MongoDB Repositories<\/h3>\n<p>First, add the necessary repositories to install Pritunl, OpenVPN, and MongoDB.<\/p>\n<p>Add the MongoDB repo:<\/p>\n<pre><code>sudo tee \/etc\/apt\/sources.list.d\/mongodb-org.list &lt;&lt; EOF\ndeb [ signed-by=\/usr\/share\/keyrings\/mongodb-server-8.0.gpg ] https:\/\/repo.mongodb.org\/apt\/ubuntu noble\/mongodb-org\/8.0 multiverse\nEOF\n<\/code><\/pre>\n<p>Add the the OpenVPN repo:<\/p>\n<pre><code>sudo tee \/etc\/apt\/sources.list.d\/openvpn.list &lt;&lt; EOF\ndeb [ signed-by=\/usr\/share\/keyrings\/openvpn-repo.gpg ] https:\/\/build.openvpn.net\/debian\/openvpn\/stable noble main\nEOF\n<\/code><\/pre>\n<p>Add the Pritunl VPN server repo:<\/p>\n<pre><code>sudo tee \/etc\/apt\/sources.list.d\/pritunl.list &lt;&lt; EOF\ndeb [ signed-by=\/usr\/share\/keyrings\/pritunl.gpg ] https:\/\/repo.pritunl.com\/stable\/apt noble main\nEOF\n<\/code><\/pre>\n<h3 id=\"step-4-add-gpg-keys\">Step 4: Add GPG keys<\/h3>\n<p>Install the GPG tools to handle the key verification for package sources.<\/p>\n<pre><code>sudo apt --assume-yes install gnupg\n<\/code><\/pre>\n<p>Add GPG keys for the packages.<\/p>\n<p>Download the GPG key of the MongoDB package:<\/p>\n<pre><code>curl -fsSL https:\/\/www.mongodb.org\/static\/pgp\/server-8.0.asc | sudo gpg -o \/usr\/share\/keyrings\/mongodb-server-8.0.gpg --dearmor --yes\n<\/code><\/pre>\n<p>Download the OpenVPN GPG key:<\/p>\n<pre><code>curl -fsSL https:\/\/raw.githubusercontent.com\/pritunl\/pgp\/master\/pritunl_repo_pub.asc | sudo gpg -o \/usr\/share\/keyrings\/pritunl.gpg --dearmor --yes\n<\/code><\/pre>\n<p>Download the Pritunl package GPG key:<\/p>\n<pre><code>curl -fsSL https:\/\/raw.githubusercontent.com\/pritunl\/pgp\/master\/pritunl_repo_pub.asc | sudo gpg -o \/usr\/share\/keyrings\/pritunl.gpg --dearmor --yes\n<\/code><\/pre>\n<h3 id=\"step-5-install-pritunl-openvpn-mongodb-and-wireguard\">Step 5: Install Pritunl, OpenVPN, MongoDB, and Wireguard<\/h3>\n<p>Pritunl is not a VPN server itself. Instead, it acts as a management layer for VPN servers like OpenVPN and WireGuard.<\/p>\n<p>It handles user management, connection routing, and provides a web interface.<\/p>\n<p>First, update the package list and then install the required packages:<\/p>\n<pre><code>sudo apt update\nsudo apt --assume-yes install pritunl openvpn mongodb-org wireguard wireguard-tools\n<\/code><\/pre>\n<p>Now, disable the firewall to avoid the connection issues.<\/p>\n<pre><code>sudo ufw disable\n<\/code><\/pre>\n<p>Start and enable the Pritunl and MongoDB services.<\/p>\n<pre><code>sudo systemctl start pritunl mongod\nsudo systemctl enable pritunl mongod\n<\/code><\/pre>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">Pritunl supports both <b><strong style=\"white-space: pre-wrap;\">OpenVPN<\/strong><\/b> and <b><strong style=\"white-space: pre-wrap;\">WireGuard<\/strong><\/b> protocols. You need to install at least one of them.<\/p>\n<p>By default, Pritunl uses <b><strong style=\"white-space: pre-wrap;\">OpenVPN<\/strong><\/b>.<\/p>\n<p>It generates a temporary OpenVPN configuration in the <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">\/tmp<\/code> directory.<\/p>\n<p>You can view the connection details using the <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">--management<\/code> argument in that temporary config file.<\/div>\n<\/div>\n<h3 id=\"step-6-set-up-the-pritunl-web-interface\">Step 6: Set Up the Pritunl Web Interface<\/h3>\n<p>Pritunl offers a user-friendly web interface for the configurations as well as the connection check.<\/p>\n<p>To access the web interface, ports <code>80<\/code> and <code>443<\/code> should be enabled on the security group.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-78.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"663\" height=\"447\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-78.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-78.png 663w\"><\/figure>\n<p>Edit the inbound rules of the security group to add the rules.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-79.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"901\" height=\"529\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-79.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-79.png 901w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-80.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1324\" height=\"668\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-80.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-80.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-80.png 1324w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>We can use the public IP of the Pritunl VPN server to access the dashboard.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-83.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"642\" height=\"450\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-83.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-83.png 642w\"><\/figure>\n<p>Note down the public IP and open any web browser and paste the IP address.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-84.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"825\" height=\"679\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-84.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-84.png 825w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Here, one thing you can notice is that MongoDB is automatically configured with the Pritunl server.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">MongoDB exposes the service by default on localhost port <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">27017<\/code> so, Pritunl has the predefined configuration in <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">\/etc\/pritunl.conf<\/code> as <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">localhost:27017<\/code><\/p>\n<p>But, if you are using a dedicated MongoDB server, you need to modify the <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">mongodb_uri<\/code> on the <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">\/etc\/pritunl.conf<\/code> with the external database server details.<\/div>\n<\/div>\n<p>To get the Pritunl server setup key, use the following command. <\/p>\n<pre><code>sudo pritunl setup-key<\/code><\/pre>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-85.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1222\" height=\"270\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-85.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-85.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-85.png 1222w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>The setup key differs for each deployment, so copy yours from the Pritunl server CLI and paste it into the dashboard.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-87.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"500\" height=\"560\"><\/figure>\n<p>The next page will prompt you to provide the default username and password.<\/p>\n<p>Use the following command to get the default credentials.<\/p>\n<pre><code>sudo pritunl default-password<\/code><\/pre>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-88.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1868\" height=\"424\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-88.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-88.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/04\/image-88.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-88.png 1868w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-89.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"371\" height=\"352\"><\/figure>\n<p>We need to provide this information on the login dashboard, which will again prompt you to provide new admin credentials.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-90.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"596\" height=\"420\"><\/figure>\n<h3 id=\"step-7-configure-the-pritunl-vpn-server\">Step 7: Configure the Pritunl VPN Server<\/h3>\n<p>The configuration starts with the creation of an organization, which will organize the configurations. We can create multiple organizations if necessary. <\/p>\n<p>Navigate to the <code>Users<\/code> tab and click the <code>Add Organization<\/code> button to create a new organization.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-91.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"978\" height=\"341\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-91.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-91.png 978w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Give a name for the organization <\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-92.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"596\" height=\"218\"><\/figure>\n<p>Next, we must create a server to configure the port and DNS server details.<\/p>\n<p>Navigate to the <code>Servers<\/code> tab and click the <code>Add Server<\/code> button to create a new server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-93.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"975\" height=\"293\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-93.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-93.png 975w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">In the free version of the Pritunl, we can create only one server.<\/div>\n<\/div>\n<p>On the Server Configuration tab, you need to provide a name for the server. You can also configure the DNS server details, port, protocol, virtual network, and authentication options.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-94.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"596\" height=\"367\"><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">Virtual Network is the the private network range assigned to VPN clients. Meaning, any user who uses the pritunl client to connect to this server will get an IP assigned from the configured Virtual Network CIDR.<\/p>\n<p>This network range should be range that shouldn&#8217;t be the same range in users network or network used in AWS VPCs that is part of VPN. Or else IP conflicts may occur. <\/div>\n<\/div>\n<p>Once the server configurations are completed, we need to bind the organization with the server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-95.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"971\" height=\"671\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-95.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-95.png 971w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Select the organization name and the server name to attach the organization to the server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-96.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"598\" height=\"299\"><\/figure>\n<p>We need to provide information about the AWS Private subnets that we want to connect with securely.<\/p>\n<p>You can add the entire VPC or specify only the subnets you want to access from your local workstation. This depends on your VPC setup, VPN requirements, and the design of your project.<\/p>\n<p>This defines which network the VPN server should provide secure and encrypted access to.<\/p>\n<p>Navigate to the <code>Add Route<\/code> button on the <code>Server<\/code> tab. <\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-97.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"992\" height=\"402\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-97.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-97.png 992w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>For testing purposes, I am adding the VPC CIDR.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-98.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"599\" height=\"297\"><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">If you want to add more VPCs or subnets, select the Add Route to add more networks.<\/div>\n<\/div>\n<p>All the VPN configurations are complete now. You can start the VPN Server using the start server option as highlighted below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-99.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"969\" height=\"719\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-99.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-99.png 969w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>On the dashboard, we can see the logs of the connection and the status of the server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-100.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"962\" height=\"719\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-100.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-100.png 962w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h3 id=\"step-8-create-pritunl-users-on-server\">Step 8: Create Pritunl Users on Server<\/h3>\n<p>The server is up and running.<\/p>\n<p>Now you need to create user (clients) and user configurations for VPN server access.<\/p>\n<p>Navigate to the <code>Users<\/code> tab and select <code>Add User<\/code> to add new users.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-101.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"989\" height=\"366\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-101.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-101.png 989w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Give a user name on the user creation tab, and select the organization if you have multiple.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-102.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"598\" height=\"453\"><\/figure>\n<blockquote><p>Note: Email and PIN information are optional.<\/p><\/blockquote>\n<p>We can create multiple users as per our requirements. Pritunl doesn&#8217;t have any limitations.<\/p>\n<p>During the user creation, a user profile will also be created, which will be necessary to make a connection from local to the VPN Server. <\/p>\n<p>You need to download that. <\/p>\n<p>The downloaded client configuration will be <strong>used with Pritunl client app<\/strong> that we configure in the next section.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-103.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"970\" height=\"412\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-103.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-103.png 970w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">The client connection will be established through the UDP port <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">15000<\/code> of the VPN Server.<\/p>\n<p>You need to ensure that the VPN server port <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">15000<\/code> is open for the client in the Pritunl servers security group. <\/div>\n<\/div>\n<p>Lets add port to the security group limiting access only to the public IP of the workstation.<\/p>\n<p>To get the public IP of your workstation, use the following command on the terminal<\/p>\n<pre><code>curl ifconfig.me<\/code><\/pre>\n<p>This command will work on Mac, Windows CMD, and Linux CLI.<\/p>\n<p>Once get the workstations public IP, update the server&#8217;s security group with the public IP address.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-104.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1361\" height=\"769\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-104.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-104.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-104.png 1361w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Server side configurations for the client are completed. Next we need to download the Pritunl client app on our local workstation.<\/p>\n<h3 id=\"step-9-download-the-install-pritunl-client\">Step 9: Download the Install Pritunl Client<\/h3>\n<p>You can use the <a href=\"https:\/\/client.pritunl.com\/?ref=devopscube.com\" rel=\"noreferrer\">official Pritunl client<\/a> page to download the client, and choose the appropriate one for your operating system. <\/p>\n<p>After the download is complete, open the VPN client application and import the profile you downloaded earlier.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-105.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"424\" height=\"528\"><\/figure>\n<p>After importing the client profile, click the <code>Connect<\/code> button to make a connection between the local workstation and the VPN server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-106.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"424\" height=\"304\"><\/figure>\n<p>If you have enabled PIN or Google authentication, you will be prompted to provide them.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-107.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"424\" height=\"330\"><\/figure>\n<p>The connection is established.<\/p>\n<p>However, this is a full-tunnel VPN connection, which means not only AWS traffic but all internet access will be routed through the VPN and encrypted.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-134.png\" class=\"kg-image\" alt=\"full-tunnel VPN connection\" loading=\"lazy\" width=\"2000\" height=\"1145\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-134.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-134.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/04\/image-134.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/04\/image-134.png 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>This can <strong>impact the performance<\/strong> of regular non-AWS internet traffic.<\/p>\n<p>To avoid this, you can <strong>configure a split-tunnel VPN<\/strong>. This setup allows normal internet traffic to flow directly, while only AWS-specific traffic is routed through the VPN and encrypted.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-135.png\" class=\"kg-image\" alt=\"split-tunnel VPN\" loading=\"lazy\" width=\"2000\" height=\"1148\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-135.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-135.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/04\/image-135.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/04\/image-135.png 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h3 id=\"step-10-configure-split-tunnel-vpn\">Step 10: Configure Split Tunnel VPN<\/h3>\n<p>The split tunnel configuration will route the VPN traffic only to the AWS network that you have configured( For example, VPC CIDR <code>172.31.0.0\/16<\/code>)<\/p>\n<p>If the VPN server is running and you need to modify its configuration, you must stop the server before making any changes.<\/p>\n<p>On the <code>Servers<\/code> tab, click the <code>Stop Server<\/code> button to stop the server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-108.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1153\" height=\"714\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-108.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-108.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-108.png 1153w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>The route <code>0.0.0.0\/0<\/code> indicates, all the traffic should go through the VPN tunnel, so we need to remove that from the existing routes.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-110.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"964\" height=\"711\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-110.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-110.png 964w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Once the route is removed, we need to start the server again to update the modified changes to the server.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-111.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"975\" height=\"674\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-111.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-111.png 975w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h3 id=\"step-11-validating-pritunl-vpn-setup\">Step 11: Validating Pritunl VPN Setup<\/h3>\n<p>To validate the Pritunl setup, you need to test connectivity to AWS ec2 instance using its private IP.<\/p>\n<p>For this, you need create an EC2 instance in a private subnet that is configured in the pritunl server.<\/p>\n<p>Lets create a instance.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-112.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"960\" height=\"825\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-112.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-112.png 960w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Choosing the default VPC and security group.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-115.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"957\" height=\"680\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-115.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-115.png 957w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Once the test server is up and running, note down the private IP of the server to validate the VPN setup.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-116.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1234\" height=\"769\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-116.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-116.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-116.png 1234w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Now, try SSH with the private IP from your local workstation<\/p>\n<pre><code>ssh -i &lt;PATH_TO_KEY_PAIRS&gt; ubuntu@&lt;PRIVATE_IP&gt;<\/code><\/pre>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-117.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1841\" height=\"776\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-117.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-117.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/04\/image-117.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-117.png 1841w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>If all configurations are correct, you should be able to SSH into the EC2 instance without any errors, as shown below.<\/p>\n<p>Once connected, install a simple Nginx server on the ec2 server to test HTTP access<\/p>\n<pre><code>sudo apt update &amp;&amp; sudo apt install nginx -y<\/code><\/pre>\n<p>To ensure the Nginx, web server is installed and running properly, check the status.<\/p>\n<pre><code>systemctl status nginx.service\n<\/code><\/pre>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-118.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1858\" height=\"686\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-118.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-118.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/04\/image-118.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-118.png 1858w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>The web server is in running state.<\/p>\n<p>Now, open any browser in your workstation and paste the private IP as a URL to access the default nginx homepage as shown below<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-119.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"872\" height=\"455\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-119.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-119.png 872w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">In an actual environment, the entire network will be private except the one that hosts the pritunl server.<\/p>\n<p>Also, wee can use the VPC Peering to connect various VPCs to communicate each other over the VPN server.<\/p><\/div>\n<\/div>\n<p>The following image shows the entire workflow of our Pritunl setup and traffic flow.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/pritunl.gif\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"800\" height=\"1040\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/pritunl.gif 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/pritunl.gif 800w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h2 id=\"pritunl-ami-automation-using-packer\">Pritunl AMI Automation Using Packer<\/h2>\n<p>In real-world scenarios, you may need to deploy Pritunl in different environments.<\/p>\n<p>Instead of setting up the Pritunl VPN server manually each time, you can automate the process by creating a custom AMI using <strong>Packer<\/strong> and <strong>Ansible<\/strong>. <\/p>\n<p>Packer is an open-source tool that will help automate the creation of AMI.<\/p>\n<p>To use the Packer, we need to install it in the local workstation, I am providing the <a href=\"https:\/\/developer.hashicorp.com\/packer\/tutorials\/docker-get-started\/get-started-install-cli?ref=devopscube.com\" rel=\"noreferrer\">official documentation<\/a> to install Packer.<\/p>\n<p>You can download the Packer configuration from this <a href=\"https:\/\/github.com\/techiescamp\/pritunl-vpn?ref=devopscube.com\" rel=\"noreferrer\">GitHub repo<\/a>.<\/p>\n<p>The following is the directory structure of the Packer configuration.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-120.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"960\" height=\"1710\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-120.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-120.png 960w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Packer launches a temporary server on AWS, and Ansible installs packages such as Pritunl, MongoDB, etc. on that server.<\/p>\n<p>After installing everything, Packer creates an Amazon Machine Image (AMI)<\/p>\n<p>You can use that AMI at any time so that all the packages will be pre-installed on that server.<\/p>\n<p>After pull the repo from the GitHub, open the following directory.<\/p>\n<pre><code>cd packer<\/code><\/pre>\n<p>To initialize, use the following command. <\/p>\n<pre><code>packer init .<\/code><\/pre>\n<p>To run the configuration.<\/p>\n<pre><code>packer build vpn.pkr.hcl<\/code><\/pre>\n<p>The build will take some time to complete. Once it is completed, we can see that AMI in the AMIs section of the EC2 dashboard.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-121.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1169\" height=\"520\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/04\/image-121.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/04\/image-121.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/04\/image-121.png 1169w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>We can click the launch icon to launch the Pritunl VPN Server instance.<\/p>\n<h2 id=\"pritunl-performance-requirements-for-production\">Pritunl Performance Requirements for Production<\/h2>\n<p>For production grade Pritunl VPN setup, it is recommended to use high CPU EC2 instances types (e.g., C5) that can handle large number of connections.<\/p>\n<p>Also, a dedicated MongoDB servers on optimized EC2 instances will provide good performance (e.g., r3).<\/p>\n<p>To get more information about the production scaling, please refer to this <a href=\"https:\/\/docs.pritunl.com\/docs\/scaling?ref=devopscube.com#example-deployments\" rel=\"noreferrer\">official documentation<\/a>.<\/p>\n<h3 id=\"pritunl-vs-openvpn\">Pritunl Vs OpenVPN<\/h3>\n<p>As compared to free openVPN server, Pritunl setup and mangement is very easy.<\/p>\n<p>Also, the free version of OpenVPN doesnt have a web UI for user management. Whereas Pritunl offers webUI for easy mangement.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>AWS offers various solutions, such as Client VPN Endpoint, and Site-to-Site VPN etc.<\/p>\n<p>These managed services are good for big or growing projects because they scale based on the connections, and management is quite easy.<\/p>\n<p>Pritunl on the other hand is a cost-effective poor-mans soltion that is suitable for small projects. It also offers subscription options for enterprises, with various authentication mechanisms, features, and performance.<\/p>\n<p>Hope this guide was useful!<\/p>\n<p>If you face any issues during the setup or have any queries, do let us know in the comments. We will help you out.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/setup-pritunl-vpn-on-ec2\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to Setup Pritunl VPN on AWS EC2 (Step by Step Guide) \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/setup-pritunl-vpn-on-ec2\/<\/p>\n","protected":false},"author":1,"featured_media":447,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-446","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/446","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=446"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/446\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/447"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=446"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}