Teil von SELFHTML aktuell Teil von Artikel Teil von Serverkonfiguration Teil von SELFHTML Server Konfiguration

SELFHTML Server Konfiguration:
Userverwaltung und Rechtevergabe

nach unten Einleitung
nach unten Die Gruppen
nach unten Die User
nach unten Die Passwörter
nach unten Die Rechte

Einleitung

Die Userverwaltung war die meiner Meinung nach größte Herausforderung: das User- und Gruppen-Konzept mußte so angelegt sein, dass zwar der Apache in jedes Verzeichnis darf, die verschiedenen System-User jedoch nur zu bestimmten Bereichen Zugang haben.

nach obennach unten

Die Gruppen

Zunächst haben wir eine Gruppe "xyz" fuer den Apache-User selber. Weiterhin hat jedes Projekt seine eigene Gruppe, abgesehen von den "Zwitter-Projekten". So hat z. B. das Projekt "SELFHTML-Suche" die Gruppe "zxy", der alle Dateien innerhalb des Projekt-Verzeichnisbaums zugeordnet sind. Dafür wird über das "set-group-ID-on-execution-bit" (siehe Manpage englischsprachige Seite chmod) gesorgt, ein Bit, das, wenn es auf ein Verzeichnis gesetzt wird, unterhalb dieses Verzeichnisses wiederum für alle neu angelegten Verzeichnisse und Dateien per Default die Gruppe des Projekt-Verzeichnisses setzt. Doch das allein genügt nicht: User haben die Angewohnheit, sich nicht an Bestimmungen zu halten (sorry, wenn ich jetzt jemandem auf die Füße trete), also mußte ein Absicherungs-Mechanismus her, der dafür sorgt, dass die Dateien und Verzeichnisse die richtige Gruppen-Zugehörigkeit haben. Hierfür habe ich ein Perl-Script geschrieben (Seite Die Rechte).

nach obennach unten

Die User

Zunächst wollten wir weg von der Multi-User-Verwaltung. Auf dem alten Server war es so, dass jeder für jedes Projekt ein eigenes Login bekamen, sprich ein User, der für die Projekte SELFHTML und SELFHTML-Suche eingetragen war, hatte wenigstens 2 Logins. War er noch weiteren Projekten zugeordnet, hatte er noch zusätzlich pro Projekt ein Login. Das war sehr, sehr umständlich und nervig, außerdem bot es eine Sicherheitslücke: mit jedem Account auf dem System wird der Server angreifbarer.

So bekam jetzt jeder User lediglich einen Account. Der Zugriff wurde über die Gruppen-Zugehörigkeit geregelt. User, die keinen SSH-Zugriff benötigten, erhielten keine Shell (/sbin/nologin), die anderen erhielten die englischsprachige Seite BASH2 als Shell.

nach obennach unten

Die Passwörter

Jeder User bekam ein maschinen-generiertes Passwort, das wenigstens 8 Zeichen lang war. Das heißt, die Passwörter sind keiner bekannten Sprache entnommen und bestehen aus sämtlichen, im ASCII-Code verfügbaren Zeichen. So ist z. B. das Ausprobieren durch Wörterbücher sinnlos und durch Brute-Force mehr als sehr aufwendig: es gibt bei einem Zeichensatz von sagen wir mal 128 Zeichen und einer Einschränkung von 12 Zeichen Passwort-Länge 1288 (= 72057594037927936) bis 12812 (= 19342813113834066795298816) mögliche Kombinationen (in Wirklichkeit ist die Maximal-Länge nicht gesetzt).

Eine Ausnahme bildet der Apache-Prozess: er bekam ein Passwort, das durch crypt() oder md5() nicht erreichbar ist. Außerdem bekam er keine Shell. So ist es im Grunde unmöglich, sich über ihn einzuloggen.

nach obennach unten

Die Rechte

Jetzt war zwar die Aufteilung in Gruppen geregelt, jedoch noch nicht die Rechtevergabe. Mit einer zu restriktiven Rechtevergabe (z. B. 700) könnte der Apache-Prozess keinen Zugriff auf alle Projekte haben. Allerdings sollten Projekt-Mitglieder auch vollen Schreib- und Lesezugriff erhalten. So blieb nur eine Wahl: Verzeichnisse und Scripts erhielten 770 (rwxrwx---) als Mode, "normale" Dateien erhielten 660 (rw-rw----) als Mode.

Das lief soweit sehr gut — solange die Anzahl der Projekte sich in Grenzen hielt. Danach saßen wir einem Bug des Apachen auf: war er zu vielen Gruppen zugeordnet, glaubte er, bestimmte Dateien nicht mehr ausführen zu duerfen. Ich weiß nicht, woran das liegt, ich weiß nur, dass für dieses Problem eine Lösung gefunden werden mußte. So änderte ich die Modes für Scripte auf 771 (rwxrwx--x).

Dieses Rechte-System war sehr empfindlich. Ich hatte zwar die entsprechenden umode-Einstellungen gemacht, aber wenn sich nur ein User nicht daran hielt, war alles sinnlos. Um sicherzustellen, dass die Modes richtig eingestellt blieben, erarbeitete ich ein Script, das einmal pro Stunde läuft:

#!/usr/bin/perl -w

use strict;

use vars qw($VERSION $CONFF);

BEGIN
 {
  $VERSION = 1.02;
  $CONFF   = '/home/cron/modes/modes.xml';
 }

use XML::Simple;  # um die Konfigurations-Datei einzulesen

sub readin($$$);

my $config = XMLin($CONFF);

foreach(@{$config->{groups}->{group}}) # jede Gruppe durchiterieren
 {
  chmod oct( # und bei jeder Gruppe das Basis-Verzeichnis ändern
    $config->{modes}->{mode}->{$_->{groupname}} ?
     $config->{modes}->{mode}->{$_->{groupname}}->{content} :
     $config->{modes}->{mode}->{normdir}->{content}
  ), $_->{dir} or do {
    print 'Error in chmod: ',$!, 'Directory: ',$_->{dir},"\n";
    next;
  };

  # leider scheint es kein chgrp zu geben - also backticks benutzen
  my $command = "chgrp ".$_->{groupname}." ".$_->{dir};
  print `$command`; # eventuelle fehlermeldungen ausgeben, die werden dann per Mail verschickt

  readin(
    $_->{dir},
    $_->{groupname},
    $_->{recursive} eq 'yes' ? 1 : 0
  );

 }

sub readin($$$)
 {
  my $aktdir  = shift;
  my $grpname = shift;
  my $rec     = shift;

  local *DIR;

  opendir DIR, $aktdir or print 'Error: ',$aktdir,': ',$!,"\n" and return; # das verzeichnis öffnen und einlesen

  foreach my $file (readdir DIR)
   {
    next if $file eq "." || $file eq ".."; # . und .. ignorieren

    if(-d $aktdir.'/'.$file) # bei verzeichnissen eine neue rekursions-stufe starten
     {
      chmod oct($config->{modes}->{mode}->{normdir}->{content}), $aktdir.'/'.$file or do {
        print 'Error in chmod: ',$!,' at directory ',$aktdir,'/',$file,"\n";
        next;
      };

      my $command = 'chgrp '.$grpname.' '.$aktdir.'/'.$file;
      print `$command`;

      readin($aktdir.'/'.$file,$grpname,$rec) if $rec;
      next;
     }

    if($file =~ /\.([^\.]+)$/) # die Datei-Endung ist ermittelbar
     {
      if(defined $config->{modes}->{mode}->{$1}) # gibt es einen fuer die Datei-Endung definierten
       {                                                  # Mode, so wird dieser genommen
        chmod oct($config->{modes}->{mode}->{$1}->{content}),$aktdir.'/'.$file or do {
          print 'Error in chmod: ',$!,' at directory ',$aktdir,'/',$file,"\n";
          next;
        };

        my $command = 'chgrp '.$grpname.' '.$aktdir.'/'.$file;
        print `$command`;
       }
      else # wenn nicht - Standard-Modes nehmen
       {
        chmod oct($config->{modes}->{mode}->{normfile}->{content}), $aktdir.'/'.$file or do {
          print 'Error in chmod: ',$!,' at directory ',$aktdir,'/',$file,"\n";
          next;
        };

        my $command = 'chgrp '.$grpname.' '.$aktdir.'/'.$file;
        print `$command`;
       }
     }
    else # Datei-Endung nicht ermittelbar, Standard-Modes nehmen
     {
      chmod oct($config->{modes}->{mode}->{normfile}->{content}),$aktdir.'/'.$file or do {
        print 'Error in chmod: ',$!,' at directory ',$aktdir,'/',$file,"\n";
        next;
      };

      my $command = 'chgrp '.$grpname.' '.$aktdir.'/'.$file;
      print `$command`;
     }
   }

  closedir DIR or print 'Error: ',$aktdir,': ',$!,"\n" and return;
 }

# eof

Tja, jetzt fehlt nur noch die Konfiguration:

<?xml version="1.0"?>
<!DOCTYPE config SYSTEM "modes.dtd">

<config>
 <groups>
  <!-- webroot -->
  <group recursive="yes">
   <dir>/home/www/teamone.de/selfaktuell</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/selfhtml</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/www</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/selfsuche</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/rockyhorrorpictureshow</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/selfdeveloper</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/selffan</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/selfforum</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/alpentouren</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/selfhtml.com.fr/selfforum</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/selfhtml.com.fr/selfhtml</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/selfhtml.com.fr/www</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/selfhtml.com.fr/recherche</dir>
   <groupname>gruppenname</groupname>
  </group>

  <group recursive="yes">
   <dir>/home/www/teamone.de/webalizer</dir>
   <groupname>gruppenname</groupname>
  </group>
 </groups>

 <modes>
  <mode name="pl">771</mode>
  <mode name="cgi">771</mode>
  <mode name="sh">771</mode>
  <mode name="php">771</mode>
  <mode name="normfile">660</mode>
  <mode name="normdir">771</mode>
 </modes>
</config>

Und natürlich darf auch die DTD nicht fehlen:

<!ELEMENT config (groups,modes)>
  <!ELEMENT groups (group+)>
    <!ELEMENT group (dir,groupname)>
    <!ATTLIST group
              recursive  CDATA  #IMPLIED
              >
      <!ELEMENT dir       (#PCDATA)>
      <!ELEMENT groupname (#PCDATA)>

  <!ELEMENT modes (mode+)>
    <!ELEMENT mode (#PCDATA)>
    <!ATTLIST mode
              name  CDATA  #REQUIRED
              >

Mit diesem Script ist es mir möglich, die Rechte relativ genau zu verteilen und sicherzustellen, dass sie auch eingehalten werden.

weiter Seite Logfile-Auswertung

zurück Seite Struktur des URL-Baumes

Teil von SELFHTML aktuell Teil von Artikel Teil von Serverkonfiguration Teil von SELFHTML Server Konfiguration

© 2007 bereichsübergreifende Seite Impressum