added documentation and configuration example for FreeRadius;
This commit is contained in:
110
README.md
110
README.md
@@ -0,0 +1,110 @@
|
||||
privacyidea-checkotp
|
||||
====================
|
||||
|
||||
Shell script implementing the [PrivacyIDEA](http://www.privacyidea.org) OTP (One
|
||||
Time Password) check to integrate with [FreeRadius](http://www.freeradius.org)
|
||||
in environments where the FreeRadius Perl plugin is not available to use the
|
||||
standard check script (e.g. on OS X 10.9).
|
||||
|
||||
**Version 1.0**, latest version, documentation and bugtracker available on my
|
||||
[GitLab instance](https://gitlab.lindenaar.net/scripts/privacyidea-checkotp)
|
||||
|
||||
Copyright (c) 2015 Frederik Lindenaar. free for distribution under the GNU
|
||||
License, see [below](#license)
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
When integrating PrivacyIDEA with the stock OS X Server FreeRadius server, I was
|
||||
blocked by the installation not including the `rlm_perl` module. This bash
|
||||
(shell) script was created to get around that as it is to be executed using the
|
||||
FreeRadius `rlm_exec` module. Please bear in mind that this module suits my
|
||||
needs and probably still has a few glitches, though it turned out to be a stable
|
||||
solution for my needs. In case you have any comments / questions or issues,
|
||||
please raise them through my [GitLab instance](https://gitlab.lindenaar.net/scripts/privacyidea-checkotp) so that all users benefit.
|
||||
|
||||
Setup
|
||||
-----
|
||||
This script will be executed using the FreeRadius `rtl_exec` module, which is
|
||||
not the most efficient way to integrate but will suffice for low to medium
|
||||
volume use. The script depends on `curl` and `sed` being installed, which is
|
||||
the case in most environments.
|
||||
|
||||
The setup of this solution consists of the following steps:
|
||||
|
||||
1. Setup PrivacyIDEA and make sure it is working on its own
|
||||
2. Install the `privacyidea-checkotp` on your FreeRadius server and make it
|
||||
executable
|
||||
3. Copy the provided `privacyidea.freeradiusmodule` into the FreeRadius
|
||||
`raddb/modules` directory as `privacyidea`
|
||||
4. Update `raddb/modules/privacyidea` so that `[WRAPPERSCRIPT_PATH]` points to
|
||||
the script as installed in step #1 and `[PRIVACYIDEA_URL]` is replaced with
|
||||
the base URL of your PrivacyIDEA instance.
|
||||
5. Check your configuration by running the command configured in
|
||||
`raddb/modules/privacyidea` followed by a username and valid
|
||||
password/OTP/PIN combination (depending on your configuration. To avoid the
|
||||
password being captured in your shell history, use `` `cat` `` instead of
|
||||
the password on the commandline and after entering the command, enter the
|
||||
password/OTP/PIN combination as PrivacyIDEA expects followed by an enter
|
||||
and `CTRL-D`.
|
||||
6. After successfully testing the base setup, add PrivacyIDEA as authorization
|
||||
and authentication provider with the following steps:
|
||||
1. Open the virtual host file you want to add PrivacyIDEA authentication to
|
||||
(typically in `raddb/sites-available`)
|
||||
2. In the section `authorize {`:
|
||||
* disable all authorization modules you do not want to succeed
|
||||
* add the following to the bottom of this section:
|
||||
|
||||
~~~
|
||||
# Use PrivacyIDEA
|
||||
if(! Service-Type == "Outbound-User") {
|
||||
update control {
|
||||
Auth-Type := PrivacyIDEA
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Service-Type == "Outbound-User"
|
||||
if(NAS-Port-Type == "Virtual" && NAS-Port > 0 ) {
|
||||
update control {
|
||||
Auth-Type := Accept
|
||||
}
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
3. In the section `authenticate {`:
|
||||
* Disable all authentication modules you do not want to succeed
|
||||
* add the following to the top of this section so that PrivacyIDEA
|
||||
authentication is tried first:
|
||||
|
||||
~~~
|
||||
Auth-Type PrivacyIDEA {
|
||||
privacyidea
|
||||
}
|
||||
~~~
|
||||
|
||||
7. Last step is to test the configuration, run FreeRadius as `radiusd -X` and
|
||||
check what happens with an authentication requests reaching the FreeRadius
|
||||
server. Specifc requirements on what needs to happen is dependant on your
|
||||
setup (e.g. I am normally not using any PIN codes for the OTP, but require
|
||||
the user's password followed by the OTP).
|
||||
|
||||
Please note that this setups works for plain-text (i.e. non-EAP) authentication
|
||||
with FreeRadius, which is what my setup needs. The configuration above does not
|
||||
work with EAP authentication, I am still working on that (any hints for that are
|
||||
welcome!)
|
||||
|
||||
<a name="license">License</a>
|
||||
-----------------------------
|
||||
This script, documentation and configration examples are free software: you can
|
||||
redistribute and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
This script, documenatation and configuration examples are distributed in the
|
||||
hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, download it from <http://www.gnu.org/licenses/>.
|
||||
|
||||
105
privacyidea.freeradiusmodule
Normal file
105
privacyidea.freeradiusmodule
Normal file
@@ -0,0 +1,105 @@
|
||||
#
|
||||
# Sample FreeRadius rlm_exec wrapper configuration to perform OTP authentication
|
||||
# against privacyidea without rtl_perl module (unavailable on OS X 10.9 Server)
|
||||
#
|
||||
# Version 1.0, latest version, documentation and bugtracker available at:
|
||||
# https://gitlab.lindenaar.net/scripts/privacyidea-checkotp
|
||||
#
|
||||
# Copyleft (c) 2015 by Frederik Lindenaar
|
||||
#
|
||||
|
||||
#
|
||||
# Return value of the program run determines the result of the exec instance
|
||||
# call (See doc/configurable_failover for details) as follows:
|
||||
#
|
||||
# < 0 : fail the module failed
|
||||
# = 0 : ok the module succeeded
|
||||
# = 1 : reject the module rejected the user
|
||||
# = 2 : fail the module failed
|
||||
# = 3 : ok the module succeeded
|
||||
# = 4 : handled the module has done everything to handle the request
|
||||
# = 5 : invalid the user's configuration entry was invalid
|
||||
# = 6 : userlock the user was locked out
|
||||
# = 7 : notfound the user was not found
|
||||
# = 8 : noop the module did nothing
|
||||
# = 9 : updated the module updated information in the request
|
||||
# > 9 : fail the module failed
|
||||
#
|
||||
|
||||
exec privacyidea {
|
||||
#
|
||||
# Wait for the program to finish.
|
||||
#
|
||||
# If we do NOT wait, then the program is "fire and
|
||||
# forget", and any output attributes from it are ignored.
|
||||
#
|
||||
# If we are looking for the program to output
|
||||
# attributes, and want to add those attributes to the
|
||||
# request, then we MUST wait for the program to
|
||||
# finish, and therefore set 'wait=yes'
|
||||
#
|
||||
# allowed values: {no, yes}
|
||||
wait = yes
|
||||
|
||||
#
|
||||
# The name of the program to execute, and it's
|
||||
# arguments. Dynamic translation is done on this
|
||||
# field, so things like the following example will
|
||||
# work.
|
||||
#
|
||||
program = "[WRAPPERSCRIPT_PATH]/privacyidea-checkotp [PRIVACYIDEA_URL]"
|
||||
|
||||
#
|
||||
# The attributes which are placed into the
|
||||
# environment variables for the program.
|
||||
#
|
||||
# Allowed values are:
|
||||
#
|
||||
# request attributes from the request
|
||||
# config attributes from the configuration items list
|
||||
# reply attributes from the reply
|
||||
# proxy-request attributes from the proxy request
|
||||
# proxy-reply attributes from the proxy reply
|
||||
#
|
||||
# Note that some attributes may not exist at some
|
||||
# stages. e.g. There may be no proxy-reply
|
||||
# attributes if this module is used in the
|
||||
# 'authorize' section.
|
||||
#
|
||||
input_pairs = request
|
||||
|
||||
#
|
||||
# Where to place the output attributes (if any) from
|
||||
# the executed program. The values allowed, and the
|
||||
# restrictions as to availability, are the same as
|
||||
# for the input_pairs.
|
||||
#
|
||||
output_pairs =
|
||||
|
||||
#
|
||||
# When to execute the program. If the packet
|
||||
# type does NOT match what's listed here, then
|
||||
# the module does NOT execute the program.
|
||||
#
|
||||
# For a list of allowed packet types, see
|
||||
# the 'dictionary' file, and look for VALUEs
|
||||
# of the Packet-Type attribute.
|
||||
#
|
||||
# By default, the module executes on ANY packet.
|
||||
# Un-comment out the following line to tell the
|
||||
# module to execute only if an Access-Accept is
|
||||
# being sent to the NAS.
|
||||
#
|
||||
packet_type = Access-Request
|
||||
|
||||
#
|
||||
# Should we escape the environment variables?
|
||||
#
|
||||
# If this is set, all the RADIUS attributes
|
||||
# are capitalised and dashes replaced with
|
||||
# underscores. Also, RADIUS values are surrounded
|
||||
# with double-quotes.
|
||||
#
|
||||
# That is to say: User-Name=BobUser => USER_NAME="BobUser"
|
||||
shell_escape = yes
|
||||
}
|
||||
Reference in New Issue
Block a user