Samba: Kleine Firma mit Standalone-Server

Ziel: Implementieren einer beispielhaften ‚smb.conf‘, die eine kleine Firma ohne Domänenkontroller abbildet.

Im Detail: Die Firma möchte drei Freigaben mit abgestufter Sicherheit nutzen:

  1. Austausch: Für Jedermann schreibfähig

  2. Dokumente: Nur für authentifizierte Benutzer bei Verwendung einer Schreibliste (otto, kaspar)

  3. Verwaltung: Nur für die vertrauenswürdigen Benutzer der Verwaltung otto und kaspar)

Dabei sollen möglichst robuste Einstellungen für den Zugriff auf das Dateisystem getroffen werden.

Vorbereitungen

  1. Software installieren: apt-get install samba smbclient

  2. Eine Gruppe und entsprechende Benutzer anlegen:

groupadd verwaltung
useradd -m -s /bin/bash -g verwaltung otto
useradd -m -s /bin/bash -g verwaltung hans
useradd -m -s /bin/bash -G verwaltung kaspar
smbpasswd -a otto
smbpasswd -a hans
smbpasswd -a kaspar
  1. Dateirechte anpassen:

mkdir -p -m 777 /srv/samba/free
mkdir -m 775 /srv/samba/doc
mkdir -m 770 /srv/samba/verwaltung
chgrp verwaltung /srv/samba/doc /srv/samba/verwaltung

Erstellung der Konfigurationsdatei

Die Hauptkonfigurationsdatei für Samba ist neu anzulegen, deshalb die alte erst einmal sichern:

mv /etc/samba/smb.conf /etc/samba/smb.conf.old

Danach einfach eine neue Datei erzeugen:

vi /etc/samba/smb.conf

Nun werden die folgenden Zeilen eingefügt:

[global]
  workgroup = firma1
  security = user
  map to guest = bad user

[Austausch]
  path = /srv/samba/free
  guest ok = yes
  read only = no
  create mask = 666
  directory mask = 777
  ; Alternativ zu den beiden mask-Zeilen:
  ;force user = nobody

[Dokumente]
  path = /srv/samba/doc
  read only = yes
  write list = otto,kaspar
  create mask = 775
  directory mask = 775
  force group = verwaltung

[Verwaltung]
  path = /srv/samba/verwaltung
  read only = no
  create mask = 770
  valid users = otto,kaspar
  force group = verwaltung

Das Dokument bitte speichern und den Editor beenden.

Neustarten des Daemons und Testings

Nun muss die Konfiguration z.B. mit service smbd restart neu eingelesen werden, dasselbe sollte mit dem ‚nmbd‘ geschehen. Dann kann es ans Testen gehen.

SMB-Clients:

  1. Linux-Kommandozeile: smbclient, smbfs: mount -t cifs //host/Austausch /mnt -o guest (Voraussetzung: Installiertes Paket „cifs-utils“)

  2. Linux-GUI: nautilus, konqueror

  3. Windows-Workstation

Testen der neuen Config im Einzelnen

Hier folgt nun ein kommentierter Auszug aus der Shell-Sitzung…

Zuerst einmal nur die Browseliste abrufen:

my@bash $ smbclient -NL localhost

    Sharename       Type      Comment
    ---------       ----      -------
    Austausch       Disk      Vorsicht, jeder darf alles!
    Dokumente       Disk
    Verwaltung      Disk
    IPC$            IPC       IPC Service (Samba 4.9.5-Debian)
Reconnecting with SMB1 for workgroup listing.

    Server               Comment
    ---------            -------

    Workgroup            Master
    ---------            -------
    HAUS1                DEB2
    WORKGROUP            ARTIX-WKS
my@bash $
my@bash $ ##   >> Das versteckte Share 'IPC$' ist elementar; nicht versuchen, es zu löschen!

Das 1. Share, was wir testen, ist als allgemeines Austauschverzeichnis für jeden gedacht:

my@bash $ smbclient //localhost/Austausch -U%
Try "help" to get a list of possible commands.
smb: \>
smb: \> mkdir ABC
smb: \>
smb: \> exit
my@bash $
my@bash $ ls -ltrc /srv/samba/free/
total 0
drwxrwxrwx 1 nobody nogroup 0 Nov 30 12:27 ABC
my@bash $
my@bash $

Das 2. Share, was nun dran ist, können nur authentifizierte User benutzen:

my@bash $ smbclient //localhost/Dokumente -Ukaspar
Enter HAUS1\kaspar's password:
Try "help" to get a list of possible commands.
smb: \>
smb: \> mkdir VonKaspar
smb: \>
smb: \> exit
my@bash $
my@bash $ smbclient //localhost/Dokumente -U%
tree connect failed: NT_STATUS_ACCESS_DENIED
my@bash $
my@bash $ ##   >> Hier gibt es ja kein "guest ok = yes"!
my@bash $
my@bash $
my@bash $ smbclient //localhost/Dokumente -Uhans
Enter HAUS1\hans's password:
Try "help" to get a list of possible commands.
smb: \>
smb: \> ls
  .                                   D        0  Mon Nov 30 12:29:15 2020
  ..                                  D        0  Mon Nov 30 12:11:11 2020
  VonKaspar                           D        0  Mon Nov 30 12:29:15 2020

            50321408 blocks of size 1024. 40677936 blocks available
smb: \>
smb: \> mkdir VonHans
NT_STATUS_ACCESS_DENIED making remote directory \VonHans
smb: \>
smb: \> exit
my@bash $
my@bash $ ##    >> Richtig: Es dürfen nur vorhandene, mit SambaSamAccount ausgestattete User hier herein,
my@bash $ ##    gemäß 'write list = otto,kaspar' hat "hans" kein Schreibrecht!

Das 3. Share, was wir schließlich testen, ist noch restriktiver eingestellt:

my@bash $ smbclient //localhost/Verwaltung -Uhans
Enter HAUS1\hans's password:
tree connect failed: NT_STATUS_ACCESS_DENIED
my@bash $
my@bash $ ##    >> Richtig: Trotz korrekter Passworteingabe!
my@bash $
my@bash $ smbclient //localhost/Verwaltung -Uotto
Enter HAUS1\otto's password:
Try "help" to get a list of possible commands.
smb: \>
smb: \> mkdir VonOtto
smb: \>
smb: \> exit
my@bash $
my@bash $ smbclient //localhost/Verwaltung -U%
tree connect failed: NT_STATUS_ACCESS_DENIED
my@bash $
my@bash $ ##   >> Richtig: Dies darf schon gar nicht gehen!!
my@bash $
my@bash $ ls -ltrc /srv/samba/doc/
total 0
drwxrwxr-x 1 kaspar verwaltung 0 Nov 30 12:29 VonKaspar
my@bash $
my@bash $ ls -ltrc /srv/samba/verwaltung/
total 0
drwxr-xr-x 1 otto verwaltung 0 Nov 30 12:34 VonOtto
my@bash $

Aus der entsprechendem Kommandozeilensitzung unter Windows:

C:\>
C:\>net use v: \\192.168.2.232\Verwaltung /user:kaspar k@SSpErS-Pw
Der Befehl wurde erfolgreich ausgeführt.


C:\>
C:\>v:

V:\>
V:\>dir
 Datenträger in Laufwerk V: ist Verwaltung
 Volumeseriennummer: 57E8-17C0

 Verzeichnis von V:\

30.11.2020  12:34    <DIR>          .
30.11.2020  12:11    <DIR>          ..
30.11.2020  12:34    <DIR>          VonOtto
               0 Datei(en),              0 Bytes
               3 Verzeichnis(se), 41.654.181.888 Bytes frei

V:\>
V:\>mkdir VonKaspar
V:\>echo 123 > datei-von-kaspar.txt


my@bash $ ls -ltrc /srv/samba/verwaltung/
total 4
drwxr-xr-x 1 otto   verwaltung 0 Nov 30 12:34 VonOtto
drwxr-xr-x 1 kaspar verwaltung 0 Nov 30 12:40 VonKaspar
-rwxrw---- 1 kaspar verwaltung 6 Nov 30 12:42 datei-von-kaspar.txt
my@bash $

Daemons via Superserver starten

In einem minimalen Szenario (z.B. auf Raspberry Pi) müssen die beiden Daemons ‚smbd‘ und ‚nmbd‘ gar nicht ständig laufen, sie können bei Bedarf vom Superserver Inetd automatisch an den Start gebracht werden.

Daher sorgen wir zuerst dafür, dass die Daemons nicht mehr wie üblich per Init/Systemd gestartet werden und stoppen sie außerdem:

systemctl disable smbd nmbd
systemctl stop smbd nmbd

Für das Starten via Inetd ist ausschlaggebend, wie sich die Dienste der zu öffnenden Ports 137 und 445 laut der Datei /etc/services bezeichnen:

my@bash $ grep '\<445/tcp' /etc/services
microsoft-ds        445/tcp                         # Microsoft Naked CIFS
my@bash $
my@bash $ grep '\<137/udp' /etc/services
netbios-ns  137/udp
my@bash $

Wir entdecken hier also „microsoft-ds“ für die eigentlichen Freigaben und „netbios-ns“ für die Namensauflösung.

Nach der Installation des Superservers mittels apt-get install openbsd-inetd fügen wir folgende zwei Zeilen an die Konfigurationsdatei /etc/inetd.conf an:

microsoft-ds   stream   tcp   nowait   root   /usr/sbin/smbd   smbd
netbios-ns   dgram   udp   wait   root   /usr/sbin/nmbd   nmbd

In der Regel läuft der Inetd bereits beim Installationsvorgang los, damit aber diese Änderung eingelesen wird, ermitteln wir zuerst mit ps -C inetd die Prozess-ID des Superservers und senden ihm danach das SIGHUP-Signal mittels kill -1 <PID> (= typischer Anwendungsfall für das „Hangup“-Signal). Alternativ kann er mit systemctl restart openbsd-inetd neu gestartet werden.

Schließlich gehen wir ans testen, indem wir den Zustand der Ports direkt abfragen. Heutzutage finden wir zumeist das Kommando „SocketState“ vor:

my@bash $ ss -lpn 'sport = 445'
Netid          State      Recv-Q      Send-Q     Local Address:Port     Peer Address:Port
tcp            LISTEN     0           128              0.0.0.0:445             0.0.0.0:*    users:(("inetd",pid=3131,fd=7))
my@bash $
my@bash $
my@bash $ ss -lpn 'sport = 137'
Netid          State      Recv-Q      Send-Q    Local Address:Port      Peer Address:Port
udp            UNCONN     0           0               0.0.0.0:137              0.0.0.0:*    users:(("inetd",pid=3131,fd=8))
my@bash $

Alternativ kann auf „List Open Files“ zurückgegriffen werden (sofern installiert):

my@bash $ lsof -Pni:445
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
inetd   3131 root    7u  IPv4  29565      0t0  TCP *:445 (LISTEN)
my@bash $
my@bash $
my@bash $ lsof -Pni:137
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
inetd   3131 root    8u  IPv4  29567      0t0  UDP *:137
my@bash $

Damit dürfte der üblichen Nutzung nichts im Wege stehen. Have a lot of fun…