Secure Firefox with AppArmor

To „lock down“ Firefox on an openSUSE 11.3 machine, I used the four AppArmor profiles you find below. The first is an openSUSE default profile and the second is based on the openSUSE default profile. My changes include support for PulseAudio sound and the Flash plugin, where the latter is realized with local profiles that are stronger confined than Firefox itself. Finally, I added permission for Zotero requirements.

# /etc/apparmor.d/usr.lib.firefox.firefox.sh

#include 

/usr/lib/firefox/firefox.sh {
  #include 
  #include 
  #include 

  deny capability sys_ptrace,

  /bin/basename rix,
  /bin/bash rix,
  /bin/grep rix,
  /etc/magic r,
  /usr/bin/file rix,
  /usr/lib/firefox/firefox px,
  /usr/share/misc/magic.mgc r,
}
# /etc/apparmor.d/usr.lib.firefox.firefox

#include 

/usr/lib/firefox/firefox {
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include    

  deny /usr/lib/firefox/firefox.sh x,
  deny /usr/lib/mozilla/extensions/*/ w,

  /bin/bash ix,
  /bin/uname ix,

  /etc/gai.conf r,
  /etc/gnome-vfs-2.0/modules/ r,
  /etc/gre.d/ r,
  /etc/gre.d/* r,
  /etc/mailcap r,
  /etc/mime.types r,
  /etc/mtab r,
  /etc/opt/kde3/share/applications/ r,
  /etc/opt/kde3/share/applications/mimeinfo.cache r,

  owner @{HOME}/.ICEauthority r,
  owner @{HOME}/.beagle/ToIndex/* rw,
  owner @{HOME}/.fontconfig/* r,
  owner @{HOME}/.icons/ r,
  owner @{HOME}/.local/share/applications/ r,
  owner @{HOME}/.local/share/applications/* r,
  owner @{HOME}/.local/share/mime/* r,
  owner @{HOME}/.mozilla/extensions/** rw,
  owner @{HOME}/.mozilla/firefox/** rw,
  owner @{HOME}/.mozilla/firefox/**.sqlite* k,
  owner @{HOME}/.mozilla/firefox/**/.parentlock k,

  /opt/kde3/share/applications/ r,
  /opt/kde3/share/applications/mimeinfo.cache r,

  owner @{PROC}/*/mounts r,
  owner @{PROC}/*/fd/ r,
  @{PROC}/meminfo r,
  @{PROC}/sys/kernel/ngroups_max r,

  /usr/bin/tr ix,
  /usr/bin/which ix,

  /usr/lib/**.so mr,
  /usr/lib/firefox/firefox rix,
  /usr/lib/libproxy/pxgconf ix,
  /usr/lib/nspluginwrapper/*/linux/npviewer rcx -> npviewer,
  /usr/lib/xulrunner-*/plugin-container cx -> plugin_container,

  /usr/local/share/applications/ r,
  /usr/local/share/applications/* r,
  /usr/share/applications/ r,
  /usr/share/applications/* r,
  /usr/share/gvfs/remote-volume-monitors/ r,
  /usr/share/gvfs/remote-volume-monitors/* r,
  /usr/share/locale-bundle/**.mo r,
  /usr/share/mime/**.xml r,
  /usr/share/mozilla/extensions/** r,
  /usr/share/myspell/* r,

  /var/cache/gio-2.0/defaults.list r,
  /var/cache/libx11/compose/* r,
  owner /var/run/gdm/*/database r,

  profile npviewer {
    #include 
    #include 
    #include 

    /bin/bash rix,
    /bin/uname rix,
    /usr/bin/tr rix,
    /usr/bin/which rix,
    /usr/lib/nspluginwrapper/*/linux/npviewer.bin rix,
  }

  profile plugin_container {
    #include 
    #include 
    #include 
    #include 
    #include 

    deny /etc/passwd r,
    deny @{PROC}/uptime r,
    deny @{HOME}/.mozilla/firefox/profiles.ini r,

    /bin/bash ix,
    /bin/grep ix,
    /bin/ps ix,

    owner @{PROC}/*/fd/ r,
    owner @{PROC}/*/stat r,

    owner /var/run/gdm/*/database r,
    owner @{HOME}/.adobe/Flash_Player/**/ w,
    owner @{HOME}/.adobe/Flash_Player/AssetCache/ r,
    owner @{HOME}/.macromedia/Flash_Player/** rw,
  }

  # Zotero-specific rules
  owner @{HOME}/.mozilla/firefox/*/zotero/pdfinfo-Linux-* cx -> zotero_tools,
  owner @{HOME}/.mozilla/firefox/*/zotero/pdftotext-Linux-* cx -> zotero_tools,
  owner @{HOME}/.zoteroIntegrationPipe rw,
  /usr/bin/evince Ux,
  /usr/bin/mkfifo ix,
  profile zotero_tools {
    #include 

    owner @{HOME}/.mozilla/firefox/*/zotero/storage/*/* r,
    owner @{HOME}/.mozilla/firefox/*/zotero/storage/*/.zotero-ft-info w,
    owner @{HOME}/.mozilla/firefox/*/zotero/storage/*/.zotero-ft-cache w,
  }
}
# /etc/apparmor.d/abstractions/pulseaudio

/dev/shm/ r,
owner /dev/shm/pulse-shm-* rw,
/dev/snd/*      rw,

/etc/alsa-pulse.conf r,
/etc/asound-pulse.conf r,
/etc/pulse/client.conf r,

owner @{HOME}/.pulse-cookie rwk,

/usr/bin/pulseaudio px,

/usr/share/alsa/** r,
/usr/share/sounds/** r,

/var/lib/dbus/machine-id r,

# vim:syntax=apparmor
# /etc/apparmor.d/usr.bin.pulseaudio

#include 

/usr/bin/pulseaudio {
  #include 
}

Inkscape Standardvorlage

Gestern war ich wieder einmal in der Situation, dass ich eine per Hand gezeichnete Skizze in einem Dokument verwenden wollte. In solchen Faellen ist Vektorgrafik Software Inkscape für mich die erste Wahl. In Inkscape angefertigte Zeichnungen lassen lassen sich ganz natürlich im EPS Format exportieren, das wiederum erste Wahl für Grafiken in LaTeX Dokumenten ist. Bei Bedarf lassen sich EPS Dateien auch unkompliziert in PDF umwandeln und mit pdfLaTeX verwenden.

Nun muss ich jedes Mal, wenn ich eine neue Zeichnung mit Inkscape beginnen wollte, zuerst eine Reihe von Dokumenteneinstellungen ändern, weil eine A4 Seite im Hochformat und mit Pixel Angaben auf den Linealen nicht das ist, was ich brauche. Stattdessen verwende ich immer A6 im Querformat mit Millimeter Angaben und einem 1mm Gitter. Die Vermutung, dass sich die Standardeinstellungen ändern lassen, bestätigte sich anhand eines Treffers in den Inkscape FAQ.

Um es kurz zu machen: Man muss ein leeres Dokument nach den eigenen Vorstellungen erstellen und es als

~/.config/inkscape/templates/default.de.svg

speichern, wenn man, wie ich, Deutsch als Systemsprache verwendet.

Einrichtung eines sicheren Fileservers

Theorie

Bei diesem Titel versteht es sich vielleicht von selbst, dass FTP hier kein Thema ist. Es ist vermutlich zu einem nicht unwesentlichen Teil persönliche Präferenz, aber wenn ich das Wort sicher im Zusammenhang mit Servern verwende, verlasse ich mich immer gern auf SSH. Im Fall eines Fileservers bietet sich also das SFTP Protokoll an. Generell wirft die Verwendung von SSH und, im Speziellen, die Weitergabe von Zugangsdaten für einen SSH Server (zumindest) zwei brennende Fragen auf.

Zum einen muss verhindert werden, dass der eingeloggte Benutzer beliebigen Code ausführen kann. Da er zumindest für das Upload Verzeichnis Schreibrechte hat, kann ein eventueller Upload von Exploits nicht prinzipiell verhindert werden, aber wenn man dem Benutzer erst gar keine Shell gibt, kann er die Ausführung des Schadcodes nicht veranlassen. Diese Strategie verfolgt die scponly Software.

Zum anderen ist man als Administator auch interessiert, dem eingeloggten Benutzer möglichst wenig Information über das System preiszugeben. Das erreicht man mit einer chroot Umgebung. Nun wird sogar von scponly ein Skript angeboten, um eine solche Umgebung zu erstellen. Dessen Verwendung wird auf der ubuntuusers Wiki beschrieben. Leider ist dafür das Setzen des SUID Bits notwendig, was meiner Meinung nach keine saubere Lösung ist. Daher werde ich hier beschreiben, wie man eine äquivalente Umgebung mit dem makejail Skript erstellt. Diese Vorgehensweise orientiert sich stark an der Anleitung zum Absichern von Debian, welche in ihrer Gesamtheit auf jeden Fall eine Lektüre wert ist, wenn man einen Debian Server administrieren muss.

Praxis

Diese Anleitung bezieht sich auf Debian Lenny. Zuerst werden die erforderlichen Pakete installiert:

# aptitude install libpam-chroot makejail scponly

Nun wird das eben installierte PAM Modul libpam-chroot für SSH Logins aktiviert. Dazu werden die folgenden Zeilen zu der Datei /etc/pam.d/sshd hinzugefügt:

session    required     pam_chroot.so

Zunächst muss der entsprechende Benutzer erstellt werden, mit dem man sich später am Server anmelden kann.

# adduser --home /home/sftp --shell /usr/bin/scponly --no-create-home sftp

Damit das PAM Modul auch wirklich greift, muss es für den neuen Benutzer aktiviert werden. Das geschieht durch folgende Zeile in der Datei /etc/security/chroot.conf.

sftp	/var/chroot/users/sftp

Als nächstes wird das Verzeichnis für die chroot Umgebung erstellt und der neue Benutzer erhält Schreibrechte für sein Heimatverzeichnis.

# mkdir -p /var/chroot/users/sftp/home/sftp
# chown sftp:sftp /var/chroot/users/sftp/home/sftp

Für die Verwendung des makejail Skripts wird eine Konfigurationsdatei mit folgendem Inhalt erstellt und als sftp-jail.py gespeichert.

chroot="/var/chroot/users/sftp"
users=["sftp"]
testCommandsInsideJail=["scponly", "ls", "scp", "rm", "ln", "mv", "chmod", "chown", "chgrp", "mkdir", "rmdir", "pwd", "groups", "id", "echo", "passwd"]
forceCopy=["/usr/lib/sftp-server"]
cleanJailFirst=1
preserve=["/home/sftp"]

Es folgt der Aufruf des Skripts.

# makejail sftp-jail.py

Die am Ende ausgegebenen Warnungen können getrost ignoriert werden. Wenn man so vorsichtig ist wie ich, muss man noch dafür sorgen, dass der SSH Login für den neuen Benutzer freigegeben wird. Dazu fügt man den neuen Benutzernamen dem AllowUsers Parameter in der Datei /etc/ssh/sshd_config hinzu und startet das SSH Service neu.

# /etc/init.d/ssh restart