Wrapping openVPN with stunnel

# Some countries like China, Syria, North Korea etc, are using deep packet inspection
# to detect and block openvpn connections.
# To get around this, VPN connections can be hidden inside another SSL envelope
# using a program called stunnel making the VPN look like something else

# This blog is based upon these
# http://kyl191.net/2012/12/tunneling-openvpn-through-stunnel/
# https://syria.hacktivist.me/?p=161
# http://pve.proxmox.com/wiki/Stunnel_in_DAB_appliances
# http://www.jeffyestrumskas.com/index.php/how-to-setup-a-secure-web-proxy-using-ssl-encryption-squid-caching-proxy-and-pam-authentication/
#
# Using Rasperry PI as Openvpn server, we wrap the openvpn signalling inside
# another SSL envelope using stunnel

# On Raspberry PI, after you have installed openvpn
# Install stunnel and openssl

sudo apt-get install stunnel4 openssl -y

# Generate your own  Private Key (server.pem)
cd /etc/stunnel/
sudo openssl genrsa -out server.key 4096
sudo openssl req -new -key server.key -out server.csr
sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
sudo bash
cat server.key > server.pem && cat server.crt >> server.pem
chmod 400 /etc/stunnel/server.pem
exit

# enable stunnel
sudo nano /etc/default/stunnel4

ENABLED=1

#=========================================
# Server stunnel.conf   on Raspberry PI
#=========================================

sudo nano /etc/stunnel/stunnel.conf

sslVersion = all
options = NO_SSLv2
cert = /etc/stunnel/server.pem
pid = /var/run/stunnel.pid
output = /var/log/stunnel

[openvpn]
client = no
accept=993
connect=34567

#=========================================
# Add Firewall setting  on Raspberry PI
#=========================================
# Edit the same firewall file we used for openvpn
# and add a new line

sudo nano /usr/local/bin/firewall.sh

iptables -A INPUT -p tcp --dport 993 -j ACCEPT

#================================================
# Restart stunnel or reboot Raspberry PI and we are done
#================================================

sudo /etc/init.d/stunnel4 restart

# check status
ps aux | grep 'stunnel*'

#================================================
# Installing & configuring stunnel on windows client:
#================================================

# You can download stunnel installer from the official website
# http://mirrors.go-part.com/stunnel/stunnel-4.54-installer.exe
# or check here http://www.stunnel.org/downloads.html
# Installation shouldn’t be a problem… it’s a few clicks

# On windows, you should see an stunnel icon on your desktop, run it as administrator.  
# Now you should see the stunnel icon also on the taskbar.
# Do a right click on it, and choose “Edit stunnel.conf”

# Notepad will opened automatically, to edit the stunnel.conf file…

# add the following lines:
[openvpn]

client = yes
accept = 127.0.0.1:1194
connect = change_this_to_your_to_raspberry_PI_server_address_from_no-ip.com:993

# Save & exit
# right click on stunnel icon, and click reload stunnel.conf

# in Windows, create a new text file called
# C:\Program Files (x86)\OpenVPN\config\raspberry_via_stunnel.ovpn
# this is the OpenVPN client configuration

client
dev tun
proto tcp
remote  localhost 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca capi.crt
cert clientpi.crt
key clientpi.key
tls-auth tapi.key 1
ns-cert-type server
cipher AES-256-CBC
comp-lzo
verb 3

diagram

Advertisements

3 thoughts on “Wrapping openVPN with stunnel

  1. Hi there,

    I am trying to follow your guide. My setup is:

    Client -> localhost 1194 -> client stunnel 443 -> server stunnel 443 -> localhost 1194

    Client vpn conf:

    —-
    client
    dev tun
    proto tcp
    remote localhost 443
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    mute-replay-warnings
    ns-cert-type server
    key-direction 1
    cipher AES-128-CBC
    comp-lzo
    verb 1
    mute 20

    client stunnel.conf
    ——-

    [openvpn]
    client = yes
    accept = 127.0.0.1:443
    connect = SERVER_ADDRESS:443

    server stunnel.conf
    —–
    sslVersion = all
    options = NO_SSLv2
    cert = /etc/stunnel/server.pem
    pid = /var/run/stunnel.pid
    output = /var/log/stunnel

    [openvpn]
    client = no
    accept=443
    connect=127.0.0.1:1194

    server openvpn.conf
    ———–
    local 192.168.1.200 # SWAP THIS NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
    dev tun
    proto tcp
    port 1194
    ca /etc/openvpn/easy-rsa/keys/ca.crt
    cert /etc/openvpn/easy-rsa/keys/raspberrypidos.crt # SWAP WITH YOUR CRT NAME
    key /etc/openvpn/easy-rsa/keys/raspberrypidos.key # SWAP WITH YOUR KEY NAME
    dh /etc/openvpn/easy-rsa/keys/dh1024.pem # If you changed to 2048, change that here!
    server 10.8.0.0 255.255.255.0
    # server and remote endpoints
    ifconfig 10.8.0.1 10.8.0.2
    # Add route to Client routing table for the OpenVPN Server
    push “route 10.8.0.1 255.255.255.255”
    # Add route to Client routing table for the OpenVPN Subnet
    push “route 10.8.0.0 255.255.255.0”
    # your local subnet
    push “route 192.168.1.200 255.255.255.0” # SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
    # Set primary domain name server address to the SOHO Router
    # If your router does not do DNS, you can use Google DNS 8.8.8.8
    push “dhcp-option DNS 192.168.1.1” # This should already match your router address and not need to be changed.
    # Override the Client default gateway by using 0.0.0.0/1 and
    # 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
    # overriding but not wiping out the original default gateway.
    push “redirect-gateway def1”
    client-to-client
    duplicate-cn
    keepalive 10 120
    tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
    cipher AES-128-CBC
    comp-lzo
    user nobody
    group nogroup
    persist-key
    persist-tun
    status /var/log/openvpn-status.log 20
    log /var/log/openvpn.log
    verb 3

    If I connect from openvpn to openvpn, everything works fine. But if I try to connect using stunnel, I got:

    client
    ——
    sudo openvpn –config client1.ovpn
    Thu Feb 5 19:51:20 2015 OpenVPN 2.3.2 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Dec 1 2014
    Enter Private Key Password:
    Thu Feb 5 19:51:21 2015 WARNING: this configuration may cache passwords in memory — use the auth-nocache option to prevent this
    Thu Feb 5 19:51:21 2015 Control Channel Authentication: tls-auth using INLINE static key file
    Thu Feb 5 19:51:21 2015 Attempting to establish TCP connection with [AF_INET]127.0.0.1:443 [nonblock]
    Thu Feb 5 19:51:21 2015 TCP connection established with [AF_INET]127.0.0.1:443
    Thu Feb 5 19:51:21 2015 TCPv4_CLIENT link local: [undef]
    Thu Feb 5 19:51:21 2015 TCPv4_CLIENT link remote: [AF_INET]127.0.0.1:443
    Thu Feb 5 19:51:22 2015 Connection reset, restarting [-1]
    Thu Feb 5 19:51:22 2015 SIGUSR1[soft,connection-reset] received, process restarting
    Thu Feb 5 19:51:27 2015 Attempting to establish TCP connection with [AF_INET]127.0.0.1:443 [nonblock]
    Thu Feb 5 19:51:27 2015 TCP connection established with [AF_INET]127.0.0.1:443
    Thu Feb 5 19:51:27 2015 TCPv4_CLIENT link local: [undef]
    Thu Feb 5 19:51:27 2015 TCPv4_CLIENT link remote: [AF_INET]127.0.0.1:443
    Thu Feb 5 19:51:27 2015 Connection reset, restarting [-1]
    Thu Feb 5 19:51:27 2015 SIGUSR1[soft,connection-reset] received, process restarting
    (endless loop)

    While in my stunnel server log I see:
    ===========
    2015.02.05 18:51:27 LOG5[6667:3065402480]: Service [openvpn] accepted connection from 192.168.1.2:37616
    2015.02.05 18:51:27 LOG3[6667:3065402480]: connect_blocking: connect 127.0.0.1:1194: Connection refused (111)
    2015.02.05 18:51:27 LOG5[6667:3065402480]: Connection reset: 0 byte(s) sent to SSL, 0 byte(s) sent to socket

    Openvpn log doesn’t have any output. I have removed iptables just in case. Do you have any clue that could help me?

    Thanks a log, regards

  2. Hi

    Thank you for your repply. You were right, I had some typos in the blog post (not in the actual conf files). Now I am managing to connect, but I think I have a route problem. I can’t surf internet and my openvpn client output is:

    ————
    openvpn –config client1.ovpn
    Fri Feb 6 18:41:52 2015 OpenVPN 2.3.2 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Dec 1 2014
    Enter Private Key Password:
    Fri Feb 6 18:41:53 2015 WARNING: this configuration may cache passwords in memory — use the auth-nocache option to prevent this
    Fri Feb 6 18:41:53 2015 Control Channel Authentication: tls-auth using INLINE static key file
    Fri Feb 6 18:41:53 2015 Outgoing Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
    Fri Feb 6 18:41:53 2015 Incoming Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
    Fri Feb 6 18:41:53 2015 Socket Buffers: R=[87380->131072] S=[16384->131072]
    Fri Feb 6 18:41:53 2015 Attempting to establish TCP connection with [AF_INET]127.0.0.1:1194 [nonblock]
    Fri Feb 6 18:41:53 2015 TCP connection established with [AF_INET]127.0.0.1:1194
    Fri Feb 6 18:41:53 2015 TCPv4_CLIENT link local: [undef]
    Fri Feb 6 18:41:53 2015 TCPv4_CLIENT link remote: [AF_INET]127.0.0.1:1194
    Fri Feb 6 18:41:53 2015 TLS: Initial packet from [AF_INET]127.0.0.1:1194, sid=fbc26914 d4514d80
    Fri Feb 6 18:41:54 2015 VERIFY OK: depth=1, C=ES, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=changeme, name=changeme, emailAddress=mail@host.domain
    Fri Feb 6 18:41:54 2015 VERIFY OK: nsCertType=SERVER
    Fri Feb 6 18:41:54 2015 VERIFY OK: depth=0, C=ES, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=filenest.mooo.com, name=changeme, emailAddress=mail@host.domain
    Fri Feb 6 18:41:56 2015 Data Channel Encrypt: Cipher ‘AES-128-CBC’ initialized with 128 bit key
    Fri Feb 6 18:41:56 2015 Data Channel Encrypt: Using 160 bit message hash ‘SHA1’ for HMAC authentication
    Fri Feb 6 18:41:56 2015 Data Channel Decrypt: Cipher ‘AES-128-CBC’ initialized with 128 bit key
    Fri Feb 6 18:41:56 2015 Data Channel Decrypt: Using 160 bit message hash ‘SHA1’ for HMAC authentication
    Fri Feb 6 18:41:56 2015 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA
    Fri Feb 6 18:41:56 2015 [filenest.mooo.com] Peer Connection Initiated with [AF_INET]127.0.0.1:1194
    Fri Feb 6 18:41:58 2015 SENT CONTROL [filenest.mooo.com]: ‘PUSH_REQUEST’ (status=1)
    Fri Feb 6 18:41:59 2015 PUSH: Received control message: ‘PUSH_REPLY,route 10.8.0.1 255.255.255.255,route 10.8.0.0 255.255.255.0,route 192.168.1.200 255.255.255.0,dhcp-option DNS 192.168.1.1,redirect-gateway def1,route 10.8.0.0 255.255.255.0,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5’
    Fri Feb 6 18:41:59 2015 OPTIONS IMPORT: timers and/or timeouts modified
    Fri Feb 6 18:41:59 2015 OPTIONS IMPORT: –ifconfig/up options modified
    Fri Feb 6 18:41:59 2015 OPTIONS IMPORT: route options modified
    Fri Feb 6 18:41:59 2015 OPTIONS IMPORT: –ip-win32 and/or –dhcp-option options modified
    Fri Feb 6 18:41:59 2015 ROUTE_GATEWAY 192.168.43.1/255.255.255.0 IFACE=wlan0 HWADDR=00:1d:0f:b7:a2:b4
    Fri Feb 6 18:41:59 2015 TUN/TAP device tun0 opened
    Fri Feb 6 18:41:59 2015 TUN/TAP TX queue length set to 100
    Fri Feb 6 18:41:59 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
    Fri Feb 6 18:41:59 2015 /sbin/ip link set dev tun0 up mtu 1500
    Fri Feb 6 18:41:59 2015 /sbin/ip addr add dev tun0 local 10.8.0.6 peer 10.8.0.5
    Fri Feb 6 18:41:59 2015 /sbin/ip route add 127.0.0.1/32 via 192.168.43.1
    Fri Feb 6 18:41:59 2015 /sbin/ip route add 0.0.0.0/1 via 10.8.0.5
    Fri Feb 6 18:41:59 2015 /sbin/ip route add 128.0.0.0/1 via 10.8.0.5
    Fri Feb 6 18:41:59 2015 /sbin/ip route add 10.8.0.1/32 via 10.8.0.5
    Fri Feb 6 18:41:59 2015 /sbin/ip route add 10.8.0.0/24 via 10.8.0.5
    Fri Feb 6 18:41:59 2015 /sbin/ip route add 192.168.1.200/24 via 10.8.0.5
    RTNETLINK answers: Invalid argument
    Fri Feb 6 18:41:59 2015 ERROR: Linux route add command failed: external program exited with error status: 2
    Fri Feb 6 18:41:59 2015 /sbin/ip route add 10.8.0.0/24 via 10.8.0.5
    RTNETLINK answers: File exists
    Fri Feb 6 18:41:59 2015 ERROR: Linux route add command failed: external program exited with error status: 2
    Fri Feb 6 18:41:59 2015 Initialization Sequence Completed
    ^CFri Feb 6 18:43:25 2015 event_wait : Interrupted system call (code=4)
    Fri Feb 6 18:43:25 2015 /sbin/ip route del 10.8.0.0/24
    Fri Feb 6 18:43:25 2015 /sbin/ip route del 10.8.0.1/32
    Fri Feb 6 18:43:25 2015 /sbin/ip route del 127.0.0.1/32
    Fri Feb 6 18:43:25 2015 /sbin/ip route del 0.0.0.0/1
    Fri Feb 6 18:43:25 2015 /sbin/ip route del 128.0.0.0/1
    Fri Feb 6 18:43:25 2015 Closing TUN/TAP interface
    Fri Feb 6 18:43:25 2015 /sbin/ip addr del dev tun0 local 10.8.0.6 peer 10.8.0.5
    Fri Feb 6 18:43:25 2015 SIGINT[hard,] received, process exiting
    ————-

    My question is: do I have to add any new route because of the fact that I am using stunnel with openvpn? My conf files are:

    client vpn:
    ——-
    client
    dev tun
    proto tcp
    remote 127.0.0.1 1194
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    ns-cert-type server
    key-direction 1
    cipher AES-128-CBC
    comp-lzo
    verb 3
    mute 20

    client stunnel
    ========
    [openvpn]
    client = yes
    accept = 127.0.0.1:1194
    connect = RPI_PUBLIC_IP:443

    server stunnel
    ========
    sslVersion = all
    options = NO_SSLv2
    cert = /etc/stunnel/server.pem
    pid = /var/run/stunnel.pid
    output = /var/log/stunnel
    debug = 1

    [openvpn]
    client = no
    accept=443
    connect=LOCAL_IP_RPI (wouldnt work with localhost or 127.0.0.1):1194

    sever openvpn
    ==========
    local LOCAL_RPI_IP
    dev tun
    proto tcp
    port 1194
    ca /etc/openvpn/easy-rsa/keys/ca.crt
    cert /etc/openvpn/easy-rsa/keys/raspberrypidos.crt # SWAP WITH YOUR CRT NAME
    key /etc/openvpn/easy-rsa/keys/raspberrypidos.key # SWAP WITH YOUR KEY NAME
    dh /etc/openvpn/easy-rsa/keys/dh1024.pem # If you changed to 2048, change that here!
    server 10.8.0.0 255.255.255.0
    # server and remote endpoints
    ifconfig 10.8.0.1 10.8.0.2
    # Add route to Client routing table for the OpenVPN Server
    push “route 10.8.0.1 255.255.255.255”
    # Add route to Client routing table for the OpenVPN Subnet
    push “route 10.8.0.0 255.255.255.0”
    # your local subnet
    push “route 192.168.1.200 255.255.255.0” # SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
    # Set primary domain name server address to the SOHO Router
    # If your router does not do DNS, you can use Google DNS 8.8.8.8
    push “dhcp-option DNS 192.168.1.1” # This should already match your router address and not need to be changed.
    # Override the Client default gateway by using 0.0.0.0/1 and
    # 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
    # overriding but not wiping out the original default gateway.
    push “redirect-gateway def1”
    client-to-client
    duplicate-cn
    keepalive 10 120
    tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
    cipher AES-128-CBC
    comp-lzo
    user nobody
    group nogroup
    persist-key
    persist-tun
    status /var/log/openvpn-status.log 20
    log /var/log/openvpn.log
    verb 7

    Thanks again, regards

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s