Benutzer-Werkzeuge

Webseiten-Werkzeuge


doku:pamsshaccess

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.


doku:pamsshaccess [2009-05-16 09:00] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +======  SSH-Login nur von bestimmten Hosts ======
  
 +Per SSH sollen sich Benutzer jeweils nur von bestimmten Hosts erlaubt werden. 
 +
 +Siehe auch [[pamdiensteerlauben]]
 +
 +Beispiel Benutzer <nowiki>testuser</nowiki> darf nur von Host <nowiki>fc4.strukturpunkt.de</nowiki>.
 +
 +  *  /etc/pam.d/sshd (Debian: /etc/pam.d/ssh)
 + <code>
 +account    required     pam_access.so
 +</code>
 +
 +  *  /etc/security/access.conf
 + <code>
 ++ : testuser : fc4.strukturpunkt.de
 +- : testuser : ALL
 +</code>
 +
 +  *  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:
 + <code>
 ++ : root : cron
 ++ : root : 192.168.4.1
 +- : root : ALL
 +</code>
 +
 +Getestet:
 +  * Zugriff via Passwort und/oder authorized_keys
 +  * Fedora 7
 +  * Debian 4.0 (Etch)
 +===== Umgang mit dynamischen IP-Nummern  =====
 +
 +  *  /usr/local/bin/dynipget
 + <code>
 +
 +# (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;
 +
 +</code>
 +  * 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)
 + <code>
 +account    required     pam_exec.so log=/var/log/dynipget.log /usr/bin/perl /usr/local/bin/dynipget
 +account    required     pam_access.so
 +</code>
 +    * :!: Debian-Trouble: pam_exec.so ist nicht mehr dabei, früher wars im Paket ''libpam-modules''
 +
 +  *  /etc/security/access.conf.TEMPLATE
 + <code>
 ++ : testuser : dynip(fc4.strukturpunkt.de)
 +- : testuser : ALL
 +</code>
 +
 +===== Ausblick  =====
 +  *  pam_exec.so
 +===== Trouble gelöst =====
 +<code>
 +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?
 +</code>
 +
 +Variante wurde umgesetzt, s. o.

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki