apache: Am ActiveDirectory authentifizieren

Den Weg Benutzer über .htaccess und .htpasswd beim apache Webserver zu authentifizieren ist hinlänglich bekannt.
Noch interessanter ist jedoch die Authentifizierung über ein Zentrales ActiveDirectory (oder einen beliebigen LDAP Server) – Und dabei ist es fast so einfach wie über die .htpasswd files.

Als erstes benötigt man das modul yum install mod_ldap:

yum install mod_ldap

Danach erstellt man im zu schützenden Web-verzeichnis einfach eine Datei mit dem Namen .htaccess und folgendem Inhalt:

# Username to bind
AuthLDAPBindDN "CN=unprivilegierter-user,OU=User Accounts,DC=ad,DC=example,DC=net"
AuthLDAPBindPassword "xxxxxx"
 
# search for users
AuthLDAPURL "ldap://ad.example.net/OU=User Accounts,DC=ad,DC=example,DC=net?sAMAccountName?sub?(objectClass=*)"
 
AuthType Basic
AuthName "WINDOWS ACCOUNT LOGIN"
AuthBasicProvider ldap
 
# Important, otherwise "(9)Bad file descriptor: Could not open password file: (null)"
AuthUserFile /dev/null
require valid-user

[stextbox id=“note“ caption=“Hinweis bei der Verwendung von SSL (ldaps://)“]
Verwendet man SSL, also als AuthLDAPURL beispielsweise: ldaps://ad.example.net/, muss man im apache in der Server Konfiguration das checken des CA-Zertifikats deaktivieren, z.B. mit der folgenden Zeile in: /etc/httpd/conf.d/ldap.conf:

LDAPVerifyServerCert Off

Alternativ kann man auch das CA-Zertifikat vom LDAP-Server auf den Webserver kopieren (z.B. nach: /etc/openldap/certs/ldap_ca.crt und dann in: /etc/httpd/conf.d/ldap.conf anstelle von: LDAPVerifyServerCert Off die Option:

LDAPTrustedGlobalCert CA_BASE64 "/etc/openldap/certs/samba_ca.crt"

einfügen.
[/stextbox]

Die einzelnen Anweisungen bedeuten folgendes:

  • AuthLDAPBindDN: Dies ist der DN eines unprivilegierten users; da man beim ActiveDirectory nur schon einen user braucht um andere user zu suchen. 😉
  • AuthLDAPBindPassword: Das Passwort für diesen (system-) user
  • AuthLDAPURL: Die URL für die Domain Suche (muss mindestens ein Unterverzeichnis (OU) enthalten!)

Der Rest entspricht den Standard Apache-Authentifizierungs Konfigurationen.

[stextbox id=“tip“ caption=“mod_ldap debuggen“]
Falls bei mod_ldap etwas nicht funktioniert, erhält man nicht mehr als einen HTTP 500 Fehler im apacher error.log und mit dieser Info lässt sich leider nicht so viel anfangen.
Glücklicherweise gibt es die Option: LDAPLibraryDebug, welche man in der Server-Konfiguration, beipspielsweise mit der folgenden Zeile in: /etc/httpd/conf.d/ldap.conf hinzufügen kann:

LDAPLibraryDebug 7

Nach einem restart des apache servers steht dann die ganze LDAP connection info im error.log.

Hinweis: Auch SELinux kann in diesem Kontext für Probleme verantwortlich sein.
[/stextbox]

Quellen

Red Hat init-script Vorlagen

Sobald man mal ein eigenes start script schreiben will, sucht man nach einem guten template, welches Möglichst die Standard Funktionen benutzt; diese sind bei RedHat z.B. in der Datei: /etc/init.d/functions zu finden.

Nachfolgend finden sich zwei Beispiele; das erste benutzt man, wenn man das „daemon-handling“ selbst machen will, dass zweite nutzt die entsprechende Funktion in der functions Datei.

# Init-Script template
#
# Written by Steven Varco <email@adresse.tld>
#
# chkconfig: - 80 20
# description: SERVICENAME daemon
#
# processname: SERVICENAME
# config: /etc/SERVICENAME.conf
# pidfile: /var/run/SERVICENAME
 
# source functions library
. /etc/init.d/functions
 
 
APP_NAME=myApp                                  # Name of the application (will be excecuted!)
APP_DESC="SERVICE DESCRIPTION"                  # Short description
APP_PID=/var/run/$APP_NAME                      # PID file
APP_CONFIG="/etc/SERVICENAME.conf"              # Config file
 
 
case "$1" in
start)
  echo -n "Starting $APP_NAME..."
 
  # Start functions
  #$(which runuser) -l myuser $APP_NAME
  echo $! > $APP_PID
 
  # Output OK or FAIL
  RETVAL=$?
  if [ $RETVAL -eq 0 ]; then
    echo_success
  else
    echo_failure
  fi
 
  # Create PID-File
  if [ ! -f "$APP_PID" ] ; then
    touch $APP_PID
  fi
;;
 
 
 
stop)
  echo "Stopping $APP_NAME..."
 
# Stop functions
  if [ -f $APP_PID ] ; then
    kill $($APP_PID)
 
    # Output OK or FAIL
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
      echo_success
    else
      echo_failure
    fi
  else
    echo "$APP_NAME is not running"
  fi
 
  # Remove PID-File
  if [ -f "$APP_PID" ] ; then
    rm -f $APP_PID
  fi
;;
 
 
 
restart)
$0 stop && sleep 3 && $0 start || return=$0
;;
 
 
status)
  if [ -f "$APP_PID" ] ; then
    PID=$(cat $PID_FILE)
    PSPID=$(ps -p $PID -o comm=)
    if [ -n "$PSPID" ]; then
      echo -n "$APP_NAME is running as PID: $PID and command: $PSPID"
      echo_success
    else
      echo -n "$APP_NAME dead but pid file exists!"
      echo_warn
    fi
  else
    echo -n "$APP_NAME is not running"
  fi
  exit $RETVAL
;;
 
*)
  echo "Usage: $0 {start|stop|restart|status}"
  exit 1
esac
#!/bin/bash
#
# Init file for myApp
#
# Written by Vorname Name <email@adresse.tld>.
#
# chkconfig: - 80 20
# description: MyApp daemon
#
# processname: myapp
# config: /etc/myapp.cfg
# pidfile: /var/run/myapp
 
source /etc/rc.d/init.d/functions
 
### Default variables
CONFIG="/etc/myapp.cfg"
 
[ -x /usr/sbin/myapp ] || exit 1
[ -r "$CONFIG" ] || exit 1
 
RETVAL=0
prog="myapp"
desc="myApp daemon"
 
start() {
        echo -n $"Starting $desc ($prog): "
        daemon $prog -c "$CONFIG" -d
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
        return $RETVAL
}
 
stop() {
        echo -n $"Shutting down $desc ($prog): "
        killproc $prog
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
        return $RETVAL
}
 
restart() {
        stop
        start
}
 
reload() {
        echo -n $"Reloading $desc ($prog): "
        killproc $prog -HUP
        RETVAL=$?
        echo
        return $RETVAL
}
 
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  reload)
        reload
        ;;
  status)
        status $prog
        RETVAL=$?
        ;;
*)
  echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}"
  RETVAL=1
esac
 
exit $RETVAL

Drupal7: Bildergalerie erstellen

In Drupal7 wuede einiges vereinfacht, z.B. das erstellen einer Bilder-Galerie, was früher unzählige module brauchte, lässt sich jetzt mit einem Bewerkstelligen – inlk. "shadowbox effekt".

Folgendes vorgehen ist dazu vonnöten:

  • Einen neuen content type erstellen (admin/structure/types/add)

Titel: Bildergalerie Name: bildergalerie

  • Speichern und Felder hinzufügen wählen
  • Neues Feld: hinzugügen

Beschriftung: Bild Name: field_image Feld: Bild Steuerelement: Bild

  • Feldeinstellungen speichern wählen
  • Im nachfolgenden Dialog den Wert von: Anzahl von Werten auf unbegrenzt setzen
  • Einstellungen speichern
  • Das "shadowbox" Modul herunter laden und installieren
  • Eine View (Ansicht" für die Galerie erstellen

Nun funktioniert die Galerie zwar schon, die Bilder werden jedoch untereinander angezeigt.
Damit die Bilder nun nebeneinander angezeigt werden muss man das "style.css" seines verwendeten Themes um diese Zeile erweitern:

.node-bildergalerie .field-name-field-picture .field-item {float:left; margin:20px;}

Ressourcen

http://drupal.org/node/1025556#comment-4355506
http://drupal.org/node/1025556#comment-4784220

BIND: forward pro Zone

Die Option forwarders in der bind Konfiguration, die meist im globalen "options" Teil zu finden ist, ist hinlänglich bekannt; damit kann man nämlich DNS-Anfragen an einen anderen server weiter leiten. – Doch, was ist, wenn man dies nur für bestimmte Domänen und nicht generell machen möchte?

Die forwarders option lässt sich dazu auch in einer Zone definieren; so kann man für eine bestimmte zone angeben, dass nur diese queries forwarded werden sollen, was z.B. nützlich ist, wenn man im Heimnetzwerk eine eigene DNS Zone hat und für eine allfällige VPN-Verbindung zur Firma, dann für die Firmen Domain deren Nameserver nutzen möchte.

So kann man z.B. eine zones.conf wie folgt machen:

zone "home.lan" { type master; file "/etc/named/zones/home.lan"; allow-query { any; }; };
zone "company.net" { type forward; forwarders { x.x.x.x; }; };

Anfragen an .home.lan werden so lokal abgehandelt, solche an .company.net jedoch weiter geleitet auf x.x.x.x. Alle anderen anfragen können weiterhin lokal über die root-server oder über eine globale forwardes Option an die Nameserver des ISPs weitergeleitet werden.

Weitere Infos: http://www.zytrax.com/books/dns/ch7/queries.html#forwarders

MPC: Playlisten vom Kontextmenü erstellen

Einige Windows Anwender sind vom „neuen“ Windows Media Player ab Version 7 nicht begeistert: Zu aufgebläht, unübersichtlich, etc.

Deshalb gibt es den wunderbaren MediaPlayerClassic. Mit einem kleine Trick, kann man sich sogar im Kontextmenü einen Eintrag machen: „Der MPC Wiedergabeliste hinzufügen“ und so einfach MP3 Dateien markieren und diese automatisch in der Liste abspielen lassen.

Dazu muss man wie folgt Vorgehen:

  • Einen Ordner öffnen und im Menu Extras->Ordneroptionen->TAB: Dateitypen wählen
  • Die gewünschte Dateiendung aussuchen und auf Erweitert klicken.
  • Auf Neu klicken

Hier macht man folgende Angaben:
Vorgang: Zur MPC Playliste hinzufügen
Anwendung für diesen Vorgang: „<PFAD_ZU>mpc-hc.exe“ /play /add „%1″

{img fileId=“61″ thumb=“y“ rel=“box[g]“ imalign=“left“}

Dann auf OK und man kann entsprechend mehrere Files gleich aus dem Kontextmenü abspielen!

Drupal: CKEditor konfigurieren

In einem anderen KB-Eintrag wurde erklärt, wie man dem bei [http://www.tech-island.com/kb-Platformunabh%C3%A4ngig-Internet-WordPress%3A+Mehrfache+Zeilenumbr%C3%BCche&structure=kb|Wordpress dem WYSIWYG-Editor einen schmaleren Zeilenumbruch] hinkriegt.

Das selbe kann man auch beim in Drupal erhaltenen CKEditor machen:

Erstelle ein Verzeichnis mit dem Namen overrides in sites/all/modules

Erstelle darin folgende zwei Dateien:

overrides.info und overrides.module

in overrides.info schreibe dies:

name = Overrides
description = Overrides settings
core = 7.x
 
package = own

und in overrides.module:

<?php
/<em> wysiwyg overrides </em>/
 
function overrides_wysiwyg_editor_settings_alter(&$settings, $context) {
  if($context['profile']->editor == 'ckeditor') {
    $settings['enterMode'] = 2;
    $settings['shiftEnterMode'] = 1;
  } else if($context['profile']->editor == 'tinymce') {
    $settings['forced_root_block'] = FALSE;
    $settings['force_br_newlines'] = TRUE;
    $settings['force_p_newlines'] = FALSE;
  }
}

Achtung: Das end-tag von <?php ist hier bewusst weg gelassen!

Gehe danach zur Module seite in: admin/modules Dort findest du in der Kategorie "OWN", das Modul "overrides". Aktiviere dieses.

Die Änderung sollte sofort wirksam werden, falls nicht wähle im cache menu: "Flush all caches".

Quelle: Dieser Tip stammt von: http://wdtutorials.com/drupal7/50

apache: An einer mySQL Datenbank authentifizieren

Die Methode mit .htaccess/.htpasswd ist vielen bekannt um ein Verzeichnis per passwort zu schützen – Und dies geht mit dem apache-modul: mod_auth_mysql auch über eine mysql Datenbank!

Die Möglichkeiten dieser Methode sind fast unerschröpflich, so kann z.B. ein Forum einen Verzeichnisschutz implementiert haben, bei dem man sich automatisch mit seinem normalen Foren-Login anmelden kann, usw.

Und so gehts:

Erst mal muss das mod_auth_mysql installiert werden, z.B. bei CentOS mittels:

yum install mod_auth_mysql

Dann legt man im zu schützenden Verzeichnis einfach ein normales .htaccess file an mit folgendem Inhalt:

AuthName "SeitenName"
AuthType Basic
AuthMySQLHost <DB_HOST>
AuthMySQLUser <DB_USER>
AuthMySQLPassword <DB_PASSWORT>
 
AuthMySQLDB <DB>
AuthMySQLUserTable <USER_TABELLE>
AuthMySQLNameField <FELD_NAME>
AuthMySQLPasswordField <FELD_PASSWORT>
AuthMySQLPwEncryption <passwort Verschlüsselung, z.B. md5>
AuthMySQLEnable On
AuthMySQLUserCondition "<ggf. weitere Kontitionen>"
require valid-user

Hier ist noch ein Beispiel, wie man das ganze auch auf Gruppenberechtigungen ausdehnen kann:

AuthName "YourSite"
AuthType Basic
 
# Database settings:
AuthMySQLHost localhost
AuthMySQLUser dbuser
AuthMySQLPassword dbpass
AuthMySQLDB dbname
 
# User table
AuthMySQLUserTable users
AuthMySQLNameField users.name
AuthMySQLPasswordField users.pass
 
# User Roles tables
AuthMySQLGroupTable "users, users_roles"
AuthMySQLGroupField users_role.rid
 
# Where clauses
AuthMySQLUserCondition "users.status = 1 and users.access <> 0"
AuthMySQLGroupCondition "users.uid = users_roles.uid AND users_roles.rid > 2"
 
# Do it to it!
AuthMySQLPwEncryption md5
AuthMySQLEnable On
require valid-user

Und wenn alles klappt kann man sich dann mit den Login-Daten aus der Datenbank anmelden! 😉

Quelle: [http://drupal.org/node/156547|drupal.org: Sharing authentication with HTTP-Auth]

BIND: Sag mir von wo du kommst und ich sage dir wohin du gehen sollst

bind hat ein sehr praktisches Feature, dass allerdings nur wenigen bekannt ist: anhand einer ACL kann man verschiedene "Sichten" erstellen; so kann man z.B. sagen, dass jemand der von einer Adresse vom internen Netzwerk kommt die interne Adresse eines Server erhält und jemand der von "draussen" kommt die externe, öffentlich zugängliche Adresse.

Und so gehts: Erstmal definieren wir in /etc/named/named.conf die entsprechende Zone für das interne Netz:

acl internal-network
{
  // Local
  127.0.0.0/8;
 
  // 10.1.1.0 - 10.1.1.255 (Internal Network)
  10.1.1.0/24;
};

Dann definieren wir je für die interne Zone und für den „rest“ eine view und includen das entsprechende Zonefile:

view "internal"
{
  match-clients { internal-network; };
  include "/etc/bind/zones.conf.int";
};
 
view "external"
{
  match-clients { any; };
  include "/etc/bind/zones.conf";
};

amavis/clamav: Fehler bei DB-Updates (connect(): Permission denied)

Falls man auf einmal von cron mails bekommt wie:

/etc/cron.daily/freshclam:
 
connect(): Permission denied

Und im freshclam.log:

WARNING: Clamd was NOT notified: Can't connect to clamd through /var/spool/amavisd/clamd.sock

Dann kann das unter anderem daran liegen, dass die Verzeichnisberechtigungen vom Verzeichnis in dem das file clamd.sock liegt (in diesem Falle: /var/spool/amavisd) falsch eingestellt sind.

Diese müssen chmod 770 sein. Falls sie z.B. 700 sind löst ein Umstellen der Berechtigungen das Problem:

chmod -v 770 /var/spool/amavisd

Weitere Infos: [https://bugzilla.redhat.com/show_bug.cgi?id=548234|Red Hat: Bug 548234 – Freshclam cannot notify clamd of database updates due to permission denied]

Suchen und Ersetzen in mehreren Dateien

Manchmal will man in mehreren Datei ein „Suchen & Ersetzten machen.
Dies geht mit folgendem sed Konstrukt ganz einfach:

sed -e 's/search/replace/g' -i *.txt

Die Option bedeuten:
-e Führe den folgenden code (expression) aus
-i editiere das file

[stextbox id=“tip“ caption=“Tip: Ersetzten von Strings mit slash (/)“]Falls man einen String mit slash (z.B. einen Pfad) ersetzten will, kann man % als alternatives Trennungszeichen verwenden. Z.B.

sed -e 's%/alter/pfad%/neuer/pfad%g' -i *.txt

[/stextbox]

Will man in einem Verzeichnis und allen Unterverzeichnissen in allen Dateien einen String ersetzen, so kann man noch find miteinbeziehen:

find ./ -type f -exec sed -i 's/search/replace/g' {} \;

Quelle: http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php