Tag: php

phpmyadmin mit fail2ban absichern

seit phpmyadmin 4.8 gibt es endlich eine logging funktion fuer die fehlgeschlagenen logins. diese kann man dann wunderbar per fail2ban auswerten. frueher war das eher eine wurschtelei mit customized apache logs oder gar aenderungen an den installierten phpmyadmin dateien (welche nach einem update wieder futsch waren). standardmaessig ist diese logging funktion auch enabled und schreibt die fehlgeschlagenen logins ins php error logfile oder syslog. der parameter in der config.inc.php heisst $cfg[‘AuthLog’] und hat den wert “auto”. phpmyadmin entscheidet dann selbststaendig, ob es ins php error log oder syslog schreibt. in meinem falle machte es das ins php error log. wenn nicht, kann man den wert entsprechend setzen.

hier ist das die datei /var/www/webxxxx/logs/priv/php_errors.log. die eintraege im log haben dieses format:

[19-May-2019 21:07:49 Europe/Berlin] user denied: phpmyadmin (mysql-denied) from 46.246.65.167

zuerst muss man einen entsprechenden filter fuer fail2ban konfigurieren. dazu einfach die datei /etc/fail2ban/filter.d/phpmyadmin.conf mit diesem inhalt anlegen:

[Definition]
denied = mysql-denied|allow-denied|root-denied|empty-denied
failregex = ^.*(%(denied)s).* from $
ignoreregex =

beim debuggen seiner eigenen regex kann die seite debuggex.com sehr hilfreich sein. testen kann man seinen selbst erstellten filter mit diesem befehl:

fail2ban-regex /var/www/webxxxx/logs/priv/php_errors.log /etc/fail2ban/filter.d/phpmyadmin.conf

im ergebnis sollten dann irgendwie so in der art aussehen:

[...]
Lines: 31 lines, 0 ignored, 10 matched, 21 missed
[...]

bei “matched” sollte eine entsprechende anzahl groesser 0 auftauchen. wenn dem so ist, braucht man noch eine “jail” konfiguration fuer phpmyadmin. dazu die datei
/etc/fail2ban/jail.d/phpmyadmin.conf mit diesem inhalt anlegen:

[phpmyadmin]
enabled = true
port = http,https
filter = phpmyadmin
logpath = /var/www/webxxxx/logs/priv/php_errors.log

einmal neu laden ….

service fail2ban reload

… und einfach mal ein paar fehlerhafte loginversuche ausloesen. im php error log sieht das so aus:

[24-May-2019 07:51:45 Europe/Berlin] user denied: dasdsadsadas (empty-denied) from 87.xxx.xx.xx
[24-May-2019 07:51:46 Europe/Berlin] user denied: dasdsadsadas (empty-denied) from 87.xxx.xx.xx
[24-May-2019 07:51:47 Europe/Berlin] user denied: dasdsadsadas (empty-denied) from 87.xxx.xx.xx
[24-May-2019 07:51:48 Europe/Berlin] user denied: dasdsadsadas (empty-denied) from 87.xxx.xx.xx
[24-May-2019 07:51:49 Europe/Berlin] user denied: dasdsadsadas (empty-denied) from 87.xxx.xx.xx

und korrespondierend im fail2ban logfile:

/var/log/fail2ban.log

2019-05-24 07:51:45,862 fail2ban.filter         [1144]: INFO    [phpmyadmin] Found 87.xxx.xx.xx
2019-05-24 07:51:46,936 fail2ban.filter         [1144]: INFO    [phpmyadmin] Found 87.xxx.xx.xx
2019-05-24 07:51:47,952 fail2ban.filter         [1144]: INFO    [phpmyadmin] Found 87.xxx.xx.xx
2019-05-24 07:51:48,832 fail2ban.filter         [1144]: INFO    [phpmyadmin] Found 87.xxx.xx.xx
2019-05-24 07:51:49,592 fail2ban.filter         [1144]: INFO    [phpmyadmin] Found 87.xxx.xx.xx
2019-05-24 07:51:50,303 fail2ban.actions        [1144]: NOTICE  [phpmyadmin] Ban 87.xxx.xx.xx
2019-05-24 08:01:51,276 fail2ban.actions        [1144]: NOTICE  [phpmyadmin] Unban 87.xxx.xx.xx

bei dem jail greifen hier die fail2ban standard werte einer debian 9 installation. nach 5 fehlerhaften logins von einer IP wird diese fuer 10 minuten per iptables geblockt.

that’s it.

fehlende authorization header mit mod_fcgid

na bis ich das gerafft hab, warum diese werte nicht beim php skript ankamen…

die loesung gefunden in den kommentaren der hilfe zu php und http-auth

Workaround for missing Authorization header under CGI/FastCGI Apache:

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

Now PHP should automatically declare $_SERVER[PHP_AUTH_*] variables if the client sends the Authorization header.

…ab damit in die .htaccess und schon hats funktioniert

update:
ein sehr interessanter artikel zu php und http auth auf administrator.de.

fehler nach owncloud update: “zend_mm_heap corrupted”

nachdem ich heute meine owncloud installation auf 7.0.4 aktualisiert habe, gabs erstmal nur noch “500 Internal Server Error” 🙁

im apache error.log fand ich folgenden eintrag:

zend_mm_heap corrupted

und nach ein wenig googlen habe ich abhilfe gefunden:

after much trial and error, I found that if I increase the output_buffering= value in the php.ini file, this error goes away

hmm… gesagt – getan… funktioniert. nun muss ich nur noch weiter suchen und den hintergrund verstehen 😉

DIY werbeblocker

wo wir gerade bei werbung waren… werbeblocker in browsern sind ja eh doof, weil da teilweise auch eine riesige geldmaschine dahinter steht. (also nicht bei der werbung, sondern auch bei den werbeblockern!)

hier eine kurze beschreibung, wie ich mir einen rudimentaeren werbeblocker selbst gebastelt habe. und da ich von natuer aus neugierig bin, wollte ich auch ein bischen statistik haben, was mir das ganze bringt.

als erstes brauchen wir eine liste bekannter urls der anbieter von werbung. es gibt eine android app, welche eine solche liste bzw mehrere listen aus dem netz zieht und diese kumuliert in die hosts datei des geraetes rein kopiert. die hostnamen der “ad-server” werden dann einfach auf localhost (127.0.0.1) umgeleitet und die anfragen landen so im nirvana, weshalb keine werbung angezeigt wird. praktischerweise stehen die urls der gepflegten listen auch als kommentar drin:

# http://adaway.org/hosts.txt
# http://hosts-file.net/ad_servers.asp
# http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext
# http://winhelp2002.mvps.org/hosts.txt

diese laedt man sich einfach runter und fügt sie ans ende seiner eigenen hosts datei an. wo die hosts datei bei welchem betreibssystem liegt, sagt euch wikipedia. theoretisch funktioniert das nun schon. praktisch ist diese liste schon immer beim erscheinen veraltet und muss staendig aktualisiert und ergaenzt werden. deshalb sollte man sich fuer diese arbeit ein scriptchen bauen und regelmaessig laufen lassen. (todo fuer die zukunft: die hosts des dsl routers damit fuettern, damit man das nicht fuer jedes geraet im lan machen muss.)

wie schon erwaehnt wollte ich auch wissen, was da denn ueberhaupt ablaeuft, was wie und wie oft “geblockt”. dazu habe ich die eintraege in der hosts nicht auf 127.0.0.1 umgeleitet, sondern auf die ip eines webservers bei mir im lokalen netz. dieser liefert nur eine leere seite zurueck und schreibt mir die aufrufe in eine logdatei.

das erledigt ein kleines php skriptchen, welches ich als index.php abgespeichert habe:


damit auch alles “funktioniert”, was nach dem hostnamen in aufruf einer url steht und nicht vom webserver mit einem “not found” quittiert wird, werden alle anfragen per .htaccess datei auf die zuvor erstellt datei index.php umgeleitet. um zu verhindern, dass die index.php in einer schleife auf sich selbst umgeleitet wird, muss man sie “excluden”. selbiges macht man mit dem logfile, damit man es sich auch im browser anschauen kann.

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_URI} !adblock.log
RewriteRule .* index.php [R=307,L]

voila… 10 minuten arbeit mit testen. ein wenig finetuning kann man natuerlich noch machen. vielleicht poste ich nochmal was.

und was hats gebracht? beim morgendlichen stöbern in den news des tages, die man so bei ner tasse kaffe liest, wurden mir in 15 minuten ganze 358 (!!!!) werbeeinblendungen NICHT angezeigt. wenn man sich diese zahl anschaut – liebe webseitenbetreiber – da wundert ihr euch, dass menschen werbeblocker benutzen? so viel werbung kann man in 15 minuten gar nicht verarbeiten.

20140822_werbeblockerder focus online hats dann aber doch gemerkt, obwohl ich im browser keinen werbeblocker installiert habe. da muss ich nochmal ein bischen forschen, wie die das machen und wie man das umgehen kann.

eine idee fuer einen werbe blocker im browser waere doch, dass die werbung zwar geladen, aber nicht angezeigt wird. so muessten die bloeden webseitenbetreiber nicht mehr rumnoehlen, dass ihnen die werbeeinnahmen (von den einblendungen) floeten gehen und die besucher waeren gluecklich. die paar leute, die es auf der welt gibt, die wirklich werbung anklicken, haben und wollen sicher auch keinen werbeblocker.

to be continued… 🙂

homematic: yamaha av receiver steuern

um einen yamaha av receiver zu steuern (hier z.b. ein RX-V771), brauchts irgendwas, was die kommandos uebers netz zu den diesem sendet. vorraussetzung fuer dieses script ist ein installierter cuxd auf der omemativ ccu2.

dieses script soll nur als beispiel dienen, da die umsetzung doch etwas quick and dirty ist 😉

der erste uebergabeparameter ist der hostname oder die ipadresse des receivert. der zweite uebergabeparameter ist ein kommando, welches im script definiert ist. siehe case anweisung…

#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/addons/cuxd

url="http://$1:80/YamahaRemoteControl/ctrl"
header="Content-Type: text/plain"
curlp="-f -s -X POST"

xmlhead=""
xmlfoot=""

case "$2" in
	"poweron") ycmd="On"
	;;
	"poweroff") ycmd="Standby"
	;;
	"muteon") ycmd="On"
	;;
	"muteoff") ycmd="On/Off"
	;;
	"muteonoff") ycmd="On/Off"
	;;
	"vol55") ycmd="-5501dB"
	;;
	"vol65") ycmd="-6501dB"
	;;
	"volplus2") ycmd="Up 2 dB"
	;;
	"volminus2") ycmd="Down 2 dB"
	;;
esac

/usr/local/addons/cuxd/curl $curlp --header "$header" -d "$xmlhead$ycmd$xmlfoot" $url > /dev/null

ich hab das unter /usr/local/addons/yamaha als “yamaha.sh” abgespeichert.

es ist ein shellscript geworden, da ich mit diesem tcl kram auf der ccu irgendwie auf kriegsfuss stehe. damit ist es ein leichtes, z.b. den receiver auszuschalten, wenn man den raum verlaesst und das licht ausschaltet. (passt in meinem szenario im büro. im wohnzimmer will man es zu filme schauen vielleicht andersrum haben?)

mit geringfuegigen anpassungen was den curl pfad angeht, sollte das auch ohne homematic auf beliebigen linux rechnern laufen.

configured post variable limit exceeded

wenn man bei einem debian (lenny oder squeeze) php mit dem suhosin patch installiert (php5-suhosin) und nutzt, kann es z.b. fuer manche content management systeme “zu sicher” eingestellt sein. suhosin begrenzt dabei die maximale groesse der POST requests. im falle von contao fuehrt das dazu, dass manche einstellungen nicht mehr abgespeichert werden koennen und still und heimlich im error.log folgender eintrag zu finden ist:

[warn] mod_fcgid: stderr: ALERT - configured POST variable limit exceeded - dropped variable 'start' (attacker 'xxx.xxx.xxx.xxx', file '/var/www/contao/main.php')

abhilfe schafft eine vergroesserung der entsprechenden werte in der php.ini. z.b. so:

suhosin.post.max_vars = 200000 
suhosin.request.max_vars = 20000 
suhosin.post.max_value_length = 265000 
suhosin.request.max_value_length = 265000

owncloud external storage support

seit version 4 bietet owncloud die moeglichkeit, “externes” storage einzubinden. d.h. man kann bereits vorhandene “cloudspeicher” einbinden und ueber das owncloud interface darauf zugreifen. irgendie soll das wohl mit dropbox und gdrive usw funktionieren, aber ich habs erstmal mit ftp probiert. hilfe findet man auf der seite “Custom Mount Configuration“. da steht auch nix von dropbox etc. geschrieben.

um einen ftp server einzubinden muss man die datei config/mount.php anlegen. in meinem falle mit folgendem inhalt (benutzernamen etc. sind natuerlich anzupassen);

array(
  'ich'=>array(
   '/ich/files/mountpoint/'=>array('class'=>'OC_Filestorage_FTP',
    'options'=>array('host'=>'www.ftphost.tld',
                     'user'=>'ftpUserName',
                     'password'=>'ftpPassWord'))
    	)
    )
);
?>

diese mounts kann man wahlweise fuer bestimmte user und gruppen oder auch fuer alle anlegen. details siehe link oben.
ich habe auf dem besagten ftp ca. 3000 bilder liegen. owncloud “scannt” diese natuerlich erstmal. dabei werden die dateisystem objekte erstmal mit name, datum, hashwert etc in der tabelle fscache abgelegt. wenn es sich um bilder handelt und man mit der integrierten gallery durch diese browst, legt owncloud auch noch thumbnails im userverzeichnis (unterverzeichnis “gallery”) unterhalb des “datadirectory” an.
zu weiteren spielereien bin ich noch nicht gekommen… ich finds aber irgendwie suboptimal, dass owncloud fuer meine 3000 bilder auf dem remoteserver 22672 (!) einzelne logins gemacht hat.

problem mit umlauten nach owncloud update

.. von version 3 auf 4… sieht scheisse aus:

der kalender sah aehnlich aus. und so kriegt man es weg, ohne an der collation der datenbank rumschrauben zu muessen. was jetzt sinnvoller ist, mag ich fuer mich gerade nicht entscheiden. so hab ich wenigstens die datenbank so, wie sie bei der installation mal angelegt wurde.

UPDATE calendar_objects SET summary = REPLACE(summary, 'ä', 'ä');
UPDATE calendar_objects SET summary = REPLACE(summary, 'ü', 'ü');
UPDATE calendar_objects SET summary = REPLACE(summary, 'ö', 'ö'); 
UPDATE calendar_objects SET summary = REPLACE(summary, 'Ãœ', 'Ü');
UPDATE calendar_objects SET summary = REPLACE(summary, 'Ä', 'Ä');
UPDATE calendar_objects SET summary = REPLACE(summary, 'Ãœ', 'Ö');
UPDATE calendar_objects SET summary = REPLACE(summary, 'ß', 'ß');

UPDATE calendar_objects SET calendardata = REPLACE(calendardata, 'ä', 'ä');
UPDATE calendar_objects SET calendardata = REPLACE(calendardata, 'ü', 'ü');
UPDATE calendar_objects SET calendardata = REPLACE(calendardata, 'ö', 'ö'); 
UPDATE calendar_objects SET calendardata = REPLACE(calendardata, 'Ãœ', 'Ü');
UPDATE calendar_objects SET calendardata = REPLACE(calendardata, 'Ä', 'Ä');
UPDATE calendar_objects SET calendardata = REPLACE(calendardata, 'Ãœ', 'Ö');
UPDATE calendar_objects SET calendardata = REPLACE(calendardata, 'ß', 'ß');

UPDATE contacts_cards SET carddata = REPLACE(carddata, 'ä', 'ä');
UPDATE contacts_cards SET carddata = REPLACE(carddata, 'ü', 'ü');
UPDATE contacts_cards SET carddata = REPLACE(carddata, 'ö', 'ö'); 
UPDATE contacts_cards SET carddata = REPLACE(carddata, 'Ãœ', 'Ü');
UPDATE contacts_cards SET carddata = REPLACE(carddata, 'Ä', 'Ä');
UPDATE contacts_cards SET carddata = REPLACE(carddata, 'Ãœ', 'Ö');
UPDATE contacts_cards SET carddata = REPLACE(carddata, 'ß', 'ß');

UPDATE contacts_cards SET fullname = REPLACE(fullname, 'ä', 'ä');
UPDATE contacts_cards SET fullname = REPLACE(fullname, 'ü', 'ü');
UPDATE contacts_cards SET fullname = REPLACE(fullname, 'ö', 'ö'); 
UPDATE contacts_cards SET fullname = REPLACE(fullname, 'Ãœ', 'Ü');
UPDATE contacts_cards SET fullname = REPLACE(fullname, 'Ä', 'Ä');
UPDATE contacts_cards SET fullname = REPLACE(fullname, 'Ãœ', 'Ö');
UPDATE contacts_cards SET fullname = REPLACE(fullname, 'ß', 'ß');

php – bilder im verzeichnis anzeigen

fuer eine kleine spielerei musste ich ein php scriptchen basteln, dass mir bilder in einem verzeichnis anzeigt. und zwar immer nur eins und beim klick auf das bild dann das naechste. das gnaze natuerlich der reihe nach alphabetisch sortiert. in meinem fall entsprachen die dateinamen dem datum und der uhrzeit in umgekehrter reihenfolge (z.b. 201103251840), so dass eine alphabetische sortierung auch gleich dem sortieren nach datum und uhrzeit entspricht.

';
// aktuelles bild als absende button im formular
echo '';
// naechstes bild ($key+1) als uebergabeparameter 
echo '';
echo '';
// und noch ein paar sachen wie dateinamen, -groesse 
// und anzahl ausgeben
$filesize=round(filesize($pfad.'/'.$arr[$key])/1024,2);
echo 'file '.($key+1).'/'.count($arr).'
'; echo 'filename: '.$arr[$key].'
'; echo 'size: '.$filesize.' kB
'; echo '# files: '.count($arr).'
'; ?>

davor und danach nur noch standard html header und was man so alles haben will und fertig isses.

erst dachte ich… ups.. .aufpassen, dass man damit nicht x-beliebige dateien aufm webserver anzeigen kann. aber wenn man die POST header manipuliert und eine datei wie ../../../etc/passwd aufrufen will, wird die nicht angezeigt, da sie nicht in dem dem array mit den dateien im aktuellen verzeichnis steht. faellt sonst noch jemandem ein hack dazu ein?

UPDATE: danke schonmal an roland fuer den tip mit den dateiendungen in den kommentaren. das kann jeder nach belieben einbauen. ich habe hier aber noch ein schmankerl. naemlich einfach beim laden der seite die naechsten beiden bilder “vorladen” und nur nicht anzeigen lassen. das hat den charme, dass beim klick auf das naechste bild dieses sofort und ohne wartezeit erscheint. hier der code dazu, den man natuerlich einfach erweitern kann, damit noch mehr bilder vorgeladen werden um das “durchklicken” fluessiger zu machen:

echo '';
echo '';

hab ich hier gefunden: http://www.flexib.de/grafiken-vorladen-html-css-javascript/