SSL/TLS VPN with stunnel

From the stunnel manual page:

The stunnel program is designed to work as SSL encryption wrapper between remote clients and local (inetd-startable) or remote servers. The concept is that by having non-SSL aware daemons running on your system you can easily set them up to communicate with clients over secure SSL channels.

stunnel can be used to add SSL functionality to commonly used inetd daemons like POP-2, POP-3, and IMAP servers, to standalone daemons like NNTP, SMTP and HTTP, and in tunneling PPP over network sockets without changes to the source code.

I will use stunnel to encapsulate PPP frames into the SSL tunnel, in order to create an SSL VPN between two peers. Both peers will have two network interfaces each:

  • a eth0, or eth0-like interface, which is the native, physical, non-tunneled network interface, used by each peer to directly reach the other via a WAN, insecure connection, like the Internet or a Wireless network.

    Traffic sent directly between peers through eth0 is assumed to be sent in the clear, without confidentiality, authentication or integrity.

  • a ppp0 network interface which acts as a Layer 2 interface, using PPP framing to tunnel traffic between both peers over an insecure network connection. PPP frames will get wrapped inside an SSL/TLS session between both peers and delivered via the real eth0 interface.

    Thus, traffic sent to the ppp0 interface will get wrapped inside a PPP frame, then transported over an SSL/TLS tunnel through the eth0 insecure interface to the other peer.

    SSL/TLS adds confidentiality, authentication and integrity by means of an SSL/TLS session.

Configuring the server

The configuration file for the stunnel server will be stored in the /root/stunnel-server.conf file:

# The CA certificate file CAfile = /root/cacert.pem # The server public key certificate cert = /root/server.pem # The server private key key = /root/server.key # Name of server PID file pid = /root/server.pid # Verify peer certificate verify = 2 # The directory where all the certificates can be found # Only used when verify = 3 # CApath = /root # Some debugging stuff debug = 7 # output = /root/server.log # Use it for client mode client = no foreground = yes # Protocol Specific options # We need to specify DES-CBC3-SHA since there are some AES # ciphers that, when used with RSA, can't be decoded by ssldump ciphers = DES-CBC3-SHA:IDEA-CBC-MD5 # Service-level configuration [vpn] # incoming port number accept = 9871 # argv[0] for the PPP server exec = /usr/bin/pppd # argv[0], argv[1], ... argv[n] for the PPP server execargs = /usr/sbin/pppd debug noauth noaccomp noccp nodeflate nopcomp novj novjccomp 192.168.1.1:192.168.1.2 # Use a pty, since the PPP server will write PPP frames to a pty pty = yes

Some of the options used in this configuration file are described in the next paragraphs:

  • CAfile, cert and key point to the location of the PEM-encoded CA certificate file, PEM-encoded server public certificate and PEM-encoded server private key, respectively.
  • verify defines the level of peer certificate verification:
    1. verify peer certificate, if present
    2. always verify peer certificate
    3. verify peer with locally installed certificate

    If no verify option is supplied, no peer certificate verification is performed.

  • client = no tells stunnel this side will act as the server.
  • foreground =yes requests stunnel not to fork off and log to stderr instead of using syslog.
  • ciphers = DES-CBC3-SHA:IDEA-CBC-MD5 configures the ciphers preferred list for the server when negotiating a cipher and MAC protocol with the client.

    I have chosen DES-CBC3-SHA in first place and IDEA-CBC-MD5 in second place cause if no cipher list is supplied, OpenSSL tends to select RSA-AES-256-SHA which ssldump is, at the time of this writing, is unable to decode.

  • accept defines the port stunnel will listen to.
  • exec specifies the program to execute in order to set up the PPP server used to encapsulate traffic inside the SSL/TLS tunnel.

    In this case, we use /usr/sbin/pppd.

  • execargs defines the arguments, starting at argv[0], that will be supplied to the command specified by the exec option (in this case, /usr/sbin/pppd):
    • debug, enables debugging information
    • noauth, disables any form of PPP authentication
    • noccp novj novjccomp noaccomp, disables any form of compression.

      noaccomp disables address/control compression in both directions.
      noccp disables CCP (Compression Control Protocol) negotiation.
      nodeflate disables Deflate compression support.
      nopcomp disables protocol field compression negotiation, in both the receive and the transmit direction.
      novj disables Van Jacobson style TCP/IP header compression in both the transmit and receive direction.
      novjccomp disables the connection-ID compression option in the Van Jacobson style TCP/IP header compression.

      This will be useful when using ssldump to decode traffic between the client and the server.

    • 192.168.1.1:192.168.1.2, tells the PPP server the remote peer ppp0 interface will get assigned IP 192.168.1.2, while the server, local ppp0 interface will get assigned IP 192.168.1.1.
  • pty = yes tells stunnel to allocate a pseudo-terminal used for the exec program.

    stunnel will get traffic from the remote peer through the SSL/TLS tunnel, will decrypt it using the private key and the resulting PPP frame will be written to this pseudo-tty so the PPP server can process it and send it back to the TCP/IP stack for further processing.

    Any time the local machine sends traffic to the ppp0 interface, the PPP server capture it and encapsulate it into a PPP frame that will get written to the pseudo-tty. stunnel will see that PPP frame, will send it to the remote peer trough the SSL/TLS tunnel.

Launching the server

To make things easier, create a shell-script called launch-server.sh with the following lines:

#!/bin/sh /usr/sbin/stunnel /root/stunnel.conf

Configuring the client

The configuration file for the stunnel client will be stored in the /root/stunnel-client.conf file:

# The CA certificate file CAfile = /root/cacert.pem # The client public key certificate cert = /root/client.pem # The client private key key = /root/client.key # Name of client PID file pid = /root/client.pid # Verify peer certificate verify = 2 # The directory where all the certificates can be found # Only used when verify = 3 # CApath = /root # Some debugging stuff debug = 7 #output = /root/client.log # Use it for client mode client = yes foreground = yes # Service-level configuration # host and port where stunnel server peer is listening connect = stunnel-server:9871

Some of the options used in this configuration file are described in the next paragraphs:

  • CAfile, cert and key point to the location of the PEM-encoded CA certificate file, PEM-encoded client public certificate and PEM-encoded client private key, respectively.
  • verify defines the level of peer certificate verification:
    1. verify peer certificate, if present
    2. always verify peer certificate
    3. verify peer with locally installed certificate

    If no verify option is supplied, no peer certificate verification is performed.

  • client = yes tells stunnel this side will act as the client.
  • foreground =yes requests stunnel not to fork off and log to stderr instead of using syslog.
  • connect is used when client = yes and tells stunnel which host and port to connect to.

Launching the client

To make things easier, create a shell-script called launch-client.sh with the following lines:

#!/bin/sh /usr/sbin/pppd noauth debug dump passive noaccomp noccp nodeflate nopcomp novj novjccomp nodetach pty "/usr/sbin/stunnel /root/stunnel.conf"

This will launch the PPP client, pppd, using an SSL/TLS tunnel supplied by stunnel as the encapsulating Layer 2 tunneling protocol.

  • noccp novj novjccomp noaccomp, disables any form of compression.

    noaccomp disables address/control compression in both directions.
    noccp disables CCP (Compression Control Protocol) negotiation.
    nodeflate disables Deflate compression support.
    nopcomp disables protocol field compression negotiation, in both the receive and the transmit direction.
    novj disables Van Jacobson style TCP/IP header compression in both the transmit and receive direction.
    novjccomp disables the connection-ID compression option in the Van Jacobson style TCP/IP header compression.

    This will be useful when using ssldump to decode traffic between the client and the server.

  • debug, enables debugging information
  • noauth, disables any form of PPP authentication
  • passive, enables the passive option in the LCP.

    With this option, pppd will attempt to initiate a connection. If no reply is received from the peer, pppd will then just wait passively for a valid LCP packet from the peer, instead of exiting, as it would do without this option.

  • nodetach, tells pppd to not detach from the controlling terminal. Useful to keep pppd in the foreground, so it can get stopped with a SIGINT signal.
  • pty, specifies the command script used to communicate rather than a specific terminal device. pppd will allocate itself a pseudo-tty master/slave pair and use the slave as its terminal device. The script will be run in a child process with the pseudo-tty master as its standard input and output.

    The command script is just the invocation to stunnel, in order to encapsulate all the PPP frames generated by pppd inside the SSL/TLS tunnel.

Testing connectivity

After launching the client, a new ppp0 interface should be automatically configured with the following parameters:

ppp0      Link encap:Point-to-Point Protocol
          inet addr:192.168.1.2  P-t-P:192.168.1.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:30 (30.0 b)  TX bytes:30 (30.0 b)

A simply ping 192.168.1.1 command executed from the client should suffice to trigger traffic through the SSL/TLS tunnel and test connectivity.

Advertisements

11 thoughts on “SSL/TLS VPN with stunnel

  1. Pingback: Docunext Tech Stuff Archive » PC Engines WRAP

  2. Hi, i follow your tutorial and i got this:

    [root@deploy ~]# sh launch-client.sh
    pppd options in effect:
    debug # (from command line)
    nodetach # (from command line)
    dump # (from command line)
    noauth # (from command line)
    # (from /etc/ppp/options)
    pty /usr/sbin/stunnel /etc/stunnel/stunnel.conf # (from command line)
    noaccomp # (from command line)
    nopcomp # (from command line)
    passive # (from command line)
    novj # (from command line)
    novjccomp # (from command line)
    noccp # (from command line)
    nodeflate # (from command line)
    2009.02.03 20:39:49 LOG7[16896:3086616256]: RAND_status claims sufficient entropy for the PRNG
    2009.02.03 20:39:49 LOG6[16896:3086616256]: PRNG seeded successfully
    2009.02.03 20:39:49 LOG7[16896:3086616256]: Certificate: /etc/stunnel/stunnel.pem
    2009.02.03 20:39:49 LOG7[16896:3086616256]: Key file: /etc/stunnel/stunnel.key
    2009.02.03 20:39:49 LOG7[16896:3086616256]: Loaded verify certificates from /etc/stunnel/stunnel.pem
    2009.02.03 20:39:49 LOG7[16896:3086616256]: SSL context initialized for service stunnel
    using channel 20
    Using interface ppp0
    Connect: ppp0 /dev/pts/3
    sent [LCP ConfReq id=0x1 ]
    sent [LCP ConfReq id=0x1 ]
    sent [LCP ConfReq id=0x1 ]
    Modem hangup
    Connection terminated.
    Script /usr/sbin/stunnel /etc/stunnel/stunnel.conf finished (pid 16896), status = 0x0
    [root@deploy ~]#

    Can you help me please?
    Regards

  3. Can I just say that of a relief to find someone who actually knows just what exactly theyre discussing on the internet. You certainly know how to carry an issue for you to light making it crucial. More people ought to read this along with understand this part of the narrative. I cannot believe you aren’t more popular as you definitely develop the gift.

  4. Orange Limited Edition Headphones,Dre studio Pittsburgh,Beats studio Pittsburgh Steelers,Pittsburgh Beats studio,Beats studio Red Sox,Dre studio Red Sox,Red Sox studio Edition Headphones,Beats studio Spiderman,Dre studio Spiderman,studio Spiderman For Justin Bieber,Dre studio Superman,Beats studio Superman For Dwight Howard,Superman Special Edition,Cheap Beats solo HD black,Cheap Beats By Dre solo HD,Cheap black Beats solo HD,Cheap Beats By Dre solo HD with controltalk,Cheap Beats solo HD with controltalk white,Cheap white Beats solo HD,Cheap Beats studio Kobe Bryant,Beats By Dre Australia,Cheap Beats By Dre,Beats By Dr.Dre,Beats By Dre Headphones,free shipping beats by dre,beats by dre sale,cheap beats headphones australia,hot beats headphones,cheap beats pro headphones,cheap beats Solo HD headphones,

  5. Hi. Good news. Your solution between Microsoft Windows 7 and a couple of Microsoft Windows 2000 PCs was working perfectly for some time. Bad news is that although Microsoft Windows 2000 can access Microsoft Windows 7, I can no longer see the Microsoft Windows 2000 PCs across the network. I have double checked the security settings. I am not aware of having made any changes to either computer.

  6. I’m still learning from you, while I’m improving myself. I absolutely love reading everything that is written on your site.Keep the information coming. I liked it!

  7. The enterprise card printing supplied by Shade Printing Pros can aid you develop the excellent company card. If you need to have high quality cheap business card printing, we’re the firm for you!

  8. You really make it seem really easy along with your
    presentation but I to find this matter to be actually one thing that I feel I might never understand.
    It seems too complicated and extremely broad for
    me. I’m having a look forward on your next submit, I’ll attempt to get the grasp of
    it!

  9. My spouse and I stumbled over here different page and thought I should
    check things out. I like what I see so now i’m following you.
    Look forward to looking into your web page for a second time.

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