<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Felipe Alfaro Solana &#187; VPN</title>
	<atom:link href="http://www.felipe-alfaro.org/blog/category/vpn/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.felipe-alfaro.org/blog</link>
	<description>A little bit of technology, security and networking with Linux, FreeBSD and Mac OS X, plus some personal opinions.</description>
	<lastBuildDate>Sun, 23 Oct 2011 16:46:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>IPSec transport mode with X.509 certificates</title>
		<link>http://www.felipe-alfaro.org/blog/2005/11/19/ipsec-transport-mode-with-x509-certificates/</link>
		<comments>http://www.felipe-alfaro.org/blog/2005/11/19/ipsec-transport-mode-with-x509-certificates/#comments</comments>
		<pubDate>Sat, 19 Nov 2005 12:46:26 +0000</pubDate>
		<dc:creator>Felipe Alfaro Solana</dc:creator>
				<category><![CDATA[IPSec]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[VPN]]></category>
		<category><![CDATA[X.509]]></category>

		<guid isPermaLink="false">http://felipe-alfaro.org/blog/?p=76</guid>
		<description><![CDATA[Scenario This article describes how to create a secure network-level transport between two hosts. All traffic sent between both hosts will be encrypted automatically as in enters the TCP/IP stack at the network (IP) level by using IPSec Encapsulating Security Payload (ESP) protocol. For more details about IPSec, read IPSec pilot between glass and teapot. [...]]]></description>
			<content:encoded><![CDATA[<h4>Scenario</h4>
<p>This article describes how to create a secure network-level transport between two hosts. All traffic sent between both hosts will be encrypted automatically as in enters the TCP/IP stack at the network (IP) level by using IPSec Encapsulating Security Payload (ESP) protocol.</p>
<p>For more details about IPSec, read <a href="http://felipe-alfaro.org/blog/2004/02/26/ipsec-pilot-between-glass-and-teapot/" title="IPSec pilot between glass and teapot">IPSec pilot between glass and teapot</a>.</p>
<h4>Security Policy Database (SPD) configuration</h4>
<p>The Security Policy Database (SPD) defines which IP traffic flows are to be affected by IPSec. Any traffic protected by IPSec can be protected by two different security mechanisms:</p>
<ul>
<li><b>Confidentiality.</b></p>
<p>Is achieved by using IPSec Encapsulating Security Payload (ESP) protocol.</p>
<p>The IPSec ESP protocol cyphers the contents of the payload to be transported over IP. ESP, optionally, offers authentication and integrity, but it is considered weak since it does only affect the payload but not the header of the encapsulating IP datagram.</li>
<li><b>Authentication and Integrity.</b>
<p>Is achieved by using IPSec Authentication Header (AH) protocol.</p>
<p>The IPSec AH protocol protects that payload and any unmutable field of the encapsulating IP header.</li>
</ul>
<p>By configuring the SPD, it is possible to use:</p>
<ul>
<li>IPSec Transport Mode to protect all the traffic sent between two hosts.</li>
<li>IPSec Tunnel Mode to protect all the traffic sent between to networks.</li>
</ul>
<h5>For the machine <em>ipsec-a</em>:</h5>
<p>Create the file <tt>/etc/racoon/setkey.sh</tt> with the following lines:</p>
<pre>
<div>#!/sbin/setkey -f
spdflush ;
spdadd 192.168.0.40 192.168.0.41 any -P out ipsec esp/transport//require ;
spdadd 192.168.0.41 192.168.0.40 any -P in  ipsec esp/transport//require ;</div>
</pre>
<p>This file should be marked executable and will be executed before launching <em>racoon</em> in order to populate the SPD with the proper entries.</p>
<h5>For the machine <em>ipsec-b</em>:</h5>
<p>Create the file <tt>/etc/racoon/setkey.sh</tt> with the following lines:</p>
<pre>
<div>#!/sbin/setkey -f
spdflush ;
spdadd 192.168.0.41 192.168.0.40 any -P out ipsec esp/transport//require ;
spdadd 192.168.0.40 192.168.0.41 any -P in  ipsec esp/transport//require ;</div>
</pre>
<p>This file should be marked executable and will be executed before launching <em>racoon</em> in order to populate the SPD with the proper entries.</p>
<h4>Racoon configuration</h4>
<p><em>racoon</em> is a user-space daemon in charge of negotiating and establishing the Security Associations (SA) between two peer.</p>
<p>When the kernel sees an IP datagram, affected by a SPD rule, for which there is no SA yet established, the kernel will invoke <em>racoon</em> in order to negotiate and set it up with the corresponding peer defined in the SPD.</p>
<p>The peers can authenticate using some of the following:</p>
<ul>
<li><b>Pre-Shared Keys (PSK)</b></p>
<p>Both peers mutually agree on a shared secret, which is manually configured by the administrator and stored in the file <tt>/etc/racoon/psk.txt</tt>.</li>
<li><b>RSA Signature</b>
<p>Each peer has an associated private key and public key X.509 certificate. Authentication takes place by exchanging certificates between peers and validating them, while RSA is used for authentication.</li>
<li><b>GSSAPI</b>
<p>Kerberos is used for authentication of both peers.</li>
</ul>
<p>In out scenario, RSA Signature using X.509 public key certificates will be used for authentication between the peers so, in first place, we need to generate private keys and their corresponding certificates for each peer. The steps used to generate the certificates are described in <a href="http://felipe-alfaro.org/blog/2005/11/18/setting-up-certificate-authority-ca-using-openssl/" title="Setting up Certificate Authority (CA) using OpenSSL">Setting up Certificate Authority (CA) using OpenSSL</a>.</p>
<p>The configuration for both peers is identical, so we will use the same <em>racoon</em> configuration file. However, the private key and public key certificate for each peer is different, so we should take this into consideration.</p>
<p>The peer private key must be installed into <tt>/etc/racoon/certs/key.pem</tt>, the peer signed public key certificate into <tt>/etc/racooon/certs/cert.pem</tt> and the CA public key certificate into <tt>/etc/racoon/certs/cacert.pem</tt>.</p>
<p>This is the <tt>/etc/racoon/racoon.conf</tt> configuration file:</p>
<pre>
<div>path include "/etc/racoon";
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";

remote anonymous
{
	# Some IPSec implementations have been found to
	# be vulnerable when used in aggressive exchange
	# mode
	exchange_mode main ;

	# Allow for the extension described in RFC 2407
	# called Domain of Interpretation which allows
	# negotiation of the traditional 32-bit sequence
	# numbers or extended 64-bit sequence numbers
	doi ipsec_doi ;

	# Local identifier is taken from the Subject field
	# of the X.509 certificate (Distinguised Name)
	my_identifier asn1dn ;

	# Remote identifier is taken from the Subject field
	# of the X.509 certificate presented by the remote
	# peer (Distinguised Name)
	peers_identifier asn1dn ;

	# Checks that the oeer identity that appears in the
	# ID payload matches the identity specified in the
	# peers_identifier option
	verify_identifier on ;

	# Specifies the path to the certificate and private
	# key files, encoded in PEM, relative to the
	# "path certificate" option specified above
	certificate_type x509 "cert.pem" "key.pem" ;

	# Specifies the path to the CA certificate file,
	# encoded in PEM, relative to the "path certificate"
	# option specified above
	ca_type x509 "cacert.pem" ;

	# Configures the size of the nonce in bytes, which
	# must be no less than 8 and no more than 256
	nonce_size 16 ;

	# Lifetime the Phase 1 SA proposal
	lifetime time 24 hour ;

	proposal
	{
		# Encryption algorithm for phase 1
		encryption_algorithm 3des ;

		# Hash algorithm for phase 1
		hash_algorithm sha1 ;

		# RSA Signature authentication
		authentication_method rsasig ;

		# Diffie-Hellman group for phase 1
		dh_group 2 ;
	}
}

sainfo anonymous
{
	# Diffie-Hellman group for phase 2
	pfs_group 2;

	# Lifetime for the SA
	lifetime time 12 hour ;

	# Encryption algorithms to be used in the SA
	encryption_algorithm 3des, blowfish, des, rijndael ;

	# Authentication algorithms to be used in the SA
	authentication_algorithm hmac_sha1, hmac_md5 ;

	# Use deflate compression (IPComp)
	compression_algorithm deflate ;
}</div>
</pre>
<h4>Starting peers</h4>
<p>For every peer, we need to launch <em>racoon</em>. For testing purpouses, we will launch <em>racoon</em> in foreground, so all messages are dumped to the screen:</p>
<pre>/usr/sbin/racoon -F</pre>
<p><em>racoon</em> will dump the following messages to the console:</p>
<pre>INFO: @(#)ipsec-tools 0.5 (http://ipsec-tools.sourceforge.net)
INFO: @(#)This product linked OpenSSL 0.9.7f 22 Mar 2005 \
      (http://www.openssl.org/)
INFO: 127.0.0.1[500] used as isakmp port (fd=7)
INFO: 127.0.0.1[500] used for NAT-T
INFO: 192.168.0.41[500] used as isakmp port (fd=8)
INFO: 192.168.0.41[500] used for NAT-T
INFO: ::1[500] used as isakmp port (fd=9)
INFO: fe80::20c:29ff:fea1:d55c%eth0[500] used as isakmp port (fd=10)</pre>
<p>Next, we need to initialize the SPD:</p>
<pre>/etc/racoon/setkey.sh</pre>
<h4>Testing connectivity</h4>
<p>To trigger the SA establishment we can <tt>ping</tt> the other host. The kernel will apply the SPD policy and will ask <em>racoon</em> to negotiate and set up the proper SA between both peers. <em>racoon</em> should dump something like this to the console:</p>
<pre>INFO: IPsec-SA request for 192.168.0.40 queued due to no phase1 found.
INFO: initiate new phase 1 negotiation: \
      192.168.0.41[500]< =>192.168.0.40[500]
INFO: begin Identity Protection mode.
INFO: received Vendor ID: DPD
WARNING: unable to get certificate CRL(3) at depth:0 SubjectName:\
         /C=ES/ST=Madrid/O=Software AG/OU=IT/CN=ipsec-a
WARNING: unable to get certificate CRL(3) at depth:1 SubjectName:\
         /C=ES/ST=Madrid/L=Madrid/O=Software AG/OU=IT/CN=ca-server
INFO: ISAKMP-SA established 192.168.0.41[500]-192.168.0.40[500] \
      spi:2698c81446191f6c:9b9127e3b6956065
INFO: initiate new phase 2 negotiation: 192.168.0.41[0]< =>192.168.0.40[0]
INFO: IPsec-SA established: ESP/Transport 192.168.0.40->192.168.0.41 \
      spi=78608282(0x4af779a)
INFO: IPsec-SA established: ESP/Transport 192.168.0.41->192.168.0.40 \
      spi=118550227(0x710eed3)</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.felipe-alfaro.org/blog/2005/11/19/ipsec-transport-mode-with-x509-certificates/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>SSL/TLS VPN with stunnel</title>
		<link>http://www.felipe-alfaro.org/blog/2005/11/18/ssltls-vpn-with-stunnel/</link>
		<comments>http://www.felipe-alfaro.org/blog/2005/11/18/ssltls-vpn-with-stunnel/#comments</comments>
		<pubDate>Fri, 18 Nov 2005 17:54:42 +0000</pubDate>
		<dc:creator>Felipe Alfaro Solana</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://felipe-alfaro.org/blog/?p=74</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>From the <em>stunnel</em> manual page:</p>
<blockquote><p>The <em>stunnel</em> 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.</p>
<p><em>stunnel</em> 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.</p></blockquote>
<p>I will use <em>stunnel</em> 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:</p>
<ul>
<li>a <em>eth0</em>, or <em>eth0</em>-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.</p>
<p>Traffic sent directly between peers through <em>eth0</em> is assumed to be sent in the clear, without confidentiality, authentication or integrity.</li>
<li>a <em>ppp0</em> 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 <em>eth0</em> interface.
<p>Thus, traffic sent to the <em>ppp0</em> interface will get wrapped inside a PPP frame, then transported over an SSL/TLS tunnel through the <em>eth0</em> insecure interface to the other peer.</p>
<p>SSL/TLS adds confidentiality, authentication and integrity by means of an SSL/TLS session.</li>
</ul>
<h3>Configuring the server</h3>
<p>The configuration file for the <em>stunnel</em> server will be stored in the <em>/root/stunnel-server.conf</em> file:</p>
<pre>
<div># 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</div>
</pre>
<p>Some of the options used in this configuration file are described in the next paragraphs:</p>
<ul>
<li><em>CAfile</em>, <em>cert</em> and <em>key</em> point to the location of the PEM-encoded CA certificate file, PEM-encoded server public certificate and PEM-encoded server private key, respectively.</li>
<li><em>verify</em> defines the level of peer certificate verification:
<ol>
<li>verify peer certificate, if present</li>
<li>always verify peer certificate</li>
<li>verify peer with locally installed certificate</li>
</ol>
<p>If no <em>verify</em> option is supplied, no peer certificate verification is performed.</li>
<li><em>client = no</em> tells <em>stunnel</em> this side will act as the server.</li>
<li><em>foreground =yes</em> requests <em>stunnel</em> not to fork off and log to <em>stderr</em> instead of using <em>syslog</em>.</li>
<li><em>ciphers = DES-CBC3-SHA:IDEA-CBC-MD5</em> configures the ciphers preferred list for the server when negotiating a cipher and MAC protocol with the client.
<p>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 <em>ssldump</em> is, at the time of this writing, is unable to decode.</li>
<li><em>accept</em> defines the port <em>stunnel</em> will listen to.</li>
<li><em>exec</em> specifies the program to execute in order to set up the PPP server used to encapsulate traffic inside the SSL/TLS tunnel.
<p>In this case, we use <em>/usr/sbin/pppd</em>.</li>
<li><em>execargs</em> defines the arguments, starting at argv[0], that will be supplied to the command specified by the <em>exec</em> option (in this case, <em>/usr/sbin/pppd</em>):
<ul>
<li><em>debug</em>, enables debugging information</li>
<li><em>noauth</em>, disables any form of PPP authentication</li>
<li><em>noccp novj novjccomp noaccomp</em>, disables any form of compression.
<p><em>noaccomp</em> disables address/control compression in both directions.<br />
<em>noccp</em> disables CCP (Compression Control Protocol) negotiation.<br />
<em>nodeflate</em> disables Deflate compression support.<br />
<em>nopcomp</em> disables protocol field compression negotiation, in both the receive and the transmit direction.<br />
<em>novj</em> disables Van Jacobson style TCP/IP header compression in both the transmit and receive direction.<br />
<em>novjccomp</em> disables the connection-ID compression option in the Van Jacobson style TCP/IP header compression.</p>
<p>This will be useful when using <em>ssldump</em> to decode traffic between the client and the server.</li>
<li><em>192.168.1.1:192.168.1.2</em>, 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.</li>
</ul>
</li>
<li><em>pty = yes</em> tells <em>stunnel</em> to allocate a pseudo-terminal used for the <em>exec</em> program.
<p><em>stunnel</em> 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.</p>
<p>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. <em>stunnel</em> will see that PPP frame, will send it to the remote peer trough the SSL/TLS tunnel.</li>
</ul>
<h3>Launching the server</h3>
<p>To make things easier, create a shell-script called <em>launch-server.sh</em> with the following lines:</p>
<pre>
<div>#!/bin/sh
/usr/sbin/stunnel /root/stunnel.conf</div>
</pre>
<h3>Configuring the client</h3>
<p>The configuration file for the <em>stunnel</em> client will be stored in the <em>/root/stunnel-client.conf</em> file:</p>
<pre>
<div># 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</div>
</pre>
<p>Some of the options used in this configuration file are described in the next paragraphs:</p>
<ul>
<li><em>CAfile</em>, <em>cert</em> and <em>key</em> point to the location of the PEM-encoded CA certificate file, PEM-encoded client public certificate and PEM-encoded client private key, respectively.</li>
<li><em>verify</em> defines the level of peer certificate verification:
<ol>
<li>verify peer certificate, if present</li>
<li>always verify peer certificate</li>
<li>verify peer with locally installed certificate</li>
</ol>
<p>If no <em>verify</em> option is supplied, no peer certificate verification is performed.</li>
<li><em>client = yes</em> tells <em>stunnel</em> this side will act as the client.</li>
<li><em>foreground =yes</em> requests <em>stunnel</em> not to fork off and log to <em>stderr</em> instead of using <em>syslog</em>.</li>
<li><em>connect</em> is used when <em>client = yes</em> and tells <em>stunnel</em> which host and port to connect to.</li>
</ul>
<h3>Launching the client</h3>
<p>To make things easier, create a shell-script called <em>launch-client.sh</em> with the following lines:</p>
<pre>
<div>#!/bin/sh
/usr/sbin/pppd noauth debug dump passive noaccomp noccp \
  nodeflate nopcomp novj novjccomp nodetach \
  pty "/usr/sbin/stunnel /root/stunnel.conf"</div>
</pre>
<p>This will launch the PPP client, <em>pppd</em>, using an SSL/TLS tunnel supplied by <em>stunnel</em> as the encapsulating Layer 2 tunneling protocol.</p>
<ul>
<li><em>noccp novj novjccomp noaccomp</em>, disables any form of compression.</p>
<p><em>noaccomp</em> disables address/control compression in both directions.<br />
<em>noccp</em> disables CCP (Compression Control Protocol) negotiation.<br />
<em>nodeflate</em> disables Deflate compression support.<br />
<em>nopcomp</em> disables protocol field compression negotiation, in both the receive and the transmit direction.<br />
<em>novj</em> disables Van Jacobson style TCP/IP header compression in both the transmit and receive direction.<br />
<em>novjccomp</em> disables the connection-ID compression option in the Van Jacobson style TCP/IP header compression.</p>
<p>This will be useful when using <em>ssldump</em> to decode traffic between the client and the server.</li>
<li><em>debug</em>, enables debugging information</li>
<li><em>noauth</em>, disables any form of PPP authentication</li>
<li><em>passive</em>, enables the passive option in the LCP.
<p>With this option, <em>pppd</em> will attempt to initiate a connection. If no reply is received from the peer, <em>pppd</em> will then just wait passively for a valid LCP packet from the peer, instead of exiting, as it would do without this option.</li>
<li><em>nodetach</em><em>, tells </em><em>pppd</em> to not detach from the controlling terminal. Useful to keep <em>pppd</em> in the foreground, so it can get stopped with a SIGINT signal.</li>
<li><em>pty</em>, specifies the command script used to communicate rather than a specific terminal device. <em>pppd</em> 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.
<p>The command script is just the invocation to stunnel, in order to encapsulate all the PPP frames generated by <em>pppd</em> inside the SSL/TLS tunnel.</li>
</ul>
<h3>Testing connectivity</h3>
<p>After launching the client, a new <em>ppp0</em> interface should be automatically configured with the following parameters:</p>
<pre>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)</pre>
<p>A simply <tt>ping 192.168.1.1</tt> command executed from the client should suffice to trigger traffic through the SSL/TLS tunnel and test connectivity.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.felipe-alfaro.org/blog/2005/11/18/ssltls-vpn-with-stunnel/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>SSLTunnel</title>
		<link>http://www.felipe-alfaro.org/blog/2005/11/14/ssltunnel/</link>
		<comments>http://www.felipe-alfaro.org/blog/2005/11/14/ssltunnel/#comments</comments>
		<pubDate>Mon, 14 Nov 2005 00:58:30 +0000</pubDate>
		<dc:creator>Felipe Alfaro Solana</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://felipe-alfaro.org/blog/?p=69</guid>
		<description><![CDATA[SSLTunnel is a beautiful piece of software used to create an SSL/TLS VPN between two hosts, usually a client host and a VPN concentrator or server. Inside this tunnel, the traffic between the client and the server gets encapsulated inside PPP frames which are encapsulated inside the SSL/TLS tunnel. The tunnel itself is built using [...]]]></description>
			<content:encoded><![CDATA[<p><a href ="http://www.hsc.fr/ressources/outils/ssltunnel/index.html.en" title="SSLTunnel"><samp>SSLTunnel</samp></a> is a beautiful piece of software used to create an SSL/TLS VPN between two hosts, usually a client host and a VPN concentrator or server. Inside this tunnel, the traffic between the client and the server gets encapsulated inside PPP frames which are encapsulated inside the SSL/TLS tunnel. The tunnel itself is built using kernel PPP support, which materializes in the form of a ppp0 network interface.</p>
<p><samp>SSLTunnel</samp> requires the following:</p>
<ul>
<li>PPP daemon (tested with ppp-2.4.3-6)</li>
<li>PPP kernel support, like a ppp0 interface (minimally ppp_generic, ppp_async, ppp_deflate kernel modules)</li>
<li>OpenSSL (tested with openssl-0.9.8a-1)</li>
</ul>
<p>This describes roughly how <samp>SSLTunnel</samp> works:</p>
<blockquote>
<ul>
<li>the server listens on port 443 of the destination machine</li>
<li>the client connects himself (if need be, through a relay like Squid, ISA-Server, the proxy does not have *ANY* mean to check if it is a navigator < - > HTTPS Web server session, because the beginning of the not crypted session and the SSL negotiation are exactly identical)</li>
<li>at the establishment of the connection, the server forks</li>
<li>the server sends its certificate, the client checks that it is well signed by an authority it trusts</li>
<li>the client sends his certificate</li>
<li>the server checks this certificate and seeks if it corresponds to a certificate declared in its base</li>
<li>the crypted session starts</li>
<li>the server sends its banner with its version number and its protocol version</li>
<li>the client receives the banner, checks and sends his</li>
<li>the client forks, opens a pty, launches pppd in client mode on this pty, without specifying which IP address it wants</li>
<li>the server gets PPP parameters from the user file, changes its identity, opens a pty, forks and launches pppd on this pty with the options given by the file</li>
<li>the PPP session is established between the two ends, the program at each end cyphers/uncyphers and reads/sends the data in the pty connected to pppd.</li>
</ul>
</blockquote>
<h3>Server</h3>
<p>The following section describes how to get the source code for <samp>SSLTunnel</samp>, how to compile and patch it, how to configure it and how to set it up.</p>
<h4>Server compilation</h4>
<p>At the moment of this writing, the last stable version of <samp>SSLTunnel</samp> is 1.15, which can be obtained from <a href="http://www.hsc.fr/ressources/outils/ssltunnel/download/ssltunnel-1.15.tar.gz">here</a>.</p>
<p>Before compiling the server components of SSLTunnel, I applied the following <a href="/blog/wp-content/ssltunnel-1.15-server.patch">patch</a> to SSLTunnel 1.15:</p>
<pre>
<div>--- ssltunnel-1.15/server/main.c.old	2005-11-13 18:45:56.000000000 +0000
+++ ssltunnel-1.15/server/main.c	2005-11-13 18:29:14.000000000 +0000
@@ -796,7 +796,7 @@
   ctx=SSL_CTX_new(meth);

   /* Load our keys and certificates*/
-  if(!(SSL_CTX_use_certificate_chain_file(ctx, certfile)))
+  if(!(SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM)))
       berr_exit("Can't read certificate file");

   if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM)))</div>
</pre>
<p>This patch essentially allows using a PEM-encoded X.509 certificate file for the server certificate instead of a PKCS#12-encoded chain of certificates, which eases the configuration and certificate generation a lot.</p>
<pre>tar xvfz ssltunnel-<version>.tar.gz
cd ssltunnel-</version><version>
./configure --disable-client
make
make install</version></pre>
<p>This will install the following files:</p>
<ul>
<li><samp>/usr/local/libexec/pppserver</samp>
<p>The VPN server daemon.</li>
<li><samp>/usr/local/etc/ssltunnel/tunnel.conf</samp>
<p><samp>pppserver</samp> configuration file.</li>
<li><samp>/usr/local/etc/ssltunnel/tunnel.conf.default</samp>
<p>Default configuration file.</li>
<li><samp>/usr/local/sbin/pppwho</samp>
<p>Used to query the utmp(3) file mantained by <samp>pppserver</samp> with the list of currently established tunnels.</li>
</ul>
<h4>Server certificate generation</h4>
<p>Once the server components of SSLTunnel are built and installed, the <samp>pppserver</samp> certificate and its corresponding private key must be created. For information on how to create a CA using OpenSSL and generating server and client certificates, read <a href="http://felipe-alfaro.org/blog/2005/11/18/setting-up-certificate-authority-ca-using-openssl/" title="Setting up Certificate Authority (CA) using OpenSSL">Setting up Certificate Authority (CA) using OpenSSL</a>.</p>
<h4>Server configuration</h4>
<p>The CA certificate will be installed as <samp>/usr/local/etc/ssltunnel/cacert.pem</samp>. The <samp>pppserver</samp> signed certificate will be installed as <samp>/usr/local/etc/ssltunnel/server.pem</samp>. The VPN private key will be installed as <samp>/usr/local/etc/ssltunnel/server.key</samp> and will be properly protected (0600 permission mask).</p>
<p>The <samp>pppserver</samp> configuration is stored in <samp>/usr/local/etc/ssltunnel/tunnel.conf</samp>, and should look like this:</p>
<pre>keyfile        /usr/local/etc/ssltunnel/server.key
certfile       /usr/local/etc/ssltunnel/server.pem
cacertfile     /usr/local/etc/ssltunnel/cacert.pem
userfile       /usr/local/etc/ssltunnel/users
wtmp           /var/log/ssltunnel.wtmp
pidfile        /var/run/pppserver.pid
timeout        20
maxusers       10
port           443
#listenaddr    192.168.0.1,192.168.1.1
lockdir        /var/lock/ssltunnel</pre>
<p>Following is a brief description of every configuration option:</p>
<ul>
<li><samp>keyfile</samp> points to the VPN server private key.</li>
<li><samp>certfile</samp> points to the VPN server certificate.</li>
<li><samp>cacertfile</samp> points to the CA certificate.</li>
<li><samp>userfile</samp> points to the file that defines which users are allowed to request a tunnel to be established.</li>
<li><samp>wtmp</samp> points to a utmp(3) file that is maintained by <samp>pppserver</samp>. This file stores information about currently established tunnels and can be queried by using the <samp>pppwho</samp> command.</li>
<li><samp>pidfile</samp> points to the file that holds the PID of the currently <samp>pppserver</samp> daemon.</li>
<li><samp>timeout</samp> defines how much time must be elapsed for a tunnel request to be declared unsatisfiable.</li>
<li><samp>maxusers</samp> defines the maximum number of simultaneous tunnels that can be established.</li>
<li><samp>port</samp> defines the port used by the SSL/TLS tunnel.</li>
<li><samp>listenaddr</samp> is an optional comma-separated list of IP addresses that can be used to tell the VPN server which interfaces it should listen to.</li>
<li><samp>lockdir</samp> points to the directory used to store <samp>pppserver</samp> locks.</li>
</ul>
<p>Finally, the <samp>/usr/local/etc/ssltunnel/users</samp> file must be modified in order to declare which users should be recognized by <samp>pppserver</samp> and allowed to establish an SSL/TLS tunnel.</p>
<p>The format of this file consists of one or more user blocks, each one referencing a remote user and its related options. Each user block is separated from the following one by a blank line.</p>
<p>A user block consists of several options:</p>
<ul>
<li><samp>user <user distinguised name></user></samp></p>
<p>The <samp>user</samp> option holds the X.509 distinguised name of the client certificate for which its owner is allowed to establish an SSL/TLS tunnel. The following command extracts the distinguised name from the X.509 client certificate:</p>
<pre>openssl x509 -nout -subject < client.cert</pre>
<p>For example:</p>
</pre>
<pre>user /C=ES/O=felipe-alfaro.org/OU=IT/cn=Felipe Alfaro</pre>
</li>
<li>
<pre>fingerprint <user certificate fingerprint></user></pre>
<p>The optional <samp>fingerprint</samp> option specifies the fingerprint for the client certificate associated with this user. It can be calculated with the following command:</p>
<p><samp>openssl x509 -noout -fingerprint < certificat_client</samp></samp></li>
<li><samp>command
<path to pppd></path></samp></p>
<p>The <samp>command</samp> option holds the path to the PPP daemon executable. This is usually <samp>/usr/sbin/pppd</samp>.</li>
<li><samp>pty
<pseudo -terminal number></pseudo></samp></p>
<p>The <samp>pty</samp> option defines the pseudo-terminal number that will be used by the PPP daemon. This is usually 1.</li>
<li><samp>args
<ppp daemon arguments></ppp></samp></p>
<p>The <samp>args</samp> option defines the additional arguments that will be supplied when invoking the PPP server specified by the <samp>command</samp> option.</p>
<p>At least one argument must be supplied to the PPP server. This argument defines the local IP address for the tunnel interface and the remote IP address for the tunnel interface, separated by a colon.</p>
<p>For example, if the local IP address for the tunnel, on the VPN server machine, is 192.168.1.1, and the remote IP address for the tunnel, on the VPN client, is 192.168.1.2, the <samp>args</samp> option will look like this:</p>
<p><samp>args 192.168.1.1:192.168.1.2</samp></li>
<li><samp>uid <uid></uid></samp><br />
<samp>gid <gid></gid></samp></p>
<p>Allows to change Unix identity before running pppd: permits to reduce the privileges. Attention, it will be necessary that used user and group have the right to run pppd! Obviously, that also implies that pppd is setuid root, so that it can set up routes, handle ARP table, etc.</p>
<p>If these lines aren&#8217;t present, everything will be executed as root.</li>
</ul>
<p>The resulting <samp>/usr/local/etc/ssltunnel/users</samp> file should look like this:</p>
<p><samp>user /C=ES/O=felipe-alfaro.org/OU=IT/cn=Felipe Alfaro<br />
command /usr/sbin/pppd<br />
pty 1<br />
args 192.168.1.1:192.168.1.2</p>
<p>user /C=ES/&#8230;</samp></p>
<h4>Server start</h4>
<p>Once the configuration user files have been modified, the <samp>pppserver</samp> VPN server daemon can be started with the following command:</p>
<p><samp>/usr/local/libexec/pppserver /usr/local/etc/ssltunnel/tunnel.conf</samp></p>
<p>There should be a new process named <samp>pppserver</samp>. <samp>pppserver</samp> uses the syslog local6 facility to log errors, so in case the daemon does not start properly, check <samp>/var/log/messages</samp> to see why it failed to start.</p>
<h3>Client</h3>
<p>The following section enumerates the steps used to build, compile, configure and run the VPN client software.</p>
<h4>Client compilation</h4>
<p>Before building the client software, it is recommended to apply the following <a href="/blog/wp-content/ssltunnel-1.15-client.patch">patch</a>:</p>
<pre>
<div>--- ssltunnel-1.15/client/main.c.old	2005-11-13 18:46:59.000000000 +0000
+++ ssltunnel-1.15/client/main.c	2005-11-13 18:38:47.000000000 +000

@@ -626,7 +626,7 @@
   ctx=SSL_CTX_new(meth);

   /* Load our keys and certificates*/
-  if(!(SSL_CTX_use_certificate_chain_file(ctx, certfile)))
+  if(!(SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM)))
       berr_exit("Can't read certificate file");

   if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM)))</div>
</pre>
<p>This patch allows using a PEM-encoded certificate for the VPN client instead of a PKCS#12-encoded certificate chain, which makes things a lot easier.</p>
<p>The commands used to extract, build and install the VPN client are the following:</p>
<pre>tar xvfz ssltunnel-<version>.tar.gz
cd ssltunnel-</version><version>
./configure --disable-server
make
make install</version></pre>
<p>This will install the following files:</p>
<ul>
<li><samp>/usr/local/man/man5/ssltunnelrc.5</samp>
<p>The manual page for the VPN client configuration file.</li>
<li><samp>/usr/local/man/man1/pppclient.1</samp>
<p>The manual page for the <samp>pppclient</samp>VPN client.</li>
<li><samp>/usr/local/bin/pppclient</samp>
<p>The VPN client.</li>
</ul>
<h4>Client certificate generation</h4>
<p>Once the client components of SSLTunnel are built and installed, the <samp>pppclient</samp> X.509 user certificate and its corresponding private key must be created. For information on how to generate the client certificate, read <a href="http://felipe-alfaro.org/blog/2005/11/18/setting-up-certificate-authority-ca-using-openssl/" title="Setting up Certificate Authority (CA) using OpenSSL">Setting up Certificate Authority (CA) using OpenSSL</a>.</p>
<h4>Client configuration</h4>
<p>The CA certificate will be installed as <samp>/home/user/cacert.pem</samp>. The <samp>pppclient</samp> signed user certificate will be installed as <samp>/home/user/client.pem</samp>. The client private key will be installed as <samp>/home/user/client.key</samp> and will be properly protected (0600 permission mask).</p>
<p>The VPN client configuration file is usually stored in the <samp>/home/user/.stunnelrc</samp>, although it can be overridden when invoking <samp>pppclient</samp>, and should look like this:</p>
<pre>verbose         1
remotehost      192.168.0.20
port            443
localppp        /usr/sbin/pppd
ipparam         tunnel
#bsdppp         0
#peer           tunnelserver
localproxyarp   0
#useproxy       0
#proxy          A.B.C.D
#proxyport      8080
#proxyuser      user
#proxypass      pass
localechoint    10
localechofail   10
localdebug      1
timeout         20
cacertfile      /home/user/cacert.pem
keyfile         /home/user/client.key
certfile        /home/user/client.pem
daemon          0
autoreconnect   0
logfile         /home/user/pppclient.log</pre>
<p>Following is a brief description of every configuration option:</p>
<ul>
<li><samp>verbose</samp>, when set to 1, increases the level of verbosity. Setting it to 0 makes <samp>pppclient</samp> to be quiet.</li>
<li><samp>remotehost</samp> specifies the IP address of the VPN server machine (the one running <samp>pppserver
<li><samp>port</samp> specifies the port used by <samp>pppserver</samp> to negotiate and establish the SSL/TLS tunnel.</li>
<li><samp>localppp</samp> points to the PPP daemon executable.</li>
<li><samp>ipparam</samp> specifies a tag which is passed to PPP to determine which configuration rules should be obeyed in order to set up routes, update ARP entries and so on.</li>
<li><samp>bsdppp</samp>, when set to 1 specifies whether to use userland PPP support in *BSD.</li>
<li><samp>peer</samp> defines which PPP peer to call as defined in <samp>/etc/ppp/peers/peer</samp></li>
<li><samp>localproxyarp</samp>, when set to 1 specifies that ARP proxying should be performed.</li>
<li><samp>useproxy</samp>, when set to 1 specifies that the client must pass through a HTTP proxy before reaching the VPN server.</li>
<li><samp>proxyport</samp> specifies the proxy port number, if any.</li>
<li><samp>proxyuser</samp> specifies the username used to authenticate against the proxy server, if any.</li>
<li><samp>proxypass</samp> specifies the password used to authenticate against the proxy server, if any.</li>
<li><samp>localechoint</samp> defines the local echo internal, in seconds, used as a keepalive.</li>
<li><samp>localechofail</samp> specifies the number of failed echo retries that would trigger the SSL/TLS tunnel down at the client.</li>
<li><samp>localdebug</samp>, when set to 1 forces the PPP daemon to be launched in debug mode.</li>
<li><samp>timeout</samp> the maximum amount of time used to established the SSL/TLS tunnel. If this time is exceeded, the VPN client will give up.</li>
<li><samp>keyfile</samp> points to the VPN client private key.</li>
<li><samp>certfile</samp> points to the VPN client certificate.</li>
<li><samp>cacertfile</samp> points to the CA certificate.</li>
<li><samp>daemon</samp>, when set to 1 request <samp>pppclient</samp> to daemonize itself and detach from the terminal.</li>
<li><samp>autoreconnect</samp>, when set to 1 request <samp>pppclient</samp> to re-establish the tunnel if it is broken down by any unexpected reason.</li>
<li><samp>logfile</samp> points to the log file where <samp>pppclient</samp> will log its errors or debug messages.</li>
<p></samp></li>
</ul>
<p>There is a sample <samp>pppclient</samp> file located inside the <samp>SSLTunnel</samp> source code, named <samp>client/tunnel.conf</samp>.</p>
<h4>Client start</h4>
<p>Once the <samp>pppclient</samp> configuration has been created, the <samp>pppclient</samp> VPN client daemon can be started with the following command:</p>
<p>/usr/local/bin/pppserver [optional path to configuration file]</p>
<p>The <samp>pppclient</samp> VPN client should chat like this with the VPN server:</p>
<pre>22:52:47 Connecting to 192.168.0.20
22:52:47 Connected
22:52:48 SSL connect successful
22:52:48 Server version : 1.15
22:52:48 Server Protocol version : 1.0
22:52:48 forking ppp
22:52:48   45 < -----
22:52:48              ----->   45
22:52:48   46 < -----
22:52:51   45 <-----
22:52:51              ----->   96
22:52:51   17 < -----
22:52:51              ----->   17
22:52:51   66 < -----
22:52:51              ----->   21
22:52:51              ----->   21
22:52:51   21 < -----
22:52:00              ----->   89
22:52:00   89 < -----
22:52:01              ----->   13
22:52:01   13 < -----</pre>
<p>To check the SSL/TLS tunnel has been set up by checking the state of the <samp>ppp0</samp> network interface:</p>
</pre>
<pre>ppp0      Link ecanp: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:5 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:66 (66.0 b)  TX bytes:72 (72.0 b)</pre>
<p>If everything has gone right, it should be possible to ping our remote VPN peer:</p>
<p><samp>ping 192.168.1.1</samp></p>
<h3>Acknowledgements</h3>
<p>This document has been created based on the information contained in the <a href="http://www.hsc.fr/ressources/outils/ssltunnel/download/README" title="README">README</a> file from the SSL Tunnel documentation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.felipe-alfaro.org/blog/2005/11/14/ssltunnel/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

