Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

(password access) backward compat breakage for gl-shell-setup; read b…

…elow

gl-shell-setup has a "run as hosting user" piece that basically
automates the adding of the user's (new) key to the admin repo.

This is now gone.  (It's not that hard to automate yourself if you want
to do it anyway, using gl-admin-push).

I did this because I needed to allow someone in through a gateway, and
realised that that has the exact same needs.  So the whole scheme has
been changed to treat the proxy and the gitolite host as being two
different servers.

At that point it became cumbersome to do the second bit, and I left it
out.

Other changes:
  - you can define exceptions for the default shell in gl-shell
  - the doc has been simplified.
  • Loading branch information...
commit a103417da299e82b2f5073580e2763b73c1659c1 1 parent 97bd5c5
Sitaram Chamarty authored
75 contrib/real-users/gl-shell
View
@@ -5,31 +5,49 @@ use warnings;
# ------------------------------------------------------------------------------
-# site-local changes
-
-# the original login shell your users had (or) the shell to forward
-# non-gitolite commands to
-my $shell = "/bin/bash";
-# suggested values if you really don't want them actually logging in:
-# /sbin/nologin - obvious
-# /usr/bin/passwd - same, but allows them to change their passwords
-
-# 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";
-
-# ADCs...
-# either list all the ADCs you wish to allow forwarding to (SPACE-separated):
-my $ADC_list = "";
-# -- OR --
-# if you upgraded to the new 'help' adc with the '-list' option, set this to 1:
-my $detect_ADCs = 0;
-# if you do neither, ADCs are not forwarded
+# BEGIN site-local changes
+
+ # the original login shell your users had (or) the shell to forward
+ # non-gitolite commands to
+ my $shell = "/usr/bin/passwd";
+
+ # exceptions...
+ my %shells = (
+ 'some.one' => '/bin/bash',
+ );
+
+ # the gitolite host you want to forward git commands to. Typically this will
+ # be 'git' or perhaps 'gitolite', but actually could be anything. Don't
+ # forget to change the host part if needed and mind the quotes!
+ my $gl_host = 'git@server2';
+
+ # ADCs...
+ # either list all the ADCs you wish to allow forwarding to (SPACE-separated):
+ my $ADC_list = "";
+ # -- OR --
+ # if you upgraded to the new 'help' adc with the '-list' option, set this to 1:
+ my $detect_ADCs = 0;
+ # if you do neither, ADCs are not forwarded
+
+# END site-local changes
# ------------------------------------------------------------------------------
+# change the user's default shell if he is an 'exception'
+$shell= $shells{$ENV{USER}} if $shells{$ENV{USER}};
+
# no arguments? nothing to forward
-exec($shell) unless @ARGV;
+exec($shell) if (not @ARGV and not $ENV{SSH_ORIGINAL_COMMAND});
+
+# note: we attempt to work the same whether invoked via 'command=' of authkeys
+# (in which case SSH_ORIGINAL_COMMAND is set) or via us being the login shell
+# (chsh). Only the latter has been *tested* though.
+
+# massage SSHOC into @ARGV shape for ease of parsing
+@ARGV = ("-c", $ENV{SSH_ORIGINAL_COMMAND}) if $ENV{SSH_ORIGINAL_COMMAND};
+# we ignore SSHOC from now on...
+
+# ------------------------------------------------------------------------------
# forward normal git ops
forward(@ARGV) if
@@ -37,12 +55,16 @@ forward(@ARGV) if
$ARGV[1] =~ /^(git-receive-pack|git-upload-pack|git-upload-archive) '(\S+)'$/ and
( not -d "$2" );
+# ------------------------------------------------------------------------------
+
# forward gitolite special commands
forward(@ARGV) if $ARGV[0] eq '-c' and $ARGV[1] =~ /^(info|expand|((set|get)(perms|desc)))( |$)/;
+# ------------------------------------------------------------------------------
+
# forward ADCs
if ($ADC_list or $detect_ADCs) {
- $ADC_list ||= `ssh $hosting_user\@localhost help -list`;
+ $ADC_list ||= `ssh $gl_host help -list`;
$ADC_list =~ s/\s+/ /g;
# find the command he's running
@@ -51,20 +73,23 @@ if ($ADC_list or $detect_ADCs) {
forward(@ARGV) if $ARGV[0] eq '-c' and $cmd and $ADC_list =~ /(^| )$cmd( |$)/;
}
+# ------------------------------------------------------------------------------
+
# at this point it's back to local processing
exec($shell, @ARGV);
# ------------------------------------------------------------------------------
+# ------------------------------------------------------------------------------
-# forward to the hosting user
+# forward to the gitolite host
sub forward {
# this message is important in debugging and trouble shooting; see
# documentation
- print STDERR "[forwarding to $hosting_user\@localhost]\n";
+ print STDERR "[forwarding to $gl_host]\n";
# but first we check for rsa key
-f ".ssh/id_rsa" or die "ask your admin to add you to gitolite";
shift if $_[0] eq '-c';
- exec("ssh", "$hosting_user\@localhost", @_);
+ exec("ssh", "$gl_host", @_);
}
80 contrib/real-users/gl-shell-setup
View
@@ -3,36 +3,26 @@
# 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.
+# NOTE 1: this script is run as root.
# ------------------------------------------------------------------------------
+# ------------------------------------------------------------------------------
-# 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"
+# BEGIN site-local changes
-# 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"
-# 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 >&2
+ }
-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 >&2; exit 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; }
+# END site-local changes
# ------------------------------------------------------------------------------
@@ -44,10 +34,6 @@ 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"
@@ -55,51 +41,37 @@ then
# now fix up the user's login shell
my_chsh $user
+ pubkey="$PWD/$user.pub"
+ [ -f "$pubkey" ] && {
+ echo "$user.pub already exists. Shell changed, exiting..." >&2
+ exit 0
+ }
+
# 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
+ # now set up her rsa key, creating it if needed. This will get used if
+ # she comes in via password or without agent forwarding.
[ -d .ssh ] || {
mkdir .ssh
chown $user .ssh
chmod go-w .ssh
}
+
[ -f .ssh/id_rsa.pub ] || {
- ssh-keygen -q -N "" -f .ssh/id_rsa
+ ssh-keygen -q -N "" -f .ssh/id_rsa >&2
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
+ # create alice.pub
+ cat .ssh/id_rsa.pub > $pubkey
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
+ die "needs to run as root"
fi
158 contrib/real-users/password-access.mkd
View
@@ -4,121 +4,105 @@
## problems
-*Problem 1*: Here's one type of problem some admins have:
+This document solves several different problems. But first some names:
- * 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.
+ * `alice`: our user
+ * `server1`: a server on which alice has a shell account or the admin is
+ willing to give her one
+ * `git@server2`: the gitolite host (user@server). Server2 may be, but need
+ not be, the same as server1.
-This document has a solution to this problem!
+The problems it solves are:
-*Problem 2*: And here's a somewhat different one:
+1. Alice doesn't like ssh keys and wants to stick to password access (which
+ won't work with gitolite!), and she has or can get a real (unix) userid on
+ server1.
- * 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).
+2. Alice is outside your corporate environment and needs to get in to server2
+ via server1.
-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 ;-)
+It does this by making `alice@server1` act like a "proxy" for `git@server2`.
-<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>
+## what the 2 scripts actually do
-## solution
+ * `gl-shell` will become the login shell for these users on server1. This
+ shell will forward git clone/fetch/push requests to "git" on server2.
-Briefly, the Unix userid is made to act like a "gitolite proxy".
+ This redirection is so transparent that I had to explicitly code a message
+ ("forwarding to git@server") to make troubleshooting easier.
-Here's a more detailed explanation.
+ * `gl-shell-setup` sets things up. It needs to be run on server1, where it
+ changes the user's shell to `gl-shell` (full path), then sets up an RSA
+ key if needed.
-Normal gitolite flow, for a user called Alice, is like this:
+## instructions
- ssh key
- alice ----------------------------------------> git
- (workstation) (REQUIRED) (server)
+### server setup
-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:
+**Server1**:
- password
- alice ------ OR -----> alice
- (workstation) ssh key (server)
+ * Add the host key for server2 to `/etc/ssh/ssh_known_hosts` on server1.
+ And if it ever changes, update it.
-The **important** thing to note here is that she doesn't need ssh keys; she
-can use passwords if she wants to.
+ ssh-keyscan -t rsa,dsa server2 >> /etc/ssh/ssh_known_hosts
-Behind the scenes, the gitolite/git conversation is being transparently
-forwarded to the gitolite hosting user, so it is *actually* like this:
+ * You will need to copy the 2 scripts supplied (in contrib/real-users) to
+ "/usr/local/bin" on server1 and customise them -- i.e., edit the files and
+ change stuff in the section clearly-marked "site-local changes".
- password ssh key
- alice ------ OR -----> alice - - - - - - - > git
- (workstation) ssh key (server) (REQUIRED) (localhost)
+ **NOTE** on fixing the "chsh" function: this is OS-dependent. Use
+ whatever command the OS on server1 requires for this to work. The
+ supplied command is good for Fedora. (Server2's OS does not matter for
+ this customisation, even though the script is needed there also).
-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`.
+**Server2**: We assume gitolite is already installed on server2.
-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.
+### per-user setup
-## some hints, notes and caveats
+There are 2 types of users.
- * 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.
+1. Alice uses a password to access server1, or Alice uses a pubkey to access
+ server1 but does not use an agent or enable agent forwarding.
-## what the 2 scripts actually do
+ * login as root on server 1.
+ * make sure a file called 'alice.pub' does NOT exist in the current
+ directory.
+ * run `gl-shell-setup alice`. This will create a file called
+ 'alice.pub' (since it does not exist).
- * `gl-shell` will become the new login shell for these users. This shell
- will forward git clone/fetch/push requests to the gitolite server.
+2. alice uses a pubkey to access server1, and does agent forwarding.
- 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][oldmultikeys] to allow Alice to allow users
- to have other (gitolite normal) keys as well, such as perhaps from a
- laptop.
+ * login as root on server 1.
+ * ask the user for the pubkey she uses or get it from the
+ `authorized_keys` file in her `$HOME/.ssh` on server1. Copy it as
+ 'alice.pub' in the current directory.
+ * run `gl-shell-setup alice`. (It will not create the pub file, since
+ it already exists).
-## setting up password access
+You can do this for several users in one shot, and collect all the the
+pubkeys.
-Here's how to set this up. First, the **one-time** tasks:
+Once you have collected all of them, send them to server2 or to someone who
+has push rights to the admin repo.
- * Do this first, or you'll forget :-) Add the host key for 'localhost' to
- `/etc/ssh/ssh_known_hosts`. And if it ever changes, update it.
-
- * 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.
+## some hints, notes and caveats
- * As root, copy the program `contrib/real-users/gl-shell` to
- `/usr/local/bin`.
+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. (I strongly suggest
+that all such keys be placed in `keydir/indirect/` instead of in `keydir/`).
- * As root, customise the program `/usr/local/bin/gl-shell`. You will need
- to change some variables at the top in a section clearly marked
- 'site-local changes'.
+### security and trust discussion
- * 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.
+For type 1 users, a default key *pair* (i.e., *including* a private key) must
+be generated on server1 and given to the gitolite admin for inclusion as the
+user's key for gitolite.
-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`.
+This means that the user must implicitly trust server1's administrators, since
+they can impersonate her to server2. (If server1 and server2 are the same
+machine or have the same administrators, this does not matter).
-And that's really all there is to it.
+For a type 2 user, no keys need to be generated, and this type of user need
+not trust server1 at all. In fact, she's only using this method due to
+firewall issues, and the only thing that gl-shell-setup is doing is to run
+'chsh'.
Please sign in to comment.
Something went wrong with that request. Please try again.