Kerberos authentication with gitolite

31 views
Skip to first unread message

Ken Hornstein

unread,
Aug 2, 2024, 2:06:46 AM8/2/24
to gito...@googlegroups.com
Howdy all,

I recently had a reason to get Kerberos authentication working with
gitolite. Searches for people doing the same thing showed a lot of
old information (and one or two things I would personally classify as "kind
of scary" from a security point of view), and once I dug into it I realized
it was kind of simple so I thought it might be useful to let people know
what I did in case anyone wants to replicate it (also, if anyone has any
feedback on my solution I welcome it).

The good news is this requires ZERO changes to gitolite! Here are the
steps:

1) Configure Kerberos authentication for sshd. There is plenty of
documentation how to do this so I won't go into this here.

2) Configure the Kerberos principals you wish to give access to gitolite
to permit logins to your shared git/gitolite account. How that works
depends on the specific details of your site setup, but one common
way to do that is to add them to the .k5login file in the home directory
of the shared gitolite account. E.g., if you use "git@server" as
part of your git URL, you'd add things like this to the .k5login file
in the git user's home directory:

us...@YOUR.REALM
us...@YOUR.REALM

3) Put the following lines in the sshd configuration file (adjusting, of
course, for your site's specific configuration). This requires an sshd
that supports ExposeAuthInfo which I think is relatively common now:

Match User git
ForceCommand /usr/libexec/gitolite/gitolite-wrapper
ExposeAuthInfo yes

4) Create a gitolite-wrapper program/script which reads the contents of the
file specified by the SSH_USER_AUTH environment variable (that's what
the ExposeAuthInfo setting does). Here's what I use:

#!/bin/sh

set -e

if [ -z "$SSH_USER_AUTH" ]; then
echo "Cannot determine authentication method"
exit 1
fi

if [ ! -r "$SSH_USER_AUTH" ]; then
echo "Cannot find user auth file $SSH_USER_AUTH"
exit 1
fi

if ! read -r authmethod user < "$SSH_USER_AUTH"; then
echo "Cannot read from $SSH_USER_AUTH"
exit 1
fi

if [ "$authmethod" != gssapi-with-mic -a "$authmethod" != gssapi-keyex ]; then
echo "Unknown authentication method: \"$authmethod\""
exit 1
fi

exec /usr/libexec/gitolite/gitolite-shell "$user"

And that's basically all you need.

Now, there are some things to be aware of when following these steps:

- In the above implementation the complete Kerberos principal name is
passed as a user to gitolite, which means that you need to put full
Kerberos principals as users in the gitolite configuration file
(e.g., "us...@YOUR.REALM" instead of just "user1"). We make use of a
lot of cross-realm authentication at our site so this was a deliberate
design decision on my part, and using full principal names works just
fine with gitolite. If you didn't want to do that you could could
modify the above script to strip out the Kerberos realm, or better
yet just strip out the realm if it corresponded to your local realm,
use existing Kerberos a2ln rules, read another file for mappings from
Kerberos principals to gitolite users, etc etc ... there are plenty
of options. The basic idea is: do whatever you want to the Kerberos
principal and then pass the result of "whatever" as the argument
to gitolite-shell.

- Because of the use of "ForceCommand" in the sshd config file, this
prevents the normal gitolite configuration where you authenticate
via ssh keys. I mean, the ssh authentication piece will still work,
but the magic that makes that work in terms of gitolite is the
userid specified in the "command" option in the authorized_keys file
and that's overridden by the use of ForceCommand in the sshd config
file. In theory you could put those smarts into the gitolite-wrapper
program, but I'll leave that to anyone who is interested (I'd personally
write that in something other than Bourne shell). We do not use
ssh keys for authentication at our site so this was not an obstacle
for us.

I'm open to feedback or hearing from people who would find this usable.

--Ken

Björn Kautler

unread,
Aug 2, 2024, 7:34:17 AM8/2/24
to Ken Hornstein, gito...@googlegroups.com
When I did it, I
- enabled Kerberos login via winbind / pam / samba / nsswitch
- added a "require_membership_of" to the pam winbind configuration so that only users having the group "git-users" in the active directory can authenticate successfully
- added to sshd_config
Match Group git-users
        X11Forwarding no
        AllowTcpForwarding no
        AllowAgentForwarding no
        PermitTTY no
        ForceCommand sudo -u git -g git -H /opt/gitolite/src/gitolite-shell $USER
- configured sudo configuration to preserve SSH_CONNECTION and SSH_ORIGINAL_COMMAND and to allow the group git-users to do the gitolite-shell command as git:git without password
- created the file gitolite-shell-suexec-wrapper with permission 700 and owner git:git with content:
#!/usr/bin/env bash
 
export GIT_PROJECT_ROOT=/path/to/repositories
export GITOLITE_HTTP_HOME=/path/to/gitolite/installation
export GIT_HTTP_EXPORT_ALL=
exec /opt/gitolite/src/gitolite-shell
- configured the virtual host in Apache to do Kerberos authentication (optionally also as Single-Sign-On), and have "SuexecUserGroup git git" and "ScriptAlias /git /.../gitolite-shell-suexec-wrapper"

Now you can use
- https://git.company.com/git with credentials or SSO to execute Gitolite commands from the browser,
- https://git.company.com/git/[repo] with credentials as remote URL for Git with the credential manager usually being able to preserve them
- [user]@git.company.com with credentials to execute Gitolite commands through SSH
- [user]@git.company.com:[repo] with credentials as remote URL for Git with the credential manager not being able to preserve them (at least when I last tested)
- g...@git.company.com with SSH certificate to execute Gitolite commands through SSH
- g...@git.company.com:[repo] with SSH certificate as remote URL for Git

As Gitolite controls the authorized keys file, only those SSH certificates work, that you manually add to the Gitolite config repository anyway.

Cheers
Björn

--
You received this message because you are subscribed to the Google Groups "gitolite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gitolite+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gitolite/20240729180944.5E61A29295%40pb-smtp1.pobox.com.

Ken Hornstein

unread,
Aug 2, 2024, 10:20:44 PM8/2/24
to gito...@googlegroups.com
>When I did it, I
>- enabled Kerberos login via winbind / pam / samba / nsswitch
>- added a "require_membership_of" to the pam winbind configuration so that
>only users having the group "git-users" in the active directory can
>authenticate successfully
>- added to sshd_config
>Match Group git-users
> X11Forwarding no
> AllowTcpForwarding no
> AllowAgentForwarding no
> PermitTTY no
> ForceCommand sudo -u git -g git -H /opt/gitolite/src/gitolite-shell $USER

Thanks for the feedback! I don't think this would have worked for us,
as we do not use a Windows DC so winbind / samba wasn't an option.
Also, to me the entire point of gitolite is to avoid having those
users in the password file (either directly in /etc/passwd or via your
favorite distributed password database). This also strikes me as a
lot of moving parts and I'm not sure how this would interact with
cross-realm. But, to each his or her own.

--Ken

Ken Hornstein

unread,
Aug 2, 2024, 10:34:39 PM8/2/24
to gito...@googlegroups.com
>When I did it, I
>[...]

I just had another thought ... does this work with submodules? I ask
because the submodule URL is stored in the .gitmodules file in the
superproject repository, e.g.:

[submodule "foo"]
path = foo
url = git@gitserver:foo

But if user "a" accesses your gitserver as "a@gitserver" (via Kerberos)
and user "b" uses "git@gitserver" via publickey (or even "b@gitserver")
then I'm not sure what you can put in the superproject's .gitmodules
file to make that work for different developers. It is entirely
possible I am missing something.

--Ken

Björn Kautler

unread,
Aug 3, 2024, 8:44:26 AM8/3/24
to Ken Hornstein, gito...@googlegroups.com
>  I don't think this would have worked for us, as we do not use a Windows DC so winbind / samba wasn't an option.

It's quite some time ago, so I don't fully remember the details, but the point is, that any authentication you can set up through PAM will work for the SSH part and I think also for the HTTPS part.
While for the HTTPS part I used a GSSAPI configuration to have the single-sign-on with the Windows login.
But both, PAM and Apache should also be able to just authenticate using pure Kerberos.

> Also, to me the entire point of gitolite is to avoid having those users in the password file (either directly in /etc/passwd or via your favorite distributed password database).

Yes, definitely. The only user I have there is `git` which is the user that owns the gitolite files and repositories and is used for the sudo calls.
No other user is in the password file.

> I'm not sure how this would interact with cross-realm

That's not a relevant point for my setup.
But you probably just need to manipulate the username given to gitolite somewhere like in your solution.

>  It is entirely possible I am missing something.

Two of the three URLs are user-agnostic.
If you need submodules, you should probably use one of those.
The `a@gitserver` is bad for usage by Git client anyway as the credential manager cannot store the credentials and you need to give the credentials on every remote operation.
The `a@gitserver` is more suited for doing Gitolite commands via SSH.
If all relevant people use certificates, you can use the `git@gitserver` URL for the submodules,
if not you can use the `https://gitserver/git` URL which should work for everyone using Kerberos.

Cheers Björn

--
You received this message because you are subscribed to the Google Groups "gitolite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gitolite+u...@googlegroups.com.

Ken Hornstein

unread,
Aug 3, 2024, 3:11:00 PM8/3/24
to gito...@googlegroups.com
>> I don't think this would have worked for us, as we do not use a
>> Windows DC so winbind / samba wasn't an option.
>
>It's quite some time ago, so I don't fully remember the details, but the
>point is, that any authentication you can set up through PAM will work
>for the SSH part and I think also for the HTTPS part. While for the
>HTTPS part I used a GSSAPI configuration to have the single-sign-on with
>the Windows login. But both, PAM and Apache should also be able to just
>authenticate using pure Kerberos.

Forgive me, but maybe we're using different termology.

When I say "Kerberos", I mean "Kerberos authentication using a Kerberos
TGT and tickets". In that model you just get your TGT once, on your
local system, and you don't have to enter your password again for
authentication until your TGT expires (or in our case, you don't
have a password at all, you can just use a smartcard to authenticate).

Reading your previous messages carefully, it doesn't sound like you're
talking about that; it looks like you're talking about Kerberos
_password_ authentication, where you treat Kerberos just like a password
store and don't do what I would call "true" Kerberos authentication.
And that's fine; I understand why people do that. But it's not what I
am talking about. You can't use PAM with Kerberos authentication;
the PAM stack can only handle a password, and Kerberos authentication
happens way before the PAM stack is called (you never call the PAM
authentication modules during Kerberos authentication, just the
session modules).

>> Also, to me the entire point of gitolite is to avoid having those
>> users in the password file (either directly in /etc/passwd or via your
>>favorite distributed password database).
>
>Yes, definitely. The only user I have there is `git` which is the user
>that owns the gitolite files and repositories and is used for the sudo
>calls. No other user is in the password file.

Hm, I mean ... maybe this is splitting hairs, but you said that you use
winbind / nsswitch. If you're doing THAT, then you're making those
users visible to the entire operating system. Yes, your users are
not in the _file_ /etc/passwd but they're available via the standard
getpw*() library calls, the same as if the users were stored in LDAP or
NIS. And again, that's fine if you want to do that but that is what we
specifically wanted to avoid doing.

Also, you talk about Apache and PAM, and the same things apply there;
all of the Apache PAM support is doing Basic authentication and verifying
a password via the PAM stack. Again, that's fine, but not what I was
talking about. You ALSO mention the use of a GSSAPI configuration with
HTTPS, which I assume was done via mod_auth_gssapi or something similar;
that's true Kerberos authentication. My only issue with that is the
client support there is sometimes lacking. If Git uses curl for HTTPS
access then that's not an issue as most modern libcurl libraries support
Kerberos authentication.

--Ken

Björn Kautler

unread,
Aug 3, 2024, 4:03:29 PM8/3/24
to Ken Hornstein, gito...@googlegroups.com
Ah, sorry, yeah, mixed up things.
Too long ago that I dealt with it.
The Kerberos part in my solution actually was just the Single-Sign-On part when accessing the HTTPS part through the browser.

Cheers
Björn

--
You received this message because you are subscribed to the Google Groups "gitolite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gitolite+u...@googlegroups.com.

Alfredo Licciardello

unread,
Aug 6, 2024, 1:20:12 AM8/6/24
to Ken Hornstein, gito...@googlegroups.com

Thank you


--
You received this message because you are subscribed to the Google Groups "gitolite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gitolite+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages