Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Specifying KRB5CCNAME#309

anybodysguest started this conversation inGeneral
Dec 19, 2022· 6 comments· 4 replies
Discussion options

It looks like by default python-gssapi create a ticket cache located in API:xxxxxxx. Is there a way to tell python-gssapi to create the ticket in a specific folder?

You must be logged in to vote

Replies: 6 comments 4 replies

Comment options

It just calls the C api so you can specify the env varKRB5CCNAME usingos.environ and it will work in the same way. What API are you trying to call, what are you trying to achieve with a custom ccache?

You must be logged in to vote
0 replies
Comment options

Hi Jordan,

I am calling two API. One isgssapi.raw.acquire_cred_with_password and the other isgssapi.SecurityContext. I'm thinking that the first API is the one generating the ticket. I can easily supply the KRBCCNAME env variable (I do that for other apps using the KRB5 library). I am doing this in Docker because the I believe it is expecting to look for the ticket cache in a "temp/" folder. So I need to tell to use a specific one since. If I run this within Pycharm I don't need to do anything, but when I put it in a container, it can't find the ticket. I have a separate python file called kerberos.py (below). You can see the commented out lines where I was trying to use thegssapi.raw.ext_cred_store.store_cred_into API, obviously I don't know what I'm doing! This was from an example I found online, I think it might be yours?

import gssapidef kinit(username=None, password=None, realm=None, exe=None, keytab=None, krb5ccname=None, verbose=False):    server_name = gssapi.Name('krbtgt/' + realm)    user = gssapi.Name(base=username, name_type=gssapi.NameType.user)    bpass = password.encode('utf-8')    result = False    try:        creds = gssapi.raw.acquire_cred_with_password(user, bpass, usage='initiate')        creds = creds.creds        # cache_store = {'FILE', '/etc/ccache'}        # gssapi.raw.ext_cred_store.store_cred_into(cache_store)        context = gssapi.SecurityContext(name=server_name, creds=creds, usage='initiate')        result = True    except AttributeError:        print("AttributeError")    except gssapi.exceptions.GSSError as er:        print(er)    # acquire_cred_with_password returns a wrapper, we want the creds    # object inside this wrapper    print(result)
You must be logged in to vote
0 replies
Comment options

Thegss_store_cred_into can be annoying to use, I've found that the cache needs to exist for it to work unless you specifyoverwrite=True. We even do this in the tests

store_res=gb.store_cred_into(store,initial_creds,overwrite=True,
**store_kwargs)
for this function. Even then I've not had too much luck with it before.

A few more things to point out

  • The cache store key should identify the type of store to use, for Kerberos you wantccache
  • acquire_cred_with_password will always get a MEMORY ccache credential
  • Unless you need persistence beyond the process you don't need to store it in a file
  • Using thecreds kwarg onSecurityContext will have it only use that credential, it won't lookup the ccache ofKRB5CCNAME

So for this to work you need to do

importosimportgssapiusername='...'password='...'user=gssapi.Name(base=username,name_type=gssapi.NameType.user)bpass=password.encode('utf-8')creds=gssapi.raw.acquire_cred_with_password(user,bpass,usage='initiate').credsifkrb5ccname:=os.environ.get('KRB5CCNAME',None):store= {'ccache':f'FILE:{krb5ccname}',    }gssapi.raw.ext_cred_store.store_cred_into(store,creds,overwrite=True)...
You must be logged in to vote
0 replies
Comment options

I gave this a try today and I am running into this issue:

gssapi.raw.ext_cred_store.store_cred_into(store, creds, overwrite=True)
AttributeError: module 'gssapi.raw' has no attribute 'ext_cred_store'

I commented out the AttributeError catch block and let the code fall through to the next general exception catch. That's how I got the details above.

I've checked the docs and there indeed is an 'ext_cred_store' attribute.

Do I need to import something else?

Here's the code I used:

def kinit(username=None, password=None, realm=None, exe=None, keytab=None, verbose=False):
server_name = gssapi.Name('krbtgt/' + realm)

user = gssapi.Name(base=username, name_type=gssapi.NameType.user)bpass = password.encode('utf-8')result = Falsetry:    creds = gssapi.raw.acquire_cred_with_password(user, bpass, usage='initiate')    creds = creds.creds    if krb5ccname := os.environ.get('KRB5CCNAME', None):        krb5ccname='temp'        store = {            'ccache': f'FILE:{krb5ccname}',        }        gssapi.raw.ext_cred_store.store_cred_into(store, creds, overwrite=True)    result = True#except AttributeError:#    print("AttributeError")except gssapi.exceptions.GSSError as er:    print(er)# acquire_cred_with_password returns a wrapper, we want the creds# object inside this wrapperprint(result)
You must be logged in to vote
0 replies
Comment options

AttributeError: module 'gssapi.raw' has no attribute 'ext_cred_store'

This means that your GSSAPI C library doesn't have the extension methods present so you won't be able to call it in python-gssapi. There's little that we can do about that unfortunately. If the C library doesn't have it Python can't call it. I believe this has only been recently added to Heimdal based GSSAPI libs but that hasn't made it into an actual release. Considering your default isAPI I'm guessing you are on a macOS host which uses their own forked version of Heimdal so it makes sense they don't have it.

Unfortunately your options are limited, if you really need to persist the credentials to a file you might be better off using the krb5 APIs directly withhttps://github.com/jborean93/pykrb5. if you didn't need to persist the TGT then why are you wanting to callstore_cred_into?

An example ofkinit using the raw krb5 APIs can be seen inhttps://github.com/jborean93/pyspnego/blob/main/src/spnego/_gss.py#L183-L285. It shows you how it can store a credential in a custom ccache (the implementation there uses a unique MEMORY ccache but you can change it to use a file). It also shows how you can load a credential from the library for use with this one.

You must be logged in to vote
4 replies
@anybodysguest
Comment options

Hi Jordan,
The reason I want to keep this TGT in it's own location is because it is a predictable location. When I run this in Python I can use the memory location fine, but when I package it up in Docker, it can't find the TGT. Why, I don't know. However,using a pre-defined location I can say "Go look here for the ticket" and it will find it. I'll look into using the KRB5 library. Worse case, I guess I could shell out to the kinit app.

@jborean93
Comment options

But if you are using an explicit credential at runtime you don't need to store the TGT at all. You have an in memory credential acquired byacquire_cred_with_password that you can use directly withgssapi.SecurityContext(creds=cred). I don't understand why you need to cache it, and if you do, why can't you just rely on whatever has been cached already.

@anybodysguest
Comment options

The main reason I am trying to assert some kind of control is that within a container it doesn't seem to work. Like I said, outside of a Docker container it works great (using memory credential). But when that same code is running within a Docker container, it doesn't know where to find the ticket. I get an error like this. Note that it is looking for the ticket in FILE:/tmp/krbcc_0.
pyodbc.Error: ('HY000', '[HY000] [Microsoft][ODBC Driver 18 for SQL Server]SSPI Provider: No Kerberos credentials available (default cache: FILE:/tmp/krb5cc_0) (851968) (SQLDriverConnect)')

@jborean93
Comment options

Ah ok I think I see now, you don't control the code that creates the security context so you can't provide it the credentials retrieved fromacquire_cred_with_password? At least with Heimdal based implementations withoutstore_cred_into you are limited to the following:

  • Callingkinit as a subprocess with an explicitKRB5CCNAME env var
  • Using the krb5 API directly to get the cred name to set toKRB5CCNAME - you should still be able to use the MEMORY ccache it's just now you know the ccache type and name to set toKRB5CCNAME
Comment options

Yeah, it's not the end of the working to call kinit as a sub-process, but requires I install kinit into the container. Also, not a big deal. All I'm trying to solve for now is to be able to use a service account to make connections to the db and that requires kerberos. It's the curse of working in a serverless environment. The containers (in AWS) are not domain-joined so they have no awareness of AD/KDC. You have to do this manually. With Fargate, which allows multiple containers to run in the same task, I use a sidecar that does all the KDC Auth and brings the TGT back to the container and shares the ticket with the application container. Unfortunately the new service I am using, AWS Batch, only a single container to run so that's what I am trying to create now: one image that get an ticket for a given service principal and password, and then running some processing against a SQL Server db (uses a trusted connection) then exiting the container.

You must be logged in to vote
0 replies
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
General
Labels
None yet
2 participants
@anybodysguest@jborean93

[8]ページ先頭

©2009-2025 Movatter.jp