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