FHEMWEB-Authentifizierung mit Zugangsdaten des Linux-Users

Begonnen von Christian., 11 Dezember 2014, 22:47:23

Vorheriges Thema - Nächstes Thema

Christian.

Hallo zusammen,

das Modul FHEMWEB bietet ja die Möglichkeit zur Authentifizierung (Attribut basicAuth). Auf einer FritzBox gibt es die Möglichkeit, Benutzernamen und Passwort vom System (der FritzBox) prüfen zu lassen und so auf BASE64-kodierte Zugangsdaten zu verzichten. Ich hätte dieses Feature gerne auf einem Raspberry Pi. Ich habe gelesen, dass es dafür unter Linux die Pluggable Authentication Modules (PAM) und ein passendes Perl-Modul gibt. Folgende Funktion soll die Authentifizierung übernehmen:


use Authen::PAM;

sub authenticate($$) {
  my $service = "login";
  my $username = shift;
  my $password = shift;

  sub fill_credentials {
    my @res;
    while ( @_ ) {
      my $code = shift;
      my $msg = shift;
      my $ans = "";

      $ans = $username if ($code == PAM_PROMPT_ECHO_ON() );
      $ans = $password if ($code == PAM_PROMPT_ECHO_OFF() );

      push @res, (PAM_SUCCESS(), $ans);
    }
    push @res, PAM_SUCCESS();
    return @res;
  }
  my $pamh;
  ref($pamh = new Authen::PAM($service, $username, \&fill_credentials)) ||
         die "Error code $pamh during PAM init!";

  return $pamh->pam_authenticate;
}


Wenn ich die Funktion als User pi (ohne sudo) ausführe, erhalte ich PAM_SUCCESS. Wenn ich sie als User fhem ausführe, erhalte ich PAM_PERM_DENIED.

Kann mir jemand sagen:

  • Warum?
  • Wie kann ich das ändern?

Raspberry Pi 3 mit FHEM; Arduino Nano mit ConfigurableFirmata (S0-Stromzähler); nanoCUL (MAX!); SIGNALduino (RXB6, 433 MHz); eBus; RS485 & D0 (SolarView); DVB-T (Thermo-/Hygrometer); Z-Wave; ZigBee

Christian.

Ich bin etwas weiter. In /var/log/auth.log fand ich
pam_securetty(login:auth): cannot determine user's tty

Deshalb habe ich mein Skript wie folgt erweitert:

use Authen::PAM;
use POSIX qw(ttyname);

my $service = "login";
my $username = shift;
my $password = shift;
my $tty_name = ttyname(fileno(STDIN));
...
$res = $pamh->pam_set_item(PAM_TTY(), $tty_name);
$res = $pamh->pam_authenticate;
...


Damit erhalte ich im Log jetzt

pam_securetty(login:auth): access denied: tty '/dev/pts/1' is not secure !
pam_unix(login:auth): check pass; user unknown


Nach Eintrag von
pts/1 in /etc/securetty verschwindet die erste Meldung. Bleibt noch die zweite...
Raspberry Pi 3 mit FHEM; Arduino Nano mit ConfigurableFirmata (S0-Stromzähler); nanoCUL (MAX!); SIGNALduino (RXB6, 433 MHz); eBus; RS485 & D0 (SolarView); DVB-T (Thermo-/Hygrometer); Z-Wave; ZigBee

rudolfkoenig

FHEM ist ein Daemon, und hat kein tty: ich vermute du musst einen Weg ohne tty finden.

Christian.

#3
Ich habe in einem StackExchange-Artikel gelernt, dass meine Idee nicht funktionieren wird, solange der ausführende Prozess keine root-Rechte hat. Der Artikel verweist aber auf einen anderen Lösungsansatz basierend auf einem Tool namens expect. Ich habe daraufhin ein Skript geschrieben, dass die Authentifizierung aus FHEM heraus erfolgreich durchführt.

Inhalt des Skriptes:
#!/usr/bin/expect -f
log_user 0
set username [lindex $argv 0]
set password [lindex $argv 1]
if { $username == "" || $password == "" }  {
  puts "Usage: <username> <password>\n"
  exit 1
}

spawn su -l $username -c "echo OK"
expect ":"
send "$password\n"
expect {
  "OK"    { send_user "OK"  }
  "su:"   { send_user "NOK" }
  timeout { send_user "Timeout" }
  eof     { send_user "EOF" }
}


Das Skript habe ich unter /home/pi/auth.expect gespeichert und mittels
chmod +x /home/pi/auth.expect ausführbar gemacht.

Für die Ausführung des Skriptes benötigt man das Tool expect, das sich z.B. durch
sudo apt-get install expect
installieren lässt.

In der FHEM-Konfiguration kann es durch Setzen von
attr WEB basicAuth { `/home/pi/auth.expect $user $password` eq "OK" }
verwendet werden.
Raspberry Pi 3 mit FHEM; Arduino Nano mit ConfigurableFirmata (S0-Stromzähler); nanoCUL (MAX!); SIGNALduino (RXB6, 433 MHz); eBus; RS485 & D0 (SolarView); DVB-T (Thermo-/Hygrometer); Z-Wave; ZigBee

Christian.

Nach ein paar Minuten Einsatz habe ich festgestellt, dass die Reaktion der Weboberfläche dadurch sehr träge geworden ist. Die Authentifizierung wird offenbar beim Laden jeder HTTP-Ressource durchgeführt, also ein paar mal pro Klick. Das dauert dann natürlich. Ich glaube nicht, dass ich das in dieser Form nutzen möchte.  :-\
Raspberry Pi 3 mit FHEM; Arduino Nano mit ConfigurableFirmata (S0-Stromzähler); nanoCUL (MAX!); SIGNALduino (RXB6, 433 MHz); eBus; RS485 & D0 (SolarView); DVB-T (Thermo-/Hygrometer); Z-Wave; ZigBee

rapster

Du kannst einen lokalen reverse Proxy auf der Fhem Kiste einsetzen, mit einem Apache bist du da z.B. deutlich flexibler was die Authentication anbelangt und könntest die Anmeldedaten aus verschiedenen Quellen beziehen, sowie wird es dann auch nur einmalig beim Login ausgeführt.
Siehe z.B. => http://forum.fhem.de/index.php/topic,29909.0.html

Christian.

Raspberry Pi 3 mit FHEM; Arduino Nano mit ConfigurableFirmata (S0-Stromzähler); nanoCUL (MAX!); SIGNALduino (RXB6, 433 MHz); eBus; RS485 & D0 (SolarView); DVB-T (Thermo-/Hygrometer); Z-Wave; ZigBee