Comments (11)
I think it is a bug, we do not handle lifetime, that I can see at a glance.
from gssproxy.
But I need to reprouce to figure out what is the issue.
As the "encrypted" creds are special so I need to figure out if there is something we can do or it makes sense to do something about the user accessbile credentials.
In either case I am surprised the mechglue interposer is not making a call to gssproxy to get the lifetime?
@stanislavlevin could you turn on debugging in gssproxy and show me what calls are made over the wire with the first code snippet you posted?
from gssproxy.
Sure, gssproxy log for that steps:
gssproxy.log
[root@master1 /]# cat /etc/gssproxy/10-ipa.conf
#Installed and maintained by ipa update tools, please do not modify
[service/ipa-httpd]
mechs = krb5
cred_store = keytab:/var/lib/ipa/gssproxy/http.keytab
cred_store = client_keytab:/var/lib/ipa/gssproxy/http.keytab
allow_protocol_transition = true
allow_client_ccache_sync = true
cred_usage = both
euid = apache
[service/ipa-api]
mechs = krb5
cred_store = keytab:/var/lib/ipa/gssproxy/http.keytab
cred_store = client_keytab:/var/lib/ipa/gssproxy/http.keytab
allow_constrained_delegation = true
allow_client_ccache_sync = true
cred_usage = initiate
euid = ipaapi
[service/ipa-sweeper]
mechs = krb5
cred_store = keytab:/var/lib/ipa/gssproxy/http.keytab
socket = /var/lib/gssproxy/ipa_ccache_sweeper.sock
euid = ipaapi
cred_usage = initiate
The overall process is:
- ipa krbtpolicy-mod --maxlife 20
- kdestroy && kinit
- I inject pdb_clone into https://github.com/freeipa/freeipa/blob/6f49cc06569f46c8830d57498421a7e6fd9e4d94/ipaserver/plugins/ldap2.py#L202
diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index 095e74b2a..c46da7c15 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -199,6 +199,18 @@ class ldap2(CrudBackend, LDAPCache):
else:
os.environ['KRB5CCNAME'] = ccache
+ import time
+ import gssapi
+ time.sleep(25)
+ from pdb_clone import pdb
+ pdb.set_trace_remote()
+
+ store = {'ccache': ccache}
+ creds = gssapi.Credentials(
+ usage="initiate", name=None, store=store
+ )
+ creds.lifetime
+
principal = krb_utils.get_principal(ccache_name=ccache)
client.gssapi_bind(server_controls=serverctrls,
- trigger plugin, for example,
ipa dnszone-find ipa.test.
I modified (in FreeIPA PR) krb_utils.get_principal
and check it for that PR. I expect that it will raise ExpiredCredentialsError
after expiration, but nothing happens.
Next (in the same method) gssapi_bind
to LDAP unexpectedly (for me) works.
Something like this:
auth_tokens = ldap.sasl.sasl({}, 'GSS-SPNEGO')
conn = ldap.initialize(
"ldapi://%2Frun%2Fslapd-IPA-TEST.socket",
)
conn.sasl_interactive_bind_s('', auth_tokens, None, None)
It seems that gssproxy on every gss_acquire_cred
(may be a145ea3 and gpp_store_remote_creds
) attempts to refresh expired ccache, but overwrite with wrong(?) credentials ( different default principal (even the original one differs)) based on client_keytab:/var/lib/ipa/gssproxy/http.keytab
:
[root@master1 /]# ls -lat /run/ipa/ccaches/ | head -n 3
total 380
drwsrws---+ 2 ipaapi ipaapi 4096 Jun 8 15:27 .
-rw-rw---- 1 apache ipaapi 2906 Jun 8 15:27 [email protected]
[root@master1 /]# KRB5_KTNAME=/var/lib/ipa/gssproxy/http.keytab /usr/sbin/gssproxy -d --extract-ccache /run/ipa/ccaches/[email protected] --into-ccache ~/decryptedccache
[2021/06/08 15:27:43]: Debug Enabled (level: 1)
[2021/06/08 15:27:43]: Service: Extract Ccache, Keytab: /var/lib/ipa/gssproxy/http.keytab, Enctype: 18
decrypted
[root@master1 /]# klist ~/decryptedccache
Ticket cache: FILE:/root/decryptedccache
Default principal: [email protected]
Valid starting Expires Service principal
06/08/2021 15:27:30 06/08/2021 15:27:50 krbtgt/[email protected]
for client HTTP/[email protected], renew until 06/09/2021 15:27:30
06/08/2021 15:27:30 06/08/2021 15:27:49 HTTP/[email protected]
renew until 06/09/2021 15:27:29
after expiration and gss_acquire_cred
:
[root@master1 /]# ls -lat /run/ipa/ccaches/ | head -n 3
total 380
drwsrws---+ 2 ipaapi ipaapi 4096 Jun 8 15:29 .
-rw------- 1 ipaapi ipaapi 2104 Jun 8 15:29 [email protected]
[root@master1 /]# KRB5_KTNAME=/var/lib/ipa/gssproxy/http.keytab /usr/sbin/gssproxy -d --extract-ccache /run/ipa/ccaches/[email protected] --into-ccache ~/decryptedccache_
[2021/06/08 15:29:47]: Debug Enabled (level: 1)
[2021/06/08 15:29:47]: Service: Extract Ccache, Keytab: /var/lib/ipa/gssproxy/http.keytab, Enctype: 18
decrypted
[root@master1 /]# klist ~/decryptedccache_
Ticket cache: FILE:/root/decryptedccache_
Default principal: HTTP/[email protected]
Valid starting Expires Service principal
06/08/2021 15:29:32 06/08/2021 15:29:52 krbtgt/[email protected]
renew until 06/09/2021 15:29:32
from gssproxy.
I do not see why krb_utils.get_princpial would raise any exception, the information is available, then fact a ccache is expired does not invalidate it's contents.
Have you checked what's in creds.lifetime?
I recall that we did change acquire_cred to cause the mechglue to explicity inquire the credentials if lifetime is requested during a gss_acquire_cred() call. So I am sureprised that gssapi.Credentials() wouldn't cause that call to happen (I do not see it in the log).
As for the behavior on initiate:
A client_keytab should not be specified if you do not intend to have gss-proxy use it for initiation.
Alternatively you must insure the caller always provide the name for the credentials to use, so that gss-proxy will not select a client keytab with an unmatching name in it.
from gssproxy.
Ok, so setting name=None if you mean to test "admin" credentials is definitely not ok given's gssproxy configuration for HTTP, so the log you gave me is not useful, as I see that what happens is that a new credential based on client_keytab is returned.
from gssproxy.
I do not see why krb_utils.get_princpial would raise any exception, the information is available, then fact a ccache is expired does not invalidate it's contents.
Based on the current behaviour of python-gssapi for non-gssproxy env I expect ExpiredCredentialsError
. For example,
[root@master1 /]# cat test.py
import time
import gssapi
store = {'ccache': '/tmp/admin_ccache'}
creds = gssapi.Credentials(usage='initiate', name=None, store=store)
for i in range(1, 12):
print(creds.name)
time.sleep(2)
[root@master1 /]# echo Secret123 | KRB5CCNAME=/tmp/admin_ccache kinit
[root@master1 /]# python3 test.py
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Traceback (most recent call last):
File "//test.py", line 8, in <module>
print(creds.name)
File "/usr/lib64/python3.9/site-packages/gssapi/creds.py", line 72, in name
return self.inquire(name=True, lifetime=False,
File "/usr/lib64/python3.9/site-packages/gssapi/creds.py", line 259, in inquire
res = rcreds.inquire_cred(self, name, lifetime, usage, mechs)
File "gssapi/raw/creds.pyx", line 357, in gssapi.raw.creds.inquire_cred
gssapi.raw.exceptions.ExpiredCredentialsError: Major (720896): The referenced credential has expired, Minor (100001): Success
So, I can't know the principal name from expired creds using python-gssapi.
Have you checked what's in creds.lifetime?
I recall that we did change acquire_cred to cause the mechglue to explicity inquire the credentials if lifetime is requested during a gss_acquire_cred() call. So I am sureprised that gssapi.Credentials() wouldn't cause that call to happen (I do not see it in the log).
creds.lifetime
is always 20.
As for the behavior on initiate:
A client_keytab should not be specified if you do not intend to have gss-proxy use it for initiation.
Alternatively you must insure the caller always provide the name for the credentials to use, so that gss-proxy will not select a client keytab with an unmatching name in it.
Yes, this is the actual behaviour I see.
I provide the default settings of gssproxy for IPA, where the service/ipa-api
is in use, nothing was changed there.
from gssproxy.
The problem is that you are calling this:
creds = gssapi.Credentials(usage='initiate', name=None, store=store)
Where name=None, and gss-proxy in this case is allowed to obtain a new fresh credential for you with the keytab in the configuration.
If you want to test for expired cred you need to pass the name of principal to get creds for so that gss-proxy is not going to try the keytab
from gssproxy.
that example is for non-gssproxy environment.
from gssproxy.
The problem is that you are calling this:
creds = gssapi.Credentials(usage='initiate', name=None, store=store)
Where name=None, and gss-proxy in this case is allowed to obtain a new fresh credential for you with the keytab in the configuration.
If you want to test for expired cred you need to pass the name of principal to get creds for so that gss-proxy is not going to try the keytab
I see that.
I'm just trying to demonstrate you the issue.
In this example #33 (comment)
creds = gssapi.Credentials(usage='initiate', name=None, store=store)
was a visual replacement of ipalib/krb_utils::get_credentials
, which is always called with name=None
.
Regarding lifetime
I tried to set name to [email protected]
.
code:
principal = "[email protected]"
name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
store = {'ccache': ccache}
creds = gssapi.Credentials(
usage="initiate", name=name, store=store
)
creds.lifetime
result for valid (not expired) creds is some constant value (not changed from call to call for credentials instance):
(Pdb) creds.lifetime
16
log:
gssproxy.log
Instantiation of Credentials on expired creds:
(Pdb) creds = gssapi.Credentials(usage="initiate", name=name, store=store)
*** gssapi.raw.exceptions.MissingCredentialsError: Major (458752): No credentials were supplied, or the credentials were unavailable or inaccessible, Minor (2598845123): No credentials cache found
from gssproxy.
Ok, so the second one is kind of expected, given gss-proxy cannot get you creds for admin and the original creds are expired.
But the creds.lifetime is not adjusted ...
I need to find some time to reproduce in this scenario, thanks for the examples.
@frozencemetery do you know if we have a test setup somewhere that I can use to try this out ?
from gssproxy.
Hi, not really sure what you're asking for. Long-lived machines isn't a thing we can do on our infrastructure. If you need a KDC set up, you could use gssapi-console, but it's only a handful of commands to set one up (or fewer, if you use IPA).
from gssproxy.
Related Issues (20)
- Reference that libidmap interface is not implemented and that one hat to use the krb5.conf for id-mapping requirements. HOT 4
- Idle timeout not working HOT 3
- krb5 traces missing from journald logs at debug level 3
- A "usermode" to use gssproxy with flatpaks
- User mode proxy should quit after a short timeout
- [0.9.0] doesn't allow disabled systemd HOT 8
- gssproxy 0.9.0 exits when idle and crashes HOT 3
- Unexpected failure in realpath: 13 (Permission denied) HOT 4
- Multi-homed NFS client does not select correct service principal HOT 13
- gssproxy breaks no_root_squash export option with knfsd HOT 2
- Crash in gssrpc_xdr_free() HOT 9
- Make check failed to execute normally. HOT 2
- Figure out how to proxy multiple ticket caches
- error messages from kerberos are not logged HOT 1
- Can we get a 0.9.2 release? HOT 1
- Variable substitution for hostname / FDQN HOT 5
- Autoconf complains about obsolete options HOT 4
- The gp_workers_free function in gp_workers.c has a wrong param issue HOT 1
- The purpose of Encrypted/Credentials/v1@X-GSSPROXY:
- static idmapping is working different whe gssproxy is installed on the nfs server HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gssproxy.