sshkeys-lint: new program
run without arguments for usage
This commit is contained in:
parent
11e8ab048a
commit
c3ec349721
|
@ -25,6 +25,10 @@ very detailed look at how gitolite uses ssh's features on the server side.
|
||||||
Most people don't know ssh as well as they *think* they do; even if you dont
|
Most people don't know ssh as well as they *think* they do; even if you dont
|
||||||
have any problems right now, it's worth skimming over.
|
have any problems right now, it's worth skimming over.
|
||||||
|
|
||||||
|
In addition to both these documents, there's now a program called
|
||||||
|
`sshkeys-lint` that you can run on your client. Run it without arguments to
|
||||||
|
get help on how to run it and what inputs it needs.
|
||||||
|
|
||||||
Please also note that ssh problems don't always look like ssh problems. One
|
Please also note that ssh problems don't always look like ssh problems. One
|
||||||
common example: when the remote says the repo you're trying to access "does
|
common example: when the remote says the repo you're trying to access "does
|
||||||
not appear to be a git repository", and yet you are sure it exists, you
|
not appear to be a git repository", and yet you are sure it exists, you
|
||||||
|
|
100
src/sshkeys-lint
Executable file
100
src/sshkeys-lint
Executable file
|
@ -0,0 +1,100 @@
|
||||||
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
our (%users, %linenos);
|
||||||
|
|
||||||
|
&usage unless $ARGV[0] and -f $ARGV[0];
|
||||||
|
my @authlines = &filelines($ARGV[0]);
|
||||||
|
my $lineno = 0;
|
||||||
|
for (@authlines)
|
||||||
|
{
|
||||||
|
$lineno++;
|
||||||
|
if (/^# gitolite start/ .. /^# gitolite end/) {
|
||||||
|
warn "line $lineno: non-gitolite key found in gitolite section" if /ssh-rsa|ssh-dss/ and not /command=.*gl-auth-command/;
|
||||||
|
} else {
|
||||||
|
warn "line $lineno: gitolite key found outside gitolite section" if /command=.*gl-auth-command/;
|
||||||
|
}
|
||||||
|
next if /\# gitolite (start|end)/;
|
||||||
|
die "line $lineno: unrecognised line\n" unless /^(?:command=".*gl-auth-command (\S+?)"\S+ )?(?:ssh-rsa|ssh-dss) (\S+)/;
|
||||||
|
my ($user, $key) = ($1 || '', $2);
|
||||||
|
if ($linenos{$key}) {
|
||||||
|
warn "authkeys file line $lineno is repeat of line $linenos{$key}, will be ignored by server sshd\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
$linenos{$key} = $lineno;
|
||||||
|
$users{$key} = ($user ? "maps to gitolite user $user" : "gets you a command line");
|
||||||
|
}
|
||||||
|
|
||||||
|
print "\n";
|
||||||
|
|
||||||
|
# all *.pub in current dir should be exactly one line, starting with ssh-rsa
|
||||||
|
# or ssh-dss
|
||||||
|
|
||||||
|
my @pubkeys = glob("*.pub");
|
||||||
|
die "no *.pub files here\n" unless @pubkeys;
|
||||||
|
for my $pub (@pubkeys) {
|
||||||
|
my @lines = &filelines($pub);
|
||||||
|
die "$pub has more than one line\n" if @lines > 1;
|
||||||
|
die "$pub does not start with ssh-rsa or ssh-dss\n" unless $lines[0] =~ /^(?:ssh-rsa|ssh-dss) (\S+)/;
|
||||||
|
my $key = $1;
|
||||||
|
if ($users{$key}) {
|
||||||
|
print "$pub $users{$key}\n";
|
||||||
|
} else {
|
||||||
|
print "$pub has NO ACCESS to the server\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print <<INFO;
|
||||||
|
|
||||||
|
Git operations using a pubkey that gets you a command line will BYPASS
|
||||||
|
gitolite completely. This means:
|
||||||
|
|
||||||
|
- using "git clone git\@server:reponame" will get you the "does not appear to
|
||||||
|
be a git repository" message
|
||||||
|
- using "git clone git\@server:repositories/reponame" [assuming default value
|
||||||
|
of \$REPO_BASE) will work but subsequent push will fail
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Now you know what pubkey gets you what access.
|
||||||
|
|
||||||
|
To see what key is *actually* being used when you run your commands, try "ssh
|
||||||
|
-v git\@server" or "ssh -v gitolite", and look for a line saying "Offering
|
||||||
|
public key". If there are more than one such lines, the last one is what
|
||||||
|
counts.
|
||||||
|
|
||||||
|
If at any time you are asked for a password (password, not passphrase; see
|
||||||
|
doc/6 for the difference, if needed), then none of this applies anyway.
|
||||||
|
|
||||||
|
INFO
|
||||||
|
|
||||||
|
sub filelines
|
||||||
|
{
|
||||||
|
my $f;
|
||||||
|
my $fn = shift;
|
||||||
|
open ($f, "<", $fn) or die "open $fn failed: $!\n";
|
||||||
|
return <$f>;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub usage
|
||||||
|
{
|
||||||
|
print STDERR <<EOF;
|
||||||
|
|
||||||
|
On your *client*:
|
||||||
|
|
||||||
|
- copy the server's ~/.ssh/authorized_keys file to your *client*'s
|
||||||
|
/tmp/foo (maybe using "scp" or whatever)
|
||||||
|
|
||||||
|
- cd to the ~/.ssh directory (which contains all the pub keys this client
|
||||||
|
can use)
|
||||||
|
|
||||||
|
- run "$0 /tmp/foo"
|
||||||
|
|
||||||
|
Note: people who have so many keypairs they keep them in *sub*-directories of
|
||||||
|
~/.ssh [you know who you are ;-)] can figure it out themselves; you clearly
|
||||||
|
know enough about ssh not to need my help!
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
exit 1;
|
||||||
|
}
|
Loading…
Reference in a new issue