On 01/07/2023 16.15, dweller dweller via FreeIPA-users wrote:
Hi,
I'm impressed! You figured out most of the authentication and
authorization workflow yourself. This is quite an achievement! The
system is complex and goes through multiple stacks. I'm sure you would
have figured out the rest if you would have found the code behind the
"/ipa/session/login_password" route.
Let me fill in some gaps...
1. So user is already sees before him FreeIPA login form. He types his
login/password and submits the form
2. Request goes to /ipa/login_password. /ipa/login_password location by itself
does not offer much:
<Location "/ipa/session/login_password">
Satisfy Any
Require all granted
</Location>
The login_password route does more work than you give it credit. When a
user enters a password, mod_wsgi runs this Python code to authenticate
the credentials with kinit. More later in my post. The route has
authentication disabled because there is no authenticated session yet.
https://github.com/freeipa/freeipa/blob/master/ipaserver/rpcserver.py#L979
Here is where things become vague for me. We see *GssapiImpersonate On* and
*GssapiUseS4U2Proxy on*.
```
GssapiImpersonate
This option can be used even if AuthType GSSAPI is not used for given Location
or LocationMatch, to obtain service ticket for a user that was already
authenticated by different module
```
and
```
GssapiUseS4U2Proxy
Enables the use of the s4u2Proxy Kerberos extension also known as constrained
delegation This option allows an application running within Apache to operate
on behalf of the user against other servers by using the provided ticket
(subject to KDC authorization).
```
So why do we need both? Isn't GssapiUseS4U2Proxy enough to issue service
tickets on behalf of user and use them? Also, is there is no TGT actually
obtained for the client's principal, only service tickets?
The options enable both s4u2self and s4u2proxy.
A typical web application implements access control in the backend and
has a database user to talk to a database like Postgres. FreeIPA works
differently.
There is no database account for FreeIPA HTTP backend. Instead it uses
constraint delegation between HTTP/$(hostname) and ldap/$(hostname). The
HTTP service principal is allowed to request a service ticket on behalf
of the user. This allows the HTTP service to talk to LDAP while
impersonating the user. LDAP thinks that LDAP operations are made by the
user account and enforces access permission based on the user's permissions.
The document
https://freeipa.org/page/Troubleshooting/PrivilegeSeparation explains
the concepts in greater details.
Let's review options for ipa-httpd and ipa-api services:
- allow_protocol_transition (This option controls whether s4u2self requests are
allowed for the requesting client)
Ok, understandable, we need it in conjuction with GssapiUseS4U2Proxy on of the
Apache, otherways it won't work. Though it is present for service/ipa-api and
not for the service/ipa-httpd. Why so?
- allow_client_ccache_sync
This one is kind of vague for me. This option allows the proxy, in certain
circumstances, to send back an additional option in the response structure of
certain calls when it determines that a new ticket may have been added to the
internal ccache. Clients can then replace their (encrypted) copy with the
updated ccache.
So gssproxy injects option in response for a client (apache in our case?) to renew
service tickets? What are the "certain calls"?
Correct, in this case Apache HTTP is the client. mod_auth_gssapi caches
the impersonated service ticket that the HTTP service principal
requested on behalf of the user for access to LDAP. AFAIK "certain
calls" are (1) acquire a new service ticket from KDC, (2) renew expired
ticket.
4. Somehow user getting autheticated. But there is no TGT, is it? So how is it
done?
The Python code behind "login_password" uses kinit to acquire an amore
ccache, then a TGT with username and password (or password + OTP). The
TGT is stored in a temporary ccache. The code then performs an internal
request to "/ipa/session/cookie" in order to fetch session cookie from
mod_auth_gssapi. Finally the ccache with the TGT is destoyed and the
cookie is returned to the user.
There is also a /ipa/session/login_x509 route that uses
mod_lookup_identity and SSSD to perform mTLS authentication for
smartcards and client certs.
8. Perfoming http response with data from LDAP, and setting a coockie
ipa_session. What is in the cookie, by the way? I thought it was TGT but now
I'm not that sure
It's not the TGT. HTTP negotiate never transmits the user's TGT, only a
service ticket. I'm not entire sure but I *think* it's either the user's
encrypted service ticket for HTTP service of the host or something
similar that let's mod_auth_gssapi map the session cookie to the
encrypted ccache on disk.
HTH,
Christian
--
Christian Heimes
Principal Software Engineer, Identity Management and Platform Security
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael
O'Neill
_______________________________________________
FreeIPA-users mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct:
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives:
https://lists.fedorahosted.org/archives/list/[email protected]
Do not reply to spam, report it:
https://pagure.io/fedora-infrastructure/new_issue