Double VPN in one click. How to easily separate the IP address of the entry point and exit point.

Father

Professional
Messages
2,602
Reaction score
805
Points
113
This article describes the easiest way to configure a VPN server with a different IP address for VPN clients than the IP address from which clients access the Internet.

Do you use a VPN to protect your privacy on the Internet and rent your own server for this? That being said, are you the only client that connects to this server in the whole world? Is it as hard to find your real IP address as you think? With the coming into force, it becomes much easier.

Double VPN is a popular topic around which there is a lot of speculation. Often this term is used to refer to completely different technologies, but almost always it means points of connection and access to the Internet that are located at the level of IP addresses. We will look at the easiest way to configure a VPN server in this mode, which does not require additional configuration on the server side and allows you to get the maximum speed and lowest latency.

Threat model
In order to defend against something, you need to clearly understand the threat model. We will not talk about new laws requiring providers to store all customer traffic, but we can definitely say that connection data, the so-called. Netflow, storing is quite simple, and it has been successfully done for a long time. That is, the fact that a conditional IP address is connected 1.1.1.1 to an address 2.2.2.2 at a certain time of the day is recorded.

Having access to such information on the scale of the provider, city or country, it is enough to simply establish who exactly is hiding behind the VPN.

To increase privacy when using a VPN, it is necessary to separate the connection point and the Internet access point at the IP level. In the picture above, our user is behind the fence under the close scrutiny of Irina Yarovaya. Irina strictly remembers all connections through the fence. The user, as a decent citizen, connects to the address good.citizen.vpn, while he returns back from the address super.cool.guy.vpn. As a result, for Irina, these two connections look unrelated.

What are double VPNs?
Under the name "double" VPN is often understood different things, but almost always it means geographically or at the network level, nodes of connection and Internet access. Sometimes this is just a marketing gimmick of VPN providers, which means absolutely nothing, such services can be called "triple" and "quadruple" VPNs.

We will analyze the most typical schemes that are used in practice.

VPN between servers
The most common way. In this mode, the client only establishes a VPN connection to the first server. On the first server, a tunnel is configured to the second, and all traffic from the client goes to the second server, and so on. There can be several intermediate servers. In this case, the tunnel between the servers can be established using any other protocol other than the protocol over which the client is connected, for example IPsec, or without encryption at all, such as GRE or IPIP. In this mode, all intermediate servers can be seen in the route trace . There is no way to check exactly how intermediate servers are connected to each other on the client side, so you can only trust the provider.

Along the entire route of traffic, the minimum MTU (Maximum transmission unit) remains equal to the value of the very first tunnel, and each intermediate server has access to the decrypted client traffic.

VPN over proxy
Also a fairly common way. Often used to mask VPN traffic under another protocol, for example in China. This method is more convenient than a chain of proxies, because using a VPN it is easy to route all system traffic to the tunnel. There are also tools for intercepting system calls of programs and redirecting them to a proxy: ProxyCap, Proxifier, but they are less stable, as sometimes they miss requests and they go by the proxy or work incorrectly with some programs.

In this mode, the proxy is not visible in the route trace.

VPN inside VPN
The most paranoid and slowest way: all tunnels rise on the client side, each inside the other. This method requires cleverly configuring client-side routes and launching all VPN clients in the correct order. This has a negative impact on latency and performance, but intermediate servers do not have access to open client traffic. All encapsulation overheads are added up, and the maximum packet size (MTU) that is ultimately available to the client is reduced depending on the number of tunnels. Intermediate servers are not visible in route tracing.

VDS setup
The easiest way to set up a VPN with separate entry and exit points is to connect multiple IP addresses to one virtual server. This method allows you to get the maximum speed and minimum latency, since in fact the traffic is terminated on one server. With us, at Vdsina.ru, you can do it yourself from the control panel. While IPv4 runs out everywhere, we issue additional IP addresses even on servers for $ 1!

Let's analyze the server setup step by step.

Choosing a server
We order VDS with a suitable tariff, in the right data center. Considering our task, let's choose a data center further away, in the Netherlands;)

We connect an additional IP address
After purchasing an additional IP-address, you need to configure it according to the instructions.

For clarity, let's assign a PTR record to an IP. This is the domain name that will be seen when the IP address is converted back to a domain. This can be any value, including a non-existent domain.

For examples, we will use the following values:
Code:
xxx.xxx.38.220 - super.cool.guy.vpn # external address (exit point)
xxx.xxx.39.154 - good.citizen.vpn # connection address (entry point)

Checking two IPs
It is important to remember that the IP address that was initially set on the server will be the exit point, so the new address will be the entry point. Let's connect via SSH to the server and check which address is used as the external one.

To do this, the easiest way is to use the ifconfig.co service from the console. When requested via curl, it returns the IP address from which the request was made.
Code:
$ curl ifconfig.co
xxx.xxx.38.220

The last figures show that our external address really corresponds to the exit point. Let's try to check the correctness of the second IP as an entry point. To do this, simply use the built-in SOCKS proxy function in SSH.

Commands are executed on the client:
Code:
ssh -D 9999 root@good.citizen.vpn

# in a new window
curl -x socks5h://127.0.0.1:9999 ifconfig.co
super.cool.guy.vpn

The first command establishes an SSH session with the address good.citizen.vpn and simultaneously activates a SOCKS proxy within this session, which is available on the local port. The second makes a regular HTTP request through this proxy.
It's important to remember that our examples use fake domain names for queries. They will be displayed only during PTR resolution, and you will not be able to make a full request for them. Therefore, at this stage, you need to contact the server through the IP address.

Configuring an IKEv2 Server
IPsec IKEv2 is a modern VPN protocol supported by almost all operating systems out of the box. It is used as the default protocol on Windows, macOS, and iOS. At the same time, it does not require the installation of third-party software and works in most cases faster than OpenVPN. Habré already had articles on configuring the IKEv2 server, but they all describe the use of self-signed certificates, and are inconvenient in that they require you to install a root certificate on the VPN client side.

We will analyze an example of setting up a server using a trusted certificate from Let's Encrypt. This allows the client not to install third-party root certificates, but to issue only a username and password.

Server preparation
We will be using a server based on Ubuntu 18.04, but the instructions are also suitable for most modern distributions.
We update the system and install the necessary packages
Code:
apt update && apt upgrade
apt install certbot strongswan libstrongswan-extra-plugins

Issuing a certificate
To issue a trusted certificate, you need to point the real domain to the IP address of the entry point. We will not consider this point in detail, as it is beyond the scope of the article. We'll use the fictitious domain good.citizen.vpn as an example.

If you already have a web server on your server, use the appropriate way to issue a certificate via certbot or another Let's Encrypt client. This example assumes that the HTTP port (80) is not busy.
Code:
certbot certonly --standalone --agree-tos -d good.citizen.vpn

By answering the master's questions? we will get the signed certificate and key
Code:
# find /etc/letsencrypt/live/good.citizen.vpn/

/etc/letsencrypt/live/good.citizen.vpn/
/etc/letsencrypt/live/good.citizen.vpn/fullchain.pem
/etc/letsencrypt/live/good.citizen.vpn/README
/etc/letsencrypt/live/good.citizen.vpn/cert.pem
/etc/letsencrypt/live/good.citizen.vpn/privkey.pem
/etc/letsencrypt/live/good.citizen.vpn/chain.pem

IKEv2 server authentication uses the same X.509 certificates as
HTTPS. To Strongswan could use these certificates, they must be copied to the folder /etc/ipsec.d.

This is how the certificates should be located:
Code:
cp /etc/letsencrypt/live/good.citizen.vpn/cert.pem /etc/ipsec.d/certs/
cp /etc/letsencrypt/live/good.citizen.vpn/privkey.pem /etc/ipsec.d/private/
cp /etc/letsencrypt/live/good.citizen.vpn/chain.pem /etc/ipsec.d/cacerts/

Since letsencrypt certificates are frequently reissued, doing it manually is inconvenient. Therefore, we will automate this process using a hook for certbot.
The task of the script is to copy three files to the correct folder each time the certificate is updated, and then send the command strongswan to re-read the certificates.

Create a file /etc/letsencrypt/renewal-hooks/deploy/renew-copy.sh and make it executable.

Code:
#!/bin/sh

set -e

for domain in $RENEWED_DOMAINS; do
        case $domain in
        good.citizen.vpn)
                daemon_cert_root=/etc/ipsec.d/

                # Make sure the certificate and private key files are
                # never world readable, even just for an instant while
                # we're copying them into daemon_cert_root.
                umask 077

                cp "$RENEWED_LINEAGE/cert.pem" "$daemon_cert_root/certs/"
                cp "$RENEWED_LINEAGE/chain.pem" "$daemon_cert_root/cacerts/"
                cp "$RENEWED_LINEAGE/privkey.pem" "$daemon_cert_root/private/"

                 # Reread certificates
                /usr/sbin/ipsec reload
                /usr/sbin/ipsec purgecerts
                /usr/sbin/ipsec rereadall
                ;;
        esac
done

Now, after each certificate reissue, the script will copy new files to the strongswan folders and send a command to the daemon to re-read the certificates.

Strongswan setup
Add config strongswan /etc/ipsec.conf
Code:
config setup

# Allow multiple connections from one account
    uniqueids=no

    # Increase debug level
    # charondebug = ike 3, cfg 3

conn %default

# Universal cipher suite for most platforms

     ike = aes256-sha256-modp1024, aes256-sha256-modp2048

     # Dead connection timeouts
    dpdaction=clear
    dpddelay=35s
    dpdtimeout=2000s

    keyexchange=ikev2
    auto=add
    rekey=no
    reauth=no
    fragmentation=yes
    #compress=yes

    # left - local (server) side
leftcert = cert.pem # Certificate file name in /etc/ipsec.d/certs/ folder
leftsendcert = always
# Routes sent to the client
    leftsubnet=0.0.0.0/0

    # right - remote (client) side
    eap_identity=%identity
# Range of internal IP addresses assigned to VPN clients

    rightsourceip=10.0.1.0/24
    rightdns=8.8.8.8,1.1.1.1

 # Windows and BlackBerry clients usually goes here
conn ikev2-mschapv2
    rightauth=eap-mschapv2

# Apple clients usually goes here
conn ikev2-mschapv2-apple
    rightauth=eap-mschapv2
    leftid=good.citizen.vpn

Logins and passwords VPN-clients are given in the file /etc/ipsec.secrets

This file also need to specify the name of the private key, which we have previously copied from a folder letsencrypt:
Code:
# The name of the private key file in the /etc/ipsec.d/private/ folder
: RSA privkey.pem

# VPN Users
# name: EAP "Password"
IrinaYarovaya : EAP "PleaseLoveMe123"
Mizooleena : EAP "IwannaLoveToo3332"

At this stage, you can restart the strongswan server and check if the new config has been activated:
Code:
$ systemctl restart strongswan

$ ipsec statusall
Virtual IP pools (size/online/offline):
  10.0.1.0/24: 254/0/0
Listening IP addresses:
 xxx.xxx.38.220
Connections:
ikev2-mschapv2:  %any...%any  IKEv2, dpddelay=35s
ikev2-mschapv2:   local:  [CN=good.citizen.vpn] uses public key authentication
ikev2-mschapv2:    cert:  "CN=good.citizen.vpn"
ikev2-mschapv2:   remote: uses EAP_MSCHAPV2 authentication with EAP identity '%any'
ikev2-mschapv2:   child:  0.0.0.0/0 === dynamic TUNNEL, dpdaction=clear
ikev2-mschapv2-apple:  %any...%any  IKEv2, dpddelay=35s
ikev2-mschapv2-apple:   local:  [good.citizen.vpn] uses public key authentication
ikev2-mschapv2-apple:    cert:  "CN=good.citizen.vpn"
ikev2-mschapv2-apple:   remote: uses EAP_MSCHAPV2 authentication with EAP identity '%any'
ikev2-mschapv2-apple:   child:  0.0.0.0/0 === dynamic TUNNEL, dpdaction=clear

You can see that the config has been successfully activated and the certificate is connected. At this stage, you can already connect to the VPN server, but it will be without access to the Internet. To release clients to the Internet, you need to enable forwarding and configure NAT.

NAT setup
We activate packet forwarding:
Code:
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

Turn on NAT. It is important to keep in mind that this is just an example of a minimal iptables configuration. Adjust the rest of the rules based on your needs.

ethName0 - replace with your interface name
10.0.1.0/24 - the range of IP addresses that will be issued to VPN clients. We asked him to /etc/ipsec.conf
111.111.111.111 - the IP-address of the exit point, in this example, the address super.cool.guy.vpn
Code:
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -o ethName0 -j SNAT --to-source 111.111.111.111

Debugging
At this stage of configuration, we should get a fully working server, to which clients can already connect. It's best to verify this by checking the connection before proceeding.

In case of connection problems, you can watch the log in real time:
Code:
journalctl -f -u strongswan

Autostart at boot
If everything is successful, you can add strongswan to autostart at boot:
Code:
systemctl enable strongswan

Saving iptables rules
To persist iptables rules across reboots, there is a special iptables-persistent package. It is important to remember that it will save the current ruleset and add it to startup.
Code:
apt install iptables-persistent

Configuring clients
Setting up on the client side is extremely simple - just tell the client the server address, username and password. For macOS and iOS, you can create auto-configuration profiles that can be activated in two clicks.

Windows setup
In newer versions of Windows, IKEv2 is configured in a simple wizard that can be invoked from the WiFi connection menu.

muhq_rn7iubyixxxsislcmmqvzm.png


Windows does not set a default route for such a connection, so we will set it up manually. In the properties of the VPN connection, go to the TCP / IPv4 properties -> additionally and check the box "Use a gateway on a remote network" clickable

rac5_xi76rjiuadeswi3e1m8rug.png


MacOS setup
IKEv2 is supported on macOS since version 10.11 (El Capitan). The connection is created through the network settings menu.

f4adhkw9swpneyfo0jn9jgro9s4.png


Let's add a new connection. Set any arbitrary name as the connection name.

xcngzqon0ilejqrl7hqla-8vbf4.png


To verify the authenticity of the certificate, you need to specify the domain name. At the same time, in the “Server Address” field, you can specify the IP address of the server, and the domain only in the “Remote ID”, then the DNS resolution will not be performed for the connection, and it will be a little faster.

x4c2eqk2waefy8woi_pnaa8o5uw.png


The username and password are specified from the /etc/ipsec.secrets file

-pgu98eevkywzjzqjd7dfvq94zc.png


IOS setup
IOS configuration can be done manually through the wizard, but it is much more convenient to use the mobileconfig auto-configuration profile.
Manual configuration is similar in meaning to the desktop macOS:
Settings -> VPN -> Add VPN configuration

Auto-configuration profile for Apple devices:

sjr2up4rsqjjrxzltdldqrepnmk.png


The .mobileconfig autoconfiguration profiles are an XML file with settings that can configure anything from SSL certificates to VPN connections.
The user just needs to click on the file, and all the necessary settings will be installed automatically.

An example of a config for connecting to our IKEv2 server.
To customize the file for its configuration, it is enough to edit several parameters in this template:

AuthName - the user name of the file /etc/ipsec.secrets
AuthPassword - user password /etc/ipsec.secrets
RemoteAddress - domain or server IP-address
RemoteIdentifier - domain on which issued the certificate

Code:
<?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>

<!-- Username and password from ipsec.secrets -->
<key>AuthName</key>
<string>IrinaYarovaya</string>
<key>AuthPassword</key>
<string>PleaseLoveMe123</string>

<!-- Hostname or IP address of VPN server.
Chosing IP address instead of DNS name can avoid issues with client DNS resolvers and speed up connection process. -->
<key>RemoteAddress</key>
<string>123.123.123.123</string>

<!-- leftid in ipsec.conf -->
<key>RemoteIdentifier</key>
<string>good.citizen.vpn</string>

<key>AuthenticationMethod</key>
<string>Certificate</string>
<key>ChildSecurityAssociationParameters</key>
<dict>

<!-- in ipsec.conf this proposal is: ike=aes256-sha256-modp2048 -->
<key>DiffieHellmanGroup</key>
<integer>14</integer>
<key>EncryptionAlgorithm</key>
<string>AES-256</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-256</string>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>DeadPeerDetectionRate</key>

<!--
None (Disable)
Low (keepalive sent every 30 minutes)
Medium (keepalive sent every 10 minutes)
High (keepalive sent every 1 minute)
-->
<string>High</string>
<key>ExtendedAuthEnabled</key>
<true/>
<key>IKESecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>14</integer>
<key>EncryptionAlgorithm</key>
<string>AES-256</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-256</string>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>

<!--
Always On OnDemand Rule
Cen be disabled in connection preferences by "On Demand" checkbox
http://www.v2ex.com/t/137653
https://developer.apple.com/library/mac/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html
https://github.com/iphoting/ovpnmcgen.rb
-->
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>PayloadDescription</key>
<string>Configures VPN settings</string>
<key>PayloadDisplayName</key>
<string>VPN</string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.96C1C38F-D4D6-472E-BA90-9117ED8896B5</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string>96C1C38F-D4D6-472E-BA90-9117ED8896B5</string>
<key>PayloadVersion</key>
<integer>1</integer>

<!-- VPN connection name in Network Preferences -->
<key>UserDefinedName</key>
<string>London VPN</string>
<key>VPNType</key>
<string>IKEv2</string>
</dict>
</array>

<!-- Set the name to whatever you like, it is used in the profile list on the device -->
<key>PayloadDisplayName</key>
<string>My Super IKEv2 VPN</string>

<!-- A reverse-DNS style identifier (com.example.myprofile, for example) that identifies the profile. This string is used to determine whether a new profile should replace an existing one or should be added. -->
<key>PayloadIdentifier</key>
<string>vpn.googd.citizen</string>

<!-- A globally unique identifier, use uuidgen on Linux/Mac OS X to generate it -->
<key>PayloadUUID</key>
<string>F3FAD91C-019C-4A79-87A1-CF334C583339</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

Android setup
Unfortunately, Android is the only popular operating system that still doesn't have built-in IKEv2 support. To connect, you can use the official Strongswan client from PlayMarket

Outcome
We have shown the simplest option for setting up a server with spaced entry and exit points. This configuration allows you to get the maximum VPN speed, since it does not use additional tunnels between servers, despite the fact that the IP addresses of the entry and exit points are on different subnets. This approach allows you to experiment further by connecting more than two IP addresses to the server.

The IKEv2 protocol is perfect for using it on desktop OS for everyday work, since it is as natively integrated into the system as possible and, all other things being equal, allows you to get higher speed than through third-party VPN programs.

(c) vdsina.ru
 
Last edited:
Top