Build your own VPN

This is assuming you know how to setup an Ubuntu Server as a virtual machine. If not, let me know in the comments and I’ll help you figure out how to setup a private virtual data center with IONOS.

The assumptions we’re going to make are the following:

  • Operating System: Ubuntu Server 24.04 LTS
  • One Network Interface named “ens6”
  • Fresh install of the operating system
  • We will use 10.1.60.0/24 and fd:10:1:60::/64 as our tunnel IPs
  • You know your current public IP address
  • We are using Cloudflare’s Malware Prevention DNS

Here are the install commands, please be aware for [BRACKETS] where you need to substitute it with your information.

sudo apt update && sudo apt upgrade -y

sudo apt install -y certbot strongswan libstrongswan-standard-plugins strongswan-libcharon libcharon-extra-plugins libcharon-extauth-plugins

sudo rm /etc/letsencrypt/cli.ini

sudo nano /etc/letsencrypt/cli.ini

Contents of: /etc/letsencrypt/cli.ini

# Because we are using logrotate for greater flexibility, disable the
# internal certbot logrotation.
max-log-backups = 0
# Adjust interactive output regarding automated renewal
preconfigured-renewal = True
standalone = true
agree-tos = true
non-interactive = true
preferred-challenges = http
key-type = ecdsa
elliptic-curve = secp384r1
email = [YOUR EMAIL]
pre-hook = /sbin/ufw allow from any to any port 80 proto tcp
post-hook = /sbin/ufw delete allow from any to any port 80 proto tcp
renew-hook = /usr/sbin/ipsec reload && /usr/sbin/ipsec secrets
sudo certbot certonly --key-type ecdsa -d [YOUR DOMAIN]

sudo ln -f -s "/etc/letsencrypt/live/[YOUR DOMAIN]/cert.pem" /etc/ipsec.d/certs/cert.pem

sudo ln -f -s "/etc/letsencrypt/live/[YOUR DOMAIN]/privkey.pem" /etc/ipsec.d/private/privkey.pem

sudo ln -f -s "/etc/letsencrypt/live/[YOUR DOMAIN]/fullchain.pem" /etc/ipsec.d/cacerts/chain.pem

sudo nano /etc/apparmor.d/local/usr.lib.ipsec.charon

Contents of: /etc/apparmor.d/local/usr.lib.ipsec.charon

/etc/letsencrypt/archive/[YOUR DOMAIN]/* r,
sudo aa-status --enabled && invoke-rc.d apparmor reload

sudo nano /etc/sysctl.conf

Append this to the end of: /etc/sysctl.conf

net.ipv4.ip_forward = 1
net.ipv4.ip_no_pmtu_disc = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.forwarding = 1
sudo sysctl -p

sudo nano /etc/default/ufw

Change the following in: /etc/default/ufw

- DEFAULT_FORWARD_POLICY="DROP"
+ DEFAULT_FORWARD_POLICY="ACCEPT"
sudo nano /etc/ufw/before.rules

Append this to the end of: /etc/ufw/before.rules

# NAT for IPSec
*nat
:POSTROUTING ACCEPT [0:0]

-A POSTROUTING -s 10.1.60.0/24 -o ens6 -j MASQUERADE

COMMIT

NOTE: Please change the interface name from ens6 to whatever you are using on your instance.

sudo nano /etc/ufw/before6.rules

Append this to the end of: /etc/ufw/before6.rules

# NAT for IPSec
*nat
:POSTROUTING ACCEPT [0:0]

-A POSTROUTING -s fd:10:1:60::/64 -o ens6 -j MASQUERADE

COMMIT

NOTE: Please change the interface name from ens6 to whatever you are using on your instance.

sudo ufw allow from any to any port 500 proto udp

sudo ufw allow from any to any port 4500 proto udp

sudo ufw allow from 10.1.60.0/24 to any

sudo ufw allow from fd:10:1:60::/64 to any

sudo ufw limit from [YOUR IPv4 ADDRESS] to any port 22 proto tcp

sudo ufw limit from [YOUR IPv6 NETWORK] to any port 22 proto tcp

sudo ufw enable

sudo rm /etc/ipsec.conf

sudo nano /etc/ipsec.conf

The contents of: /etc/ipsec.conf

config setup
  strictcrlpolicy=yes
  uniqueids=never

conn roadwarrior
  auto=add
  compress=no
  type=tunnel
  keyexchange=ikev2
  fragmentation=yes
  forceencaps=yes
  ike=aes256gcm16-prfsha384-ecp384,aes256gcm16-prfsha256-ecp256!
  esp=aes256gcm16-ecp384!
  dpdaction=clear
  dpddelay=900s
  rekey=no
  left=%any
  leftid=@[YOUR DOMAIN]
  leftcert=cert.pem
  leftsendcert=always
  leftsubnet=::/0,0.0.0.0/0
  right=%any
  rightid=%any
  rightauth=eap-mschapv2
  eap_identity=%any
  rightdns=2606:4700:4700::1112,2606:4700:4700::1002,1.1.1.2,1.0.0.2
  rightsourceip=fd:10:1:60::/64,10.1.60.0/24
  rightsendcert=never
sudo rm /etc/ipsec.secrets

sudo nano /etc/ipsec.secrets

The contents of: /etc/ipsec.secrets

[YOUR DOMAIN] : ECDSA "privkey.pem"
user : EAP "password"

NOTE: You can enter as many user names and passwords as you like. I recommend a different one for each device.

sudo systemctl enable ipsec

sudo systemctl restart ipsec

sudo systemctl status ipsec

sudo reboot now

You now have a functional VPN Server

Apple Profile Configuration

If you would like to use a configuration profile to automatically configure the VPN on your devices, please save the following text with the suffix .mobileconfig or .mc.

This configuration profile will automatically configure the IKEv2 VPN on macOS, iPadOS, and iOS. It will automatically enable the VPN. If you would like to disable “connect on demand”, you can do so in settings on your device.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC '-//Apple//DTD PLIST 1.0//EN' 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'>
<plist version='1.0'>
<dict>
  <key>PayloadContent</key>
  <array>
    <dict>
      <key>IKEv2</key>
      <dict>
        <key>AuthenticationMethod</key>
        <string>None</string>
        <key>ChildSecurityAssociationParameters</key>
        <dict>
          <key>EncryptionAlgorithm</key>
          <string>AES-256-GCM</string>
          <key>IntegrityAlgorithm</key>
          <string>SHA2-384</string>
          <key>DiffieHellmanGroup</key>
          <integer>20</integer>
          <key>LifeTimeInMinutes</key>
          <integer>1440</integer>
        </dict>
        <key>DeadPeerDetectionRate</key>
        <string>Medium</string>
        <key>DisableMOBIKE</key>
        <integer>0</integer>
        <key>DisableRedirect</key>
        <integer>0</integer>
        <key>EnableCertificateRevocationCheck</key>
        <integer>0</integer>
        <key>EnablePFS</key>
        <true/>
        <key>ExtendedAuthEnabled</key>
        <true/>
        <key>IKESecurityAssociationParameters</key>
        <dict>
          <key>EncryptionAlgorithm</key>
          <string>AES-256-GCM</string>
          <key>IntegrityAlgorithm</key>
          <string>SHA2-384</string>
          <key>DiffieHellmanGroup</key>
          <integer>20</integer>
          <key>LifeTimeInMinutes</key>
          <integer>1440</integer>
        </dict>
        <key>OnDemandEnabled</key>
        <integer>1</integer>
        <key>OnDemandRules</key>
        <array>
          <dict>
            <key>Action</key>
            <string>Connect</string>
          </dict>
        </array>
        <key>RemoteAddress</key>
        <string>[YOUR DOMAIN]</string>
        <key>RemoteIdentifier</key>
        <string>[YOUR DOMAIN]</string>
        <key>UseConfigurationAttributeInternalIPSubnet</key>
        <integer>0</integer>
      </dict>
      <key>IPv4</key>
      <dict>
        <key>OverridePrimary</key>
        <integer>1</integer>
      </dict>
      <key>PayloadDescription</key>
      <string>Configures VPN settings</string>
      <key>PayloadDisplayName</key>
      <string>[YOUR DOMAIN]</string>
      <key>PayloadIdentifier</key>
      <string>com.apple.vpn.managed.463a6902-149e-426c-8629-a5562fc5a317</string>
      <key>PayloadType</key>
      <string>com.apple.vpn.managed</string>
      <key>PayloadUUID</key>
      <string>ae2ed0d5-5bc9-4656-b80a-140284466276</string>
      <key>PayloadVersion</key>
      <integer>1</integer>
      <key>Proxies</key>
      <dict>
        <key>HTTPEnable</key>
        <integer>0</integer>
        <key>HTTPSEnable</key>
        <integer>0</integer>
      </dict>
      <key>UserDefinedName</key>
      <string>[YOUR DOMAIN]</string>
      <key>VPNType</key>
      <string>IKEv2</string>
    </dict>
  </array>
  <key>PayloadDisplayName</key>
  <string>IKEv2 VPN configuration ([YOUR DOMAIN])</string>
  <key>PayloadIdentifier</key>
<string>b2408ec3-3107-4cc5-ac44-b6b96991bc29</string>
  <key>PayloadRemovalDisallowed</key>
  <false/>
  <key>PayloadType</key>
  <string>Configuration</string>
  <key>PayloadUUID</key>
  <string>cd1a0dd5-5638-4676-b523-144dc71f54fb</string>
  <key>PayloadVersion</key>
  <integer>1</integer>
</dict>
</plist>

❕On macOS, you will need to go to System Settings > VPN > Click on the “i” and change “Authentication” to “Username.”

❕The country your server is based in will become your “locale” when you are browsing the internet. Language, currency, and location may change.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *