Skip to content

Quick VPN setup on Linux with additional proxy rules for particular sites

This article describes a simple minimal configuration of VPN server on Linux server with additional ability to use different proxies for particular sites.

Intro

StrongSwan VPN server with IKEv2 protocol is used in this scenario. Additional configuration is used to access particular sites through Socks5 proxy. VPN server installed on OpenSUSE and placed behind a router. All steps are done under root user. Any popular Linux OS can be used instead of OpenSUSE.

Setup VPN server

Install VPN server

OpenSUSE command is used below (should be straight forward to do on other OS):

zypper install openssl strongswan iputils

Create directory for certificates

mkdir ~/vpn-certs
cd ~/vpn-certs

Create server private key

ipsec pki --gen --type rsa --size 4096 --outform pem > server-root-key.pem
chmod 600 server-root-key.pem

Create server self-signed certificate authority

ipsec pki --self --ca --lifetime 7300 \
    --in server-root-key.pem \
    --type rsa --dn "C=RU, S=St. Petersburg, L=St. Petersburg, O=Company, OU=Company.com, CN=VPN Server Root CA" \
    --outform pem > server-root-ca.pem

Create VPN server private key

ipsec pki --gen --type rsa --size 4096 --outform pem > vpn-server-key.pem

Create VPN server public key

ipsec pki --pub --in vpn-server-key.pem \
    --type rsa | ipsec pki --issue --lifetime 7300 \
    --cacert server-root-ca.pem \
    --cakey server-root-key.pem \
    --dn "C=RU, S=St. Petersburg, L=St. Petersburg, O=Company, OU=Company.com, CN=company.com" \
    --san company.com \
    --flag serverAuth --flag ikeIntermediate \
    --outform pem > vpn-server-cert.pem

Place VPN server keys at their places

cp vpn-server-cert.pem /etc/ipsec.d/certs/vpn-server-cert.pem
cp vpn-server-key.pem /etc/ipsec.d/private/vpn-server-key.pem

chown root /etc/ipsec.d/private/vpn-server-key.pem
chgrp root /etc/ipsec.d/private/vpn-server-key.pem
chmod 600 /etc/ipsec.d/private/vpn-server-key.pem

Configure VPN server

Backup VPN server configuration just in case:

cp /etc/ipsec.conf{,.bak}

Create new configuration:

echo '
config setup
  charondebug="ike 1, knl 1, cfg 0"
  uniqueids=no
conn ikev2-vpn
  auto=add
  compress=no
  type=tunnel
  keyexchange=ikev2
  fragmentation=yes
  forceencaps=yes
  ike=aes256-sha1-modp1024,3des-sha1-modp1024!
  esp=aes256-sha1,3des-sha1!
  dpdaction=clear
  dpddelay=300s
  rekey=no
  left=%any
  leftid=@company.com
  leftcert=/etc/ipsec.d/certs/vpn-server-cert.pem
  leftsendcert=always
  leftsubnet=0.0.0.0/0
  right=%any
  rightid=%any
  rightauth=eap-mschapv2
  rightsourceip=10.10.10.0/24
  rightdns=8.8.8.8,8.8.4.4
  rightsendcert=never
  eap_identity=%identity
' > /etc/ipsec.conf

Note: in case IP address is used as "leftid" then "@" character should be omitted.

Configure VPN authentication

Backup VPN server secrets configuration just in case:

cp /etc/ipsec.secrets{,.bak}

Grant access to "user" with "secret_word" password:

cat > /etc/ipsec.secrets <<EOF
company.com : RSA "/etc/ipsec.d/private/vpn-server-key.pem"
user %any% : EAP "secret_word"
EOF

Reload VPN server configuration:

ipsec reload

Check that access rights refreshed and appropriate records exist in runtime:

ipsec listall | grep -i -C 5 -e company -e user

Setup Socks5 proxy for particular sites access

Configure

The commands below will:

  • Use simple dynamic port forwarding to establish Socks5 proxy connection
  • Use 9999 local port on server for proxy
  • Use remote SSH connection at remote-user@remote-server.com on SSH default port (22)

Firstly check that SSH key authorization works from local server to remote host and known_hosts is updated accordingly:

ssh -p 22 remote-user@remote-server.com "echo test passed"

Start

echo 'ssh -D 9999 -p 22 remote-user@remote-server.com -f -N' > /root/proxy-start.sh
chmod u+x /root/proxy-start.sh
/root/proxy-start.sh

Schedule start on reboot

echo '/root/proxy-start.sh' >> /etc/init.d/boot.local

Setup redsocks as a bridge between iptables and proxy

Install

OpenSUSE command is used below (should be straight forward to do on other OS):

zypper install iptables git-core make gcc libevent-devel
cd ~
git clone http://github.com/darkk/redsocks.git
cd redsocks/
make

Configure

Configuration below means that redsocks will listen on any interface on 9978 port and forward requests to local host on 9977 port, where Socks5 proxy is running:

echo '
base {
    log_debug = on; log_info = on; log = "file:/tmp/reddi.log"; 
    daemon = on;
    redirector = iptables;
}
redsocks {
    local_ip = 0.0.0.0; local_port = 9978;
    ip = 127.0.0.1; port = 9977;
    type = socks5;
}
' > ~/redsocks/redsocks.conf

Start

/root/redsocks/redsocks -c redsocks.conf

Schedule start on reboot

echo '/root/redsocks/redsocks -c /root/redsocks/redsocks.conf' >> /etc/init.d/boot.local

Configuring firewall and iptables rules

Router setup

If VPN server is behind a router then the following ports should be opened on router and forwarded to VPN server ports, respectively:

  • UDP: 500
  • UDP: 4500

Disable OS specific firewall

OpenSUSE command is used below (should be straight forward to do on other OS):

yast firewall

Use UI to disable it.

Configure iptables

echo '

# clear existing route rules
iptables -F
iptables -X 
iptables -Z
iptables -t nat -F
iptables -t nat -X
iptables -t nat -Z
iptables -t mangle -F
iptables -t mangle -X
iptables -t mangle -Z

# define proxy usage for particular sites
iptables -t nat -N REDSOCKS

# particular site1 configuration, e.g. proxy should be used for 99.99.99.01/32
iptables -t nat -A REDSOCKS -p tcp -d 99.99.99.01/32 -j REDIRECT --to-ports 9978

# particular site2 configuration, e.g. proxy should be used for 99.99.99.02/32
iptables -t nat -A REDSOCKS -p tcp -d 99.99.99.02/32 -j REDIRECT --to-ports 9978

# no proxy by default
iptables -t nat -A REDSOCKS -p tcp -j RETURN

# enable redsocks
iptables -t nat -A PREROUTING -p tcp -j REDSOCKS
iptables -t nat -A OUTPUT -p tcp -j REDSOCKS

# enable internet sharing for vpn clients
iptables -t nat -A POSTROUTING -s 10.10.10.10/24 -o eth0 -j MASQUERADE

# ensure tcp packets size not bigger than required max length
iptables -t mangle -A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.10/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360

' > ~/iptables-config.sh

Note: no blocking rules are defined in this configuration. For a better security they should be defined.

Note: in case DNS changes required as well either try to put them into /etc/hosts or think of using some DNS server configuration.

Make the script to be executable:

chmod u+x ~/iptables-config.sh

Configure kernel settings

Backup configuration just in case:

cp /etc/sysctl.conf{,.bak}

Edit configuration:

vi /etc/sysctl.conf

Configuration should like like below:

kernel.sysrq = 0
net.ipv4.ip_forward = 1
net.ipv4.tcp_syncookies = 1
net.ipv6.conf.all.forwarding = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.ip_no_pmtu_disc = 1

Start

/root/iptables-config.sh
sysctl net.ipv4.ip_forward=1
sysctl net.ipv4.conf.all.accept_redirects=0
sysctl net.ipv4.conf.all.send_redirects=0
sysctl net.ipv4.ip_no_pmtu_disc=1

Schedule start on reboot

echo '/root/iptables-config.sh' >> /etc/init.d/boot.local

Configure access to VPN

Windows

Copy server-root-ca.pem generated during VPN setup to your computer.

Run mmc.exe

Menu:

  • File -> Add/Remove Snap-in... -> Certificates -> Computer account -> Local Computer

Left Navigation:

  • Console Root -> Certificates -> Trusted Root Cerification Authorities -> Certificates

Menu:

  • Action -> All Tasks -> Import...
  • .../server-root-ca.pem

Control Panel -> Network and Sharing Center -> Set up a new connection or network -> Connect to a workplace -> Use my Internet connection (VPN):

  • Internet address: company.com
  • Destination name: VPN Connection
  • ...

iOS

Copy server-root-ca.pem generated during VPN setup to your email box and open it on your device. Install the profile.

Settings -> General -> VPN -> Add Configuration:

  • Description: Company
  • Server: company.com
  • Remote ID: company.com
  • User Authenctication: Username:
  • Username:
  • Password: