evgeny-gridasov / openvpn-otp

OpenVPN OTP token support plugin
GNU General Public License v3.0
277 stars 74 forks source link

LDAP Integration #20

Open jonnymccullagh opened 7 years ago

jonnymccullagh commented 7 years ago

Hi, Not reporting a bug - more of a support request.
I have OpenVPN set up with LDAP authentication and now openvpn-otp - but I can only use one at a time.

plugin /usr/lib/openvpn/openvpn-otp.so "debug=1"
plugin /usr/lib/openvpn/openvpn-auth-ldap.so "/etc/openvpn/auth/ldap.conf"

Rather than having the PIN/password listed in the opt-secrets file I would rather they entered their LDAP password with their OTP token. Or enter their LDAP username and password first and then be prompted fort eh OTP. I can't see a way to do this so I would appreciate any feedback/discussion. Cheers, jonny

evgeny-gridasov commented 7 years ago

Hi Jonny,

I think you can use linotp together with PAM authentication to achieve this. This plugin was never meant to be used as an enterprise solution. Option number 1 is definitely possible to implement but will require LDAP logic on the openvpn-otp plugin side.

Alternatively, you may hack both plugins, and in the first one, use the last 6 digits as OTP token and in the second one remove 6 digits from the end and use the remainder as a password. Both plugins must return success (0) for authentication to work.

I suggest you use a strong PIN together with an OTP token instead.

guywyers commented 6 years ago

Hey Evgeny,

I'm facing the same situation as Johny and I think option 2 is the best way to go. I wouldn’t call it a hack however, because all this is actually provided in openvpn.
What I mean is that it is perfectly possible to use what is called the “Challenge/Response Protocol” described here (scroll down to the bottom of this page to find the relevant section).
If this is used, the password string can have one of two forms. It can be something like CRV1::XYDFGER::123456 which is the case of the dynamic protocol and in the case of the static protocol it looks like this SCRV1:XYFDFGER:123456. In both cases XYDFGER is the password and 123456 is the response (this is where the otp would arrive).
So instead of a hack, both plug-ins require a small change to inform them that that they need to parse the password string and only look at the part that is relevant for them.
The concrete use case would be the following:

Guy

guywyers commented 6 years ago

Hey guys,

I went ahead and developed a patch to this. I submitted it as pull request #22. For the moment this is only half of the story. I'm gonna "go after" openvpn-auth-ldap next.

Cheers,

Guy

evgeny-gridasov commented 6 years ago

Hey Guy,

I've reviewed the code, good job. Many thanks for contributing. I've obviously underlooked, I should have used challenge/response from the start.

Please add a link to your modified plugin in the readme file when you finish working on it, so we have a complete solution.

Cheers, Evgeny.

moxom88 commented 6 years ago

Hey, I'm trying to use this - I've been looking for this exact feature together with the LDAP plugin.

I have both the OTP & LDAP plugin working seperately, but when I'm trying to use both of them, I get an authentication error.. Should I wait for an update to the LDAP plugin before this will work concurrently, or should it work as it is now?

Thanks a lot for your work on this, I've been scratching my head how to get this to work for a long time now :)

guywyers commented 6 years ago

Yes indeed you'll need to wait for the patch of openvpn-auth-ldap. That one turns out to be a bit outdated in terms of gcc versions. Like Evgeny requested, I'll drop a link here as soon as I have something working, so that you guys can play with it.

Guy

moxom88 commented 6 years ago

Thanks, keep up the good work! :)

guywyers commented 6 years ago

Hey guys,

As you can see above, I logged a feature request for openvpn-auth-ldap yesterday. I just checked in a patch on my own fork here.

So if you want you can build it an try it out. It works much in the same way as for openvpn-otp: there is a new flag in the openvpn-auth-ldap config file: ``PasswordIsCR". If that flag is present and set to "true", openvpn-auth-ldap will expect the password to be in Challenge/Response format and will be able to coexist with openvpn-otp.

Next I'm going to issue a pull request on the main fork, but I'm not sure it is still active. Wait and see.

I'm also going to get the build process a bit more reliable, because that is far from simple for the moment.

Have fun.

Guy

moxom88 commented 6 years ago

Thanks a lot guywyers,

I'm sure its my mistake here, but when I try to build the package with ./configure I'm getting the following error: configure: error: Could not locate a working openvpn source tree.

Before that I got the same error with OpenLDAP and I fixed it by installing libldap2-dev. I should however have openvpn installed, so I'm not quite sure how to fix this - I've tried specifying a path with --with-openvpn=/usr/share/openvpn/ with no luck..

If you have a quick fix, that would be much appreciated, otherwise I'll wait for you to make the build process more reliable! ;)

guywyers commented 6 years ago

You should specify --with-openvpn=/usr/include/openvpn I think that it will still not build, however. There is a problem with old gcc versions that's breaking the build. I was hoping that somebody on the other side would pick up my pull request and maybe contribute to get the build going, but so far it's silence. I think it's really no longer maintained.

To get it build I had to use the "way back machine" -almost literally. I installed a clean Ubuntu 14.0x and forced it to use gcc 4.6. With some minor tweaks I got it to build and run. I'll post some detailed instructions here (or on the other side) tomorrow, because it would be good if somebody else could dogfood it :-)

moxom88 commented 6 years ago

Thanks, you're right - I'm getting a GCC error now :( Looking forward to your next post, you're a life-saver :D

guywyers commented 6 years ago

All right. Here is how I have built it. As I said, I can't believe this is the right way, but I'm still trying to figure out a better one.

I started with a clean VM, on which I installed Ubuntu 14.0x. This makes life a bit easier, because that's the last release which contains gcc 4.6.

Then I installed the compilers: apt install gcc-4.6 apt install gobjc-4.6 To be sure that the gcc that will actually be used is 4.6: update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 50

Then, of course, make sure that all the build prerequisites are there:

Clone the package, run ./regen.sh in the package folder and you're ready to build. I got it to build with one additional tweak (passing the -fPIC flag to the compiler): ./configure --with-openvpn=/usr/include/openvpn CFLAGS="-fPIC"

When you deploy it, openvpn may crash because of a broken link to libobjc.3.so:

Tue Oct 31 11:48:14 2017 us=424159 SIGTERM[hard,] received, process exiting
Wed Nov  1 11:47:52 2017 us=712147 PLUGIN_INIT: could not load plugin shared object /usr/lib/openvpn/openvpn-auth-ldap.so: libobjc.so.3: cannot open shared object file: No such file or directory: No such file or directory (errno=2)
Wed Nov  1 11:47:52 2017 us=712183 Exiting due to fatal error

This is because the build environment links to an old version of libobjc.3.so. You can fix that by putting a symbolic link like so (on Ubuntu): ln -s /usr/lib/x86_64-linux-gnu/libobjc.so.4 /usr/lib/x86_64-linux-gnu/libobjc.so.3

I still think it should be possible to get it built in a more recent environment, but that remains a bit of a struggle certainly without the help of the original maintainers.

Guy

guywyers commented 6 years ago

Hey guys,

It's done! I just committed a patch on my openvpn-auth-ldap fork, which allows openvpn-auth-ldap to be build on a recent config. I have tried it on Ubuntu 16 with GCC version 5. You can now simply clone the package, run ./regen.sh in the package folder and you're ready to build. You still need to pass two flags to configure (besides the openvpn include folder): ./configure --with-openvpn=/usr/include/openvpn CFLAGS="-fPIC" OBJCFLAGS="-std=gnu11" I could have put these in the autogen scripts, but I'm not sure to what extend they're specific to my configuration, so I preferred to keep them out of the standard scripts.

Obviously, what you'll find in my fork, and therefore also in the pull request, is the changed version containing the Challenge/Response changes.

Play around with it and let me know.

Guy

moxom88 commented 6 years ago

Hi again,

I might be misunderstanding something, but shouldnt the ./configure command produce an openvpn-auth-ldap.so file? I can't find it anywhere on my system :'(

guywyers commented 6 years ago

Yes and no: the ./configure command will create the build environment for you. In the next step you should launch the actual build by doing 'make'. If that succeeds and if you haven't specified any specific destination, 'openvpn-auth-ldap.so' will be built in the src folder.

moxom88 commented 6 years ago

Hi guywyers, Ofcourse, I knew I was missing something obvious ;), thanks for all the help and your work on this, the plugin works flawlessly with TOTP hardware tokens now.

snowrider311 commented 6 years ago

Hey all,

I had all kinds of issues trying to build the openvpn-auth-ldap fork until I finally found this discussion thread.

I've created my own fork of the fork which includes build and packaging scripts for Ubuntu 16.04 LTS (all build dependencies are explicitly listed in those scripts), as well as build instructions in the README.md.

I'm creating a pull request for these changes, but in the meantime, you can find my fork here:

https://github.com/snowrider311/openvpn-auth-ldap

guywyers commented 6 years ago

HI Snowrider,

Thanks for your input.

I went through similar sufferings. The root cause of all this is that the original package is no longer maintained. I needed a simple patch for to enable coexistence of the two plugins, which in itself was easy to do, but I needed to go back to an old config (Ubuntu 14 with gcc 4.x) to get the basic thing to build. So the sequence I went through was:

Thanks,

Guy

-Guy

On Sat, Jan 27, 2018 at 8:03 PM, snowrider311 notifications@github.com wrote:

Hey all,

I had all kinds of issues trying to build the openvpn-auth-ldap fork until I finally found this discussion thread.

I've created my own fork of the fork which includes build and packaging scripts for Ubuntu 16.04 LTS (all build dependencies are explicitly listed in those scripts), as well as build instructions in the README.md.

I'm creating a pull request for these changes, but in the meantime, you can find my fork here:

https://github.com/snowrider311/openvpn-auth-ldap

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/evgeny-gridasov/openvpn-otp/issues/20#issuecomment-361007113, or mute the thread https://github.com/notifications/unsubscribe-auth/AK7Q22VCLhv13YoTH3Y7mMYwEX5lv_Ynks5tO3LpgaJpZM4O_t32 .

k0ste commented 5 years ago

@guywyers, as far I can see current implementation is partial LDAP integration, because:

So If some employers recruited or fired we need to sync otp-secrets file with LDAP. For large deployments when humans in-out for a several dozen per week this does not look like a very convenient and reliable solution. How you personally managed this, with script on OpenVPN server or some orchestrator?

So my question is: technically possible to tell openvpn-otp by openvpn-auth-ldap use key (or full string, e.g. totp:sha1:base32:K7BYLIU5D2V33X6S:1234:xxx) from some ldap field instead file? This will be stateless configuration.

Thanks.

guywyers commented 5 years ago

Yes you're right, all current implementations I've seen maintain "OTP state" on the OpenVPN server. I was also frustrated to discover this. And, indeed, to get this setup to work, you need to use scripts or the manual instructions given at https://github.com/evgeny-gridasov/openvpn-otp

I actually looked at several setups that support OTP, but didn't find anything that doesn't keep state on the server.

Your idea of putting the OTP info in the LDAP configuration is probably the best one, but requires quite a lot of redevelopment and the code base of the openvpn-auth-ldap is actually quite old, so adding this would be a major challenge.

Br,

Guy

On Thu, Feb 7, 2019 at 7:33 AM Konstantin Shalygin notifications@github.com wrote:

@guywyers https://github.com/guywyers, as far I can see current implementation is partial LDAP integration, because:

  • auth data for openvpn-auth-ldap in LDAP.
  • auth data for openvpn-otp in file on OpenVPN server.

So If some employers recruited or fired we need to sync otp-secrets file with LDAP. For large deployments when humans in-out for a several dozen per week this does not look like a very convenient and reliable solution. How you personally managed this, with script on OpenVPN server or some orchestrator?

So my question is: technically possible to tell openvpn-otp by openvpn-auth-ldap use key (or full string, e.g. totp:sha1:base32:K7BYLIU5D2V33X6S:1234:xxx) from some ldap field instead file? This will be stateless configuration.

Thanks.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/evgeny-gridasov/openvpn-otp/issues/20#issuecomment-461303612, or mute the thread https://github.com/notifications/unsubscribe-auth/AK7Q2z-j36q2UKccjqTpRuyh6uRGMgLFks5vK8i9gaJpZM4O_t32 .

k0ste commented 5 years ago

@guywyers

Your idea of putting the OTP info in the LDAP configuration is probably the best one, but requires quite a lot of redevelopment and the code base of the openvpn-auth-ldap is actually quite old, so adding this would be a major challenge.

openvpn-auth-ldap already look into user object for password field, so check another field shouldn't be a big deal. The main restriction as I can see is a whether it is possible to transfer this field further to openvpn-otp.

I'm in the middle of:

After this give to end users some web Google auth generator:

guywyers commented 5 years ago

"The main restriction as I can see is a whether it is possible to transfer this field further to openvpn-otp. "

This is indeed a showstopper. Both openvpn-auth-ldap and openvpn-otp are authentication plugins for openvpn. As far as I can see, the way openvpn interacts with authentication plugins does not allow the passing of information between plugins. It has a list of authentication plugins and calls each of them in sequence, each time passing the same information. Every individual plugins needs to return OK for the authentication to succeed. So, because the otp plugin needs access to information in the LDAP, that will not work.

The only way I see this happening if you merge the two plugins into one with a common configuration.

Br,

Guy

On Thu, Feb 7, 2019 at 11:07 AM Konstantin Shalygin < notifications@github.com> wrote:

@guywyers https://github.com/guywyers

Your idea of putting the OTP info in the LDAP configuration is probably the best one, but requires quite a lot of redevelopment and the code base of the openvpn-auth-ldap is actually quite old, so adding this would be a major challenge.

openvpn-auth-ldap already look into user object for password field, so check another field shouldn't be a big deal. The main restriction as I can see is a whether it is possible to transfer this field further to openvpn-otp.

I'm in the middle of:

  • this is possible, and I can test your patches with OpenLDAP and various clients - iOS, Android, Windows, Linux;
  • (parse ldap uid + otp fields of posixAccount object) make's Ansible role for maintain opt-secrets file or write some python script and run it on OpenVPN Server host;

After this give to end users some web Google auth generator:

  • identify user
  • check presence of vpn_users group membership;
  • generate Google OTP key with some library;
  • write key to LDAP (user object field for otp (str));
  • return QR to user;
  • user can use OpenVPN immediately;

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/evgeny-gridasov/openvpn-otp/issues/20#issuecomment-461357605, or mute the thread https://github.com/notifications/unsubscribe-auth/AK7Q25l-pSPSLrgE3B21I8TNg3UY-yPnks5vK_rZgaJpZM4O_t32 .

k0ste commented 5 years ago

As far as I can see, the way openvpn interacts with authentication plugins does not allow the passing of information between plugins.

Thanks.

The only way I see this happening if you merge the two plugins into one with a common configuration.

Or openvpn-otp can use LDAP as alternative to file storage (if storage_type == 'ldap') . But maybe @evgeny-gridasov will be against that, because this overhead for this plugin.

guywyers commented 5 years ago

storage_type == 'ldap' will not be enough. Not only do you need to inform openvpn-otp that the information is coming from LDAP, but it also needs the credentials to access the LDAP.

What could work is the following approach: In the openvpn config there should be two lines:

plugin /usr/local/lib/openvpn-auth-ldap.so ""

plugin /usr/lib64/openvpn/plugins/openvpn-otp.so

It is in the "" file of the first line that are the credentials you need to access the LDAP. So to make your approach work, what you would need to do is something like:

plugin /usr/lib64/openvpn/plugins/openvpn-otp.so storage_type == 'ldap' ldap_config=""

In that scenario, openvpn-otp could either handle the full authentication itself, or it could simply access the LDAP config to get the specific field that you haved added. I think it is a bit of a hack, so I don't like it, but ity could work.

Br,

Guy

On Fri, Feb 8, 2019 at 4:39 AM Konstantin Shalygin notifications@github.com wrote:

As far as I can see, the way openvpn interacts with authentication plugins does not allow the passing of information between plugins.

Thanks.

The only way I see this happening if you merge the two plugins into one with a common configuration.

Or openvpn-otp can use LDAP as alternative to file storage (if storage_type == 'ldap') . But maybe @evgeny-gridasov https://github.com/evgeny-gridasov will be against that, because this overhead for this plugin.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/evgeny-gridasov/openvpn-otp/issues/20#issuecomment-461680289, or mute the thread https://github.com/notifications/unsubscribe-auth/AK7Q22M_ZORnB66U0dTZecu6Gr60B8Biks5vLPF1gaJpZM4O_t32 .

k0ste commented 5 years ago

Yes, this is not good way. I maybe found another interesting solution to merge LDAP+OTP in one python plugin via aborche/openvpn-plugin-python-proxy. Well see...