We all change, when you think about it. We're all different people all through our lives. And that's OK, that's good, you've got to keep moving, so long as you remember all the people that you used to be.

The Doctor

Note to self:

Nur Dateirechte zurücksetzen

Wenn man per chmod die Permissions der Dateien geändert hat, zeigt einem GIT diese Änderungen an. Wenn man das nicht will, kann man per

git config core.fileMode false

oder global per

git config --global core.fileMode false

diese Änderungen ignorieren. Wenn man aber die Dateirechte schon geändert hat, und dies nun zurücksetzen will, kann man dies mit diesem Einzeiler:

git diff -p \
    | grep -E '^(diff|old mode|new mode)' \
    | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
    | git apply

Dies kann man auch als alias für git anlegen, dann muss man sich das nicht alles merken ;)

git config --global --add alias.permission-reset '!git diff -p | grep -E "^(diff|old mode|new mode)" | sed -e "s/^old/NEW/;s/^new/old/;s/^NEW/new/" | git apply'

Ab jetzt kann man per git permission-reset die Dateisystemrechte wieder zurücksetzen.

Quelle

Wann greifen eigentlich welche restrictions im Postfix, und was schreibt man da so rein um das meiste an Spam direkt zu blocken, bevor es überhaupt in die Mailbox kommt?

Die restrictions, die ich so nutze sind die folgenden:

  • smtp_client_restrictions
  • smtp_helo_restrictions
  • smtp_sender_restrictions
  • smtp_recipient_restrictions
  • smtp_data_restrictions

Damit man sich das besser vorstellen kann, wann eine solche Regel greift, hier mal eine Beispielsession:

> 220 mail.example.org ESMTP              # smtp_client_restrictions
< EHLO example.net                        # smtp_helo_restrictions
> 250-example.org Hello example.net
> 250 AUTH CRAM-MD5 LOGIN PLAIN
< AUTH LOGIN
> 334 VXNlcm5hbWU6
< aGFucw==
> 334 UGFzc3dvcmQ6
< c2Nobml0emVsbWl0a2FydG9mZmVsc2FsYXQ=
> 235 ok
< MAIL FROM:<hans@example.net>            # smtp_sender_restrictions
> 250 ok
< RCPT TO:<fritz@example.org>             # smtp_recipient_restrictions
> 250 ok
< DATA                                    # smtp_data_restrictions
> 354 Go ahead.
< From:<hans@example.net>                 # header_checks
< To:<fritz@example.org>
< Subject: Hallo
<
< Hallo Fritz.                            # body_checks
< .
> 250 Mail delivered.
< QUIT

Grundsätzlich gilt natürlich, dass man einen Spam-Bot, oder anderweitig spamenden Server so früh wie möglich loswerden will. Bei mir sehen diese Regeln wie folgt aus:

smtpd_client_restrictions = permit

Grundsätzlich lass ich hier erstmal noch jeden weiter machen, deswegen einfach "permit". Dass kann natürlich auch weg gelassen werden, da dies eh Standard ist.

smtpd_helo_restrictions =
    reject_rhsbl_helo zen.spamhaus.org,
    permit

Hier wird bei zen.spamhaus.org nachgefragt, ob der Domainname, der im HELO Kommando gekommen ist, dort als Spamschleuder eingetragen ist, wenn ja, wird rejected, sonst greift die nächste Regel, permit.

smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unauth_destination,
  reject_unknown_sender_domain,
  reject_non_fqdn_recipient,
  permit_dnswl_client list.dnswl.org,
  reject_rbl_client dnsbl.sorbs.net,
  reject_rbl_client bl.spamcop.net,
  reject_rbl_client ix.dnsbl.manitu.net,
  check_policy_service inet:127.0.0.1:10023,
  permit

Als erstes darf weitermachen, wer mir bekannt ist (sprich wesen IP-Adresse in der mynetworks Variable steht. Die zweite Regel sagt aus, das wer sich bis hier her authentifiziert hat auch direkt weiter darf.

An reject_unauth_destination kommen nur noch Request vorbei, für die mein Postfix der Empfänger oder Relay ist, ein Relayhost muss dann entsprechend in der main.cf eingetragen sein.

reject_non_fqdn_recipient besagt, dass die Mail abgelehnt werden soll, wenn die Empfängeradresse kein Fully-Qualified Domainname ist.

permit_dnswl_client erlaubt alle, die in der hinterlegten Whitelist gelistet sind, in diesem Fall frage ich list.dnswl.org ab.

Die nächsten drei Zeilen Fragen Realtime-Blacklists ab, in diesem Fall sorbs, spamcop und manitu.

Die check_policy_service Zeile besagt, dass Postfix noch bei Localhost auf Port 10023 anfragen soll, ob er die Verbindung akzeptieren soll. Dort läuft mein Postgrey-Dienst.

Wer es bis hier her geschafft hat, ist wohl kein Spamer (zumindest in den meisten Fällen) und wird durchgelassen.

smtpd_data_restrictions = reject_unauth_pipelining

reject_unauth_pipelining sorgt dafür, dass Verbindungen abgelehnt werden, die sich nicht an das ESMTP Protokoll halten, bzw. nicht auf den Server warten.

Ausangssituation

Wir arbeiten mit Release-Branches, vorgehen eigentlich immer so, dass ein Release-Branch vom Trunk erzeugt wird, wenn dieser dann fertig und abgenommen ist, wird der in den Trunk gemerged und live genommen, dann aus dem Trunk der nächste Release-Branch erzeugt.

  • /trunk
  • /branches
    • release-a

Jetzt begab es sich, dass der Release-Branch A soweit fertig war, aber noch nicht getestet und abgenommen, also noch nicht für den Merge in den Trunk bereit. Da der nächste Release-Branch B wieder aus dem Trunk erzeugt werden würde, könnten darin erstmal keine Anpassungen oder Weiterentwicklungen gemacht werden, die auf Funktionen im Release-Branch A basieren. Genau das sollte aber stattfinden.

Lösung:

Den Release-Branch-B nicht vom Trunk, sondern vom Release-Branch-A erzeugen. Soweit ist das noch nicht magisch, die Probleme gehen nämlich da an, wo man diesen Branch B dann in den Trunk zurück spielen will, weil der dann alles, was im Branch A passiert ist auch in den Trunk mitnimmt und das führt nur zu Konflikten und einer menge Ärger.

Die wahre Lösung

Nachdem dann Branch A in den Trunk gemerged wurde, macht man von der Revision, die den Merge in den Trunk hat einen Record-Only Merge in den Branch B. Der Branch lässt sich dann ohne Konflikte und komplett sauber mit --reintegrate am Ende seines Zykluses in den Trunk mergen.

TL;DR

$ svn cp $REPO/trunk $REPO/branches/a
# do work and commit
$ svn cp $REPO/branches/a $REPO/branches/b
# do work in branches a and b
# keep branch b in sync with branch a
$ cd $BRANCH-B
$ svn merge $REPO/branches/a
$ svn ci -m '$MERGEMESSAGE'
# branch a now ready for reintegrate in trunk
$ cd $TRUNK
$ svn merge $REPO/branches/a --reintegrate
$ svn ci -m '$MERGEMESSAGE'
...
Committed revision 1000.
# here comes the magic
$ cd $BRANCH-B
$ svn merge $REPO/trunk -c 1000 --record-only
$ svn ci -m '$MERGEMESSAGE'
# keep working in branch b, when ready, just reintegrate as normal
$ cd $TRUNK
$ svn merge $REPO/branches/b --reintegrate

XDebug installieren

Folgendes hab ich vor: Ich will PHP-Code sauber debuggen können, schön mit Debugger und Co.

Ausganssituation:

  • PHP 5.3 per CGI in Apache eingebunden
  • PHP 5.3 selber compiliert aus den Sourcen
  • Xubuntu 13.04
  • IDE: VIM

XDebug runterladen und compilieren

XDebug hab ich mir aus dem pecl gezogen und dann ein Debian Paket draus erstellt

$ wget http://pecl.php.net/get/xdebug-2.2.3.tgz
$ tar -xvzf xdebug-2.2.3.tgz
$ sudo /usr/bin/php53/phpize
$ sudo ./configure --with-php-config=/usr/bin/php53/php-config
$ sudo make
$ sudo checkinstall

checkinstall führt auch ein "make install" aus, allerdings erzeugt es gleichzeitig noch ein Debian Paket, dass man dann irgendwann bequem deinstallieren kann.

XDebug einbinden

Folgendes hab ich danach in die php.ini eingebunden um XDebug zu aktivieren

[xdebug]
zend_extension=/usr/share/php53/lib/php/20090626/xdebug.so
xdebug.remote_enable = 1 
xdebug.remote_port = 9000
xdebug.remote_host = localhost

Der Pfad muss bei dir evtl. angepasst werden, danach Apache neu starten, XDebug ist dann ab sofort einsatzbereit

XDebug mit vim nutzen

Für den VIM gibt es ein Plugin, so dass man VIM als Client für remote XDebug-Sitzungen nutzen kann, einfach runterladen und installieren.

Debug-Sitzung starten

Browser aufmachen und für example.com bspw. folgende URL eingeben:

http://example.com/?XDEBUG_SESSION_START=1

Dadurch wird im Browser ein Cookie gesetzt, dass eine Stunde gültig ist, und XDebug versucht bei jedem Pageload den Debugger zu finden, wenn er nicht gefunden wird, macht das auch nix, dann wird die Seite ganz normal geladen.

Jetzt VIM starten, F5 drücken, in den Browser wechseln Seite neu laden und los geht das lustige debuggen.

... oder zumindest verlangsamen

Neulich ist mir bei der Log-File Analyse eines Servers mal wieder aufgefallen, dass es wohl noch immer eine recht verbreitet Methode ist, per Brute Force oder Dictonary Attack zu versuchen sich Zugang zu Servern per SSH zu verschaffen.

Nachdem eine Logfileauswertung, auch automagisiert, immer nur zeitverzögert reagieren kann, habe ich weitergesucht und folgende Lösung gefunden. Ich limitiere die Anzahl SYN-Pakete am SSH Port, den jedes SYN Paket ist ein neuer Versuch, sich einzuloggen.

# cleanup
iptables -F
iptables -X SSH_CHECK

# set rules
iptables -N SSH_CHECK
iptables -A SSH_CHECK -m recent --set --name SSH
iptables -A SSH_CHECK -m recent --update --seconds 60 --hitcount 3 --name SSH -j DROP
iptables -A SSH_CHECK -m recent --update --seconds 3600 --hitcount 11 --name SSH -j DROP

iptables -A INPUT -p tcp -s 1.2.3.4 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_CHECK

Als erstes wird aufgeräumt, falls es Hinterlassenschaften gibt. Dann wird die SSH_CHECK Chain angelegt. Die erste Regel sagt, dass die IP-Adresse aller Datenpakete, die in diese Chain geleitet werden in die IP-Liste aufgenommen werden sollen. Regel zwei und drei schauen dann in dieser Liste nach, und wenn innerhalb der letzten 60 Sekunden drei oder mehr Hits existieren oder innerhalb der letzten Stunde zehn oder mehr, dann wird das Datenpaket einfach gedropt.

In der INPUT Chain legen wir dann noch einen Eintrag an, in diesem Fall meine eigene statische IP Adresse, von welcher ich Datenpakete direkt akzeptieren. Der nächste Eintrag schickt Datenpakete, die vom State NEW sind (also SYN-Pakete) und am Port 22 ankommen an die SSH_CHECK Chain, die wir oben angelegt haben.

Mit zehn versuchen pro Stunde macht Brute Force keinen Spaß ;-)