Tag: background wissen

brustschwellattacke

*hach*.. schoen, auch mal feedback zu bekommen. (per mail von der D.):

Ich lerne immer wieder neues durch deinen blog

remote filesystem mit sshfs mounten

wiedermal eine gedankestuetze fuer mich. wenns jemand anders gebrauchen kann – sehr schoen 😉

wie kann ich unter linux ueber ssh ein verzeichnis eines entfernten rechners ins lokale dateisystem mounten? dafuer gibt es z.b. unter ubuntu das paket sshfs. einfach mal installieren (abhaengigkeiten werden aufgeloest):

sudo apt-get install sshfs

aus sicherheitsgruenden benoetigt man spezielle berechtigungen fuer das binary /bin/fusermount. man muss die user, die das verwenden duerfen der gruppe “fuse” hinzufuegen:

sudo localuser fuse

wenn man das fuer den aktuell angemeldeten user macht, muss man sich einmal ausloggen und wieder einloggen, damit das greift.

dann einfach ein lokales verzeichnis erstellen:

mkdir /home/localuser/remotefs

und mit diesem befehl das entfernte verzeichnis mounten (das ist eine zeile):

sshfs remoteuser@remotehostname:/home/remoteuser/remotedir
 /home/localuser/remotefs/

tsql – zeilenanzahl aller tabellen

es gibt viele unterschiedliche wege, die zeilenanzahl aller tabellen in einer datenbank einzeigen zu lassen. gerade wenn man noch anfaenger ist, landet man erstmal bei dem altbekannten:

SELECT COUNT(*) FROM TABELLE

…was man dann fuer jede tabelle machen muss. schnell hat man sich einen cursor drumherum gebaut damit das fuer alle tabellen in einer datenbank macht.

-- BEISPIEL 1

DECLARE @tables TABLE (
	tablename	varchar(255),
	rowcounter	int
)

DECLARE @table_name varchar(255)
DECLARE @SQLSTATEMENT nvarchar(255)
DECLARE @x int

DECLARE cur CURSOR FOR
	SELECT table_name 
	FROM information_schema.tables 
	WHERE TABLE_TYPE = 'BASE TABLE'
OPEN cur
FETCH FROM cur INTO @table_name
WHILE @@fetch_status = 0
BEGIN
	SET @SQLSTATEMENT = 
	 N'SELECT @x = COUNT(*) FROM ' + @table_name
	EXEC sp_executesql
		@SQLSTATEMENT,
		N'@x int OUTPUT',
		@x OUTPUT

	INSERT INTO @tables (tablename, rowcounter) 
	VALUES (@table_name, @x)
	FETCH FROM cur INTO @table_name
END
CLOSE cur
DEALLOCATE cur
SELECT * FROM @tables ORDER BY tablename

das ist natuerlich viel code fuer das bischen abfrage. es geht naemlich auch kuerzer mit der (von microsoft undokumentierten) sql-server internen stored procedure sp_MSforeachtable

-- BEISPIEL 2

CREATE TABLE #TABLEROWCOUNT
(
 TABLENAME sysname,
 ROWCOUNTER int
)
EXEC sp_MSforeachtable 
'INSERT #TABLEROWCOUNT (TABLENAME,ROWCOUNTER) 
SELECT ''?'',Count(*) from ?'
SELECT * FROM #TABLEROWCOUNT
DROP TABLE #TABLEROWCOUNT

schick ist das aber immer noch nicht. eleganter und performanter und ausfuehrlicher gehts mit einer (auch in sql server inegrierten) stored procedure namens sp_spaceused:

-- BEISPIEL 3

DECLARE @tables TABLE (
	tablename	varchar(255),
	rowcounter	int,
	reserved	varchar(255),
	data		varchar(255),
	index_size	varchar(255),
	unused		varchar(255)
)

DECLARE @table_name varchar(255)
DECLARE cur CURSOR FOR
	SELECT table_name 
	FROM information_schema.tables 
	WHERE TABLE_TYPE = 'BASE TABLE'
OPEN cur
FETCH FROM cur INTO @table_name
WHILE @@fetch_status = 0
BEGIN
	INSERT INTO @tables
	(tablename, rowcounter, reserved,
	data, index_size, unused)
	EXEC sp_spaceused @table_name
	FETCH FROM cur INTO @table_name
END
CLOSE cur
DEALLOCATE cur
SELECT * FROM @tables ORDER BY tablename

das schoenste und auch schnellste statement ist dieses hier (funktioniert erst ab sql server 2005):

-- BEISPIEL 4
-- zeigt alle user tables und deren zeilenanzahl der aktuellen 
-- datenbank. ohne "IS_MS_SHIPPED = 0" in der where 
-- klausel werden noch die system objekte angezeigt. 

SELECT T2.NAME, T3.ROW_COUNT 
FROM SYS.INDEXES T1 
INNER JOIN SYS.OBJECTS T2 ON T1.OBJECT_ID = T2.OBJECT_ID 
INNER JOIN SYS.DM_DB_PARTITION_STATS T3 ON 
T1.OBJECT_ID = T3.OBJECT_ID AND T1.INDEX_ID = T3.INDEX_ID
WHERE T1.INDEX_ID < 2 
AND T2.IS_MS_SHIPPED = 0 
ORDER BY T2.NAME

wenn man sich die performance der vier beispiele betrachtet wird schnell klar, welches man fuer groessere datenbanken nicht mehr gebrauchen kann. ich hatte eine datenbank zum "ausprobieren", in der 475 millionen datensaetze auf 60 tabellen verteilt waren. das waren die laufzeiten in millisekunden:

BEISPIEL 1: 156183 ms ( ~ 2 minuten 60 sekunden)
BEISPIEL 2: 155573 ms ( ~ 2 minuten 59 sekunden)
BEISPIEL 3: 173 ms
BEISPIEL 4: 13 ms

ich denke, dass es zu den ergebnissen nicht viel zu sagen gibt.

dateien rekursiv von iso-8859-1 in utf-8 konvertieren

immer wieder holen einem die gleichen probleme ein. gerade windows nutzer, die keine vernuenftigen editoren benutzen, machen dem rest das leben schwer. in 95% aller faelle ist es vollkommen schnurzegal, wie man seine dateien abspeichert. ein webserver unter linux nimmts halt etwas genauer (hat er ja auch recht). das passende shirt dazu (siehe bild) gibt bei getdigital

mal so als gedaechtnisstuetze fuer mich und falls jemand auch mal so ein problem hat. ich musste dateien einer webpraesenz auf einen neuen server umziehen. das problem dabei war, dass manche schon in utf-8 abgespeichert waren und der rest in iso-8859-1. abhilfe schafft ein kleines bash scriptchen, welches man als “convert.sh” abspeichert:

#!/bin/sh
if [ `file $1|grep UTF-8|wc -l` = "0" ]; then
    # datei ist kein utf-8 -> auflisten
    echo $1 >> "kein_utf8.txt"
    # konvertieren
    iconv -f ISO-8859-1 -t UTF-8 "$1" -o "$1"_conv
    # original loeschen
    rm "$1"
    # konvertierte datei umbenennen
    mv "$1"_conv "$1"
    # falls das charset angegeben ist, dann ersetzen
    sed -i 's/charset=iso-8859-1/charset=utf-8/g' "$1"
else
    # datei ist bereits utf-8 -> auflisten
    echo $1 >> "ist_utf8.txt"
fi

sicherlich nicht das non plus ultra und noch verbesserungsfaehig, aber fuer meinen zweck hat es das getan. in der datei “kein_utf8.txt” werden die aufgelistet, die umgewandelt wurden und in der “ist_utf8.txt” nur die, die schon utf-8 encoding hatten.

diese datei ruft man dann einfach in dem verzeichnis auf, von dem aus man abwaerts die z.b. html dateien konvertieren will:

find . -name "*.html" -print | xargs -i -t ./convert.sh '{}'

27c3

wie (fast) jedes jahr war ich auch dieses jahr zwischen weihnachten und silvester beim chaos communication congress in berlin. inmitten von lauter club-mate-suechtigen gibt es immer wieder viel neues zu sehen und zu lernen. das mit der koerperhygiene scheinen die meisten nun hin zu bekommen und sogar mit anzug sind einige freaks rumgelaufen. mit serioesem, schickem, whatever aussehen hatte das aber nichts zu tun, sondern hat eher an fasching erinnert.

aufgrund der wetterlage war ich ja schonmal froh, dass mein flugzeug ueberhaupt flog und mich heil nach berlin brachte. waehrend des fluges servierte die (wie immer) nette crew von air berlin lecker gluehwein.

weniger lustig war dann die taxi knappheit auf dem flughafen tegel. die leute haben sich fast gepruegelt, um mit einem taxi der kaelte entfliehen zu koennen, denn die schlange am taxistand wurde immer laenger statt kuerzer. ich konnte nach 20 minuten eines ergattern, das aber komischerweise keiner mit mir teilen wollte. eigentlich dachte ich, dass nur die stadt offenbach es nicht geregelt bekommen mit dem streuen und raeumen, aber in berlin ists noch schlechter. genauso hat es fuer mich den anschein, dass die regelung, dass man den schnee vor seiner haustuer wegraeumen muss, in berlin anscheinend nicht gilt, oder sich zumindest niemand daran haelt.

mein hotel war ok fuer den preis. modern, aber sehr spartanisch. fruehstueck bis um 11 uhr, 24h besetzte rezeption, getraenke und cafe-bar. nur die heizung in meinem zimmer wollte nicht funktionieren. mitten in der nacht habe ich dann aber anstandslos ein anderes bekommen.

eigentlich mehr als gedankenstuetze fuer mich gedacht, aber vielleicht findet ja jemand in der folgenden aufstellung was interessantes. die aufzeichnungen zu den vortraegen werden hoffentlich in ein paar tagen online sein.

am tag 1 des 27c3 habe ich mir in der zeit von 12:00 bis 22:45 vortraege und diskussionen zu diesen themen angesehen:

tag 2: 11:30 bis 00:00 uhr

zu sehen gabs wie immer tolle und nicht tolle sachen:

tag 3: 11:30 bis 23:00 uhr

  • Chip and PIN is broken – Vulnerabilities in the EMV Protocol …kann ich nicht viel dazu sagen, denn zu beginn des vortrages habe ich den saal verlassen. das ding war gestopft voll, weil alle leute einen platz fuer die folgeveranstaltung (fefe’s und frank’s fnord jahresrueckblick) ergattern wollten. die auf dem boden sitzenden wurden aufgefordert, sich doch bitte hin zu stellen, damit mehr leute in den saal reinpassen. das war mir dann echt zu doof und ich bin gegangen. zurueck im hotel konnte ich gerade noch die letzten paar minuten davon per umts und livestrem verfolgen. aber eigentlich gings mir ja auch um den naechsten vortrag:
  • Fnord Jahresrückblick 2010 – von Atomausstieg bis Zwangsintegration … wie immer lustig und quasi pfichtprogramm. das schauen des streams im hotelzimmer war trotz vorhandenem schoppen nicht sehr entspannend, da es alle paar minuten gestockt hat. nach zwanzig minuten bin ich dann auf den stream “slides only” mit ton umgestiegen. das hat dann besser funktioniert.

tag 3: 11:30 bis 19:00 uhr

wenn die videos der veranstaltung online sind, werde ich zuhause ein paar vortraege nachholen. z.b.:

  • …und nich ein paar der vielen votraege ueber GSM. nicht, dass ich davon ahnung haette… ich bin aber neugierig, was da geht und wo es hin geht.

abschliessend noch ein paar allgemeine worte (aus der high and wide perspektive). seit ein paar jahren steht ja schon die diskussion im raum, dass der congress in einer anderen location stattfinden koennte/sollte/muesste, da das bcc aus allen naehten platzt. dieses jahr gab es erstmals die karten im vorverkauf. gefuehlt waren weniger leute da, wobei ich mich da auch taeuschen koennte.

auf jeden fall hat sich der ganze congress geaendert im vergleich zu den letzten acht jahren, die ich (bis auf ein mal) da war. bei meinen ersten besuchen herrschte echt noch chaos. leute lagen einfach mit schlafsaecken in der ecke oder unter der treppe. ueberall wurde geraucht, so dass es teilweise schon eklig war. waehrend den vortraegen lagen und sassen die leute in den gaengen rum. muellberge stapelten sich.

heute sieht das anders aus. alles laeuft geordnet ab. die saeaele haben (durch “ordner” gesteuert) festgelegte ein- und ausgaenge. die gaenge und ausgaenge muessen unbedingt freigehalten werden. die leute wurden aufgefordert, ihren muell ordnungsgemaess zu entsorgen. (frueher ist niemand ueber die muellberge gestolpert, aber heute gibts schon schwere unfaelle, wenn eine flasche auf dem boden rumliegt). zwischen den vortraegen gibt es animateuere pausenclowns die das publikum bei laune halten.

wie soll ich sagen… es ist (so scheint es zumindest) professioneller geworden. mich persoenlich nervten ein bischen die “engel”, die einem staendig irgendwas vorschreiben oder verbieten wollen bzw. muessen. klar, alles nachvollziehbar aus sicherheitsgruenden usw. die ganze veranstaltung ist nicht mehr so “authentisch” wie frueher. den permanenten schweissgeruch vermisse ich nicht, aber wenn leute anzug tragen, nur um irgendwas an ihrem image zu aendern oder cool auszusehen, finde ich das auch albern.

UPDATE: das mit den anzuegen hatte wohl einen hintergrund

mehr verschluesselung

als ich das erste mal was ueber die firefox erweiterung “https-everywhere” gehoert habe, stiegen in mir die erwartungen an dieses addon. ich hab mir sofort vorgestellt, dass dieses teil immer bei allen webseitenaufrufen ueberprueft, ob auch eine https variante existiert und dann dahin umleitet.

natuerlich ist das nicht so einfach, wie man sich das vorstellt. vor allem deswegen, weil es manche webseitenbetreiber es einfach nicht hinbekommen, dass die ssl seite die gleiche ist wie die ohne ssl. bei groesseren systemen steigt natuerlich die komplexitaet enorm. siehe facebook… ein zitat von heise.de:

“Entschärft wurde die Facebook-Regel – in der bisherigen Version waren einige Facebook-Apps aufgrund eines Zertifikatsfehlers nicht nutzbar. Wer seine Facebook-Cookies vor Diebstahl mit Tools wie Firesheep schützen will – und auf die Apps verzichten kann – muss nach der Installation des Add-ons nun den erweiterten Regelsatz Facebook+ aktivieren. Wer hingegen den Facebook-Chat nutzen will, muss bei der Seite auf sämtliche Schutzmaßnahmen verzichten und alle Facebook-Regeln deaktivieren.”

und den faq steht nochmal beschrieben, warum es nicht so einfach ist, wie ich mir das (ohne drueber nachzudenken) vorgestellt hatte:

“There are several problems with the idea of trying to automatically detect HTTPS on every site. Firstly, there is no guarantee that sites are going to give the same response via HTTPS that they give via HTTP. As of 2010, LiveJournal is a good example of this problem: compare these HTTP and HTTPS responses. Secondly, we don’t think it’s possible to test for HTTPS in real time without introducing security vulnerabilities (What should the extension do if the HTTPS connection attempt fails? Falling back to insecure HTTP isn’t safe). Lastly, in some cases, HTTPS Everywhere has to perform quite complicated transformations on URIs — for example the Wikipedia rule turns an address like http://en.wikipedia.org/wiki/World_Wide_Web into one like https://secure.wikimedia.org/wikipedia/en/wiki/World_Wide_Web.”

also ist es nun erstmal so, dass dieses addon nur die webseiten bedienen kann, die es auch von haus aus kennt. mag sein, dass da fuer viele was dabei ist, aber die seiten daraus, die ich persoenlich nutze, kann ich an einer hand abzaehlen:

wer will, kann sich eigene rulesets bauen und hinzufuegen. wie das geht steht hier geschrieben: https://www.eff.org/https-everywhere/rulesets.

fuer diese seite hier hab ichs mal gemacht und abgespeichert als sdvc.xml im verzeichnis “HTTPSEverywhereUserRules” unterhalb des firefox profile verzeichnises:


  
  
  

im screenshot rechts unten sieht man mein beispiel “sd.vc”. das kleine, aber feine plugin sollte aber nicht “https-everywhere” heissen sondern “https-somewhere” oder aehnlich… weil everywhere ist anders…

blogtuning

da diese webseite ja nur in einer kleinen, virtuellen maschine laeuft, die an einem lehmen dsl anschluss haengt, neige ich ja schon laenger dazu, die eingebetteten bilder vor dem hochladen so weit zu verkleinern, dass sie ins layout “reinpassen”. die qualitaet schraube ich zudem meist so weit runter dass man nicht mehr von schoenen bildern reden kann. ich sehe aber schon zu, dass die bilder entsprechend dem inhalt noch “nutzbar” sind. vor ein paar tagen habe ich dazu noch das apache modul “mod_deflate” aktiviert.

das an sich geht ja ganz easy:

ww:~# a2enmod deflate
Enabling module deflate.
Run '/etc/init.d/apache2 restart' to activate new configuration!

damit diverse alte browser noch zurechtkommen, habe ich die datei /etc/apache2/mods-available/deflate.conf ergaenzt um zeilen 3 bis 5:


  AddOutputFilterByType DEFLATE text/html text/plain text/xml
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

…und am ende der .htaccess datei im documentroot das hinzugefuegt:


  SetOutputFilter DEFLATE

hier gibts eine seite, mit der man dann ausprobieren kann, ob die komprimierung wie gewuenscht funktioniert. so sieht das ergebnis aus:

das ist doch schon mal ordentlich. um dann noch etwas bandbreite zu “sparen” habe ich ein paar bots per .htaccess datei ausgesperrt. die stellen zwar die anfrage, aber bekommen nur eine fehlermeldung zurueck. die hier angezeigte .htaccess ist stark verkuerzt. die komplette version gibts als download

SetEnvIfNoCase user-Agent "^AESOP_com_SpiderMan" bad_bot
SetEnvIfNoCase user-Agent "^Alexibot" bad_bot
SetEnvIfNoCase user-Agent "Anonymouse.org" bad_bot
SetEnvIfNoCase user-Agent "^asterias" bad_bot
SetEnvIfNoCase user-Agent "^attach" bad_bot
SetEnvIfNoCase user-Agent "^BackDoorBot" bad_bot
[...]

Order Allow,Deny
Allow from all
Deny from env=bad_bot

die liste mit den bad bots habe ich mir zusammengegoogelt. zum testen hab ich einfach mal den safari eingetragen. so wuerde das dann fuer einen bot “aussehen”, der in der .htaccess gelistet ist:

und im apache error-logfile steht dann:

[Fri Nov 12 09:26:57 2010] [error] [client 85.xxx.xx.xxx] 
client denied by server configuration: /xxxxxxx/sd.vc/wp/

tsql regex oder nicht regex (teil 2)

ich habe meine untersuchung der sehr beschraenkten moeglichkeiten regex mit microsofts tsql zu nutzen fortgefuehrt.

dabei kam mir noch das “^” unter. laut dokumentation dient es der negierung: “Any single character not within the specified range”. was dann in der praxis wie beim vorangegangenen beispiel wieder nicht mit den kleinbuchstaben “[a-z]” funktioniert:

der vollstaendigkeit halber noch der code zum ergaenzen des ersten beispiels:

[...]
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[^a-z]') THEN @x
  ELSE '' END AS '[^a-z]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[^A-Z]') THEN @x
  ELSE '' END AS '[^A-Z]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[^0-9]') THEN @x
  ELSE '' END AS '[^0-9]'
[...]

tsql regex oder nicht regex

bei einem sql statement stoesst man irgendwann an die grenzen der moeglichkeiten normaler vergleichsoperatoren. regulaere ausdruecke muessen her! .. denkt man sich dann. in microsofts tsql ist sowas in der art eingebaut. eigentlich nicht wirklich vergleichbar mit regulaeren ausdruecken, aber sieht ein bischen aus als ob.

und irgendwann stoesst man dann auch dabei auf grenzen. und wenn die moeglichkeiten bis zum letzten ausgereitzt sind, merkt man auch, dass nicht alles so funktioniert, wie es soll. zum demonstrieren ein kleines beispiel. (das hatte ich so aehnlich vor laengerer zeit mal auf irgendeiner webseite gefunden.)

DECLARE @tmp TABLE (wert char(1))

INSERT INTO @tmp (wert) VALUES ('1')
INSERT INTO @tmp (wert) VALUES ('A')
INSERT INTO @tmp (wert) VALUES ('a')
INSERT INTO @tmp (wert) VALUES (NULL)
INSERT INTO @tmp (wert) VALUES (' ')
INSERT INTO @tmp (wert) VALUES ('')
INSERT INTO @tmp (wert) VALUES ('J')
INSERT INTO @tmp (wert) VALUES ('!')
INSERT INTO @tmp (wert) VALUES ('9')
DECLARE @x varchar(10)

SET @x = 'MATCH'

SELECT wert,
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[A-Z]') THEN @x
  ELSE '' END AS '[A-Z]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[a-z]') THEN @x
  ELSE '' END AS '[a-z]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[a-zA-Z]') THEN @x
  ELSE '' END AS '[a-zA-Z]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[0-9]') THEN @x
  ELSE '' END AS '[0-9]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[0-8]') THEN @x
  ELSE '' END AS '[0-8]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[A-Z|0-9]') THEN @x
  ELSE '' END AS '[A-Z|0-9]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[J]') THEN @x
  ELSE '' END AS '[J]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[JERRY]') THEN @x
  ELSE '' END AS '[JERRY]',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '%[A]%') THEN @x
  ELSE '' END AS '%[A]%',
CASE
 WHEN (wert COLLATE Latin1_General_CS_AS LIKE '[ ]') THEN @x
  ELSE '' END AS '[ ]'
FROM @tmp as t

das ergebniss sieht dann so aus:
(anklicken zum vergroessern)

man sieht, dass “[A-Z]” richtig funktioniert und “[a-z]” nicht so ganz und “[ ]” findet leerzeichen, aber auch “kein zeichen”. fuer viele sachen ist es aber doch sehr brauchbar, wenn man die fehler kennt. wer mehr moeglichkeiten braucht, kommt um ein bischen programmieraufwand oder kauf von fertigen addons nicht herum.

wordpress external pages hack

da ich mich (warum auch immer) mal dafuer entschieden hatte, ein gesondertes “urlaubsblog” zu machen, stand ich die ganze zeit vor dem problem, das in diesem blog zu verlinken. ich wollte das naemlich in der rechten sidebar unter den pages auffuehren, aber wusste nicht wie. in wordpress selbst habe ich alles durchgeklickert, was es gab und hab nichts gefunden. ich wollte schon die templates umbauen, um das zu realisieren, hab aber dann noch ein wenig gegoogelt und bin auch fuendig geworden!

man muss naemlich einfach als titel einer page einen link einfuegen und schon verweist der link der page (im pages widget im menue auf der linken seite) auf eine externe url. sieht im backend etwas komisch aus, funktioniert aber prima 😉

interessierten wordpress nutzern moechte ich noch das posting “mehrere blogs mit einer wordpress installation” empfehlen. (mit einfuehrung der multisite funktionalitaet in wordpress 3 geht das zwar auch anders, die funktionsweise scheint aber aehnlich sein. ich habs mir noch nicht sooo genau angesehen. es scheint aber noch ein paar weitere features in diesem zusammenhang zu geben.)