doku:pamsshaccess
Inhaltsverzeichnis
SSH-Login nur von bestimmten Hosts
Per SSH sollen sich Benutzer jeweils nur von bestimmten Hosts erlaubt werden.
Siehe auch pamdiensteerlauben
Beispiel Benutzer testuser darf nur von Host fc4.strukturpunkt.de.
- /etc/pam.d/sshd (Debian: /etc/pam.d/ssh)
account required pam_access.so
- /etc/security/access.conf
+ : testuser : fc4.strukturpunkt.de - : testuser : ALL
- DNS-Lookup wird jeweils on-the-fly gemacht, keine Neustart nötig.
- Falls root reglementiert wird: access.conf wird auch für cron gelesen, daher für
cron
auch erlauben:
+ : root : cron + : root : 192.168.4.1 - : root : ALL
Getestet:
- Zugriff via Passwort und/oder authorized_keys
- Fedora 7
- Debian 4.0 (Etch)
Umgang mit dynamischen IP-Nummern
- /usr/local/bin/dynipget
# # (c) 2006 Klaus.Franken@StrukturPunkt.de # # creates $SYSTEMFILE from $TEMPLATE # change lines like "dynip(fc4.strukturpunkt.de)" with the actual ip-numer # store actual ip-numer in /var/run/dynipget/$HOSTNAME # print ip-number only if changed # Version: 6.12.1 use strict; use Net::DNS; use IO::File; my $SYSTEMFILE="/etc/security/access.conf"; my $TEMPLATE="/etc/security/access.conf.TEMPLATE"; sub getSaveIp ($) { my $DYNDOMAIN=shift; my $VARRUN="/var/run/dynipget/$DYNDOMAIN"; my $dynip; my $dynipLast; my $res = Net::DNS::Resolver->new; my $query = $res->search($DYNDOMAIN); if ($query) { foreach my $rr ($query->answer) { next unless $rr->type eq "A"; #print $rr->address, "\n"; $dynip=$rr->address; } } else { warn "query failed: ", $res->errorstring, "\n"; # exit 1; } if (-r $VARRUN) { my $Fd = new IO::File; open ($Fd, $VARRUN) || die ("open $VARRUN: $!"); $dynipLast = <$Fd>; chomp($dynipLast); close($Fd); } if ($dynipLast ne $dynip) { print "new dynip($DYNDOMAIN): $dynipLast -> $dynip\n"; my $Fd = new IO::File; open ($Fd, "> $VARRUN") || die ("open $VARRUN: $!"); print $Fd "$dynip\n"; close($Fd); } return ($dynip); } my $FdTemplate = new IO::File; open ($FdTemplate, $TEMPLATE) || die ("open $TEMPLATE: $!"); my $FdSystem = new IO::File; open ($FdSystem, ">$SYSTEMFILE") || die ("open $SYSTEMFILE: $!"); while (my $line = <$FdTemplate>) { if ($line =~ /dynip\((.*)\)/i) { my $hostname=$1; #print "checking for '$hostname'\n"; my $dynip=getSaveIp($hostname); if (! $dynip) { warn "cannot determine ip-number for '$hostname' \n"; } $line =~ s/dynip\((.*)\)/$dynip/i; } print $FdSystem $line; } close ($FdTemplate); close ($FdSystem); exit 0;
- Perl-Modul Net::DNS
- Test: perl -e "use Net::DNS;"
- Debian:
apt-get install libnet-dns-perl
- mkdir /var/run/dynipget
- /etc/pam.d/sshd (Debian: /etc/pam.d/ssh)
account required pam_exec.so log=/var/log/dynipget.log /usr/bin/perl /usr/local/bin/dynipget account required pam_access.so
- Debian-Trouble: pam_exec.so ist nicht mehr dabei, früher wars im Paket
libpam-modules
- /etc/security/access.conf.TEMPLATE
+ : testuser : dynip(fc4.strukturpunkt.de) - : testuser : ALL
Ausblick
- pam_exec.so
Trouble gelöst
so richtig glücklich bin ich mit den Hausmitteln von PAM nicht geworden: - in der Prüfung von pam_access.so wird dummerweise imm der erste gefundene Hostname hergenommen (also: es wird eine Reverse-Lookup auf die IP-Nummer gemacht und dieser Name wird für weitere Prüfungen hergenommen; dass weitere Hostname für die IP-existieren könnten, wird nicht überprüft) - damit können wir nicht formulieren, dass z.B. "r2d2.selfip.net" auf eine IP-Nummer aufgelöst wird und erlaubt/verboten wird. - Es gibt zwar ein PAM-Modul pam_exec. Aber darin ist nicht vorgesehen die aktuellen Login-Daten abzufragen. Man kann einfach nur ein Programm starten. Ich sehe folgende Lösungmöglichkeiten: 1. http://honk.sigxcpu.org/darcs/pam-exec/ Das pam-exec (nicht zu verwechseln mit pam_exec !) startet ein Programm _und_ übermittelt die Login-Daten ähnlich wie das Modul pam_warn. Darin könnten wir die gewünschte Prüfung machen. Allerdings muss dafür selbst compiliert werden. Das halte schlecht pflegbar und zu fehleranfällig auf Dauer (insbesondere bei vielen Systemen) 2. Wir schränken den Login auf Domains ein, z.B. .dsl.de.ignite.net Das entspricht als Login-Regel dem was wir aktuell in der Logwatch per Sichtprüfung machen. Allerdings bringt das nicht wirklich viel und Sie haben damit kein Möglichkeit mal eben von einem anderen Provider die Verbindung aufzubauen. 3. per "pam_exec" wird ein Programm gestartet, welchen die IP-Nummer von r2d2.selfip.net aktuell ermittelt und dies die Regeldatei /etc/security/access.conf einträgt. Erst danach wird dann mittels pam_access.so bzw. /etc/security/access.conf geprüft, ob man von dieser IP-Nummer darf. Das ist zwar ein wenig von hinten durch die Brust ins Auge programmier, aber der Aufwand hält sich in Grenzen und es ist IMHO übersichtlich genug. Die Variante 3 ist mein Favorit! Soll ich's so machen?
Variante wurde umgesetzt, s. o.
doku/pamsshaccess.txt · Zuletzt geändert: 2009-05-16 09:00 von 127.0.0.1