Single sign-on (SSO)/Identity and access management (IAM) for Nethserver

Unfortunately, that also doesn’t work:

[root@neth-lemon ~]# ldapsearch -x -LLL -h 192.168.1.52 -D 'cn=fred,ou=People,dc=directory,dc=nh' -W -b"dc=directory,dc=nh" -s sub "(objectClass=inetOrgPerson)" givenName
Enter LDAP Password: 
ldap_bind: Invalid credentials (49)

It’s uid=fred instead of cn. The following should work:

ldapsearch -x -LLL -h 192.168.1.52 -D 'uid=fred,ou=People,dc=directory,dc=nh' -W -b"dc=directory,dc=nh" -s sub "(objectClass=inetOrgPerson)" givenName
[root@neth-lemon ~]# ldapsearch -x -LLL -h 192.168.1.52 -D 'uid=fred,ou=People,dc=directory,dc=nh' -W -b"dc=directory,dc=nh" -s sub "(objectClass=inetOrgPerson)" givenName
Enter LDAP Password: 
ldap_bind: Invalid credentials (49)

From remote you need the -Z option for starttls instead of the -x (simple auth).
I wonder that one gets a misleading “invalid credentials” error because of wrong encryption.

ldapsearch -Z -LLL -h 192.168.1.52 -D 'uid=fred,ou=People,dc=directory,dc=nh' -W -b"dc=directory,dc=nh" -s sub "(objectClass=inetOrgPerson)" givenName
1 Like

The example I posted wasn’t from a remote host, but from the Neth host–but apparently when I connect using its IP address, it still treats it as a remote connection. If I change the command to -h localhost (keeping the -x flag in the command), that works. From the remote host, if I change -x to -Z, it works. Cool.

And more to the point, now that I know that works, once I change the connection to ldap+tls://hostname, LemonLDAP is able to authenticate against the Neth LDAP system.

Edit: I’m realizing that I made my job quite a bit harder than it needs to be by putting LemonLDAP on a separate CentOS 7 VM, rather than just running it on the Neth box. Stuff like the default firewall, SELinux, and the very limited default Apache install (it doesn’t even include mod_ssl) are things I wouldn’t need to deal with if I’d just put it on the Neth box in the first place.

2 Likes

Nice one, finally the disccuion i really been waiting for
join with SSO USer Federation in nethserver (gluu,keycloack,privacyID3A) - Feature - NethServer Community

Still TBD. I’m not at all sure what you mean by “user federation”, and it seems that the application you have in mind requires two-way user sync–I don’t think any of these solutions can handle that, at least not in a way appropriate to Nethserver.

OK, I have LemonLDAP::NG authenticating against OpenLDAP running on a Neth server. I’d expect a very similar procedure to work for AD, but I haven’t tested that yet.

Installation

  • Install LLNG per their docs. Include the sed step to replace example.com in all the config files with your domain.
  • yum install lasso lasso-perl
  • In the Neth server manager, make sure the admin user is active–reset the password if necessary.
  • Obtain cert(s) covering auth.yourdomain, manager.yourdomain, test1.yourdomain, test2.yourdomain
  • Set up DNS so that auth.yourdomain, manager.yourdomain, test1.yourdomain, and test2.yourdomain resolve to your Neth server
  • Implement HTTPS redirection for LLNG (adapted from @mrmarkuz’ config for Peertube). Edit /etc/httpd/conf.d/z-lemonldap-ng-portal.conf and z-lemonldap-ng-manager.conf to include (this configuration will give an A rating with SSLLabs):
# It's generally not a good idea to broadcast the version of Apache you run
ServerSignature Off
ServerTokens Prod

# Security configuration
SSLCipherSuite                    EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol                       All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder               on
# Requires Apache >= 2.4
SSLCompression                    off
# To use stapling, we have to enable it globally
SSLStaplingCache                  "shmcb:logs/stapling-cache(150000)"
# OCSP Stapling requires Apache >= 2.3.3
SSLUseStapling                    on
SSLStaplingResponderTimeout	  5
SSLStaplingReturnResponderErrors  off
SSLSessionTickets                 off # Requires Apache >= 2.4.11

# Manager virtual host (auth.yourdomain)
<VirtualHost *:80 [::]:80>
        ServerName auth.yourdomain
        ServerAdmin webmaster@yourdomain
#        Protocols h2c http/1.1

        RewriteEngine On
        RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
        RewriteCond %{HTTPS} off
        RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

        Alias /.well-known/acme-challenge/ /var/www/certbot/
        <Directory /var/www/certbot>
                Options None
                AllowOverride None
                ForceType text/plain
                RedirectMatch 404 "^(?!/\.well-known/acme-challenge/[\w-]{43}$)"
                Require method GET POST OPTIONS
        </Directory>

        ErrorLog "/var/log/httpd/manager.error.log"
        CustomLog "/var/log/httpd/manager.access.log" common env=!dontlog
</VirtualHost>


<VirtualHost *:443 [::]:443>
    ServerName auth.yourdomain
    LogLevel notice
    # See above to set LLNG user id in Apache logs
    #CustomLog /var/log/httpd/manager.log llng
    #ErrorLog /var/log/httpd/lm_err.log

    SSLEngine on
    # For example with certbot (you need a certificate to run https)
    SSLCertificateFile /etc/letsencrypt/live/manager.yourdomain/cert.pem
    SSLCertificateChainFile /etc/letsencrypt/live/manager.yourdomain/chain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/manager.yourdomain/privkey.pem

Set Portal URL to SSL and enforce secure cookie

  • Log in as user dwho with password dwho. Sadly it doesn’t make any TARDIS sounds on login, but it should direct you to a portal page:

  • Click on the WebSSO Manager, which will bring you to the configuration page:

  • In the left gutter, under General Parameters, expand Portal, and then select URL. Edit the value to specify HTTPS (https://auth.yourdomain)

  • Back in the left gutter, under General Parameters, expand Cookies, then click on Secured Cookie (SSL). In the drop-down, select Secured Cookie (SSL)

  • Click Save at the top of the screen, enter a description if desired, and save your work.

Configure LLNG to authenticate to the Neth OpenLDAP server

  • In the left gutter, expand Virtual Hosts, then manager.yourdomain, and click on Access rules.
  • Change each of the rules to add or $uid eq "admin" at the end.
  • Do not click Save yet
  • Back in the left gutter, expand General Parameters, then click on Authentication parameters.
  • Set Authentication module to LDAP, and Register module to None.
  • Do not click Save yet
  • Back in the left gutter, under General Parameters, under Authentication parameters, expand LDAP parameters, then click on Connection.
    • Set Verify LDAP server certificate to Optional
    • Set Users search base to dc=directory,dc=nh
    • Set Account to cn=ldapservice,dc=directory,dc=nh
    • Set Password to your LDAPService password (you’ll find it in the Neth server manager, under Users & Groups, in the details for the Local LDAP account provider)
  • Now, at the top of the page, click Save. Enter a comment if desired, then click OK.
  • Log out (under the menu in the upper-right corner)

Test

  • Browse back to http://auth.yourdomain
  • Log in as your admin user with the password for that user. You should see the same portal you saw previously when you logged in as dwho.
  • Log out, and log back in as some other user on your Neth system. You should see a different portal page, without the WebSSO Manager or related buttons.
6 Likes

Now we’re going to configure Nextcloud to authenticate to LemonLDAP::NG. This follows the LLNG docs pretty closely.

  • First, in the LLNG Manager (manager.yourdomain), enable the SAML 2.0 issuer module. In the left gutter, expand General Parameters, Issuer modules, SAML, then click on Activation. Set to On.
  • Back in the left gutter, expand SAML2 Service, then Security parameters, then click on Signature. Click the New certificate link near the top of the page. Copy the certificate from the Public Key field on this page.
  • Now, in Nextcloud, add/enable the SSO & SAML authentication app.
  • Still in Nextcloud, logged in as admin, go to the Settings page, then to SSO & SAML authentication. Click the button to use the built-in SAML authentication. Enter the parameters.
    • In the first field under General (with the default text of Attribute to map the UID to), enter uid
    • Under Identity Provider Data, in the first field, enter https://auth.yourdomain/saml/metadata
    • In the second field, enter https://auth.yourdomain/saml/singleSignOn.
    • Expand the optional Identity Provider settings
    • In the third field, enter https://auth.yourdomain/saml/singleLogout
    • Ignore the fourth field
    • In the fifth field, paste the certificate you copied above.
    • Download the metadata XML file to a convenient location.
    • Note the warning at the top of the page–this will lose access to the built-in Nextcloud admin user unless you browse directly to https://$nextcloud_URL/index.php/login?direct=1.
  • Back to the LLNG Manager. In the left gutter, click on SAML Service Providers, then click Add SAML SP at the top. Give it a descriptive name (like “Nextcloud”) and click OK.
  • Below SAML Service Providers, expand the new entry for Nextcloud, and click on Metadata. Upload the file you downloaded from Nextcloud (should be named metadata.xml), or paste in its contents.
  • Back in the left gutter, below Metadata, click on Exported attributes. At the top, click on Add attribute, and add two attributes. For the first, both the Variable name and Attribute name should be cn; for the second, they should both be uid.
  • Back in the left gutter, two lines down, expand Options, then click on Signature. Set both Check SSO message signature and Check SLO message signature to Off.
  • Save your work.

Test

Browse to your Nextcloud URL. You’ll be directed to the LLNG authentication portal. Enter a user’s uid/password there and log in, whereupon you’ll be directed back to Nextcloud and logged in as that user.

Notes

  • As I mention above, this doesn’t give you access to an admin user for Nextcloud. No doubt there’s a way to address this, but I haven’t gotten to it yet.
  • This logs the user in as his username, rather than the UUID that’s normally used internally with Nextcloud when it’s authenticating to Nethserver’s OpenLDAP. I expect this could be addressed by changing the Exported attributes above, perhaps exporting entryUUID as uid–though I have to say, I like the users’ directories to have their usernames rather than UUIDs. But obviously this would be disruptive if done on a system with existing users.

TODO

  • Figure out the admin user
  • Figure out the attribute mapping for the UUID
  • Get Nextcloud to sign the SSO/SLO messages–seems this would have to increase security
  • YubiKey authentication, of course. Yes, I know Nextcloud supports that internally, but I’m using it as a sample app here.
3 Likes

The LLNG docs also describe setting it up to authenticate for Roundcube, but it looks like they depend on Roundcube being in its own virtualhost, which doesn’t appear to be an option with Nethserver. Bother.

Edit: It turns out those docs are also out of date, as they rely on a http_authentication plugin that doesn’t appear to be available any more. There is, however, a plugin for OpenID Connect, which looks like it would work, though I haven’t tested it as yet.

Having played with LLNG a bit now, I have some observations relative to using it with Neth:

  • Its security model really expects that every resource you’ll be protecting is in its own virtual host. You can then add PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2 to the virtual host’s conf file, and LLNG will handle it (and Apache won’t serve it without LLNG saying it’s OK).
  • It kind of expects that users will be able to log into a portal (which it provides), from which they’ll have access to any apps they’re authorized to use–once again, defined as virtual hosts and for which LLNG is configured.
  • That portal also handles password resets. Since it’s from the same folks who wrote self-service password, and SSP seems to work fine, I expect it could safely handle users’ password resets on Neth–but I haven’t tested this.
  • I like that, compared to most of the other systems I compared it against, it doesn’t require Java, its own container, or a reverse proxy configuration. I don’t know that Perl is a plus, as such, but plenty of e-smith/SME/Neth is already written in Perl, so…
  • It was relatively straightforward to connect with Neth’s OpenLDAP system, and then authenticate those users.
  • I don’t know if it’s unique in this capability, but I didn’t see any of the other contenders mention their ability to authenticate using HTTP headers. This apparently allows LLNG to handle the authentication for any application that can use external authentication (a/k/a “Apache authentication”), which should make it easier to integrate with software that doesn’t support technologies like OIDC or SAML. It’s as yet unclear to me whether Cockpit or WebTop could be used with this or any other mechanism supported by LLNG.
  • This could be a deal-breaker–it looks like it would be a nightmare to template. The main .ini file wouldn’t be bad at all, and of course Apache’s virtualhost .conf files would be straightforward enough. But there are a few problems with the main configuration file:
    • LLNG keeps the last several config files on disk, making it easy to roll back to a previous config file if you break something (which I’ve done a lot). Don’t think that could be templated very easily.
    • The config file, at least by default, is JSON. I don’t think that’s a deal-breaker by itself, but it seems it could be kind of a messy format to template well. It does support YAML as well, though, if that would make things easier.
    • LLNG comes with its own web control panel (the so-called manager), which lets you control a lot of stuff. And you need to use it to add clients/relying parties and other such things. Unless we’re going to write all of it into the e-smith database structure, and code a UI to control it, we have to leave the manager there, and that means we’re not going to have any real control over the contents of the config file.
    • I think the upshot is that we could ship a preconfigured file, set up with the basic Neth applications, configured to handle their authentication, handle the correct authentication backend (local/remote OpenLDAP, AD, etc.), but then the user/admin needs to work directly with the manager. That would also mean that, whatever form that file took, it couldn’t be an ordinary template that got overwritten under normal circumstances.
    • There’s a lemonldap-ng-cli tool that will noninteractively edit the config file, and may mitigate some of these concerns. It still wouldn’t make it something that could be readily templated, but it should be relatively straightforward to script changes to the configuration (see, e.g., these instructions dealing with Gerrit)

@giacomo, thoughts?
@oneitonitram, how does this line up with what you were wanting to do?

5 Likes

@danb35

Great “Report” you made here!

For people like me, Stephdl and others, PERL is something very positive!

PERL - as an Interpreter Language - is among the fastest language in ripping strings apart. And Big Data, or any database, is a collection of strings in PERL’s view! :slight_smile:

And with CPAN, Perl is capable of extending itself, and updating/compiling PERL modules - only using PERL! Something most languages can’t do!

My 2 cents
Andy

For me, it’s pretty much neutral, but I wouldn’t count myself as competent in anything past BASIC. I don’t know how important the underlying language is; I don’t expect any of us to be modifying any SSO application Neth might go with. But I recall a number of people on the SME side expressing the opinion that Perl was holding the project back, due to their perception of a limited pool of skilled Perl developers.

But regardless of language, Gluu, and Keycloak install their own container system, which then needs a reverse proxy to expose it to the admin and users. That’s a layer of complexity I’d rather avoid if possible.

1 Like

Overall from the observations made, it meets expectations in some aspects, now what’s more important to know and figure out is.

Can the SAML authenticator integrated be used by other third party app providers that make use of SAML for authentication. if the answer to this is yes, then that’s a Tick, and for any cloud services we might need to use that’s supports SAML, then we are good to go.
Essentially this removes the need for a service like Okta for SAML authentication. (based on nextcloud instruction, i am thinking it should be fine for that)

will try to se if we can build one of our internal softwares to authenticate using it. it will really save us alot of trouble. though i must admit, we have never built a software that authenticated with third party systems, just db mostly, especially SAML

The other thing that I am yet to figure out. Will all the users be created in Nethserver, but not able to Edit or Add information on LLNG, or does it have a two way sync of sorts, Not that this is a deal breaker, its just to understand how this platform works.

i ALSO SEE ON THEIR WEBSITE HERE: Applications — LemonLDAP::NG 2.0 documentation (lemonldap-ng.org)

a good number of applications, which we are already using are supported and with a way to integrate. a huge number of them are already modules On Nethserver, and really this would and should give us an upper hand in getting them up to speed on Nethserver.

I have to say that sounds promising even if not very simple to integrate.
I also took a look to Mattermost integration thanks to @oneitonitram link: very cool.

I agree with this approach: create some configuration files depending on the account provider configuration, but without template. Let’s the manager do its job.
Eventually, we can create a reset script that recreates a fresh configuration using cli tool.

1 Like

If those providers will let you specify your own SAML Identity Provider, it seems like it could.

I believe the users would need to be created in Nethserver, and for the most part edits would need to be there too–except for passwords. LLNG will handle password changes, and I’d expect that should work fine with Neth (I haven’t tested it, but as I wrote above, the same crew wrote Self-service Password, and it works fine).

Now, LLNG does support user registration, so I’m sure it could insert a user into the LDAP database–but that wouldn’t create a home directory or otherwise make Neth aware of that user. What we’d really want to do is have it call signal-event user-create with the appropriate parameters. And it would need to do that with root permissions, if I’m not mistaken. I haven’t looked into the registration feature to see if it’s possible to run arbitrary scripts on user registration. Though if that user didn’t need mail on the Neth server, inserting him into the LDAP database might be enough. Makes me wonder if such a user would work with Nextcloud…

I’m thinking that the CLI tool could be a good way to do this too. I’m going to have to think about this some more.

2 Likes

I think I’m getting a handle on how this works. It’s kind of similar, really, to our config database commands, though it operates directly on the config file rather than needing the separate steps of expanding the templates and reloading services. So here’s that I’m thinking…

I expect I’ll be able to create a module for LLNG. It’ll have templates for the virtual host .conf files for the portal and manager, and for the lemonldap-ng.ini file (the only real variables in those are the domain name, and the cert/chain/key files). It will also have templates for a script that will go in /root/lemon_config.sh.

That script will use the CLI tool to:

  • enforce HTTPS on the portal
  • enforce secure cookies
  • remove the sample applications from the portal menu
  • configure LLNG to connect to, and authenticate against, whatever accounts provider you’ve set up in Nethserver
  • configure the access rules for the manager to allow access by your admin user

The intent would be that you’d only run the script once, post-installation, and then any further configuration would be done through the manager. Though I suppose it could be used to reset the configuration, in case you’d borked it through the manager. Once that’s run, you’d log into the manager and configure your relying parties and such from there.

3 Likes

i have a scenario where my current authentication server has a builtin hostname as : auth.domain.tld which is what i have been using to authenticate all other services.
Now if i am to add LLNG, can it work with another subdomain or would i be bale to define it on the servers default hostname.

or generally ill also need to change my current hostname.
i am not sure how much work ill have once i change the hostname but i am sure it will be a bumpy ride.

Wasn’t my plan, but I’ll see if I can put it in there. My plan was to leave the hardcoded hostnames of auth.domain for the portal, and manager.domain for the manager. But it should be something I could do.

1 Like

I think I have it taken care of, conceptually at least, for OpenLDAP–I can pull the relevant values from the config database (or they’re static), massage them as needed, and save them to the LLNG configuration. But having a little trouble with AD, specifically the Base DN.

For local OpenLDAP, the Base DN is a static value of “dc=directory,dc=nh”. For remote LDAP, it’s saved as {sssd}{BaseDN}. For AD, though, neither is the case; it seems to be constructed from the FQDN of the AD server. If the server is `ad.domain.tld`, the Base DN is `dc=ad,dc=domain,dc=tld`. But this value doesn't seem to be stored anywhere in the configuration databases. Do I need to hack this together myself (I guess by pulling apart {sssd}{Realm}), or is there somewhere else I can get this value?