Toy Story & Debian

“Toy Story was released by Pixar November 22nd, 1995. One year later Debian 1.1 was released. Bruce Perens was the DebianProjectLeader then and also worked for Pixar. He started the tradition of naming Debian releases after Toy Story characters.” – wiki.debian.org/ToyStory -> Debian


debian_wallpaper_by_voku1987
debian_wallpaper_by_voku1987

Ziproxy – HTTP-Traffic Kompression

Ziproxy ist ein nicht HTTP-Proxy Server, welcher Daten nicht zwischenspeichert, diese jedoch komprimiert und weiterleitet. Die meiste Bandbreite wird eingespart, indem Bilder neu-konvertiert werden und andere Daten per gzip komprimiert werden.

Ziproxy benötige keine Client-Software, solange der Browser die gzip-Daten korrekt dekomprimieren kann und auch mit JPEG 2000 Bildern umgehen kann. Der Proxy kann auf unterschiedliche Arten konfiguriert werden, ich hatte bereits vor langer Zeit über Ziproxy berichtet (Mein Proxy-Server) und da ich darauf aufmerksam gemacht wurde, dass die gezeigte Konfiguration in der neuen Version nicht mehr funktioniert, ich jedoch den gezeigten Proxy-Aufbau nicht mehr im Einsatz habe, wollte ich in diesem Blog-Post zumindest die beiden Grundkonfigurationen zeigen. (ggf. wäre ein solcher Proxy auch für Smartphones hilfreich)


1.) Ziproxy als Remote-Proxy

Als erstes die einfachste Variante, hier verbindet sich der Ziproxy über eine schnelle Verbindung (extern) mit dem HTTP-Servern und schickt die Daten über eine langsame Verbindung weiter.


Konfiguration: ziproxy.conf (mit ein paar Kommentaren)




Ziproxy-Standard
Ziproxy-Standard





2.) Ziproxy als Remote-Proxy + Local-Proxy

Die Konfiguration des Remote-Proxys unterscheidet sich im Grunde nicht von der ersten Variante, auch hier wird keine Client-Software benötigt, da ein zweiter lokaler Ziproxy sozusagen als Client fungiert, dies hat den Vorteil:

  • der Browser muss nicht “JPEG 2000” unterstützen
  • der Client (z.B. Squid) muss nicht “gzip” unterstützen
  • CPU-Last wird auf einen Server verlagert (ggf. wenn der Browser durch “JPEG 2000”-Bilder hohe CPU-Last erzeugt)

Konfiguration: Ziproxy-Client

Port = 8080
Address = "127.0.0.1"
NextProxy="81.169.188.94"
NextPort=3128
ImageQuality = {85,85,85,85}
JP2ImageQuality = {85,85,85,85}
MaxUncompressedGzipRatio = 4000
MinUncompressedGzipStreamEval = 250000
MaxSize = 2097152
Gzip = true
DecompressIncomingGzipData = true




Ziproxy_Dual
Ziproxy_Dual




Link: ziproxy.sourceforge.net

unoconv: umwandlung zwischen allen Dokument-Formaten von OpenOffice

Mit unoconv kann man viele Dokument-Formate konvertieren, unterstützte Formate sind unter anderem das  “Open Document Format” (.odt), “MS Word” (.doc), “MS Office Open/MS OOXML” (.xml), “Portable Document Format” (.pdf), “HTML”, “XHTML”, “RTF”, “Docbook” (.xml)…  

Funktionen:

  • konvertiert alle Formate die OpenOffice unterstützt
  • OpenOffice unterstützt bis zu 100 Dokument Formate :-)
  • kann genutzt werden um Vorgänge zu automatisieren (Skripte -> z.B. shell oder php)
  • unterstützt weitere Tools -> “asciidoc”, “docbook2odf/xhtml2odt”
  • kann Style-Vorlagen (templates) während der Konvertierung anwenden (corporate identity)
  • kann sowohl als Server, als auch als Client fungieren


Formate:

Es folgt eine Liste von Ausgabe-Formaten von OpenOffice (und somit auch von unoconv), die Eingabe-Formate können sich jedoch unterscheiden -> INPUT / EXPORT


Export:

  • bib – BibTeX [.bib]
  • doc – Microsoft Word 97/2000/XP [.doc]
  • doc6 – Microsoft Word 6.0 [.doc]
  • doc95 – Microsoft Word 95 [.doc]
  • docbook – DocBook [.xml]
  • html – HTML Document (OpenOffice.org Writer) [.html]
  • odt – Open Document Text [.odt]
  • ott – Open Document Text [.ott]
  • ooxml – Microsoft Office Open XML [.xml]
  • pdb – AportisDoc (Palm) [.pdb]
  • pdf – Portable Document Format [.pdf]
  • psw – Pocket Word [.psw]
  • rtf – Rich Text Format [.rtf]
  • latex – LaTeX 2e [.ltx]
  • sdw – StarWriter 5.0 [.sdw]
  • sdw4 – StarWriter 4.0 [.sdw]
  • sdw3 – StarWriter 3.0 [.sdw]
  • stw – Open Office.org 1.0 Text Document Template [.stw]
  • sxw – Open Office.org 1.0 Text Document [.sxw]
  • text – Text Encoded [.txt]
  • txt – Plain Text [.txt]
  • vor – StarWriter 5.0 Template [.vor]
  • vor4 – StarWriter 4.0 Template [.vor]
  • vor3 – StarWriter 3.0 Template [.vor]
  • xhtml – XHTML Document [.html]
  • […]


Installation:

aptitude install unoconv asciidoc docbook2od


Beispiele 1: Standard

Als erstes ein simples Beispiel, hier wird einfach “odt” in ein “pdf” umgewandelt. Sehr hilfreich ist auch sich die Optionen einmal anzuschauen.

# unoconv - Dienst starten
unoconv --listener &
# odt -> pdf 
unoconv -f pdf some-document.odt
# Standard 
(unoconv --server localhost --port 2002 --stdout -f pdf some-document.odt)

Beispiele 2: Vorlage

Wie bereits auf der Entwicklerseite zu lesen ist, hilf uns ein Screenshot nicht wirklich weiter, daher folgt ein zweites Beispiel mit Vorlagen.

# Beispiel Dateien herunterladen 
wget http://dag.wieers.com/cv/Makefile
wget http://dag.wieers.com/cv/curriculum-vitae-dag-wieers.txt
wget http://dag.wieers.com/cv/curriculum-vitae-docbook.ott

# unoconv - Dienst starten
unoconv --listener &
# resume.txt -> resume.xm
asciidoc -b docbook -d article -o resume.xml resume.txt
# resume.xml -> resume.tmp.odt
docbook2odf -f --params generate.meta=0 -o resume.tmp.odt resume.xml
# resume.tmp.odt -> resume.odt + Template
unoconv -f odt -t template.ott -o resume.odt resume.tmp.odt
# resume.tmp.odt -> resume.pdf + Template
unoconv -f pdf -t template.ott -o resume.pdf resume.odt
# resume.tmp.odt -> resume.html + Template
unoconv -f html -t template.ott -o resume.html resume.odt
# resume.tmp.odt -> resume.doc + Template
unoconv -f doc -t template.ott -o resume.doc resume.odt

Beispiele 3: Server <-> Client

Wie bereits erwähnt kann man den Dienst auch als Server starten und von anderen Rechnern darauf zugreifen.

# unoconv - Server-Dienst starten
unoconv --listener --server 1.2.3.4 --port 4567
# Client -> Server 
unoconv --server 1.2.3.4 --port 4567

Beispiele 4: PHP

Man kann dies nun auch in Shell-Skripten nutzen oder wie in diesem Beispiel in PHP einbinden.

$this->Filegenerator = new FilegeneratorComponent ($this->params["form"]['uploaddocfile']);
// if the filegenerator did all it's magic ok then process
if($this->Filegenerator)
// returns the text version of the PDF
$text = $this->Filegenerator->convertDocToTxt();
// returns the html of the PDF
$html = $this->Filegenerator->convertDocToHtml();
// returns the generated pdf file
$pdf = $this->Filegenerator->convertDocToPdf($doc_id);
}
<?php
/**
* Class Used to convert files.
*@author jamiescott.net
*/
class FilegeneratorComponent extends Object {

// input folder types
private $allowable_files = array ('application/msword' => 'doc' );
// variable set if the constuctor loaded correctly.
private $pass = false;
// store the file info from constuctor reference
private $fileinfo;

/**
* Enter description here...
*
* @param array $fileinfo
* Expected :
* (
[name] => test.doc
[type] => application/msword
[tmp_name] => /Applications/MAMP/tmp/php/php09PYNO
[error] => 0
[size] => 79360
)
*
*
* @return unknown
*/
function __construct($fileinfo) {

// folder to process all the files etc
define ( 'TMP_FOLDER', TMP . 'filegenerator/' . $this->generatefoldername () . '/' );

// where unoconv is installed
define ( 'UNOCONV_PATH', '/usr/bin/unoconv' );
// where to store pdf files
define ( 'PDFSTORE', ROOT . '/uploads/generatedpdfs/' );
// where to store doc files
define ( 'DOCSTORE', ROOT . '/uploads/docfiles/' );
// apache home dir
define ( 'APACHEHOME', '/home/apache' );
// set some shell enviroment vars
putenv ( "HOME=".APACHEHOME );
putenv ( "PWD=".APACHEHOME );

// check the file info is passed the tmp file is there and the correct file type is set
// and the tmp folder could be created
if (is_array ( $fileinfo ) &amp;amp;&amp;amp; file_exists ( $fileinfo ['tmp_name'] ) &amp;amp;&amp;amp; in_array ( $fileinfo ['type'], array_keys ( $this->allowable_files ) ) &amp;amp;&amp;amp; $this->createtmp ()) {

// bass by reference
$this->fileinfo = &amp;amp;$fileinfo;
// the constuctor ran ok
$this->pass = true;
// return true to the instantiation
return true;

} else {
// faild to instantiate
return false;

}

}

/**
*      * takes the file set in the constuctor and turns it into a pdf
* stores it in /uploads/docfiles and returns the filename
*
* @return filename if pdf was generated
*/
function convertDocToPdf($foldername=false) {

if ($this->pass) {

// generate a random name
$output_pdf_name = $this->generatefoldername () . '.pdf';

// move it to the tmp folder for processing
if (! copy ( $this->fileinfo ['tmp_name'], TMP_FOLDER . 'input.doc' ))
die ( 'Error copying the doc file' );

$command = UNOCONV_PATH;
$args = ' --server localhost --port 2002 --stdout -f pdf ' . TMP_FOLDER . 'input.doc';

$run = $command . $args;

//echo $run; die;
$pdf = shell_exec ( $run );
$end_of_line = strpos ( $pdf, "\n" );
$start_of_file = substr ( $pdf, 0, $end_of_line );

if (! eregi ( '%PDF', $start_of_file ))
die ( 'Error Generating the PDF file' );

if(!file_exists(PDFSTORE.$foldername)){
mkdir(PDFSTORE.$foldername);
}

// file saved
if(!$this->_createandsave($pdf, PDFSTORE.'/'.$foldername.'/', $output_pdf_name)){
die('Error Saving The PDF');
}

return $output_pdf_name;

}

}

/**
* Return a text version of the Doc
*
* @return unknown
*/
function convertDocToTxt() {

if ($this->pass) {

// move it to the tmp folder for processing
if (! copy ( $this->fileinfo ['tmp_name'], TMP_FOLDER . 'input.doc' ))
die ( 'Error copying the doc file' );

$command = UNOCONV_PATH;
$args = ' --server localhost --port 2002 --stdout -f txt ' . TMP_FOLDER . 'input.doc';

$run = $command . $args;

//echo $run; die;
$txt = shell_exec ( $run );

// guess that if there is less than this characters probably an error
if (strlen($txt) < 10)
die ( 'Error Generating the TXT' );

// return the txt from the PDF
return $txt;

}

}

/**
* Convert the do to heml and return the html
*
* @return unknown
*/
function convertDocToHtml() {

if ($this->pass) {

// move it to the tmp folder for processing
if (! copy ( $this->fileinfo ['tmp_name'], TMP_FOLDER . 'input.doc' ))
die ( 'Error copying the doc file' );

$command = UNOCONV_PATH;
$args = ' --server localhost --port 2002 --stdout -f html ' . TMP_FOLDER . 'input.doc';

$run = $command . $args;

//echo $run; die;
$html= shell_exec ( $run );
$end_of_line = strpos ( $html, "\n" );
$start_of_file = substr ( $html, 0, $end_of_line );

if (! eregi ( 'HTML', $start_of_file ))
die ( 'Error Generating the HTML' );

// return the txt from the PDF
return $html;

}

}
/**
* Create file and store data
*
* @param unknown_type $data
* @param unknown_type $location
* @return unknown
*/
function _createandsave($data, $location, $file) {

if (is_writable ( $location )) {

// In our example we're opening $filename in append mode.
// The file pointer is at the bottom of the file hence
// that's where $somecontent will go when we fwrite() it.
if (! $handle = fopen ( $location.$file, 'w' )) {
trigger_error("Cannot open file ($location$file)");
return false;
}

// Write $somecontent to our opened file.
if (fwrite ( $handle, $data ) === FALSE) {
trigger_error("Cannot write to file ($location$file)");
return false;
}

fclose ( $handle );
return true;

} else {
trigger_error("The file $location.$file is not writable");
return false;
}

}

function __destruct() {

// remove the tmp folder

if (file_exists ( TMP_FOLDER ) &amp;amp;&amp;amp; strlen ( TMP_FOLDER ) > 4)
$this->removetmp ();

}

/**
* Create the tmp directory to hold and process the files
*
* @return unknown
*/
function createtmp() {

if (is_writable ( TMP )) {

if (mkdir ( TMP_FOLDER ))
return true;

} else {

return false;
}

return false;

}

/**
* Delete the tmp dir
*
* @return unknown
*/
function removetmp() {

if (strlen ( TMP_FOLDER ) > 3 &amp;amp;&amp;amp; file_exists ( TMP_FOLDER )) {

if ($this->recursive_remove_directory ( TMP_FOLDER ))
return true;

}

return false;
}

/**
* Return a rendom string for the folder name
*
* @return unknown
*/
function generatefoldername() {

return md5 ( microtime () );

}

/**
* Recursivly delete directroy or empty it
*
* @param unknown_type $directory
* @param unknown_type $empty
* @return unknown
*/
function recursive_remove_directory($directory, $empty = FALSE) {
// if the path has a slash at the end we remove it here
if (substr ( $directory, - 1 ) == '/') {
$directory = substr ( $directory, 0, - 1 );
}

// if the path is not valid or is not a directory ...
if (! file_exists ( $directory ) || ! is_dir ( $directory )) {
// ... we return false and exit the function
return FALSE;

// ... if the path is not readable
} elseif (! is_readable ( $directory )) {
// ... we return false and exit the function
return FALSE;

// ... else if the path is readable
} else {

// we open the directory
$handle = opendir ( $directory );

// and scan through the items inside
while ( FALSE !== ($item = readdir ( $handle )) ) {
// if the filepointer is not the current directory
// or the parent directory
if ($item != '.' &amp;amp;&amp;amp; $item != '..') {
// we build the new path to delete
$path = $directory . '/' . $item;

// if the new path is a directory
if (is_dir ( $path )) {
// we call this function with the new path
recursive_remove_directory ( $path );

// if the new path is a file
} else {
// we remove the file
unlink ( $path );
}
}
}
// close the directory
closedir ( $handle );

// if the option to empty is not set to true
if ($empty == FALSE) {
// try to delete the now empty directory
if (! rmdir ( $directory )) {
// return false if not possible
return FALSE;
}
}
// return success
return TRUE;
}
}
}
?>

Droopy – Datenübertragung per HTTP

Das Python-Skript Droopy wird auf dem Zielrechner ausgeführt, so dass hier ein kleiner HTTP-Server gestartet wird, der eine einfache Seite mit Uploadformular enthält. Nun muss man nur noch dessen IP-Adresse zusammen mit der Portnummer in die Adresszeile des Browsers eingeben und kann Dateien verschicken (egal ob Windows, Mac, Linux …). Einzige Voraussetzung auf dem Zielrechner ist Python!


Download: droopy

wget http://stackp.online.fr/wp-content/uploads/droopy
mkdir uploads


Usage: droopy [options] [PORT]

Options:
  -h, --help                            show this help message and exit
  -m MESSAGE, --message=MESSAGE         set the message
  -p PICTURE, --picture=PICTURE         set the picture
  -d DIRECTORY, --directory=DIRECTORY   set the directory to upload files to
  --save-config                         save options in a configuration file
  --delete-config                       delete the configuration file and exit


Beispiel: droopy

python2 droopy -d uploads -m "Hi, schick mir doch mal ein paar Dateien... :-)" -p ~/Bilder/gemma-atkinson-108-06.jpg


droopy-Beispiel
droopy-Beispiel

bley – gewichtetes Greylisting + Cache

Auf der openrheinruhr.de habe ich gestern einen sehr interessanten Vortrag über Greylisting von Evgeni Golov gehört.


Ich selber hatte bis vor einigen Stunden noch eine Kombination aus Black- & Greylisting + SpamAssassin + ClamAV. Das Problem welches einige kennen ist, dass E-Mails dadurch ggf. verloren gehen oder zumindest verzögert werden, wenn ein “guter” Absender auf einer Blacklist kommt.

Das gewichtetet Greylisting erweitert das normale Greylisting um eine selektive Komponente, somit wenden nur auffällige Sender (welche in einer DNSBL (Blackliste) ist, nicht RFC-konformes EHLO übergibt etc…) werden gegreylisted. Das heißt, dass dem Absender mitgeteilt wird, dass momentan die E-Mail nicht zugestellt werden kann und er es gleich noch einmal versuchen soll, alle anderen werden durchgelassen. Spamer kommen jedoch (noch) nicht noch-einmal, um die selbe E-Mail ein zweites Mal zuzustellen.

Normalerweise werden bei “normalem” Greylisting unbekannten Absender direkt temporär abgewiesen und dessen Reaktion abgewartet. Bei dem “gewichtetem” (intelligentem) Greylisting wird der erste Zustellversuch zunächst analysiert. Anhand dieser Analyse wird entschieden, ob die E-Mail sofort angenommen werden soll oder ob Greylisting zum Einsatz kommt und die E-Mail somit mit einem temporären Fehler abgelehnt wird.


die Analyse:
  1. Absender hat bereits eine E-Mail erfolgreich zugestellt -> E-Mail sofort annehmen
  2. Absender in einer bekannten Whitelist -> E-Mail sofort annehmen
  3. Absender in einer bekannten Blacklist -> Greylisting
  4. Absender verwendet einen nicht standardkonformen Namen im SMTP-HELO, Absender kommt aus einem DialUp-Netzwerk etc… -> Greylisting
  5. SPF-Check (Sender Policy Framework) schlägt fehl -> Greylisting
  6. ansonsten -> E-Mail annehmen
Golov2009a.pdf (docs.google.com) -> S.42


Bley verwendet die Policy-Daemon-Schnittstelle des SMTP-Servers Postfix und ist somit leicht in existierende Umgebungen integrierbar bzw. “policyd-weight” zu ersetzen.
Als Vergleich wurde “bley” & “policyd-weight” auf einem Server mit ca 20.000 E-Mails/Tag getestet, dabei filterte policyd-weight 97,5% der E-Mails als Spam, bley 97%, der Vorteil von bley ist jedoch, dass E-Mails ggf. nicht Verzögert und nicht verloren gehen.
Für den praktischen Einsatz wird die Kombination von bley mit einer inhaltsbasierten Spam-Erkennung (z.B. SpamAssassin) vorgeschlagen. Dadurch, dass bley bereits die meisten Spam-Mails mit minimalem Rechenaufwand auf Protokollebene abweisen kann, müssen rechenaufwändige inhaltsbasierte Verfahren (z.B. SpamAssassin) nur noch auf eine sehr viel geringere Zahl von E-Mails angewendet werden.


Es folgt noch ein kurzes How-To: ;-)


Software nachinstallieren:

aptitude install python-setuptools python-twisted-core python-twisted-names python-spf python-psycopg2 postgresql python-pgsql

bley herunterladen und entpacken:

cd /usr/src
mkdir bley && cd bley
wget http://bley.mx/download/bley-0.1.4.tar.gz
tar xzvf bley-0.1.4.tar.gz
cd bley-0.1.4/

Datenbank anlegen:

su postgres
createuser bley
Enter password for new role: ********
Enter it again: ********
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

createdb --owner=bley bley

exit

bley installieren:

python setup.py build
python setup.py install

cp -vp build/scripts-2.6/bley /usr/bin/

Konfiguration anpassen (Datenbank -> Passwort):

vim /etc/bley/bley.conf

Autostart für bley anlegen:

vim /etc/init.d/bley
#! /bin/sh
### BEGIN INIT INFO
# Provides:          bley
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: bley initscript
# Description:       intelligent greylisting daemon for Postfix.
### END INIT INFO

# Author: Evgeni Golov <evgeni@debian.org>

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="intelligent greylisting daemon for Postfix"
NAME=bley
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
DAEMON_USER=$NAME
PIDFILE=/var/run/$NAME/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# Add pidfile to DAEMON_ARGS
DAEMON_ARGS="-p $PIDFILE $DAEMON_ARGS"

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started

	# prepare /var/run/bley which can be gone if /var/run is cleaned on reboot
	if [ ! -d /var/run/bley ]; then
		mkdir /var/run/bley
		chown bley:bley /var/run/bley
	fi

	# start bley
	start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON --test > /dev/null \
		|| return 1
	start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $DAEMON_USER --startas $DAEMON -- \
		$DAEMON_ARGS \
		|| return 2
	# Add code here, if necessary, that waits for the process to be ready
	# to handle requests from services started subsequently which depend
	# on this one.  As a last resort, sleep for some time.
}

#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
	RETVAL="$?"
	[ "$RETVAL" = 2 ] && return 2
	# Wait for children to finish too if this is a daemon that forks
	# and if the daemon is only ever run from this initscript.
	# If the above conditions are not satisfied then add some other code
	# that waits for the process to drop all resources that could be
	# needed by services started subsequently.  A last resort is to
	# sleep for some time.
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
	[ "$?" = 2 ] && return 2
	# Many daemons don't delete their pidfiles when they exit.
	rm -f $PIDFILE
	return "$RETVAL"
}

case "$1" in
  start)
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  status)
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
	log_daemon_msg "Restarting $DESC" "$NAME"
	do_stop
	case "$?" in
	  0|1)
		do_start
		case "$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # Old process is still running
			*) log_end_msg 1 ;; # Failed to start
		esac
		;;
	  *)
	  	# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
  *)
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
	exit 3
	;;
esac

:
chmod +x bley

update-rc.d bley defaults

User anlegen & Rechte setzen:

adduser --system --quiet --disabled-password --no-create-home --home "/var/run/bley" --gecos "intelligent greylisting daemon for Postfix" --group bley
chown root:bley /etc/bley
chmod 750 /etc/bley
chown bley:bley /etc/bley/bley.conf
chmod 600 /etc/bley/bley.conf
vim /etc/bley/bley.conf

log_file = /var/log/bley/bley.log

cd /var/log
mkdir bley
chown bley:bley bley/
mkdir /var/run/bley
chown bley:bley /var/run/bley
/etc/init.d/bley start

Postfix anpassen:

vim /etc/postfix/main.cf
smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        #reject_invalid_hostname,
        #reject_unknown_recipient_domain,
        #reject_unauth_pipelining,
        reject_unauth_destination,
        #reject_non_fqdn_hostname,
        #reject_non_fqdn_sender,
        #reject_non_fqdn_recipient,
        #reject_unknown_sender_domain,
        #reject_unknown_recipient_domain,
        #reject_unauth_pipelining,
        #reject_unauth_destination,
        #check_client_access hash:/etc/postfix/rbl_override,
        check_policy_service inet:127.0.0.1:1337,
        ##check_policy_service inet:127.0.0.1:12525,
        #reject_rbl_client multi.uribl.com,
        #reject_rbl_client dsn.rfc-ignorant.org,
        ##reject_rbl_client dul.dnsbl.sorbs.net,
        #reject_rbl_client list.dsbl.org,
        #reject_rbl_client sbl-xbl.spamhaus.org,
        #reject_rbl_client bl.spamcop.net,
        ##reject_rbl_client dnsbl.sorbs.net,
        #reject_rbl_client cbl.abuseat.org,
        ##reject_rbl_client ix.dnsbl.manitu.net,
        #reject_rbl_client combined.rbl.msrbl.net,
        #reject_rbl_client rabl.nuclearelephant.com,
        permit

Linux-Server analysieren

Dieser Blog-Post ist als Antwort auf die Frage “Nun würde mich mal interessieren, welche Tools euch zum Administrieren eines Linux Servers helfen und speziell auch welchen Taskmanager ihr verwendet.”, aus dem folgendem Blog gedacht. -> infoblog.li/besserer-taskmanager-fuer-den-linux-server-htop/

 

1.) Überblick verschaffen

Wenn man nicht genau weiß, wo das Problem liegt, muss man sich erst-einmal einen groben Überblick über die Situation verschaffen, dabei helfen die folgenden Befehle:

 

1.1) top – CPU- und Arbeitsspeicher-Auslastung analysieren

top

Es folgen einige wichtige Tastenkürzel:

1 -> zeigt die Auslastung der einzelnen CPUs an
b / B -> hebt die aktiven Prozesse hervor
z -> wie “b oder B” nur mit Farbe ;-)
i -> zeigt nur aktive Prozesse an
M -> zeigt die Prozesse sortiert nach dem Speicherverbrauch an
P -> zeigt die Prozesse sortiert nach der CPU-Last an
d -> gibt die Aktualisierungszeit an
k -> kill – tötet einen Prozess

(alternativ kann man sich auch mal “htop” anschauen)

 

1.2) df / du – Festplattenverbrauch analysieren

df -h

-h -> auch für Menschen lesbar (–human-readable)

df -h
df -h

 

Wenn wir den Speicherverbrauch nun weiter analysieren müssen, weil z.B. ein Verzeichnis unter /var zu groß ist, können wir dies mit “du” machen.

du -h | grep "^[0-9,]*[MG]" | sort -hr | less

 

Erklärung: “du” gibt die Größe von Dateien und Verzeichnissen aus “-h” zeigt dies leserlich an, “|” der Pipe leitet die Ausgabe weiter, “grep” ist universal einsetzbar, um etwas (Dateien / Ausgaben…) zu durchsuchen und wir suchen alle Zeilen, in denen “^” am Anfang eine Zahl  “0 1 2 3 4 5 6 7 8 9” oder / und “,” in beliebiger Häufigkeit “*” gefolgt von einem großen “M” oder einem “G”. Diese Ausgabe wird per Pipe “|” an “sort” weitergegeben, wo diese Ausgabe nach sortiert wird und “|” schließlich mit “less” angezeigt wird. (mit q kann man less wieder beenden) Wer mehr über Reguläre Ausdrücken lernen möchte, kann sich dies hier antun ;-) -> http://linuxwiki.de/

Wer will kann dich solche “Funktionen” einfach in die .bashrc eintragen…

alias du_suckup='du -h | grep "^[0-9,]*[MG]" | sort -hr | less'

 

1.3) iotop – Festplattenauslastung  analysieren

iotop

Der Befehl “iotop” kann die aktuellen I/O Transferraten für die laufenden Prozesse/Threads anzeigen und greift dazu direkt auf die Informationen vom Kernel zu ( >= v2.6.20 ).

Es folgen wieder einige wichtige Tastenkürzel:

Pfeiltasten – link & rechte -> ändern die Sortierung der Ausgabe, je nach Kategorie
r -> dreht die Sortierung um (reverse)
o -> Zeigt nur noch Prozesse/Threads an, welche auch I/O-Last produzieren
p-> zeigt nur noch Prozesse an (keine Threads )
a -> zeigt nicht mehr die Last in Sekunden an, sondern addiert die I/O fortlaufen (solange iotop läuft)

1.4) lsof – Beziehung zwischen Dateien & Prozessen analysieren

Der Befehl “lsof” kann eingesetzt werden, um z.B. zu analysieren, welcher Prozess oder Anwender momentan eine bestimmte Datei verwendet oder auch welcher User, welchen Port offen hält + die dazugehörige PID (ProzessID)…

lsof -a -i -u www-data

 

lsof - Beispiel
lsof – Beispiel

 

Wer mehr zu dem Thema erfahren möchte, kann in einen alten Blog-Beitrag weiter lesen -> suckup.de/blog/2010/02/22/lsof-list-open-files


2.) Prozesse analysieren

Hier verweise ich einfach mal auf zwei alte Blog-Beiträge.:

2.1) der Befehl “ps”, um bestimmte Prozesse aufzuspüren -> suckup.de/blog/2010/09/14/shell-ps-prozessstatus

2.2) und noch einige Programm, um den verbrauchten Arbeitsspeicher zu analysieren -> suckup.de/blog/2010/02/08/speicherverbrauch-anzeigen-lassen

 

3.) Hardware analysieren

Auch hier verweise ich auf einen alten Beitrag.:

3.1) hier noch eine Sammlung von Befehlen mit denen man z.B. die Festplatte auf Fehler prüfen kann ->  http://suckup.de/blog/2010/02/08/systeminfos-anzeigen-lassen/

 

4.) Netzwerk analysieren

Und auch hier verweise ich auf ein paar alte Beiträge.:

4.1) mit “TCPdump” kannst du den Netztraffik analysieren (sniffen) ähnlich wie Wireshark, nur auf der Konsole. :-) -> suckup.de/blog/2010/08/02/tcpdump-howto

4.2) offene Ports analysieren mit “nmap” + “fuser” -> suckup.de/blog/2010/03/28/offene-ports-analysieren

 

weitere Schritte

Mit Hilfe dieser Befehl sollte man einige Problem bereits eingrenzen können, ich würde parallel unter /var/log/ nachschauen, ob irgendetwas auffälliges in den Logfiles steht …

ls -altr /var/log/

-> Dateien rekursiv nach ihrer letzten Änderung anzeigen (neuste Datei steht nun unten)

tail -f test.log

-> das Logfile wird nun kontinuierlich mit-gelesen, so dass man neu auftretende Fehler bemerkt

Backup to USB-Stick per udev


Udev-tux“udev überwacht und wertet hotplug-Ereignisse aus. Finden sich dort Informationen über ein neu angeschlossenes Gerät, werden zusätzliche zu diesem Gerät vorhandene Informationen dem sysfs-Dateisystem entnommen und eine neue Gerätedatei im /dev-Verzeichnis erzeugt. Dabei ist der für die spezielle Datei verwendete Name und die Zugriffsberechtigung frei durch Regeln konfigurierbar.” – wiki


Wir möchten ein Backup auf unseren USB-Stick durchführen, sobald wir diesen mit dem PC verbinden! Dafür müssen wir als erstes einige Infos sammeln, somit schauen wir uns folgnde Datei zeitgleich zum einstecken des USB-Speichers an.


tail -f /var/log/messages

Ausgabe:

Nov  2 22:10:30 suckup-netbook kernel: [13570.309562] scsi 5:0:0:0: Direct-Access     USB 2.0  Flash Drive      8.07 PQ: 0 ANSI: 2

Nov  2 22:10:30 suckup-netbook kernel: [13570.320160] sd 5:0:0:0: Attached scsi generic sg2 type 0

Nov  2 22:10:30 suckup-netbook kernel: [13570.338740] sd 5:0:0:0: [sdc] 3938304 512-byte logical blocks: (2.01 GB/1.87 GiB)

Nov  2 22:10:30 suckup-netbook kernel: [13570.339345] sd 5:0:0:0: [sdc] Write Protect is off

Nov  2 22:10:31 suckup-netbook kernel: [13570.342397]  sdc:

Nov  2 22:10:31 suckup-netbook kernel: [13570.778378] sd 5:0:0:0: [sdc] Attached SCSI removable disk

Somit wissen wir schon einmal, wo sich der Speicher befindet… mit dem folgendem Befehl können wir uns nun alle Partitionen anschauen….
cat /proc/partitions

… und ggf. mit dem nächsten Befehl eine neue Partition anlegen.

fdisk /dev/sda


Als nächstes wollen wir nun die spezifischen Infos vom USB-Stick abfragen:

udevadm info -a -p $(udevadm info -q path -n /dev/sdc)

Ausgabe:

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb1/1-3’:

KERNELS==”1-3″

SUBSYSTEMS==”usb”

DRIVERS==”usb”

[…]

ATTRS{idVendor}==”058f”

ATTRS{idProduct}==”6387″

[…]

ATTRS{manufacturer}==”Generic”

ATTRS{product}==”Mass Storage”

ATTRS{serial}==”9D853A1BCAC440404FEF”

Um das Gerät (USB-Stick) eindeutig zu identifizieren benötigen wir nun die folgenden Angaben: “idVendor”, “idProduct” und “serial”


sudo vim /etc/udev/rules.d/80-backup-stick.rules

KERNEL==”sd?”, ATTRS{idVendor}==”058f“, ATTRS{idProduct}==”6387“, ATTRS{serial}==”9D853A1BCAC440404FEF“, SYMLINK+=”backup-stick“, RUN+=”/home/lars/bin/bash/backup-stick.shBackup‘ ‘to_Stick'”

  • ggf. Partition mit angeben: sd?1
  • RUN+= -> muss der Pfad zu deinem Skript sein
  • idProdukt u.s.w. muss natürlich noch mit den Werten von deinem Stick angepasst werden
sudo /etc/init.d/udev restart


Als nächstes müssen wir ein Skript erstellen, welches auf einem User-Desktop per root eine Pop-Up erzeugen kann…

sudo vim /usr/local/bin/root-notify-send
#!/bin/sh
user=`whoami`
pids=`pgrep -u $user gnome-panel`
title=$1
text=$2
timeout=$3
icon=$4

if [ -z "$title" ]; then
 echo You need to give me a title >&2
 exit 1
fi
if [ -z "$text" ]; then
 text=$title
fi
if [ -z "$timeout" ]; then
 timeout=60000
fi

for pid in $pids; do
 DBUS_SESSION_BUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS \
 /proc/$pid/environ | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//'`

 if [ -z $icon ]; then
 DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \
 notify-send -u low -t $timeout "$title" "$text"
 else
 DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \
 notify-send -u low -t $timeout -i "$icon" "$title" "$text"
 fi
done
sudo chmod +x /usr/local/bin/root-notify-send


vim ~/bin/bash/backup-stick.sh
#!/bin/bash

su lars -c "/bin/bash root-notify-send "$1" "$2" 6000 "/home/lars/Bilder/backup.png""
mount /dev/backupstick /media/backupstick
su lars -c "/usr/bin/rsync -rlptgzu --delete-after  /home/lars/bin/ /media/backupstick"
umount /media/backupstick

An dieser Stelle macht sich natürlich ein Bild vom Stick besondes gut. ;-) Dann noch schnell ggf. einige Programme nach-installieren, ein Verzeichnis anlegen und Rechte ändern, fertig!

chmod +x ~/bin/bash/backup-stick.sh
sudo aptitude install libnotify-bin rsync
sudo mkdir /media/backupstick




Backup to Stick
Backup to Stick


Nginx + Varnish auf Debian/Ubuntu

Zurück zur “Webseiten beschleunigen” – Übersicht

5.4) Nginx mit Varnish


“Varnish ist ein Web-Beschleuniger für dynamische Web-Seiten mit viel Inhalt. Im Gegensatz zu anderen Web-Beschleunigern, die häufig aus clientseitigen Proxies oder aus Servern entstanden, wurde Varnish von Grund auf als Web-Beschleuniger konzipiert.” – Wiki


Als erstes erweitern wir unsere sources.list, so dass wir die Varnish-Software einfach installieren / updaten können:


Ubuntu:

echo "http://repo.varnish-cache.org/ubuntu/ lucid varnish-2.1" >> /etc/apt/sources.list


Debian:

echo "deb http://repo.varnish-cache.org/debian/ lenny varnish-2.1" >> /etc/apt/sources.list


Nun installieren wir Varnish…

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
aptitude install varnish


Nun müssen wir einige Eistellungen an Varnish vornehmen, so dass dieser als erstes angesprochen wird…

vim /etc/default/varnish
# Configuration file for varnish
#
# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
# to be set from this shell script fragment.
#

# Should we start varnishd at boot?  Set to "yes" to enable.
START=yes

# Maximum number of open files (for ulimit -n)
NFILES=131072

# Maximum locked memory size (for ulimit -l)
# Used for locking the shared memory log in memory.  If you increase log size,
# you need to increase this number as well
MEMLOCK=82000

# Default varnish instance name is the local nodename.  Can be overridden with
# the -n switch, to have more instances on a single server.
INSTANCE=$(uname -n)

## Configuration with VCL
#
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"

## TEST
#
#DAEMON_OPTS="-a :80 \
#             -T localhost:6082 \
#             -f /etc/varnish/default.vcl \
#             -s malloc,512M \
#             -p lru_interval=3600 \
#             -p thread_pool_max=2000 \
#             -p listen_depth=2048 \
#             -p 'cc_command=exec cc -fpic -shared -Wl,-x -L/usr/include/libmemcached/memcached.h -lmemcached -o %o %s' \
#             -h classic,500009 \
#             -t 0"

## Alternative 3, Advanced configuration
#
# See varnishd(1) for more information.
#
# # Main configuration file. You probably want to change it :)
# VARNISH_VCL_CONF=/etc/varnish/default.vcl
#
# # Default address and port to bind to
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=
# VARNISH_LISTEN_PORT=6081

#
# # Telnet admin interface listen address and port
# VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
# VARNISH_ADMIN_LISTEN_PORT=6082
#
# # The minimum number of worker threads to start
# VARNISH_MIN_THREADS=1
#
# # The Maximum number of worker threads to start
# VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
# VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
# VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
# VARNISH_STORAGE_SIZE=1G
#
# # File containing administration secret
# VARNISH_SECRET_FILE=/etc/varnish/secret
#
# # Backend storage specification
# VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one
# VARNISH_TTL=120
#
# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
# # sure you update this section, too.
# DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
#              -f ${VARNISH_VCL_CONF} \
#              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
#              -t ${VARNISH_TTL} \
#              -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
#              -S ${VARNISH_SECRET_FILE} \
#              -s ${VARNISH_STORAGE}"
#


Nun muss du die Konfig anpassen, ich zeige hier ein Beispiel für meinen WordPress Blog… ggf. musst du für deine Webseiten jedoch noch weitere Einstellungen ändern.


vim /etc/varnish/default.vcl
backend default {
        .host = "127.0.0.1";
        .port = "8080";
}

acl purge {
        "localhost";
}

sub vcl_fetch {
        set beresp.ttl = 12h;
        set req.grace = 24h;
        if (req.url ~ "wp-(login|admin)") {
                return (pass);
        }
        if (req.url ~ "feed") {
                return (pass);
        }
        return (deliver);
        unset beresp.http.set-cookie;
        if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|txt|gz|zip|rar|bz2|tgz|tbz|html|htm|pdf|pls|torrent)$") {
                set beresp.ttl = 48h;
        }

        remove req.http.X-Forwarded-For;
        set    req.http.X-Forwarded-For = req.http.rlnclientipaddr;
        if (req.url ~ "^/w00tw00t") {
                error 403 "Not permitted";
        }
        return(deliver);
}

sub vcl_deliver {
        if (obj.hits > 0) {
                set resp.http.X-Cache = "HIT";
                set resp.http.X-Cache-Hits = obj.hits;
        } else {
                set resp.http.X-Cache = "MISS";
        }
        remove resp.http.X-Varnish;
        remove resp.http.Via;
        remove resp.http.Age;
        remove resp.http.X-Powered-By;
}

sub vcl_recv {
        set req.grace = 6h;
        if (req.request == "PURGE") {
                if(!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                purge("req.url ~ ^" req.url "$ && req.http.host == "req.http.host);
        }
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
                remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
                set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
                set req.http.Accept-Encoding = "deflate";
        } else {
                remove req.http.Accept-Encoding;
        }
        if( req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ) {
                return (pass);
        }
        if (!(req.url ~ "wp-(login|admin)")) {
                unset req.http.cookie;
        }
        if (req.request != "GET" &&
                req.request != "HEAD" &&
                req.request != "PUT" &&
                req.request != "POST" &&
                req.request != "TRACE" &&
                req.request != "OPTIONS" &&
                req.request != "DELETE") {
                return (pipe);
        }
        if (req.request != "GET" && req.request != "HEAD") {
                return (pass);
        }
        if (req.http.Authorization || req.http.Cookie) {
                return (pass);
        }
        if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|txt|gz|zip|rar|bz2|tgz|tbz|html|htm|pdf|pls|torrent)(\?.*|)$") {
                unset req.http.Authenticate;
                unset req.http.POSTDATA;
                set req.request = "GET";
                set req.url = regsub(req.url, "\?.*$", "");
                return (lookup);
        }
        unset req.http.cookie;
        return (lookup);
}

sub vcl_pipe {
        set bereq.http.connection = "close";
        if (req.http.X-Forwarded-For) {
                set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
        } else {
                set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
        }
}

sub vcl_pass {
        set bereq.http.connection = "close";
        if (req.http.X-Forwarded-For) {
                set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
        } else {
                set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
        }
}


Parallel müssen wir nun unseren Webserver, egal ob Apache oder in diesem Fall Nginx, auf den Port 8080 lauschen lassen.  Beim Nginx ist dies relativ simpel, du muss nur “listen 80” -> “listen 8080” ändern. Ich zeige an dieser Stelle jedoch einmal meine Nginx-Konfiguration für meinen WordPress Blog.

[stextbox id=”warning”]Wie immer gilt, erst verstehen, dann kopieren… :-)[/stextbox]

server {
        listen 8080;
        server_name suckup.de www.suckup.de blog.voku-online.de linux.voku-online.de windows.voku-online.de ubuntu.voku-online.de allgemein.voku-online.de cdn1.voku-online.de cdn2.voku-online.de cdn3.voku-online.de cdn4.voku-online.de cdn5.voku-online.de *.suckup.de;
        root /var/www/www.suckup.de/web/;
        index index.php;
        access_log /var/log/nginx/suckup.access.log main;
        error_log /var/log/nginx/suckup.error.log;
        log_not_found on;

        ## Cache - testen
        open_file_cache max=2500 inactive=24h;
        open_file_cache_valid    24h;
        open_file_cache_min_uses 2;
        open_file_cache_errors   on;

        location ~* ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)(\?[0-9]+)?$ {
                root /var/www/www.suckup.de/web/;
                access_log off;
                expires max;
                break;
        }

        ## Optimierung - "(css/js).php" to "(css/js)"
        location /wp-content/plugins/wp-special-textboxes/css/ {
                location ~* \.(css.php)$ {
                        if ($args ~* ver=(.*)$) {
                                rewrite ^ $scheme://$host/wp-content/cache/wp-special-textboxes.css? permanent;
                        }
                }
        }
        location /wp-content/plugins/wp-special-textboxes/js/ {
                location ~* \.(js.php)$ {
                        if ($args ~* ver=(.*)$) {
                                rewrite ^ $scheme://$host/wp-content/cache/wstb.js? permanent;
                        }
                }
        }
        if ($args ~* ver=3.0.1$) {
                rewrite ^ $scheme://$host/wp-content/cache/wp-special-textboxes.css? permanent;
        }

        if (-f $request_filename) {
                break;
        }
        if (!-e $request_filename) {
                rewrite ^(.+)$ /index.php?q=$1 last;
        }

        # -----------------------------------------
        # http://wiki.nginx.org/Wordpress

        ## remove any multislashes //
        if ($request_uri ~* "\/\/") {
                rewrite ^/(.*) $scheme://$host/$1 permanent;
        }

        ## Slash am Ende anfuegen ?!?
        #if ($request_uri ~* "^[\w\-\/]+[^\/?]$") {
                #rewrite ^(.*)$ $scheme://$host$1/ permanent;
        #}

        ## www eifuegen
        #if ($host !~* ^(www|subdomain)) {
                #rewrite ^/(.*)$ $scheme://www.$host/$1 permanent;
        #}

        ## www vorne entfernen
        if ($host ~* ^www\.(.*)) {
                set $host_without_www $1;
                rewrite ^(.*)$ http://$host_without_www$1 permanent;
        }

        ## immer SSL verwenden
        #rewrite ^(.*) https://$server_name$1 permanent;

        ## immer HTTP verwenden
        #rewrite ^(.*) http://$server_name$1 permanent;

        ## Feedburner
        rewrite ^/e107_plugins/rss_menu/rss.php?(.*)$ http://suckup.de/feed/ last;
        if ($http_user_agent !~ (FeedBurner|Googlebot)) {
                rewrite ^/feed/?$ http://feeds.feedburner.com/suckup last;
                break;
        }

        ## WordPress3
        #if (!-e $request_filename) {
                #rewrite ^(.+)$ /index.php?q=$1 last;
                #break;
        #}

        ## WordPress3 MU
        #if (!-e $request_filename) {
                #rewrite ^.+/?(/wp-.*) $1 last;
                #rewrite ^.+/?(/.*\.php)$ $1 last;
                #rewrite ^(.+)$ /index.php?q=$1 last;
                #break;
        #}

        ## WordPress3 Multi-Domain
        rewrite ^.*/files/(.*)$ /wp-includes/ms-files.php?file=$1 last;
        if (!-e $request_filename) {
                rewrite ^.+/?(/ms-.*) $1 last;
                rewrite ^/files/(.+) /wp-includes/ms-files.php?file=$1 last;
                rewrite ^.+/?(/wp-.*) $1 last;
                rewrite ^.+/?(/.*.php)$ $1 last;
                rewrite ^(.+)$ /index.php?q=$1 last;
                break;
        }
        location ~* ^.+.(htm|html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)(\?[0-9]+)?$ {
                access_log off;
                expires max;
                root /var/www/www.suckup.de/web/;
                rewrite ^/.(/wp-.*/.*.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))(\?[0-9]+)?$ $1 last;
                break;
                rewrite ^.*/files/(.*(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))(\?[0-9]+)?$ /wp-includes/ms-files.php?file=$1 last;
                break;
                if (!-e $request_filename) {
                        rewrite ^.+/?(/wp-.*) $1 last;
                        rewrite ^.+/?(/.*.php)$ $1 last;
                        rewrite ^(.+)$ /index.php?q=$1 last;
                        break;
                }
        }

        ## WordPress-Forum
        if (!-e $request_filename) {
                rewrite ^/forums/topic/(.*)$ /forums/topic.php?q=$1 last;
                rewrite ^/forums/forum/(.*)$ /forums/forum.php?q=$1 last;
                rewrite ^/forums/profile/(.*)$ /forums/profile.php?q=$1 last;
                rewrite ^/forums/view/(.*)$ /forums/view.php?q=$1 last;
                rewrite ^/forums/tags/(.*)$ /forums/tags.php?q=$1 last;
                rewrite ^/forums/rss/(.*)$ /forums/rss.php?q=$1 last;
                rewrite ^/forums/bb-admin/ /forums/bb-admin/index.php last;
                rewrite ^/forums/ /forums/index.php last;
                break;
        }

        ## WordPress W3 Total Cache
        set $totalcache_file '';
        set $totalcache_uri $request_uri;
        if ($request_method = POST) {
                set $totalcache_uri '';
        }
        if ($query_string) {
                set $totalcache_uri '';
        }
        if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
                set $totalcache_uri '';
        }
        if ($totalcache_uri ~ ^(.+)$) {
                set $totalcache_file /wp-content/w3tc-suckup.de/pgcache/$1/_default_.html.gzip;
        }
        if (-f $document_root$totalcache_file) {
                rewrite ^(.*)$ $totalcache_file break;
        }

        ## WordPress SuperCache
        #set $supercache_file '';
        #set $supercache_uri $request_uri;
        #if ($request_method = POST) {
                #set $supercache_uri '';
        #}
        #if ($query_string) {
                #set $supercache_uri '';
        #}
        #if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
                #set $supercache_uri '';
        #}
        #if ($supercache_uri ~ ^(.+)$) {
                #set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
        #}
        #if (-f $document_root$supercache_file) {
                #rewrite ^(.*)$ $supercache_file break;
        #}

        #if (!-e $request_filename) {
                #rewrite . /index.php last;
        #}

        # -----------------------------------------

        ## memchached test
        #location / {
                #default_type text/html;
                #add_header "Content" "text/html; charset=utf8";
                #charset utf-8;
                #set $memcached_key $uri;
                #memcached_pass 127.0.0.1:11211;
                #error_page 500 404 405 = @fallback;
        #}
        #location @fallback {
                #try_files $uri $uri/ @suckup;
        #}

        location / {
                try_files $uri $uri/ @suckup;
                sub_filter suckup.de:8080
                'suckup.de:80';
                sub_filter_once on;
        }

        location @suckup {
                include /etc/nginx/fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root/index.php;
                fastcgi_param QUERY_STRING q=$uri&$args;
                fastcgi_param SCRIPT_NAME /index.php;
                fastcgi_pass 127.0.0.1:11000;
        }

        location ~ \.php$ {
                try_files $uri @suckup;
                ## memchached test
                #set $memcached_key $uri;
                #memcached_pass  127.0.0.1:11211;
                fastcgi_index index.php;
                fastcgi_pass 127.0.0.1:11000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;
        }

        ## .htaccess & .htpassword sperren
        location ~ /\.ht {
                deny  all;
        }
}

Debian Backports

In der Debian-Distribution werden bekanntlich nur getestete Pakete verwendet und in einer Version (z.B. Debian-Version 5, “Lenny”) nur wichtige Korrekturen durchgeführt, aber keine weiteren Versionssprünge vorgenommen. Wenn ich nun eine neuere Version von einer bestimmten Software nutzen wollte, habe ich bisher auf backports.orgzurückgegriffen, seit zirka einem Monat gehört das Projekt nun offiziell zum Debian-Service und ist unter “packports.debian.orgzu erreichen. Die Quellen heißen deshalb “backport”, da diese aus dem Debian-Testing-Zweig (momentan Debian-Version 6, “Squeeze”) zurück portiert wurden. Das Paket “debian-backports-keyring” wird nun nicht mehr benötigt, da die Pakete nun mit den offiziellen Key von Debian unterzeichnet sind.

 

“Da sich die Adresse von backports.org zu backports.debian.org ändert, sollten alle Benutzer, um Überraschungen zu vermeiden, ihre Repositorien in sources.list so bald wie möglich anpassen. Die alte Adresse wird allerdings als Spiegel des Archivs noch für einige Zeit erhalten bleiben. Wer Pinning mit Backports-Paketen nutzt, sollte seine Einstellungen in der Datei preferences bald anpassen, da sich der Archivname in »Debian Backports« geändert hat.” – Pro-Linux.de

 

Wenn nun jedoch in im Testing-Zweig keine neue Software aufgenommen wird, wie es momentan der Fall ist und der Testing-Zweig somit eingefroren wird, um diesen auf die Stabilen-Zweig zu bringen, dann benötigt man ggf. auch noch die Quelle “lenny-backports-sloppy“. Somit kannst du bereits Software aus der Unstable-Version (Debian-Version 7, “Wheezy) verwenden, wenn du jedoch auf die kommende stabile Version “Squeeze” aktualisieren möchtest, dann benötigst du zwingend die zugehörigen Backports, zudem ist diese Quellen stets mit dem packports zu verwenden.

 

1.) Folgende Zeilen einfügen:

Entweder direkt in der “/etc/apt/sources.list”-Datei oder du musst im folgendem Unterverzeichnis (/etc/apt/sources.list.d/) eine Datei mit der Endung (.list) anlegen und dort die folgenden Zeilen einfühen.

deb http://backports.debian.org/debian-backports lenny-backports main
deb http://backports.debian.org/debian-backports lenny-backports-sloppy main

2.) Quellen aktualisieren

 

apt-get update

3.) Folgende Zeilen einfügen:

In der “/etc/apt/preferences”-Datei folgendes Einfügen, so dass du auch mit Sicherheit-Updates versorgt wirst.

 

Package: *
Pin: release a=lenny-backports
Pin-Priority: 200

4.) Pakete installieren

Mit dem folgendem Befehl kannst du nun, aus dem Backports Software installieren, hier gibt es noch mehr Infos zu aptitude. ;-)

 

aptitude -t lenny-backports install "package"

 

LibreOffice Installation unter Debian / Ubuntu

In diesem HowTo beschreibe ich wie du LibreOffice auf Debian/Ubuntu installierst. Kurz zum Hintergrund, warum OpenOffice zu -> LibreOffice wurde:

Gegründet wurde die Stiftung von verschiedenen Mitgliedern von OpenOffice.org. Auf der Webseite von “The Dokument Foundation” findet sich einer Liste der Gründungsmitglieder, diese haben diesen Schritt gewagt, da seit der Übernahmen von Sun durch Oracle nur noch wenige Ressourcen aus der Hamburger Entwicklungsabteilung ins Projekt eingeflossen seien. (Quelle: heise.de) Nun haben auch schon einige Firmen (GoogleNovell und Red Hat) angekündigt die neue Foundation zu unterstützen. Wer diesbezüglich noch mehr Infos sucht, kann sich folgenden Artikel durchlesen -> ikhaya.ubuntuusers.de


“Eine Abspaltung (auch Fork; engl. fork = Gabel, üblicherweise als Maskulinum verwendet) ist in der Softwareentwicklung ein Entwicklungszweig nach der Aufspaltung eines Projektes in zwei oder mehr Folgeprojekte, wobei Teile des Quellcodes und seiner Historie kopiert werden und dann unabhängig von dem ursprünglichen Projekt weiterentwickelt werden.” – Wiki


libreoffice


libreoffice-menü


Installation unter Ubuntu:




[stextbox id=”warning”]Fremdpakete können das System beschädigen -> wiki.ubuntuusers.de/fremdquellen[/stextbox]


sudo add-apt-repository ppa:libreoffice/ppa
sudo apt-get update
sudo apt-get install libreoffice
Gnome:
sudo apt-get install libreoffice-gnome
KDE:
sudo apt-get install libreoffice-kde


ggf. findest du hier noch weitere Infos …



Installation unter Debian:


[stextbox id=”warning”]Fremdpakete können das System beschädigen[/stextbox]


1.) Deinstallation von OpenOffice

sudo aptitude purge openoffice.org-base openoffice.org-base-core openoffice.org-common openoffice.org-gnome


Zwei mal mit “Y” bestätigen…

– Diese Lösung akzeptieren? [Y/n/q/?] Y

– Wollen Sie fortsetzen? [Y/n/?] Y

… und schon wird OpenOffice deinstalliert.


2.) LibreOffice (+deutsche Sprachdatei) herunterladen

Darauf achten, ob man die 32-Bit oder die 64-Bit Version herunterlädt.


32-Bit:
cd /tmp
wget http://ftp5.gwdg.de/pub/tdf/libreoffice/stable/3.3.0/deb/x86/LibO_3.3.0_Linux_x86_install-deb_en-US.tar.gz
wget http://ftp5.gwdg.de/pub/tdf/libreoffice/stable/3.3.0/deb/x86/LibO_3.3.0_Linux_x86_langpack-deb_de.tar.gz
64-Bit:
cd /tmp
wget http://download.documentfoundation.org/libreoffice/stable/3.3.0/deb/x86_64/LibO_3.3.0_Linux_x86-64_install-deb_en-US.tar.gz
wget http://download.documentfoundation.org/libreoffice/stable/3.3.0/deb/x86_64/LibO_3.3.0_Linux_x86-64_langpack-deb_de.tar.gz


3.) Datei entpacken

tar -xzvf LibO_3.3.0_Linux_x86_install-deb_en-US.tar.gz
tar -xzvf LibO_3.3.0_Linux_x86_langpack-deb_de.tar.gz


4.) Update LibreOffice

Falls bereits eine frühere Version von LibreOffice installiert ist, kannst du diese mit diesem Skript aktualisieren.

cd en-US
sudo ./update


5.) Installation von LibreOffice

cd DEBS
sudo dpkg -i *.deb
sudo dpkg -i desktop-integration/*menus*.deb

cd /tmp/DE/DEBS
sudo dpkg -i *.deb