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: