password access to gitolite using real users
This commit is contained in:
parent
63f18a5adf
commit
c69c10366d
46
contrib/real-users/gl-shell
Executable file
46
contrib/real-users/gl-shell
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# site-local changes
|
||||||
|
|
||||||
|
# the original login shell your users had. Set this to something like
|
||||||
|
# "/sbin/nologin" or "/bin/false" if you don't want them to have a normal
|
||||||
|
# shell (i.e., you created these accounts *only* to provide a password
|
||||||
|
# authentication passthru to gitolite)
|
||||||
|
my $shell = "/bin/bash";
|
||||||
|
|
||||||
|
# the gitolite hosting user you want to forward git commands to. Typically
|
||||||
|
# this will be 'git' or perhaps 'gitolite', but actually could be anything
|
||||||
|
my $hosting_user = "gitolite-test";
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# process normal logins (the ones that *don't* get forwarded to the gitolite
|
||||||
|
# hosting user)
|
||||||
|
|
||||||
|
# this is a normal login, not to be forwarded to the gitolite hosting user, if:
|
||||||
|
# - there are no arguments
|
||||||
|
exec($shell) unless @ARGV;
|
||||||
|
# - the first argument is not "-c"
|
||||||
|
exec($shell, @ARGV) unless $ARGV[0] eq '-c';
|
||||||
|
# - the second argument does not fit what git usually sends
|
||||||
|
exec($shell, @ARGV) unless $ARGV[1] =~ /^(git-receive-pack|git-upload-pack|git-upload-archive) '(\S+)'$/;
|
||||||
|
# - there *is* a local directory with the same name as the second part of argument #2
|
||||||
|
exec($shell, @ARGV) if -d $2;
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# if all that failed, it means we have to forward this to the hosting user
|
||||||
|
|
||||||
|
# this message is important in debugging and trouble shooting; see documentation
|
||||||
|
print STDERR "[forwarding to $hosting_user\@localhost]\n";
|
||||||
|
|
||||||
|
# but first we check for rsa key
|
||||||
|
-f ".ssh/id_rsa" or die "ask your admin to add you to gitolite";
|
||||||
|
|
||||||
|
shift; # that pesky '-c'...
|
||||||
|
exec("ssh", "$hosting_user\@localhost", @ARGV);
|
110
contrib/real-users/gl-shell-setup
Executable file
110
contrib/real-users/gl-shell-setup
Executable file
|
@ -0,0 +1,110 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# WARNING 1: probably contains bashisms galore. If you don't have bash,
|
||||||
|
# please install it.
|
||||||
|
|
||||||
|
# NOTE 1: this script is initially run as root, then it calls itself with an
|
||||||
|
# "su" so it can run as the hosting user.
|
||||||
|
|
||||||
|
# NOTE 2: if you'd rather do this manually, just do the first part as root,
|
||||||
|
# and the second part as the hosting user, with only the name of the user
|
||||||
|
# (alice) and her pub key (~alice/.ssh/id_rsa.pub) needing to be passed from
|
||||||
|
# root to the hosting user id.
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# site-local changes
|
||||||
|
|
||||||
|
# the gitolite hosting user you want to forward git commands to. Typically
|
||||||
|
# this will be 'git' or perhaps 'gitolite', but actually could be anything
|
||||||
|
hosting_user="gitolite-test"
|
||||||
|
|
||||||
|
# absolute path of the gitolite-admin repo
|
||||||
|
admin_repo="/home/gitolite-test/repositories/gitolite-admin.git"
|
||||||
|
|
||||||
|
# the full path to the new login shell to replace these users' existing shell
|
||||||
|
new_shell="/usr/local/bin/gl-shell"
|
||||||
|
|
||||||
|
my_chsh() {
|
||||||
|
# please replace with appropriate command for your OS/distro. This one is
|
||||||
|
# suitable at least for Fedora, maybe others also
|
||||||
|
chsh -s $new_shell $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove these 2 lines after you have done your customisation
|
||||||
|
[ -f /tmp/done.gl-shell-setup ] || { echo please customise $0 before using; exit 1; }
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
die() { echo "FATAL: $@" >&2; exit 1; }
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
euid=$(perl -e 'print $>')
|
||||||
|
if [ "$euid" = "0" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# stuff to be done as root
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[ -n "$1" ] || die "need a valid username"
|
||||||
|
user=$1
|
||||||
|
id $user >/dev/null || die "need a valid username"
|
||||||
|
|
||||||
|
# now fix up the user's login shell
|
||||||
|
my_chsh $user
|
||||||
|
|
||||||
|
# drat... 'cd ~$user` doesn't work...
|
||||||
|
cd $(bash -c "echo ~$user") || die "can't cd to $user's home directory"
|
||||||
|
|
||||||
|
# now set up her rsa key, creating it if needed
|
||||||
|
[ -d .ssh ] || {
|
||||||
|
mkdir .ssh
|
||||||
|
chown $user .ssh
|
||||||
|
chmod go-w .ssh
|
||||||
|
}
|
||||||
|
[ -f .ssh/id_rsa.pub ] || {
|
||||||
|
ssh-keygen -q -N "" -f .ssh/id_rsa
|
||||||
|
chown $user .ssh/id_rsa .ssh/id_rsa.pub
|
||||||
|
chmod go-rw .ssh/id_rsa
|
||||||
|
chmod go-w .ssh/id_rsa.pub
|
||||||
|
}
|
||||||
|
|
||||||
|
# now run yourself as the hosting user, piping in the pubkey to STDIN, and
|
||||||
|
# passing the username whose key it is as argument 1.
|
||||||
|
cat .ssh/id_rsa.pub | su -l -c "$0 $user" $hosting_user
|
||||||
|
|
||||||
|
# finally, as $user (alice) ssh to the hosting_user once so that the
|
||||||
|
# hostkey checking gets done and you get the correct hostkey in
|
||||||
|
# ~user/.ssh/known_hosts
|
||||||
|
su -c "ssh -o StrictHostKeyChecking=no $hosting_user@localhost info" - $user
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# stuff to be done as the hosting user
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
user=$1
|
||||||
|
|
||||||
|
# make a temp dir and switch to it
|
||||||
|
export tmp=$(mktemp -d)
|
||||||
|
cd $tmp || die "could not cd to temp dir $tmp"
|
||||||
|
trap "rm -rf $tmp" 0
|
||||||
|
|
||||||
|
# clone the admin repo here
|
||||||
|
git clone $admin_repo .
|
||||||
|
# copy alice's pubkey, which was sent in via STDIN. We don't want to
|
||||||
|
# overwrite any *other* keys she may have, hence the @localhost part.
|
||||||
|
# (See "one user, many keys" in doc/3 for more on this @ part).
|
||||||
|
cat > keydir/$user@localhost.pub
|
||||||
|
# add commit push...
|
||||||
|
git add keydir/$user@localhost.pub
|
||||||
|
git diff --cached --quiet 2>/dev/null || git commit -am "$0: added/updated local key for $user"
|
||||||
|
gl-admin-push
|
||||||
|
# see doc for what/why this is
|
||||||
|
|
||||||
|
fi
|
145
contrib/real-users/password-access.mkd
Normal file
145
contrib/real-users/password-access.mkd
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
# password access to gitolite
|
||||||
|
|
||||||
|
## (a.k.a: turning real users into gitolite users)
|
||||||
|
|
||||||
|
<a name="_problems"></a>
|
||||||
|
|
||||||
|
### problems
|
||||||
|
|
||||||
|
*Problem 1*: Here's one type of problem some admins have:
|
||||||
|
|
||||||
|
* Some of your users already have a real (unix) userid on the *same server*
|
||||||
|
as the gitolite hosting user.
|
||||||
|
* They don't all use ssh keys; some may still be using passwords and don't
|
||||||
|
want to change.
|
||||||
|
* They want to use this existing userid to access the gitolite served repos.
|
||||||
|
|
||||||
|
This document has a solution to this problem!
|
||||||
|
|
||||||
|
*Problem 2*: And here's a somewhat different one:
|
||||||
|
|
||||||
|
* Some of your users are not willing to use ssh keys; they're only
|
||||||
|
comfortable with passwords.
|
||||||
|
* But gitolite *requires* ssh key-based access; it can't work if you use a
|
||||||
|
password to get access (because then there is no way to distinguish one
|
||||||
|
user from another).
|
||||||
|
|
||||||
|
Well, as the math folks say, "reduce it to a known problem". Give them all
|
||||||
|
Unix userids on the same server as gitolite, with password access, so that
|
||||||
|
problem 2 reduces to problem 1 ;-)
|
||||||
|
|
||||||
|
<font color="gray">If you created these Unix accounts *only* to solve this
|
||||||
|
pesky password problem, and do not wish them to actually have shell access or
|
||||||
|
be able to do anything else on the server, don't worry -- that's easy to
|
||||||
|
handle too.</font>
|
||||||
|
|
||||||
|
<a name="_solution"></a>
|
||||||
|
|
||||||
|
### solution
|
||||||
|
|
||||||
|
Briefly, the Unix userid is made to act like a "gitolite proxy".
|
||||||
|
|
||||||
|
Here's a more detailed explanation.
|
||||||
|
|
||||||
|
Normal gitolite flow, for a user called Alice, is like this:
|
||||||
|
|
||||||
|
ssh key
|
||||||
|
alice ----------------------------------------> git
|
||||||
|
(workstation) (REQUIRED) (server)
|
||||||
|
|
||||||
|
However, if Alice has her own real (unix) userid on the server, and the admin
|
||||||
|
sets things up according to this document, then Alice can do this:
|
||||||
|
|
||||||
|
password
|
||||||
|
alice ------ OR -----> alice
|
||||||
|
(workstation) ssh key (server)
|
||||||
|
|
||||||
|
The **important** thing to note here is that she doesn't need ssh keys; she
|
||||||
|
can use passwords if she wants to.
|
||||||
|
|
||||||
|
Behind the scenes, the gitolite/git conversation is being transparently
|
||||||
|
forwarded to the gitolite hosting user, so it is *actually* like this:
|
||||||
|
|
||||||
|
password ssh key
|
||||||
|
alice ------ OR -----> alice - - - - - - - > git
|
||||||
|
(workstation) ssh key (server) (REQUIRED) (localhost)
|
||||||
|
|
||||||
|
The second connection is transparent to Alice; she still thinks she is talking
|
||||||
|
to her own userid. In git URL terms, she simply uses `alice@server:reponame`,
|
||||||
|
without realising that behind the scenes this is getting forwarded to
|
||||||
|
`git@server:reponame`.
|
||||||
|
|
||||||
|
This second connection *does* require ssh keys, but since they're all on the
|
||||||
|
server, it's scriptable and automatable so the user doesn't have to deal with
|
||||||
|
these pesky ssh keys.
|
||||||
|
|
||||||
|
<a name="_some_hints_notes_and_caveats"></a>
|
||||||
|
|
||||||
|
### some hints, notes and caveats
|
||||||
|
|
||||||
|
* This doesn't mean all your users have to be like this. You can have
|
||||||
|
normal users also. In fact, you can have users who give you a pub key
|
||||||
|
from their workstation the normal way, as well as use this method.
|
||||||
|
|
||||||
|
* Special commands and ADCs will NOT work from the workstation for such
|
||||||
|
users; they have to log on to their own userid on the server and run the
|
||||||
|
appropriate command (such as `ssh git@localhost info`) from there. <font
|
||||||
|
color="gray">We could have handled the known special commands (info,
|
||||||
|
expand, setperms, etc.), but considering that an ADC could be called
|
||||||
|
*anything*, a general solution is impossible.</font>
|
||||||
|
|
||||||
|
* If you server's host key changes, you may have to manually fix up all the
|
||||||
|
host keys in all the user's `~/.ssh/known_hosts` files. Not too difficult
|
||||||
|
if you're sure they all have just the one host key, but if they have
|
||||||
|
multiple, you have to carefully delete and replace just the one line that
|
||||||
|
pertains to localhost. Scripts to do this cleanly are welcome...
|
||||||
|
|
||||||
|
<a name="_what_the_2_scripts_actually_do"></a>
|
||||||
|
|
||||||
|
### what the 2 scripts actually do
|
||||||
|
|
||||||
|
* `gl-shell` will become the new login shell for these users. This shell
|
||||||
|
will forward git clone/fetch/push requests to the gitolite server.
|
||||||
|
|
||||||
|
This redirection is so transparent that I had to explicitly code a message
|
||||||
|
("forwarding to git@server") to make troubleshooting easier.
|
||||||
|
|
||||||
|
* `gl-shell-setup` is run by root, once for each user. (You can run it
|
||||||
|
multiple times; it's designed to be idempotent). As root, it changes the
|
||||||
|
user's shell to `gl-shell` (full path), then sets up an RSA key for the
|
||||||
|
user if one is not already present. Then it runs as `git` (or whatever
|
||||||
|
the hosting user is) and takes the pubkey and adds it as (to continue our
|
||||||
|
example) `alice@localhost.pub` in keydir of the admin repo, which is then
|
||||||
|
pushed.
|
||||||
|
|
||||||
|
Notice the use of [this trick][oumk] to allow Alice to allow users to have
|
||||||
|
other (gitolite normal) keys as well, such as perhaps from a laptop.
|
||||||
|
|
||||||
|
<a name="_setting_it_up"></a>
|
||||||
|
|
||||||
|
### setting it up
|
||||||
|
|
||||||
|
Here's how to set this up. First, the **one-time** tasks:
|
||||||
|
|
||||||
|
* Install gitolite as normal, if not already installed. This will require
|
||||||
|
you to use ssh keys for your (admin's) own access, but I assume that's ok.
|
||||||
|
|
||||||
|
* As root, copy the program `contrib/real-users/gl-shell` to
|
||||||
|
`/usr/local/bin`.
|
||||||
|
|
||||||
|
* As root, customise the program `/usr/local/bin/gl-shell`. You will need
|
||||||
|
to change only 2 variables at the top in a section clearly marked as
|
||||||
|
'site-local changes'.
|
||||||
|
|
||||||
|
* As root, copy `contrib/real-users/gl-shell-setup` to some place on root's
|
||||||
|
`$PATH` and customise it similarly to gl-shell. Note that there are many
|
||||||
|
more configurable values in this script. **NOTE** also that this includes
|
||||||
|
fixing the `chsh` command, which may be OS/distro dependent. The supplied
|
||||||
|
command is good for Fedora.
|
||||||
|
|
||||||
|
Now, for each user 'alice' that has her own real (unix) userid, and also needs
|
||||||
|
to access gitolite *via* her own id, run the command `gl-shell-setup alice`.
|
||||||
|
|
||||||
|
And that's really all there is to it.
|
||||||
|
|
||||||
|
[oumk]: http://sitaramc.github.com/gitolite/doc/3-faq-tips-etc.html#_one_user_many_keys
|
Loading…
Reference in a new issue