Policy based routing auf Debian Lenny/Etch mit Squid Proxyserver

Folgendes Szenario: Ein Debian Lenny Server und zwei Router mit je einer Internetverbindung befinden sich im selben (lokalen) Netzwerk. Wir wollen beide Router (sprich Internetverbindungen) für verschiedene Anwendungen nutzen.

Routing-Tabelle

Routing im privaten Netzwerk ist eigentlich ganz einfach: Liegt die Ziel-IP nicht im selben Subnetz, wird das Paket an den Default-Gateway geschickt. Das nennt sich dann static routing. Verwaltet wird das über sog. Routing-Tabellen. Unter Debian sieht das ungefähr so aus:

~$ sudo route
Kernel-IP-Routentabelle
Ziel            Router          Genmask         Flags Metric Ref    Use Iface
192.168.123.0   *                255.255.255.0   U     0      0        0 eth0
default         192.168.123.99   0.0.0.0         UG    0      0        0 eth0

192.168.123.0 ist das eigene, private Netz, 192.168.123.99 der Router an dem eine DSL oder Kabel-Verbindung hängt. Das sieht bei jedem Client-PC übrigens ähnlich aus. Windows-Benutzer müssen aber “route print” ins cmd tippen.

Policy Based Routing

So weit, so einfach. Was ist aber, wenn wir bestimmte Dienste über einen anderen Gateway leiten wollen? Dann brauchen wir policy based routing. Damit lassen sich unheimlich tolle Sachen machen – wir beschränken uns aber erstmal auf das unterschiedliche Routen anhand der Source-IP-Adresse.

Konkret: Der Lenny-Server bekommt eine zweite (virtuelle) IP, den Squid-Proxyserver binden wir exklusiv auf diese IP, und per PBR schicken wir alle Pakete die vom Squid-Proxy kommen über einen bestimmten Gateway. Der Rest geht nach wie vor zum Default-Gateway.

Mit PBR könnte man natürlich auch nach dem Desination-Port routen, und sich somit die zweite IP-Adresse sparen. Leider bietet  ”ip rule” keine Möglichkeit direkt den TCP destination port als Kriterium auszuwählen. Deshalb müssten die entsprechenden Pakete erst mit iptables markiert, und dann nach dieser Markierung gefiltert werden. Was diesen Post betrifft, blieben wir also bei zwei IPs und somit dem routing anhand der Source-IP.

Ein paar Zahlen zum Verständnis:

- Lenny-Server: 192.168.123.1 & 192.168.123.2
- Router1: 192.168.123.99
- Router2: 192.168.123.98

Die Software

Als Software brauchen wir iproute2 und iptables. Beide Tools sollten selbst bei einer minimalen Debian Installation schon vorhanden sein. Wenn nicht, installieren wir die Tools nach: apt-get install iproute iptables.

Die Konfiguration

Routing-Tabelle anlegen

Zunächst legen wir zwei neue Routing-Tabellen an. Eine für jede ausgehende Leitung. Dazu fügen wir folgenden Zeilen an das Ende von /etc/iproute2/rt_tables hinzu.

#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
100 arcor
200 kabelbw

Der Name ist jeweils frei wählbar. Ich habe hier die Namen der jeweiligen Provider genommen. Die ID ist auch frei wählbar, muss aber zwischen 1 und 254 liegen.

Routing-Konfiguration

Wir bearbeiten /etc/network/interfaces, fügen ein zweite, virtuelle IP-Adresse hinzu, und teilen Debian mit, mit welchem Adapter welche Routing-Tabellen genutzt werden sollen.

# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
#allow-hotplug eth0
auto eth0
iface eth0 inet static
        address 192.168.123.1
        netmask 255.255.255.0
        network 192.168.123.0
        broadcast 192.168.123.255
        post-up ip route add default via 192.168.123.99 dev eth0 table main
        pre-down ip route del default via 192.168.123.99 dev eth0 table main
auto eth0:1
iface eth0:1 inet static
        address 192.168.123.2
        netmask 255.255.255.0
        network 192.168.123.0
        broadcast 192.168.123.255
        post-up ip route add default via 192.168.123.98 dev eth0:1 table arcor
        post-up ip rule add from 192.168.123.2 table arcor
        pre-down ip route del default via 192.168.123.98 dev eth0:1 table arcor
        pre-down ip rule del from 192.168.123.2 table arcor

Die post-up & pre-down Einträge legen automatisch die entsprechenden Regeln in der Routing-Tabelle an, wenn die Netzwerkkarte aktiviert bzw. deaktiviert wird. Von Hand angelegte Einträge verschwinden sonst nämlich nach einem Neustart. Der Traffic über eth0 (192.168.123.1) geht demnach an den Router mit der .99. Traffic über das virtuelle Interface eth0:1 (192.168.123.2) geht an den Router mit der .98.

Squid-Konfiguration

Da nun sämtlicher Traffic der IP 192.168.123.2 über einen speziellen Gateway geht, müssen wir nur noch den Squid-Proxy explizit auf diese IP binden. Dazu öffnen wir die Datei /etc/squid/squid.conf und passen die http_port-Zeile an:

http_port 192.168.99.2:3128

Der Port ist natürlich frei wählbar – wichtig ist hier nur die IP-Adresse. Nach einem Squid-Neustart sollte jetzt sämtlicher Proxy-Traffic über die 192.168.123.98 laufen – der restliche Traffic nach wie vor über die 192.168.123.99.

Sinn?

Gute Frage! PHP-Skripte können zum Beispiel über PHP-Proxy die zwei unterschiedlichen Leitungen benutzen. Selbiges gilt natürlich auch für Clients, die in Ihrem Browser die virtuelle IP des Squid als Proxy eintragen. Somit kann man mit wenigen Klicks mal eben die IP wechseln…

Rdiff-backup unter Debian auf SMB/CIFS-Mount

Für inkrementelle Backups unter Debian Lenny kommt man an rdiff-backup wohl nicht vorbei. Es erstellt Rückwärts-Inkremente — der aktuelle (neuste) Backup-Stand liegt also jederzeit als einfache Datei vor. Vorherige Backup-Stände kann man aus dem aktuellen Stand und den Rückwärts-Deltas wiederherstellen. Das funktioniert entweder über die Kommandozeile oder mit einem Web-Interface wie z.B. rdiff-web.

Das Ganze funktioniert prinzipiell auch auf per SMB oder CIFS gemounteten Shares, zum Beispiel auf eine NAS-Box. rdiff-Backup kümmert sich sogar um das Quoten von Dateinamen, wenn das gemountete Filesystem im Gegensatz zum ext3-Filesystem des Lenny-Servers nicht case-sensitive ist. Allerdings funktioniert das erst so halbwegs reibungslos ab rdiff-backup 1.2.5 – für Etch ist also selber kompilieren angesagt.

In meinem Fall führte ein Backup auf die per SMBFS gemountete NAS aber zu einem komischen Quoting-Schema (“A-Z-”*/:<>?\\|;”). Das resultierte dann in langsamen Backups und rdiff-web wollte auch nicht mehr funktionieren.

Loopback Tricks

Diese Anleitung brachte mich dann auf eine Idee, mit der man die ganzen SMB-Eigenheiten umgehen kann: Man erstellt eine große Datei auf der NAS-Box, erstellt in dieser Datei ein ext3-Dateisystem und mountet es als Loopback-Device. Das Backup erfolgt dann direkt auf diesen ext3-mount. So geht’s:

dd if=/dev/zero of=/mnt/nas/backup.ext3 bs=1M count=100
mkfs.ext3 /mnt/nas/backup.ext3
mount /mnt/nas/backup.ext3 -t ext3 -o,sync,loop,rw,noatime /mnt/backup

Unter /mnt/nas ist die NAS-Box gemountet. Darauf erstellen wir die Datei backup.ext3 (100MB in diesem Beispiel). Das ext3-Dateisystem in dieser Datei mounten wir nach /mnt/backup.

Der Performance hilft das jetzt nicht unbedingt…

Wir messen nach:

Davor:

--------------[ Session statistics ]--------------
 StartTime 1232652246.00 (Thu Jan 22 20:24:06 2009)
 EndTime 1232652365.80 (Thu Jan 22 20:26:05 2009)
 ElapsedTime 119.80 (1 minute 59.80 seconds)
 SourceFiles 4670
 SourceFileSize 16749169 (16.0 MB)
 ...
--------------------------------------------------

Danach:

--------------[ Session statistics ]--------------
 StartTime 1232652246.00 (Thu Jan 22 20:24:06 2009)
 EndTime 1232652365.80 (Thu Jan 22 20:26:05 2009)
 ElapsedTime 48.20 (48.20 seconds)
 SourceFiles 4670
 SourceFileSize 16749169 (16.0 MB)
 ...
 --------------------------------------------------

Das war ein initiales Backup einer Dokuwiki-Installation. Ohne Quoting ist das ganze mehr als doppelt so schnell. Kann natürlich je nach Größe des Backup-Verzeichnisses, inkrementellen Backups oder Restores abweichen :)

Unterm Strich ———

Unterm Strich ist das Loopback-Device für mich die eindeutig bessere Lösung: Das Backup-Repo bleibt schön sauber, da nichts gequotet werden muss und alle SMB-Bugs in rdiff-backup sind ein für alle Mal Geschichte. Hardlink-Support gibts obendrein dazu. Leider kann man den letzten Backup-Stand nicht mehr direkt auf der NAS (von einem Windows-Rechner per Freigabe) einsehen. Hierzu muss man das gemountete ext3-Filesystem erneut mit Samba sharen. Außerdem muss man den Backup-Platz vorher belegen und die Performance ist wohl alles andere als optimal – aber irgendwas ist ja immer!

Kurz notiert: einfache CSS Browser-Hacks für IE6/7

Mit nur einem Zeichen lassen sich CSS-Eigenschaften gezielt für den Internet Explorer 6 und 7 schreiben:

#meinElement {
    background: red;    /* alle Browser */
    *background: green; /* IE 7 und darunter */
    _background: blue;  /* nur IE6 */
}

So sieht das dann aus. Doch sind solche Anpassungen für bestimmte Browser in sparaten CSS-Dateien und per Conditional-Comment eingebunden weitaus besser aufgehoben. Aber zum schnellen Debuggen für zwischendurch kann man diese Hacks schonmal benutzen..

PHP: gleich oder nicht gleich?

PHP ist schwach typisiert. Und das ist im Prinzip auch gut so! Dennoch passieren dadurch teilweise wirklich sonderbare Dinge:

"2d3" != "02d3"

Das ist einfach: Strings unterschiedlicher Länge können niemals gleich sein.

Aber:

"2e3" == "02e3"

Was läuft hier anders? Beim einfachen Vergleich (“==”) versucht PHP zuerst jeden String als Zahl zu interpretieren. Das gelingt im ersten Beispiel offensichtlich nicht, wohl aber im zweiten: “2e3″ wird als wissenschaftliche Notation (2 mal zehn hoch 3)  interpretiert und somit zur Zahl. Da bei Zahlen führende Nullen irrelevant sind, wird auch “02e3″ zur Zahl. Man könnte also genauso gut “2e3″ == 2000 schreiben.

Leider ist das mit den führenden Nullen nicht immer so:

"0012" != 0012

Hier kommt eine weitere Eigenschaft von PHP ins Spiel: Zahlen, die mit einer Null beginnen werden von PHP als Oktalzahl interpretiert. Nicht aber in Strings! Somit wird “0012″ zu 12(dec) und 0012 zu 12(oct).

Da die internen Konvertierungen und Interpretationen von PHP nicht immer offensichtlich sind, empfiehlt es sich, in gewissen Situationen den “===”-Operator (strikter Vergleich) zu verwenden. Dieser ergibt nur dann True, wenn auch die Variablentypen (int, string, ..) auf beiden Seiten übereinstimmen. Beim “===”-Operator findet niemals eine Konvertierung statt.

"2e3" !== "02e3"

Das macht Sinn. Aber auch hier gibt es Überraschungen:

2e3 !== 1000

Hmm..

echo gettype(2e3); // double

Aha!  Zahlen mit Exponentialdarstellung sind immer vom Typ double. Liegt wohl daran, dass man damit auch sehr kleine Zahlen darstellen kann ($angstrom = 1e-10;). Also gilt:

2e3 === 1000.0

Dieses Spiel ließe sich beliebig fortsetzen. Dennoch: die gezeigten Verhaltensweisen sind so gewollt und auch Dokumentiert. Diese Extremfälle zeigen lediglich, wie gefährlich (weil schwer nachvollziehbar/erkennbar) manchmal ein scheinbar einfacher Vergleich in PHP sein kann.

Spamassassin: Jahr 2010 Problem auf Debian Lenny?

Heise hat es direkt an Neujahr berichtet: Spamassassin hat offenbar ein Jahr-2010-Bug. So werden alle Mails mit Datum 2010 mit dem FH_DATE_PAST_20XX-Flag versehen.

Spam-E-Mails haben oft ein Datum weit in der Zukunft, damit Sie im Mail-Client immer ganz oben erscheinen (clever!). Spamassassin versucht dem mit dieser Regel entgegen zu wirken. Leider wurde die Jahreszahl 2010 fest einprogrammiert (clever?), und nun offenbar von der Realität eingeholt :)

Da dieses Flag eine hohe Gewichtung hat, landen jetzt also auch normale E-Mails oft fälschlicherweise im Spam-Ordner (false positive). Das Problem betrifft nicht nur den Spamfilter von  GMX und 1&1 sondern im Prinzip jede Spamassassin-Installation.

Für Debian Lenny gab es für das Spamassassin-Paket noch am selben Tag einen bugfix (Spamassassin 3.2.5-2+lenny1.1~volatile1 aus dem Debian Volatile-Repo). Mittlerweile gibt es auch ein offizielles Regel-Update, was die Installation des Volatile-Bugfixes überflüssig macht. Ein einfaches sa-update reicht aus, um die Regeln auf den neusten Stand zu bekommen und den Jahr-2010-Bug zu eliminieren.

Wie finden wir nun heraus, ob der eigene Debian Lenny/Etch-Server von diesem Bug betroffen ist?

SA-Regeln liegen im Ordner /usr/share/spamassassin/, Regel-Updates im Ordner /var/lib/spamassassin/<sa-version>/updates_spamassassin_org

Die Dateien im Update-Ordner überschreiben die Standard-Regeln. Die betroffene Datei heißt 72_active.cf. Diese öffnen wir und suchen nach der FH_DATE_PAST_20XX-Regel:

sudo vi /var/lib/spamassassin/<sa-version>/updates_spamassassin_org/72_active.cf
  ##{ FH_DATE_PAST_20XX
  header   FH_DATE_PAST_20XX      Date =~ /20[1-9][0-9]/ [if-unset: 2006]
  describe FH_DATE_PAST_20XX      The date is grossly in the future.
  ##} FH_DATE_PAST_20XX

Wichtig ist der fett markierte Regex. Dieser trifft auch auch das Datum 2010 zu. Höchste Zeit für ein Update:

sudo sa-update

Wir öffnen die Datei erneut:

sudo vi /var/lib/spamassassin/<sa-version>/updates_spamassassin_org/72_active.cf
  ##{ FH_DATE_PAST_20XX
  header   FH_DATE_PAST_20XX      Date =~ /20[2-9][0-9]/ [if-unset: 2006]
  describe FH_DATE_PAST_20XX      The date is grossly in the future.
  ##} FH_DATE_PAST_20XX

Aus [1-9] wurde [2-9].  Spamassassin-Neustart:

sudo /etc/init.d/spamassassin restart

Problem gelöst! Zumindest bis zum Jahr 2020…

Dass damit das Problem nur aufgeschoben wird, ist aber bekannt. Die Regel soll längerfristig sowieso komplett abgeschafft werden.

Spamassassin aktualisiert sich übrigens unter Lenny i.d.R. automatisch via Cronjob (/etc/cron.daily/spamassassin). Hier muss man also nichts weiter tun. Ansonsten beseitigt ein manuelles sa-update diesen Bug ganz sicher, und bringt für mindestens 10 Jahre Ruhe :)

PHP: seltener “goes to” Operator ( – – > )

PHP hat einen “goes to”-Operator. Die Integer-Variable $x geht dabei schrittweise Richtung Null. Beispiel:

<?php
$x = 10;
while ( $x --> 0 ) {
    echo $x . ' ';
}
?>

Ausgabe:

9 8 7 6 5 4 3 2 1 0

Sensationell. Im PHP-Manual wird dieser Operator nicht erwähnt. Warum? Weil es in Wirklichkeit zwei Operatoren sind. Geparst wird das ganze nämlich so:

<?php
$x = 10;
while ( $x-- > 0 ) {
    echo $x . ' ';
}?>

Und jetzt ist die Bedingung in der While-Schleife ein ganz normaler Post-Dekrement gefolgt von einem Vergleich. Das Ganze funktioniert also nur in die absteigende Richtung. Für die andere Richtung müsste man ++< schreiben – sieht dann aber nicht mehr so schick aus.

Wegwerf-E-Mail-Adressen: Sperrung umgehen

Anbieter für Wegwerf-E-Mail-Adressen gibt es viele. Ich persönlich bin Mailinator-Nutzer der ersten Stunde. Mailinator war immer zuverlässig und tut genau das was es soll: temporäre E-Mail-Postfächer bereitstellen.

Mailinator gehört zu den größten/bekanntesten Anbietern – und genau das ist auch das Problem. Viele Seiten, die eine Anmeldung mit gültiger E-Mail-Adresse fordern, blockieren die bekannten Wegwerf-E-Mail-Anbieter.

Aber es gibt Abhilfe. Statt @mailinator.com kann man auch jede andere Domain nehmen, deren MX-DNS-Eintrag auf den selben Mailserver zeigt, wie der von @mailinator.com. Doch wie ist die IP-Adresse des Mailinator-Mailservers?

$ dig MX mailinator.com
; <<>> DiG 9.5.1-P3 <<>> MX mailinator.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54319
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;mailinator.com.                        IN      MX

Wie wir sehen, sehen wir nichts. Hat eine Domain keinen MX-Record, so wird automatisch der A-Record als Mailserver angenommen:

$ dig A mailinator.com
; <<>> DiG 9.5.1-P3 <<>> A mailinator.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7356
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;mailinator.com.                        IN      A
;; ANSWER SECTION:
mailinator.com.         77483   IN      A       66.135.60.177

Blöd nur, wenn man mal eben keine Domain (Subdomain reicht auch) zur Hand hat, deren MX-Eintrag man auf die Mailinator-IP ändern kann. Zum Glück kann man bei DynDNS auch freie MX-Records vergeben:

mailinator

Isi manni! Bei “MX-Hostname” entweder mailinator.com, mail.mailinator.com (das war früher mal der MX von mailinator.com) oder direkt die IP (66.135.60.177) eintragen.

Statt irgendwas@mailinator.com kann man jetzt einfach irgendwas@dyndnsacc.kicks-ass.org verwenden. Somit umgeht man die Sperre zu 99%. Die Mails landen trotzdem direkt in der Mailinator-Inbox. Man könnte natürlich direkt den MX-Record prüfen und sperren, ist mir aber bisher auf noch keine Seite passiert. Let them eat spam!

AWStats: die eigenen Besuche ausschließen

AWStats analysiert Logfiles und erstellt nette Statistiken. So auch hier für diesen Blog. Um die schier unfassbare Menge an Visits auch nur im Ansatz zu begreifen, rödelt also jede Nacht AWStats durch die Apache-Logfiles. Das hat im Gegensatz zu Google-Analythics den Vorteil, dass die Daten schön hier lokal gespeichert werden. Außerdem erfolgt die Erfassung der Daten Serverseitig und nicht per Javascript. Das wird nämlich von vielen Usern einfach geblockt (Hallo <noscript>!).

Statistiken sind nie zu 100% genau. Dennoch stört mich, dass die eigenen Hits in den Statistiken auftauchen. Das lässt sich aber verhindern..

Methode 1: eigener vHost

Einfach einen zweiten VHost, z.b. dev.domain.com anlegen. Der VHost zeigt ins selbe Verzeichnis wie die Hauptdomain, hat aber eine extra Logdatei. AWStats wertet nur die Logs der Hauptdomain aus. Die Links auf der Webseite müssen dazu aber zwingend relativ sein – sonst landet man früher oder später wieder auf der Hauptdomain und wird “erfasst”.

Bei Wordpress stellte sich das schon mal als sehr schwierig heraus. Viele Links enthalten hier direkt den Domainnamen.

Methode 2: Apache conditional logging

Per conditional logging werden bestimmte Logeinträge erst gar nicht geschrieben. Als Kriterium kann z.B. die IP-Adresse verwendet werden. Mit DSL und daher dynamischer IP aber eher schwierig. Bleibt also nur noch der Cookie zur Identifikation. Wir setzen auf der eigenen Seite einen bestimmten Cookie, z.B. “DONTSTATME=true”. Dazu einfach in die Adressleiste des Browsers folgendes tippen:

javascript:document.cookie="DONTSTATME=true; expires=Sat, 17 Dec 2011 22:59:00 GMT"

Nach reload der Seite ist der Cookie gesetzt. Jetzt können wir das conditional logging konfigurieren:

SetEnvIf HTTP_COOKIE "(^| )DONTSTATSME=true($|;)" dontlog
CustomLog logs/access_log common env=!dontlog

Nachteil hier: Requests mit diesem Cookie werden jetzt gar nicht mehr geloggt. Nirgends. Generell eine schlechte Idee. Irgendwie. Außerdem legt Syscp pro VHost automatisch einen CustomLog-Eintrag an, der sich leider nicht so leicht um “env=!dontlog” erweitern lässt. Zumindest nicht ohne an der Source rumzufummeln.

Methode 3: Logfile greppen

AWStats akzeptiert auch Logfiles von einer Pipe: mit grep -v DONTSTATME=true /path/to/log würden bei AWStats nur “richtige” Hits ankommen. Dazu muss man den LogFile-Parameter der AWStats-Config folgendermaßen anpassen (/etc/awstats/awstats.domain.com.conf):

LogFile="grep -v DONTSTATME=true /path/to/access.log |"

Problem: Das Apache “combined”-Logformat loggt gar keine Cookies. Lässt sich aber leicht ändern. Wir öffnen die Datei /etc/apache2/apache2.conf und suchen die Zeilen mit “LogFormat”.

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Cookie}i\"" combined

Entweder die Zeile mit “combined” direkt abändern oder ein neues Logformat erstellen, z.B. combined-cookies.

Dann muss AWStats das neue Logformat noch mitgeteilt werden (/etc/awstats/awstats.domain.com.conf):

LogFormat = "%host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot %otherquot"

Apache restart/force-reload und alles ist gut. Vorausgesetzt man vergisst nicht den Cookie zu setzten, wenn man Methode 2 oder 3 verwendet.

Wie jetzt?

Jede Methode hat Ihre Vor- und Nachteile. Keine ist Perfekt. Ich bin noch am evaluieren :D Im Endeffekt müssen einfach nur insgesamt genug Hits vorhanden sein. Dann spielen die paar eigenen Visits auch keine Rolle mehr und man muss sich um das ganze Zeug keine Gedanken mehr machen. Solange das nicht der Fall ist, macht es durchaus Sinn, sich die Mühe zu machen und die eigenen Besuche auszuschließen.

Cineplex Reservierungssystem fail

Beim Cineplex Neckarsulm kann man unter http://212.20.182.131/ online Karten (Sitzplätze) reservieren. Nach kostenloser Registrierung kann man ebenfalls kostenlos bis zu vier Sitzplätze reservieren. Das ist natürlich viel zu wenig. Glücklicherweise nimmt es das System mit der Überprüfung der Formulardaten nicht so genau. Stichwort: Input Validation. Das ist die Überprüfung aller Nutzer-Daten auf Plausibilität hin: Ist die E-Mail-Adresse korrekt, ist die Postleitzahl 5-stellig oder in diesem Fall: liegt die Anzahl der zu reservierenden Sitze zwischen 1 und 4 ?

Formulare lassen sich auf Clientseite leicht manipulieren. Firebug bietet sich hier geradezu an. Firebug ist ein Firefox-Plugin, mit dem man unter anderem das DOM der Webseite einsehen und bearbeiten kann. Um die Anzahl der zu reservierenden Sitze leicht zu erhöhen, einfach mit dem Inspector auf das SELECT-Element klicken, und einen der Option-Werte anpassen. Opera kann das übrigens von  Hause aus: Darstellung -> Quelltext, <option> manipulieren, klick oben auf “Änderungen anwenden”.

cineplex1

Normalerweise sollten die Daten nach dem Absenden des manipulierten Formulars auf der Serverseite überprüft werden. Das ist hier aber offenbar nicht der Fall.

cineplex2

Schon besser.

Das Beispiel zeigt, dass eine Webanwendung grundsätzlich jedem User-Input misstrauen sollte und diese Daten niemals ungeprüft übernehmen sollte. Das betrifft nicht nur Formular-Daten sondern auch Cookie-Daten, GET/POST und sonstige, vom Nutzer übermittelte Daten.
Aber wer wird es dem armen ASP-Frickler Entwickler schon verübeln ..

Domains mit einem Domainrobot direkt registrieren

Domains gibt es überall. Meist direkt vom Server-Anbieter. Diese sind aber oft teurer als nötig und zudem ziemlich unflexibel zu verwalten. Wenn man mit dem Server zu einem anderen Anbieter umzieht, muss man alle Domains mitnehmen.

Das geht auch einfacher und billiger: mit einem Domainrobot. Voraussetzung hierfür ist zwingend ein Server mit Root-Rechten oder ein Provider, der externe Domains erlaubt.


| » Den ganzen Beitrag lesen…