ValdikSS / openvpn-radiusplugin

Radiusplugin with various patches and fixes
GNU General Public License v2.0
43 stars 41 forks source link

/*



The plugin was developed during my diploma thesis for the EWETEL GmbH (www.ewetel.net). They main idea was to create a virtualized SSL-VPN with RADIUS support. The virtualization was done by XEN. At this place I would like to thank the people from EWETEL GmbH and EWE AG (www.ewe.de) who supported me with the required equipment, hardware and helped me with all my questions.

The plugin was developed and tested under Debian Sarge and OpenVPN 2.0 on x86-machines.


The RADIUS-Class:

For this plugin was developed a RADIUS-Class in C++. It was based on the C-library FF RADIUS Library v0.1 from Fabrizio Fiorucci (http://ffradiuslib.ff.homelinux.net). If somebody is interested in a standalone RADIUS-class please contact me. There will be some little changes.

DOCUMENTATION:

The documentation is done with doxygen. To generate the documentation execute "doxygen doxygen.conf" in the folder of the plugin.

INSTALL:

  1. Requirements: the libgcrypt library.

  2. Compile: see section COMPILE

  3. Set the plugin in the OpenVPN configfile: plugin /path/to/plugin/radiusplugin.so [configfile]

  4. Create a configfile for the plugin, see radiusplugin.cnf. If no path is set in the configfile of OpenVPN the plugin will read the file /etc/openvpn/radiusplugin.cnf: . The configuration is case-sensitive, for an example see radiusplugin.cnf.

  5. Set some configuration in the config file of the OpenVPN server:

    • status /var/log/openvpn/status.log 1 # The status, where the plugin reads the accounting information from.
  6. Configure in the config file of the OpenVPN client:

    • auth-user-pass [/etc/openvpn/passwd] # Set this for sending a username and password to the server, this values are the username and password for the radius authentication.
  7. If you use auth_control_file (>= OpenVPN 2.1 rc8), the plugin directory needs write permission to the OpenVPN directory or use the "--tmp-dir" option to define a directory for the files.

  8. Maybe write your own script for vendor specific attributes (see section VENDOR SPECIFIC ATTRIBUTES).

OTHER DOCUMENTATION

An "OpenVPN - RADIUS - MySQL Howto" in german can be found at: http://www.roessner-net.com/

FREERADIUS EXAMPLE

user1 Cleartext-Password := "testing" Service-Type = Framed-User, Framed-IP-Netmask = 255.255.255.0, Framed-IP-Address = 10.8.0.33, Framed-Routing = Broadcast-Listen, Framed-Compression = Van-Jacobsen-TCP-IP, Framed-Route += "192.168.101.0/26 10.8.0.1/32 1", Framed-Route += "192.168.111.0/24 10.8.0.1/32 1", Framed-Route += "192.168.112.0/24 10.8.0.1/32 1", Acct-Interim-Interval=5, Ascend-Data-Rate=100, Ascend-Xmit-Rate=200, Framed-Protocol = PPP

The Framed-Route attribute must be in the format as shown above!

COMPILE

(tested with Debian on x86, for other architectures see section TROUBLESHOOTING):

$ make

RADIUS PACKETS and OpenVPN events (see http://openvpn.net/man.html SCRIPTING AND ENVIRONMENTAL VARIABLES)

OpenVPN event RADIUS PACKET Information


auth-user-pass-verify ACCESS REQUEST parse of attributes (see below) client-connect ACCOUNTING REQUEST (Start)

RADIUS ATTRIBUTES WHICH PARSED BY THE PLUGIN AND WRITE TO THE CLIENT CONFIG FILE:

OTHER RADIUS ATTRIBUTES

VENDOR SPECIFIC ATTRIBUTES

If you want use vendor specific attributes the plugin can call your own program or script at the OpenVPN action CLIENT-CONNECT and CLIENT-DISCONNECT. If you want to use the feature you have to specify the program and a named pipe for communication in the config file. The file vsascript.pl shows an example.

LIMITS:

commonname of the certificate 256 characters routes entry from the radius server 50 characters

LIMITS in RadiusConfig for the configfile:

(The limit is the length of the array minus 1!) char serviceType[2];
char framedProtocol[2];
char nasPortType[2];
char nasIdentifier[128];
char nasIpAddress[16];
char p2p[16]; char subnet[16];

TROUBLESHOOTING

FOR TESTING

Attention: Some values are hard coded in main.cpp testing, so you can get unexpected values when testing. For example the framedip is always 10.8.0.100, because it is read from the environment variable "ifconfig_pool_remote_ip", which is passed to the plugin from OpenVPN! All hard coded variabled: env1[0]="username=user1"; env1[1]="password=testing"; env1[2]="verb=10"; env1[3]="untrusted_ip=127.0.0.1"; env1[4]="common_name=R-VPNGateway1"; env1[5]="trusted_ip=127.0.0.1"; env1[6]="ifconfig_pool_remote_ip=10.8.0.100";

compile for test with a main function: g++ -Wall -o main AccountingProcess.cpp Exception.cpp PluginContext.cpp UserAuth.cpp AcctScheduler.cpp IpcSocket.cpp radiusplugin.cpp User.cpp AuthenticationProcess.cpp main.cpp UserAcct.cpp UserPlugin.cpp Config.cpp RadiusClass/RadiusAttribute.cpp RadiusClass/RadiusPacket.cpp RadiusClass/RadiusConfig.cpp RadiusClass/RadiusServer.cpp RadiusClass/RadiusVendorSpecificAttribute.cpp -lgcrypt