Sie sind auf Seite 1von 21

Debian Administration

System Administration Tips and Resources


[ About | Adverts | Archive | FAQ | Hall of Fame | Search | Tag Cloud |

Creating a radius based VPN with support for Windows clients


Posted by jim-barber on Thu 15 Sep 2005 at 11:45 Tags: vpn This article discusses setting up up an integrated IPSec/L2TP VPN using Radius and integrating it with Microsoft Windows clients. Introduction and Planning The software installed is going to be based on Debian packages as far as it is possible. If we need to rely on a product not within Debian, then it's source code will be retrieved and rebuilt. Also sometimes the Debian packages are available, but have a compilation feature switched off (usually SSL support). Where necessary that Debian package will need to be recompiled too. Overall Setup The goal of this article is to set up a Linux based VPN server compatible with MSWindows IPSec/L2TP clients, where users are authenticated against a RADIUS server. Each main service in this document should have it's own IP address assigned to it. That way services can be moved to different hosts in the future. While the VPN server uses the ppp daemon as part of it's solution, a separate IP needs to be allocated to that. It is the point where the VPN tunnels terminate and route into the network. For this document, the IP addresses assigned to the services follows. Note that these will need to change based on your real-world rollout.

Base Operating System: MySQL Database Server: FreeRADIUS Server: IPSec VPN Server: ppp Device:

10.10.0.216 10.10.0.217 10.10.0.218 10.10.0.219 10.10.0.220

For redundancy, these services will be mirrored on the 10.10.1.* address range. IMPORTANT NOTE: For MS windows clients that are to have the VPNs set up, make sure that the following registry key does not exist, or is set to 0. It should be like this out of the box, but if the user ever setup a non-MS IPSec connection (such as a link to Fortigate VPNs) then this may be set to 1. I wasted a full working day because I had the key set to 1:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\RasMan\Parameters\ProhibitIPSec

In creating this documentation, I read a LOT of online documentation. What I found was that there was a lot of conflicting settings across the range of documentation out there. There was a lot of things that were incorrect, and just a lot of mis-information in general. After spending nearly two weeks of pulling my hair out, I finally found the solution to the problems and this should work. Operating System Start with base install of Debian 'testing' using Linux kernel 2.6 The 'testing' distribution is used since it is more up to date than the 'stable' distribution while still protecting from the constant change of the 'unstable' distribution. NOTE: I actually deviated from this and used the 'unstable' distribution since it had the l2tpd daemon that I required since I could not get l2tpns working. For a production environment you may want to recompile a newer version of the 2.6 Linux kernel with just the features needed (ppp, IPSec stuff). It isn't necessary in order to set things up, so this can be left as a last optimisation step. If you want MPPE ppp encryption (which isn't necessary) then you will have to patch and recompile the kernel. Create required device nodes - The IPSec VPN server requires a /dev/net/tun device entry created that isn't made in the default Debian install:

# cd /dev # MAKEDEV tun

Edit the /etc/hosts file and add entries for all of the services except the ppp device:
10.10.0.217 10.10.0.218 10.10.0.219 mysql1.example.org radius1.example.org vpn1.example.org mysql1 radius1 vpn1

Also define these new addresses in the /etc/network/interfaces file like so:
auto eth0:0 iface eth0:0 inet static address 10.10.0.217 netmask 255.255.255.0 network 10.10.0.0 broadcast 10.10.0.255 gateway 10.10.0.1 auto eth0:1 iface eth0:1 inet static address 10.10.0.218 netmask 255.255.255.0 network 10.10.0.0 broadcast 10.10.0.255 gateway 10.10.0.1 auto eth0:2 iface eth0:2 inet static address 10.10.0.219 netmask 255.255.255.0 network 10.10.0.0 broadcast 10.10.0.255 gateway 10.10.0.1

(This gives the single machine the virtual addresses so that all the services can have their own IP address despite being upon the same physical host. ) You can bring the interfaces up with the following:
# ifup eth0:0 # ifup eth0:1 # ifup eth0:2

SSL encryption support A lot of the products will be relying on X.509 certificates for authenticating and encrypting. In order to generate these certicates we'll need to install OpenSSL. Install the openssl package:

# apt-get install openssl

Edit the /etc/ssl/openssl.cnf file. In the [req_distinguished_name] section, set the following variables to suit your site. For my testing I used the following values:
countryName_default stateOrProvinceName_default localityName_default 0.organizationName_default = = = = AU Western Australia Perth My Company

Certificates and Keys You'll need all your keys signed by a Certification Authority. In our case, rather than using Verisign, or some company like that, we wish to be our own Certification Authority. (It could be that we already have a certificate made up, if so it should be copied to the /etc/ssl/certs directory of the server and then the appropriate symlink made (see below).) If we don't have a proper certificate yet then we'll need to generate one. The steps to do this are as follows: To create your own Certification Authority Certificate (valid for 10 years or 3650 days):
# cd /etc/ssl/certs # openssl req -x509 -new -days 3650 -newkey rsa -nodes -keyout \ /etc/ssl/private/example-key.pem -out example-cert.pem Generating a 1024 bit RSA private key ........++++++ ...............................++++++ writing new private key to '/etc/ssl/private/example-key.pem' You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----Country Name (2 letter code) [AU]: State or Province Name (full name) [Western Australia]: Locality Name (eg, city) [Perth]: Organization Name (eg, company) [Example Company]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:Example Certification Authority Email Address []:hostmaster@example.org # ln -s example-cert.pem $(openssl x509 -noout -hash < examplecert.pem).0

After the above steps you should see something like the following:
# ls -l /etc/ssl/certs /etc/ssl/private /etc/ssl/certs: total 4 -rw-r--r-- 1 root root 1391 Sep lrwxrwxrwx 1 root root 18 Sep /etc/ssl/private: total 4 -rw-r--r-- 1 root root 887 Sep

1 09:06 example-cert.pem 1 09:09 d5160794.0 -> example-cert.pem

1 09:06 example-key.pem

Note: the symlink won't have the same hex digits because it will be unique every time you generate a new certificate. Server Keys and Certificates For each service that requires keys, you'll need to generate a public/private key pair for each, and then sign them with the Certification Authority certificate we generated in the above section. The server keys are created in the configuration areas of the software that is going to be using them. An example of how to create a server certificate:
# openssl req -new -newkey rsa -nodes -keyout \ server-key.pem -out server-csr.pem

Enter a suitable Common Name such as "MySQL Server", "VPN Server", "Web Server", etc. Enter an email address suitable for the administrator responsible for the service. Leave the challenge phrase blank. Remove the passphrase/challenge from the server key:
# openssl rsa -in server-key.pem -out server-key.pem

Sign it with the Certification Authority created in the section above:


# openssl x509 -req -days 3650 -CA /etc/ssl/certs/example-cert.pem \ -CAkey /etc/ssl/private/example-key.pem \ -CAcreateserial -CAserial ca-srl.txt -in server-csr.pem \ -out server-cert.pem

Client Keys and Certificates

Client certificates are to be given to each client. Create the client keys in a dedicated directory somewhere (to be defined later). Perhaps in the future they'll be put into some sort of PKI. You'll want to issue each client with their own keys and certificates. These keys need to be imported into their windows machines. An example of how to create a client certificate:
openssl req -new -newkey rsa -nodes -keyout client-key.pem -out clientcsr.pem

Enter a suitable Common Name such as "Dr Nick", "Anonymous Client", etc. Enter an email address suitable for the client using the key. eg. "dr_nick@example.com.au" Leave the challenge phrase blank. Remove the passphrase/challenge from the key:
# openssl rsa -in client-key.pem -out client-key.pem

Sign it by the Certification Authority:


# openssl x509 -req -days 3650 -CA /etc/ssl/certs/example-cert.pem \ -CAkey /etc/ssl/private/example-key.pem \ -CAcreateserial -CAserial ca-srl.txt -in client-csr.pem \ -out client-cert.pem

Importing client keys into MS Windows For Windows Clients you need to convert the PEM key format into pkcs#12 exchange format:
# openssl pkcs12 -export -inkey client-key.pem -in client-cert.pem \ -certfile /etc/ssl/certs/example-cert.pem \ -out export.p12 -name "Windows Cert"

Remember the password you enter since this will need to be supplied to the client when for their use to import the key. (That is, unless we automate a way to install the keys for them - there are certainl ytools out there for this.) Install the client certificates. First copy the client's export.p12 file to the Windows host, then import it like so:

Click "Start" and then "Run"

Enter "mmc" and click "OK" Select "File" and then "Add/Remove Snap-in..." Click "Add" Select "Certifictes" snap-in and click "Add". Select "Computer account" radio button and then click "Next". Select "Local Computer" radio button (probably already selected) and then click "Finish". Select "Close" and then "OK". Expand the "Certificates (Local Computer)". Right click on "Personal" branch and choose "All tasks" and then "Import". Click "Next" Click "Browse..." Change "Files of type" to "Personal Information Exchange (*.pfx, *.p12)" Choose the export.p12 file and then click "Open" Click "Next" Enter the password you entered when exporting the key into p12 format then click "Next". Select "Automatically select the certificate store based on the type of certificate" radio button and click "Next". Click "Finish" then hopefully you see a window saying the certificate was successfully imported... click "OK". Click "Action" and then "Refresh" and the new certificate should show up. Select "File" and then "Exit". Saving the settings is optional, but allows you to skip the first few steps of this next time if you want to import another certificate.

MySQL Database Server First install the appropriate MySQL server package. For this documentation, I'll install the mysql-server-5.0 package. Select a new password for mysql root (not the same as the Linux root user):
# /usr/bin/mysqladmin -u root password 'mysql_password'

Now that the password is changed, for the MySQL cronjobs to continue working correctly do the following:
# touch /root/.my.cnf # chmod 600 /root/.my.cnf

Edit the /root/.my.cnf file and add the following:


[mysqladmin] user = root password = mysql_password

Check if the MySQL binary is SSL enabled by running the following query:
# mysql -u root -p -e 'SHOW VARIABLES LIKE "%ssl%"' Enter password: +---------------+-------+ | Variable_name | Value | +---------------+-------+ | have_openssl | NO | +---------------+-------+

If the binary isn't SSL enabled and you want it to support encrypted connections to it, then you'll have to build it yourself using the following section. Note, that all the mysql-client libraries that connect to it will need SSL support too and will also need to be rebuilt. Reconfigure MySQL to bind to the correct IP address. Edit the file /etc/mysqy/my.cnf, and change the bind-address setting appropriately:
bind-address = 10.10.0.217

Then restart MySQL:


# /etc/init.d/mysql restart

You should still be able to connect via localhost, but you won't be authorised to connect via 10.10.0.217 yet. MySQL Database Server with SSL support (Optional) The MySQL binary package for Debian does not support SSL out of the box (as of the time of writing). So we have to rebuild it. We actually need to rebuild all the various versions of the server offered, since different debian packages seem to use different MySQL client library versions. The alternative is to rebuild all these packages to use the appropriate version of the MySQL client you want to use. This is beyond the scope of this document at the moment, however once we actually roll out the network, we'll probably need to maintain our own customised versions of some Debian packages that enable extra compilation options. I think it would be wise to have a dedicated machine for building packages on. These rebuilt packages could then by copied over to the server that they will be installed on. We can use the Debian tools to rebuild the MySQL server with OpenSSL support like so. Install the tools required to build the server.

# apt-get build-dep mysql-server-5.0 # apt-get install libssl-dev

Make a directory somewhere and get the server's source code.


# mkdir -p /usr/local/src/debian-mysql # cd /usr/local/src/debian-mysql # apt-get source mysql-server-5.0

Amend the default Debian build options:


# vi /usr/local/src/debian-mysql/mysql-dfsg-5.0-5.0.7beta/debian/rules

(Change --without-openssl to --with-openssl) Build the new MySQL binary packages:


# cd mysql-dfsg-5.0-5.0.7beta # ./debian/rules binary

Install the newly built packages in place of the non-SSL debian ones:
# dpkg -i mysql-server-5.0_5.0.7beta-1_i386.deb \ mysql-common_5.0.7beta-1_all.deb \ mysql-client-5.0_5.0.7beta-1_i386.deb \ libmysqlclient15_5.0.7beta-1_i386.deb

Go to the /etc/mysql directory and create a Certificate Authority and Signed Server Certificates as per the SSL section. Set up the certificates and keys in the /etc/mysql directory. You'll need to create a server key and certificate and sign them with the certificate authority. You should create a symlink to the certificate authority like so:
# cd /etc/mysql # ln -s /etc/ssl/certs/example-cert.pem cacert.pem

Edit the /etc/mysql/my.cnf file and uncomment the following lines in the [mysqld] section:
ssl-ca=/etc/mysql/cacert.pem ssl-cert=/etc/mysql/server-cert.pem ssl-key=/etc/mysql/server-key.pem

Restart MySQL and test that you can connect to it:

# /etc/init.d/mysql restart

RADIUS server Install the freeradius and freeradius-mysql package:


apt-get install freeradius freeradius-mysql

Create the radius database:


# gunzip /usr/share/doc/freeradius/examples/db_mysql.sql.gz # cp /usr/share/doc/freeradius/examples/db_mysql.sql /tmp/db_mysql.sql

Due to a bug you will need to edit the /tmp/db_mysql.sql file and in the creation of the 'nas' table at the end of the script:
Remove: DEFAULT '0' From: id int(10) DEFAULT '0' NOT NULL auto_increment So it looks like: id int(10) NOT NULL auto_increment

Create the radius database and populate it:


# mysqladmin create radius # cat /tmp/db_mysql.sql | mysql -p radius

Create a new radius user in the database and then grant it full rights to the newly created radius database. For a non-SSL setup create a 'radius' user with a password. For an SSL setup create a 'radius' user with no password but with references to the appropriately signed keys. There is much more involved for the SSL setup as all the clients that talk to the RADIUS server will need to support it as well. I have played a bit with the SSL and radius enough to prove that the following SSL steps do work: non-SSL:
# mysql -p GRANT ALL ON radius.* TO 'radius'@'localhost' IDENTIFIED BY 'radius_password'; GRANT ALL ON radius.* TO 'radius'@'%' IDENTIFIED BY 'radius_password';

SSL:

First to get the SUBJECT and ISSUER strings using the following commands on the appropriate certificate files:
# openssl verify client-cert.pem # openssl verify server-cert.pem

Then use these when generating the following commands.


# mysql -p GRANT ALL ON radius.* TO 'radius'@'localhost' REQUIRE SUBJECT "/C=AU/ST=Western Australia/L=Perth/O=Example/CN=Radius Client/emailAddress=hostmaster@example.org" AND ISSUER "/C=AU/ST=Western Australia/L=Perth/O=My Company/CN=MySQL Server/emailAddress=hostmaster@example.org"; GRANT ALL ON radius.* TO 'radius'@'%' REQUIRE SUBJECT "/C=AU/ST=Western Australia/L=Perth/O=My Company/CN=Radius Client/emailAddress=hostmaster@example.org" AND ISSUER "/C=AU/ST=Western Australia/L=Perth/O=My Company/CN=MySQL Server/emailAddress=hostmaster@example.org";

It is possible that we will still want to have a password associated with the user. That way to connect to RADIUS you'd have to know the correct password as well as possess the correct keys. To add the password, just use the "IDENTIFIED BY 'radius_password'" the same was as done in the non-SSL section. Edit the /etc/freeradius/sql.conf file and set the server, login, and password variables to the correct values:
server = "mysql1.example.org" login = "radius" password = "radius_password"

Edit the /etc/freeradius/clients.conf file: Set a new secret password (radius_secret) in the client 127.0.0.1 {} section. Create the new following section under the client 127.0.0.1{} section:
client 10.10.0.218 { secret shortname nastype } = radius_secret = radius1 = other

You can also specify network masks such as "client 10.10.0.216/29 {" for example. Edit the /etc/freeradius/radiusd.conf file:

Uncomment 'sql' in the authorise{}, accounting{}, and session{} sections. Also comment out radutmp in the accounting{} and session{} sections since it is a performance hit, and unnecessary now that we are using the SQL backend.

Restart FreeRADIUS:
# /etc/init.d/freeradius restart

Populate the MySQL tables with your users. The bare minimum for testing is:
INSERT INTO radcheck (UserName, Attribute, op, Value) VALUES ('user1', 'User-Password', '==', 'password1');

A lot of documentation talks about adding Auth-Type := Local in the radgroupcheck table. This doesn't work if using MS-CHAPv2, so don't do it. In theory, the authentication modules should detect the correct Auth-Type and go from there. Adding an Auth-Type tends to lock only one method as being valid to the exclusion of all others which is probably not whatwe want. The use of some of the tables are as follows:

The radcheck table contains the username and password pairs. o An entry for each VPN user must be in this table. The radreply table contains custom user-specific radius reply attributes. The usergroup table contains a username entry mapping to a group name. o The group names are used to determine any custom radius reply attributes for the group. The radgroupreply table contains the custom attributes to be returned for particular groups.

The following is some examples of how to populate these tables. You'll need to customise for a real world roll-out.
# Define the users and their passwords. # INSERT INTO radcheck (UserName, Attribute, op, Value) VALUES ('user1', 'User-Password', '==', 'password1'), ('user2', 'User-Password', '==', 'password2') ; # Define the users and the group they are in. # INSERT INTO usergroup (UserName, GroupName) VALUES ('user1', 'dynamic'),

('user2', 'static')

# Return attributes for particular users. # INSERT INTO radreply (UserName, Attribute, op, Value) VALUES ('user2', 'Cisco-Avpair', ':=', 'throttle=yes'); ('user2', 'Framed-IP-Address', ':=', '10.10.0.247'); # Return attributes for particular groups. # This is suboptimal as it contains a lot of DEFAULT values. # Defaults are supposed to be left out of the database # and put into the config file for performance reasons. # INSERT INTO radgroupreply (GroupName, Attribute, op, Value) VALUES ('static', 'Cisco-Avpair', ':=', 'throttle=no'); ('dynamic', 'Cisco-Avpair', ':=', 'throttle=yes'); ('dynamic', 'Framed-Compression', ':=', 'Van-JacobsenTCP-IP'), ('dynamic', 'Framed-IP-Address', ':=', '255.255.255.254'), ('dynamic', 'Framed-MTU', ':=', '1500'), ('dynamic', 'Framed-Protocol', ':=', 'PPP'), ('dynamic', 'Framed-Route', ':=', '10.10.0.1'), ('dynamic', 'Service-Type', ':=', 'Framed-User') ;

Again note that a lot of the entries that I put into the radgroupreply shouldn't be there since they should be default values which the doco recommends is kept out of the database and stored in the freeradius config files. You should be able to test that the RADIUS server is working using the radtest program:
# radtest user1 password1 localhost 1812 radius_secret # radtest user1 password1 10.10.0.218 1812 radius_secret

VPN Server After a lot of research I've settled on an IPSec based solution that can handle NAT-T. An easier solution to implement is PPTP, however all sources I refer to say that the protocol itself is inherently insecure. The only reason it is used is because it is easy. IPSec is regarded as a well understood and secure protocol. The IPSec packets will be handled by the inbuilt IPSec layer in the Linux 2.6 kernel.

Racoon will be used as the Internet Key Exchange (IKE) daemon for automatically keying IPSec connections. Racoon supports NAT-T but perhaps only in Tunnel mode. The Window clients use Transport mode. It is possible that Racoon may not support NAT-T in transport mode. Install the ipsec-tools and racoon packages:
apt-get install ipsec-tools racoon

Choose the 'direct' mode for racoon configuration. If using the modutils package instead of module-init-tools (unlikely if you're using a 2.6 kernel) allow the kernel to autoload the correct IPSec modules create the /etc/modutils/ipsec file with the following lines:
alias alias alias alias alias alias xfrm-type-2-50 xfrm-type-2-51 xfrm-type-2-108 xfrm-type-10-50 xfrm-type-10-51 xfrm-type-10-108 esp4 ah4 ipcomp esp6 ah6 ipcomp6

Then rebuild the /etc/modules.conf file to include these entries:


# update-modules

These entries were already in the /etc/modprob.d/aliases file as supplied by the modules-init-tools Debian package. Edit the /etc/racoon/racoon.conf and comment out the 'path pre_shared_key' variable and then add the following lines:
listen { isakmp isakmp_natt } padding { randomize exclusive_tail } remote anonymous { exchange_mode my_identifier public key peers_identifier public key verify_identifier 10.10.0.219[500]; 10.10.0.219[4500];

off; off;

main; asn1dn; asn1dn; on;

# Extract id from # Extract id from

certificate_type x509 "server-cert.pem" "serverkey.pem"; verify_cert off; passive on; # Racoon should not start the connection itself. generate_policy on; # Create policy when connection is initiated. nat_traversal on; # NAT-T is used when a NAT gateway is detected between the peers. proposal { encryption_algorithm hash_algorithm authentication_method public/private key dh_group } } sainfo anonymous { lifetime encryption_algorithm authentication_algorithm compression_algorithm } 3des; sha1; rsasig; modp1024;

# Use X.509 RSA

time 28800 sec; 3des; hmac_md5; deflate;

Make a directory for the racoon certificates and generate and sign the required server certificates and keys:
# mkdir /etc/racoon/certs # chmod 700 /etc/racoon/certs

Create a server key and certificate using a Common Name of "IPSec Server" or "VPN server" or something like that. Create symlinks to Certificate Authorisation keys (copy them to the host if necessary).
# ln -s /etc/ssl/certs/example-cert.pem $(cat /etc/ssl/certs/examplecert.pem | openssl x509 -noout -hash ).0 # ln -s /etc/ssl/certs/example-cert.pem cacert.pem

Restart racoon:
# /etc/init.d/racoon restart

L2TP Because of Microsoft's IPSec implementation, I also have to support L2TP. This has PPP packets that are encapsulated within L2TP packets which are further encapsulated within IPSec (and with NAT-T turned on, further encapsulated within UDP packets). That's a lot of overhead.

The L2TP layer is unnecessary, and my cynical view is this it is probably a ploy by Microsoft to lock customers into buying more, licenses by having to use Microsoft's VPN server solutions. It is possible to hack the windows registry to allow it to just use TCP/IP within IPSec, removing the need for L2TP. However hacking the registry is undesirable on the client computers, so I'll just have to live with the more complicated server setup, and the extra overhead of the network packets. l2tpns No matter what I tried, the l2tpns package just would not work from either 'testing' or 'unstable' :( It is supposed to be better than lt2pd. But it isn't, if it is impossible to get working. The problem is that it didn't seem to try and contact the RADIUS server. No connection attempt at all that I could see. I have no idea what it was waiting for and the debugging output gave me no clues. Nor was the web useful for finding the solution... Trust me, I spent HOURS on this. l2tpd and ppp Because of my failure to get l2tpns working I used the l2tpd and pppd option. This is the setup that is probably used by more users on the Internet, so there is more documentation about it. NOTE: l2tpd is no longer under active development like the l2tpns product is. Bug and security fixes only. Unfortunately the l2tpd program is only available in the 'unstable' distribution so requires mucking around to get into 'testing' (which I won't go into here). Install the l2tpd and ppp packages. Edit /etc/l2tpd/l2tpd.conf and add the following:
[global] listen-addr = 10.10.0.219 port = 1701 [lns default] ip range = 10.10.0.248 - 10.10.0.254 local ip = 10.10.0.220 hostname = vpn1 ppp debug = yes pppoptfile = /etc/ppp/options.l2tpd

length bit = yes

NOTE: the 'local ip' is not the address bound to any interfaces already on the host. This is a new IP address that will be assigned to the ppp device that gets created when a connection is established. All VPN traffic will route via this ppp device. ALSO NOTE: A lot of doco on the net tells you to put in the refuse and require entries for pap, chap, and authentication. DONT. These override the authentication settings in the ppp daemon, and they don't actually work anyway. (i.e. if you refuse PAP here, the client can still connect with PAP if so configured. Also all the more appropriate access controls in the ppp options file will be ignored, but they are more flexible, so we want them to work.) Create /etc/ppp/options.l2tpd with the following contents:
# Specify which DNS Servers the incoming Win95 or WinNT Connection should use. # Two Servers can be remotely configured. # ms-dns 10.10.0.100 #ms-dns 192.168.1.2 # Specify which WINS Servers the incoming connection Win95 or WinNT should use. # ms-wins 10.10.0.100 # Require the peer to authenticate itself before allowing network packets to be sent or received. # auth # Use hardware flow control. # crtscts # Specifies that pppd should use a UUCP-style locks to ensure exclusive access to the device. # lock # Set the MRU [Maximum Receive Unit] value to for negotiation. # Set the MTU [Maximum Transmit Unit] value to . # mru 1400 mtu 1400 # Don't fork to become a background process. # nodetach

# Turn on debugging. This can be turned off once everything is working. # debug # Add an entry to this system's ARP table with the IP address of the peer and the Ethernet address of this system. # proxyarp # pppd will accept the peer's idea of our local IP address, # even if the local IP was specified in an option. # pppd will accept the peer's idea of its (remote) IP address, # even if the remote IP was specified in an option. # ipcp-accept-local ipcp-accept-remote # Specifies that pppd should disconnect if the link is idle for seconds. # idle 1800 # Wait for up n milliseconds after the connect script finishes for a valid PPP packet from the peer. # connect-delay 5000 # Tell the windows client to to get a default route from the connection. # nodefaultroute # Force MS-CHAP-v2 authentication since it is more secure than the other options. # Though it probably doesn't matter too much since it all happens inside an IPSec tunnel anyway. # If you have an MPPE enabled kernel you can turn on support for MPPE, but it isn't necessary. # refuse-pap refuse-chap refuse-mschap require-mschap-v2 #require-mppe # Do not sent output from plugins to the pty or the stream from clients may be released. # nologfd # Turn on the RADIUS plugin. # #plugin radius.so

Add an entry to the /etc/ppp/chap-secrets file like so:

user1 *

* user1

"password1" "password1"

10.10.0.248/29 10.10.0.248/29

Restart the l2tpd daemon:


# /etc/init.d/l2tpd restart

Generate and import client certificates into a Windows client and then connect to the VPN server. (Instructions for configuring the VPN client software on Windows should be written but is straight forward with no special options requiring to be ticked/unticked, etc). If all is good, then we can move on to integrating PPP with the RADIUS server. Integrating pppd and RADIUS This is the trickiest part since there is so much bad information out there. It looks simple when it's written down like this though doesn't it :) Hopefully these are the steps that will bring you success. Delete the 'user1' entries out of the /etc/ppp/chap-secrets file again. Install the radiusclient1 package. Edit /etc/radiusclient/servers file and add the following:
radius1.example.org radius_secret

Edit /etc/radiusclient/radiusclient.conf and change the following lines from localhost:


authserver acctserver radius1.example.org radius1.example.org

Edit the /etc/ppp/option.l2tp file and uncomment the 'plugin radius.so' entry at the bottom. Radiusclient Dictionaries For MS-CHAP protocols to work with the radius server it is critical that the radiusclient setup has the microsoft dictionaries. Unfortunately these aren't installed with the radiusclient1 package. Even more unfortunate is that the format of these dictionary files have evolved over time and the radius.so plugin that is part of the ppp package only understands an very old format.

Also the radius plugin is very fussy about the INCLUDE statements used in the dictionary files. The comments in the files provided with the radiusclient1 package suggest that you'd add an entry like:
$INCLUDE dictionary.microsoft

When in fact, the radius.so plugin requires it to look like:


INCLUDE /etc/radiusclient/dictionary.microsoft

Note the lack of a leading $ sign, and the full path used in the file. The steps to getting a working dictionary.microsoft file are as follows: Copy the freeradius dictionary.microsoft file to the radiusclient1 area:
# cp /usr/share/freeradius/dictionary.microsoft /etc/radiusclient/

Edit the file to change it's format back to an older format understood by the radius.so plugin.
# vi /etc/radiusclient/dictionary.microsoft

Change all occurances of the word "octects" to "string". Delete the following lines:
BEGIN-VENDOR END-VENDOR Microsoft Microsoft

Delete all "encrypt=1", and "encrypt=2" entries from the end of the ATTRIBUTES that have them. At the end of each ATTRIBUTE line add a new field to the end that says "Microsoft" without the quotes. Watch out for the lines that have comments at the end. The new field must be before them so it isn't part of the comment. Now edit the /etc/radiusclient/dictionary file and add the following to the end of it:
INCLUDE /etc/radiusclient/dictionary.microsoft

You should now be able to connect with the VPN client and this time it will be authenticated against the radius server. If it fails for any reason, shutdown the freeradius server, and run it manually with debugging turned on to see what is happening like so:
# /etc/init.d/freeradius stop # freeradius -X

On a new connection from the VPN client you should see a whole heap of logs starting with something like:
rad_recv: Access-Request packet from host 10.10.0.218:1026, id=244, length=133 Service-Type = Framed-User Framed-Protocol = PPP User-Name = "user1" MS-CHAP-Challenge = 0xa6f98c2e3c2157432ae1622d9bad2e64 MS-CHAP2-Response = 0xe500f87302def6dbfc274ac1cb1b5ee6bcf00000000000000000497a4622ec34eff13 75a80058ad318233f21aa1ec25ea2d0 NAS-IP-Address = 10.10.0.216 NAS-Port = 0

If the MS-CHAP-Challenge, or MS-CHAP2-Response entries are not there, then there is something wrong with the dictionary setup described above, so double check it all. The dictionaries are critical to getting this to work.

Das könnte Ihnen auch gefallen