Skip to content

add support for Keycloak / UCS 5.2 #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 23, 2025

Conversation

spaceone
Copy link
Contributor

@spaceone spaceone commented Mar 26, 2025

Fixes: #204
make the necessary changes to the joinscript to support SAML via SimpleSAMLphp and via Keycloak - depending on what is installed. I tested it successfully on a DC Primary UCS 5.0-10 by just installing nextcloud, then Keycloak, then copy the adjusted joinscript to the system, and force-execute it via: univention-run-join-scripts --force --run-scripts 50nextcloud.inst. Afterwards I can successfully login and logout into nextcloud via SAML via Keycloak.

@spaceone
Copy link
Contributor Author

On top of this I tried enabling OIDC login (see univention#1) which fails due to a bug in the config fetching: pulsejet/nextcloud-oidc-login#281

@blizzz
Copy link
Member

blizzz commented Apr 11, 2025

On top of this I tried enabling OIDC login (see univention#1) which fails due to a bug in the config fetching: pulsejet/nextcloud-oidc-login#281

The officially supported OIDC backend is https://apps.nextcloud.com/apps/user_oidc

Copy link
Member

@blizzz blizzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just one question

Comment on lines +33 to +34
export NC_HOST_IPS="$(get_default_ip_address)"
export NC_TRUSTED_PROXY_IP="$(ucr get docker/daemon/default/opts/bip | cut -d "/" -f 1)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we sure this change does not have potential to cause a regression?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. The current code is broken and randomly uses the first found interface, regardless of whether it's IPv4 or IPv6. At least it would be deterministic now.

@blizzz blizzz mentioned this pull request Apr 11, 2025
6 tasks
IDP_CERT=$(univention-keycloak "$@" saml/idp/cert get --as-pem --output /dev/stdout)
SSO_URL="$(univention-keycloak "$@" get-keycloak-base-url)"
univention-app shell nextcloud sudo -u www-data php /var/www/html/occ saml:config:set \
--idp-x509cert="${IDP_CERT}" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my test run with #208 the joinscript ran through, but the IDP certificate was not set. Actually non of the key material was set, only:

root@nextc-17696382:/var/www/html# sudo -u www-data php occ saml:config:get
  - 1:
    - general-uid_mapping: uid
    - idp-entityId: https://ucs-sso.lorem-ipsum.intranet/simplesamlphp/saml2/idp/metadata.php
    - idp-singleLogoutService.url: https://ucs-sso.lorem-ipsum.intranet/simplesamlphp/saml2/idp/SingleLogoutService.php
    - idp-singleSignOnService.url: https://ucs-sso.lorem-ipsum.intranet/simplesamlphp/saml2/idp/SSOService.php

Seems like the univention-keycloak commands did not succeed?

What's the best way to invoke it manually for testing? I forgot what was passed with $@ 🙊.

I am also not seeing much in the UMC web unterface, where would these things be now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you show the log file /var/log/univention/join.log after executing the joinscript.

What's the best way to invoke it manually for testing? I forgot what was passed with $@ 🙊.

univention-run-join-scripts --force --run-scripts 50nextcloud.inst

$@ is often empty on DC Master, and contains on other roles --binddn "$dn_of_Administrator" --bindpwdfile /some/secret/file.

I am also not seeing much in the UMC web unterface, where would these things be now?

They are only in Keycloak. We didn't add UDM modules for these settings :-/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log does not contain much, but setting of the keys is missing:

RUNNING 50nextcloud.inst
2025-04-11 22:05:52.448610434+02:00 (in joinscript_init)
Object exists: cn=services,cn=univention,dc=lorem-ipsum,dc=intranet
Object created: cn=Nextcloud Hub,cn=services,cn=univention,dc=lorem-ipsum,dc=intranet
Object modified: cn=ucs-2792,cn=dc,cn=computers,dc=lorem-ipsum,dc=intranet
Create nextcloud/ucs/modifyUsersFilter
Create nextcloud/ucs/userEnabled
Create nextcloud/ucs/userQuota
Create nextcloud/ucs/debug
Create nextcloud/ldap/cacheTTL
Create nextcloud/ldap/homeFolderAttribute
Create nextcloud/ldap/userSearchAttributes
Create nextcloud/ldap/userDisplayName
Create nextcloud/ldap/groupDisplayName
Create nextcloud/ldap/base
Create nextcloud/ldap/baseUsers
Create nextcloud/ldap/baseGroups
Create nextcloud/ldap/filterLogin
Create nextcloud/ldap/filterUsers
Create nextcloud/ldap/filterGroups
Config value 'type' for app 'user_saml' is now set to 'saml', stored as mixed in fast cache
Config value 'general-require_provisioned_account' for app 'user_saml' is now set to '1', stored as mixed in fast cache
Config value 'general-allow_multiple_user_back_ends' for app 'user_saml' is now set to '1', stored as mixed in fast cache
Object created: SAMLServiceProviderIdentifier=https://ucs-2792.lorem-ipsum.intranet/nextcloud/apps/user_saml/saml/metadata,cn=saml-serviceprovider,cn=univention,dc=lorem-ipsum,dc=intranet
The provider's config was updated.
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>ok</status>
  <statuscode>200</statuscode>
  <message>OK</message>
 </meta>
 <data/>
</ocs>
Check for richdocuments app
Check for onlyoffice app
2025-04-11 22:06:00.856943343+02:00 (in joinscript_save_current_version)
EXITCODE=0
RUNNING 81univention-nfs-server.inst

$@ is often empty on DC Master, and contains on other roles --binddn "$dn_of_Administrator" --bindpwdfile /some/secret/file.

So when i run it with the empty string, I get a usage error.

# univention-keycloak "" saml/idp/cert get --as-pem --output /dev/stdout
usage: univention-keycloak [-h] [--binddn BINDDN] [--binduser BINDUSER] [--bindpwd BINDPWD] [--bindpwdfile BINDPWDFILE] [--realm REALM]
                           [--keycloak-pwd KEYCLOAK_PWD] [--keycloak-url KEYCLOAK_URL] [--no-ssl-verify]
                           {realms,proxy-realms,saml/sp,saml-client-user-attribute-mapper,saml-client-nameid-mapper,oidc/rp,saml/idp/cert,oidc/op/cert,init,kerberos-config,ldap-federation,ad-hoc,2fa,extension,upgrade-config,domain-config,user-attribute-ldap-mapper,get-keycloak-base-url,client-auth-flow,messages,login-links,legacy-authentication-flow,conditional-krb-authentication-flow}
                           ...
univention-keycloak: error: argument command: invalid choice: '' (choose from 'realms', 'proxy-realms', 'saml/sp', 'saml-client-user-attribute-mapper', 'saml-client-nameid-mapper', 'oidc/rp', 'saml/idp/cert', 'oidc/op/cert', 'init', 'kerberos-config', 'ldap-federation', 'ad-hoc', '2fa', 'extension', 'upgrade-config', 'domain-config', 'user-attribute-ldap-mapper', 'get-keycloak-base-url', 'client-auth-flow', 'messages', 'login-links', 'legacy-authentication-flow', 'conditional-krb-authentication-flow')

When I leave it out an Name or service not known:

# univention-keycloak saml/idp/cert get --as-pem --output /dev/stdout
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 174, in _new_conn
    conn = connection.create_connection(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 73, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/socket.py", line 962, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 705, in urlopen
    httplib_response = self._make_request(
                       ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 388, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 1050, in _validate_conn
    conn.connect()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 358, in connect
    self.sock = conn = self._new_conn()
                       ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 186, in _new_conn
    raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x7f32e0c7a390>: Failed to establish a new connection: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 594, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='ucs-sso-ng.lorem-ipsum.intranet', port=443): Max retries exceeded with url: /realms/ucs/protocol/saml/descriptor (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f32e0c7a390>: Failed to establish a new connection: [Errno -2] Name or service not known'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/sbin/univention-keycloak", line 3436, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/sbin/univention-keycloak", line 3432, in main
    return opt.func(opt) or 0
           ^^^^^^^^^^^^^
  File "/usr/sbin/univention-keycloak", line 1460, in download_cert_saml
    saml_descriptor = requests.get(saml_descriptor_url)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/requests/api.py", line 73, in get
    return request("get", url, params=params, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 565, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='ucs-sso-ng.lorem-ipsum.intranet', port=443): Max retries exceeded with url: /realms/ucs/protocol/saml/descriptor (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f32e0c7a390>: Failed to establish a new connection: [Errno -2] Name or service not known'))

Can it be that this is not even running? i do not see either keycloak nor java in the ps output, not a related systemd service. – Seeing your next comment it is probably not installed.

And the domain dig ucs-sso-ng.lorem-ipsum.intranet does not resolve (the "old" one – dig ucs-sso.lorem-ipsum.intranet – still does).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bash-special: "$@" does not expand to empty string but to nothing, if there are no args.

Please do univention-app install keycloak. After this, the service should run.

Copy link
Contributor Author

@spaceone spaceone Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also cherry-pick ab2fbb8, where I added handling for not-installed Keycloak. And added clearer error messages in the joinscript.

@spaceone
Copy link
Contributor Author

Thanks for review.
I think there is one other thing to consider: A system >= UCS 5.1 might not even have Keycloak installed, as it's an optional app. In that case we shouldn't do anything.

@spaceone spaceone marked this pull request as ready for review April 11, 2025 23:06
Copy link

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

@nextcloud nextcloud deleted a comment from github-actions bot Apr 14, 2025
@nextcloud nextcloud deleted a comment from github-actions bot Apr 14, 2025
@nextcloud nextcloud deleted a comment from github-actions bot Apr 14, 2025
@nextcloud nextcloud deleted a comment from github-actions bot Apr 14, 2025
@blizzz
Copy link
Member

blizzz commented Apr 14, 2025

Thanks for review. I think there is one other thing to consider: A system >= UCS 5.1 might not even have Keycloak installed, as it's an optional app. In that case we shouldn't do anything.

Am I holding something wrong here? When I try to install keycloak I get this error and the domain also does not resolve for me:

Downloading Docker image gitregistry.knut.univention.de/univention/components/keycloak-app:latest failed: Pulling keycloak ... Pulling keycloak ... error ERROR: for keycloak Get "https://gitregistry.knut.univention.de/v2/": dial tcp: lookup gitregistry.knut.univention.de on 192.168.122.207:53: no such host Get "https://gitregistry.knut.univention.de/v2/": dial tcp: lookup gitregistry.knut.univention.de on 192.168.122.207:53: no such host 

@spaceone spaceone force-pushed the ucs-5-2-compatiblity branch from cfdc1c9 to ab2fbb8 Compare April 14, 2025 20:14
@spaceone
Copy link
Contributor Author

Am I holding something wrong here? When I try to install keycloak I get this error and the domain also does not resolve for me:
Downloading Docker image gitregistry.knut.univention.de/univention/components/keycloak-app:latest failed: Pulling

That is an internal system. I guess you have the test-appcenter enabled and try to install keycloak from that?
We are currently developing Keycloak 26 integration in the test appcenter.
Please set up the official appcenter, install keycloak from there, and then activate the test-appcenter for installing/upgrading nextcloud.

@spaceone
Copy link
Contributor Author

You can install the published keycloak version via: univention-app install keycloak=25.0.6-ucs4 when the test appcenter is active.

@blizzz
Copy link
Member

blizzz commented Apr 15, 2025

I guess you have the test-appcenter enabled and try to install keycloak from that?

That's correct, and it is necessary to test in-development release before publishing 🙂

@blizzz
Copy link
Member

blizzz commented Apr 16, 2025

Thanks for review. I think there is one other thing to consider: A system >= UCS 5.1 might not even have Keycloak installed, as it's an optional app. In that case we shouldn't do anything.

Is it safe to rely on keycloak/server/sso/certificate/generation? I believe to remember seeing that being set to false before the keycloak installation attempt.

UPDATE: this does not change after the install. Probably checking for presence and value of appcenter/apps/keycloak/status: installed would appear good. Right?

@spaceone
Copy link
Contributor Author

Is it safe to rely on keycloak/server/sso/certificate/generation? I believe to remember seeing that being set to false before the keycloak installation attempt.
I don't understand the question.

UPDATE: this does not change after the install. Probably checking for presence and value of appcenter/apps/keycloak/status: installed would appear good. Right?

Don't use that variable, it's more an implementation detail. Also Keycloak can be installed on a different server than Nextcloud. Use the library function ucs_needsKeycloakSetup from univention-lib ldap.sh.

Copy link
Member

@blizzz blizzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One case spotted with Keycloak installed, without it works nicely now.

@spaceone spaceone force-pushed the ucs-5-2-compatiblity branch from e220130 to 6aaa8f5 Compare April 23, 2025 16:19
@spaceone spaceone requested a review from blizzz April 23, 2025 16:21
Fixes: nextcloud#204
Signed-off-by: Florian Best <best@univention.de>
Fixes: nextcloud#204
Signed-off-by: Florian Best <best@univention.de>
Fixes: nextcloud#204
Signed-off-by: Florian Best <best@univention.de>
…alled

Fixes: nextcloud#204
Signed-off-by: Florian Best <best@univention.de>
@spaceone spaceone force-pushed the ucs-5-2-compatiblity branch from 6aaa8f5 to 4d3aea3 Compare April 23, 2025 16:21
@blizzz blizzz merged commit 28116e1 into nextcloud:master Apr 23, 2025
1 check passed
@blizzz
Copy link
Member

blizzz commented Apr 23, 2025

Thank you @spaceone!

@spaceone
Copy link
Contributor Author

On top of this I tried enabling OIDC login (see univention#1) which fails due to a bug in the config fetching: pulsejet/nextcloud-oidc-login#281

The officially supported OIDC backend is https://apps.nextcloud.com/apps/user_oidc

Alright, I adjusted the changes to use that backend → available via #209.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Keycloak compatibility needed for UCS 5.2
2 participants