<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>PHP Gangsta - Der PHP Blog mit Praxisbezug &#187; Linux</title> <atom:link href="http://www.phpgangsta.de/category/linux/feed" rel="self" type="application/rss+xml" /><link>http://www.phpgangsta.de</link> <description>Ein PHP Blog mit Themen aller Art. Manchmal vergewaltige ich PHP...</description> <lastBuildDate>Thu, 02 Feb 2012 22:22:51 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Ausfallsichere, skalierbare und sichere Hosting-Lösung von maxcluster zu gewinnen!</title><link>http://www.phpgangsta.de/ausfallsichere-skalierbare-und-sichere-hosting-losung-von-maxcluster-zu-gewinnen</link> <comments>http://www.phpgangsta.de/ausfallsichere-skalierbare-und-sichere-hosting-losung-von-maxcluster-zu-gewinnen#comments</comments> <pubDate>Wed, 01 Feb 2012 08:38:45 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[Server-Software]]></category> <category><![CDATA[Cluster Hosting]]></category> <category><![CDATA[Gewinnspiel]]></category> <category><![CDATA[IaaS]]></category> <category><![CDATA[maxcluster]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=4236</guid> <description><![CDATA[Mit einer spannenden Aktion möchte ich in den Februar starten. Der Anbieter maxcluster stellt zwei Produkte für eine Laufzeit von 6 Monaten zur Verfügung mit einem Gesamtwert von über 2300€! Was gibt es genau zu gewinnen? Application Cluster mit einer Konfiguration von 6 CPUs, 8 GB RAM, 200 GB HDD, 20 GB Netzwerk-Storage und 500 [...]<br/><br/> Ähnliche Artikel:<ol><li><a href='http://www.phpgangsta.de/php-magazin-jahresabos-zu-gewinnen' rel='bookmark' title='PHP Magazin Jahresabos zu gewinnen'>PHP Magazin Jahresabos zu gewinnen</a></li><li><a href='http://www.phpgangsta.de/weihnachtsgewinnspiel-bei-antwerpes-arduino-zu-gewinnen' rel='bookmark' title='Weihnachtsgewinnspiel bei antwerpes: Arduino zu gewinnen'>Weihnachtsgewinnspiel bei antwerpes: Arduino zu gewinnen</a></li><li><a href='http://www.phpgangsta.de/php-test-fur-fortgeschrittene-zce-tests-zu-gewinnen' rel='bookmark' title='PHP-Test für Fortgeschrittene | ZCE Tests zu gewinnen'>PHP-Test für Fortgeschrittene | ZCE Tests zu gewinnen</a></li></ol>]]></description> <content:encoded><![CDATA[<p><a href="http://maxcluster.de/" target="_blank"><img class="alignright  wp-image-4237" style="border: 0pt none;" title="maxcluster" src="http://www.phpgangsta.de/wp-content/uploads/maxclusterlogo.png" alt="" width="214" height="34" /></a>Mit einer spannenden Aktion möchte ich in den Februar starten. Der Anbieter <a href="http://maxcluster.de/" target="_blank">maxcluster</a> stellt zwei Produkte für eine Laufzeit von 6 Monaten zur Verfügung mit einem Gesamtwert von über 2300€!</p><p>Was gibt es genau zu gewinnen?</p><ol><li>Application Cluster mit einer Konfiguration von 6 CPUs, 8 GB RAM, 200 GB HDD, 20 GB Netzwerk-Storage und 500 GB Traffic</li><li>Failover Cluster mit einer Konfiguration von 2 CPUs, 4 GB RAM, 100 GB HDD , 10 GB Netzwerk-Storage und 500 GB Traffic</li></ol><p><a href="http://maxcluster.de/magento-cluster-hosting" target="_blank"><img class="size-medium wp-image-4238 alignnone" style="border: 0pt none;" title="Failover Cluster" src="http://www.phpgangsta.de/wp-content/uploads/products-failover-cluster-architecture-300x74.jpg" alt="" width="300" height="74" /></a></p><p><strong>Wie kann man einen Cluster gewinnen?</strong></p><p>Beschreibe kurz in 2-3 Sätzen hier im Blog als Kommentar welches Projekt auf dem Cluster betrieben werden soll. Den Zuschlag bekommt das Projekt welches am faszinierendsten und interessantesten wirkt. Die Aktion läuft bis nächsten Dienstag Abend 23:59 (07.02.2012). <strong>Der Cluster kann gern von Start-Ups, Unternehmen oder privat genutzt werden.</strong></p><p>Vier Wochen nach der Vergabe würde ich mich über einen kurzen Erfahrungsbericht hier im Blog freuen, und maxcluster freut sich natürlich auch sehr über Verbesserungensvorschläge und Feedback aller Art.</p><blockquote><p>Die maxcluster GmbH stellt ausfallsichere, skalierbare und sichere virtuelle Cluster zur Verfügung. Die Infrastruktur wurde für Unternehmen mit anspruchsvollen Internetseiten und Anwendungen konzipiert und ist in Frankfurt beheimatet. Bereits ab einer monatlichen Gebühr von 59 Euro steht eine komplette Infrastruktur mit ausfallsicheren Servern, redundanten Storage, externer Firewall, täglichen Backups und Monitoring zur Verfügung, die sofort einsatzbereit ist. Neben vielen anderen Kunden und Projekten wird auch das <a href="http://wiwi.uni-paderborn.de/dep3/winfo2/forschung/projekte/paderborner-peer-instruction/" target="_blank">Paderborner Peer Instruction</a> Projekt unterstützt.</p></blockquote><p>Ich wünsche viel Erfolg bei dem Gewinnspiel! Vielen Dank an maxcluster für die Aktion!</p> <br/><br/><p>Ähnliche Artikel:</p><ol><li><a href='http://www.phpgangsta.de/php-magazin-jahresabos-zu-gewinnen' rel='bookmark' title='PHP Magazin Jahresabos zu gewinnen'>PHP Magazin Jahresabos zu gewinnen</a></li><li><a href='http://www.phpgangsta.de/weihnachtsgewinnspiel-bei-antwerpes-arduino-zu-gewinnen' rel='bookmark' title='Weihnachtsgewinnspiel bei antwerpes: Arduino zu gewinnen'>Weihnachtsgewinnspiel bei antwerpes: Arduino zu gewinnen</a></li><li><a href='http://www.phpgangsta.de/php-test-fur-fortgeschrittene-zce-tests-zu-gewinnen' rel='bookmark' title='PHP-Test für Fortgeschrittene | ZCE Tests zu gewinnen'>PHP-Test für Fortgeschrittene | ZCE Tests zu gewinnen</a></li></ol>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/ausfallsichere-skalierbare-und-sichere-hosting-losung-von-maxcluster-zu-gewinnen/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Letzte Aktion in 2011: Server via IPv6 verfügbar machen</title><link>http://www.phpgangsta.de/letzte-aktion-in-2011-server-via-ipv6-verfugbar-machen</link> <comments>http://www.phpgangsta.de/letzte-aktion-in-2011-server-via-ipv6-verfugbar-machen#comments</comments> <pubDate>Sat, 31 Dec 2011 11:13:42 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Allgemein]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[Server-Software]]></category> <category><![CDATA[DNS]]></category> <category><![CDATA[Hoster]]></category> <category><![CDATA[IPv4]]></category> <category><![CDATA[IPv6]]></category> <category><![CDATA[Mailserver]]></category> <category><![CDATA[nginx]]></category> <category><![CDATA[Postfix]]></category> <category><![CDATA[webserver]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=4119</guid> <description><![CDATA[So, damit es nicht heißt mein Blog wäre in 2011 nicht via IPv6 erreichbar gewesen ist meine letzte Aktion dieses Jahr meinen Webserver via IPv6 erreichbar zu machen. Da mein Hoster nun auch endlich IPv6 für virtuelle Server anbietet war das ziemlich einfach: Man mußte im Kundenbereich die IPv6 Konnektivität aktivieren und 10 Minuten warten. [...]<br/><br/> Ähnliche Artikel:<ol><li><a href='http://www.phpgangsta.de/zuhause-im-ipv6-web-surfen-teil2-windows' rel='bookmark' title='Zuhause im IPv6 Web surfen (Teil2: Windows)'>Zuhause im IPv6 Web surfen (Teil2: Windows)</a></li><li><a href='http://www.phpgangsta.de/zuhause-im-ipv6-web-surfen' rel='bookmark' title='Zuhause im IPv6 Web surfen (Teil1: Ubuntu)'>Zuhause im IPv6 Web surfen (Teil1: Ubuntu)</a></li></ol>]]></description> <content:encoded><![CDATA[<p><img class="alignright size-full wp-image-4136" title="IPv6 ready" src="http://www.phpgangsta.de/wp-content/uploads/ipv6-small.png" alt="" width="88" height="31" />So, damit es nicht heißt mein Blog wäre in 2011 nicht via <a href="http://www.phpgangsta.de/tag/ipv6" target="_blank">IPv6</a> erreichbar gewesen ist meine letzte Aktion dieses Jahr meinen Webserver via IPv6 erreichbar zu machen. Da mein Hoster nun auch endlich IPv6 für virtuelle Server anbietet war das ziemlich einfach: Man mußte im Kundenbereich die IPv6 Konnektivität aktivieren und 10 Minuten warten. Und schon war der Server via IPv6 erreichbar:</p><pre class="brush: bash; title: ; notranslate">$ ifconfig venet0 | grep inet6
inet6-Adresse: 2a01:238:42b6:2a00:e661:84eb:4a08:ee54/128 Gültigkeitsbereich:Global
inet6-Adresse: ::1/128 Gültigkeitsbereich:Maschine</pre><p>Dann mußte ich gerade noch den nginx neu kompilieren für die IPv6 Funktionalität (wurde eh mal wieder Zeit, war noch eine alte 0.8.53 Version), sodass ich nun die aktuelle 1.0.11 verwende:</p><p><span id="more-4119"></span></p><pre class="brush: bash; title: ; notranslate">$ wget http://nginx.org/download/nginx-1.0.11.tar.gz
$ tar -xzvf nginx-1.0.11.tar.gz
$ cd nginx-1.0.11
$ ./configure --with-http_ssl_module --without-http_memcached_module --with-http_gzip_static_module --with-ipv6
$ make
$ sudo make install
$ sudo /etc/init.d/nginx restart</pre><p>Und schon war die neue Version installiert, nun mit IPv6 Unterstützung:</p><pre class="brush: bash; title: ; notranslate">$ /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.0.11
built by gcc 4.4.5 (Debian 4.4.5-8)
TLS SNI support enabled
configure arguments: --with-http_ssl_module --without-http_memcached_module --with-http_gzip_static_module --with-ipv6</pre><p>Da ich in der nginx.conf aktuell nur eine server-Directive konfiguriert habe, da ich alles auf den dahinterliegenden Apache weiterleite, und bisher auf allen (sprich einer) IPv4 Adresse gelauscht habe kann ich das einfach ändern auf &#8220;alle IPv4+IPv6 Adressen&#8221;:</p><pre class="brush: plain; title: ; notranslate">listen [::]:80;</pre><p>Würde ich nur auf IPv6-Adressen lauschen wollen müßte ich den ipv6only Parameter nutzen:</p><pre class="brush: plain; title: ; notranslate">listen [::]:80 default ipv6only=on;</pre><p>Da ich nur eine öffentliche IPv6 Adresse habe (und auf localhost nicht lauschen möchte) könnte ich auch folgendes nehmen:</p><pre class="brush: plain; title: ; notranslate">listen [2a01:238:42b6:2a00:e661:84eb:4a08:ee54]:80;</pre><p>Nach einem erneuten Restart von nginx kann man nun meinen Server anpingen (vorausgesetzt man selbst hat IPv6 Verbindung zuhause, sonst natürlich nicht):</p><pre class="brush: bash; title: ; notranslate">$ ping6 2a01:238:42b6:2a00:e661:84eb:4a08:ee54
PING 2a01:238:42b6:2a00:e661:84eb:4a08:ee54(2a01:238:42b6:2a00:e661:84eb:4a08:ee54) 56 data bytes
64 bytes from 2a01:238:42b6:2a00:e661:84eb:4a08:ee54: icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from 2a01:238:42b6:2a00:e661:84eb:4a08:ee54: icmp_seq=2 ttl=64 time=0.068 ms</pre><p>So, was bleibt noch zu tun? Klar, DNS-Records anlegen. Für IPv6 sind das keine A Records sondern AAAA Records. Ich habe die folgenden angelegt:</p><pre class="brush: plain; title: ; notranslate">www.phpgangsta.de AAAA 2a01:238:42b6:2a00:e661:84eb:4a08:ee54
*.phpgangsta.de AAAA 2a01:238:42b6:2a00:e661:84eb:4a08:ee54
ipv6.phpgangsta.de AAAA 2a01:238:42b6:2a00:e661:84eb:4a08:ee54</pre><p>Damit ist die Domain incl. aller Subdomains nun auch via IPv6 erreichbar. Zur Überprüfung gibt es auch <a href="http://ipv6-test.com/validate.php" target="_blank">kleine Online Test Scripte</a> mit denen man schauen kann ob eine <a href="http://www.ip6test.com/server.php" target="_blank">Domain via IPv6</a> erreichbar ist. Ein weiteres <a href="http://www.subnetonline.com/pages/ipv6-network-tools/online-ipv6-ping.php" target="_blank">kleines Online-Tool für IPv6 Ping, Trace und Port Check</a>.</p><p><img class="alignnone size-full wp-image-4133" title="ipv6.phpgangsta.de" src="http://www.phpgangsta.de/wp-content/uploads/ipv6.phpgangsta.de_.png" alt="" width="722" height="749" /></p><h3>Mailserver:</h3><p>Da es so einfach und schnell ging habe ich auch noch schnell den Mailserver IPv6 ready gemacht. Dazu einfach die Postfix main.cf öffnen und folgende Zeilen ändern:</p><pre class="brush: plain; title: ; notranslate">inet_interfaces = all
inet_protocols = all</pre><p>Wer es nicht mag auf allen IP-Adressen zu lauschen kann sie natürlich auch auflisten:</p><pre class="brush: plain; title: ; notranslate">inet_interfaces = 127.0.0.1, 85.214.28.26, 2a01:238:42b6:2a00:e661:84eb:4a08:ee54, ::1
inet_protocols = ipv4, ipv6</pre><p>Danach den Postfix neustarten, fertig!</p><pre class="brush: plain; title: ; notranslate">telnet 2a01:238:42b6:2a00:e661:84eb:4a08:ee54 25</pre><p>Eingehende E-Mails können nun also auch über IPv6 empfangen werden. Hier sollte man dann darauf achten dass der DNS-MX-Eintrag richtig ist:</p><pre class="brush: bash; title: ; notranslate">$ dig -t MX phpgangsta.de +short
10 mail.phpgangsta.de.

$ dig -t AAAA mail.phpgangsta.de +short
2a01:238:42b6:2a00:e661:84eb:4a08:ee54</pre><p>Ob ausgehende E-Mails auch über IPv6 versendet werden kann man testen indem man eine E-Mail an autoreply@v6-mail.com schickt.</p><p>In /var/log/mail.log findet sich dann die folgende Zeile:</p><pre class="brush: plain; title: ; notranslate">Dec 31 02:20:51 h1440682 postfix/smtp[8177]: 68FB149CC961: to=&lt;autoreply@v6-mail.com&gt;,
relay=v6-mail.com[2001:470:18:16c::2]:25, delay=3, delays=1/0.01/1.2/0.67, dsn=2.0.0,
status=sent (250 2.0.0 Ok: queued as 9C566E401E0)</pre><h3>Fallstricke, Achtung!</h3><p>Wenn man IPv6 aktiviert sollte man natürlich über ein paar Dinge nachdenken. Beispielsweise wie die (PHP-) Applikationen mit IPv6 klarkommen, denn in $_SERVER['REMOTE_ADDR'] steht plötzlich eine IPv6 Adresse drin. Auch beim Mailserver muss man aufpassen falls man sich bisher auf IP-Blacklists (sogenannte DNSBLs) verlassen hat, bei IPv6 gibt es die nicht.</p><p>Falls man Firewall Regeln definiert hat müssen diese für IPv6 natürlich auch gemacht werden&#8230;</p><p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p><p>Wie weit seid ihr privat und auf der Arbeit mit IPv6? Sind eure Blogs, Firmenwebserver etc. schon via IPv6 erreichbar?</p> <br/><br/><p>Ähnliche Artikel:</p><ol><li><a href='http://www.phpgangsta.de/zuhause-im-ipv6-web-surfen-teil2-windows' rel='bookmark' title='Zuhause im IPv6 Web surfen (Teil2: Windows)'>Zuhause im IPv6 Web surfen (Teil2: Windows)</a></li><li><a href='http://www.phpgangsta.de/zuhause-im-ipv6-web-surfen' rel='bookmark' title='Zuhause im IPv6 Web surfen (Teil1: Ubuntu)'>Zuhause im IPv6 Web surfen (Teil1: Ubuntu)</a></li></ol>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/letzte-aktion-in-2011-server-via-ipv6-verfugbar-machen/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Das POP3 Protokoll im Detail betrachtet</title><link>http://www.phpgangsta.de/das-pop3-protokoll-im-detail-betrachtet</link> <comments>http://www.phpgangsta.de/das-pop3-protokoll-im-detail-betrachtet#comments</comments> <pubDate>Mon, 28 Nov 2011 08:53:20 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[Server-Software]]></category> <category><![CDATA[Authentifizierung]]></category> <category><![CDATA[Kommandos]]></category> <category><![CDATA[POP3]]></category> <category><![CDATA[POP3 Commands]]></category> <category><![CDATA[POP3 Telnet]]></category> <category><![CDATA[Protokoll]]></category> <category><![CDATA[Telnet]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=3970</guid> <description><![CDATA[Nachdem ich bereits das IMAP Protokoll und auch das SMTP Protokoll unter die Lupe genommen habe, möchte ich heute das POP3 Protokoll untersuchen und zeigen welche Befehle es gibt und wie man damit E-Mails von einem Mail-Server lesen kann. POP3 ist genauso wie IMAP ein Protokoll zum Abholen von E-Mails mit einem Mailclient wie zum [...]<br/><br/> Ähnliche Artikel:<ol><li><a href='http://www.phpgangsta.de/das-imap-protokoll-im-detail-betrachtet' rel='bookmark' title='Das IMAP Protokoll im Detail betrachtet'>Das IMAP Protokoll im Detail betrachtet</a></li><li><a href='http://www.phpgangsta.de/das-smtp-protokoll-im-detail-betrachtet' rel='bookmark' title='Das SMTP Protokoll im Detail betrachtet'>Das SMTP Protokoll im Detail betrachtet</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Nachdem ich bereits das <a href="http://www.phpgangsta.de/das-imap-protokoll-im-detail-betrachtet" target="_blank">IMAP Protokoll</a> und auch das <a href="http://www.phpgangsta.de/das-smtp-protokoll-im-detail-betrachtet" target="_blank">SMTP Protokoll</a> unter die Lupe genommen habe, möchte ich heute das POP3 Protokoll untersuchen und zeigen welche Befehle es gibt und wie man damit E-Mails von einem Mail-Server lesen kann. POP3 ist genauso wie IMAP ein Protokoll zum Abholen von E-Mails mit einem Mailclient wie zum Beispiel Outlook, Thunderbird etc.</p><p>Zuerst müssen wir uns zum Server verbinden, das geht entweder unverschlüsselt oder verschlüsselt mittels TLS oder SSL. Hier die verschiedenen Wege:</p><p><span id="more-3970"></span></p><pre class="brush: plain; title: ; notranslate">telnet pop3.phpgangsta.de 110
Trying 85.214.28.26...
Connected to pop3.phpgangsta.de.
Escape character is '^]'.
+OK Dovecot ready.</pre><p>Verschlüsselt mit TLS sieht das so aus:</p><pre class="brush: plain; title: ; notranslate">openssl s_client -crlf -connect pop3.phpgangsta.de:110 -starttls pop3
CONNECTED(00000003)
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=18:self signed certificate
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=10:certificate has expired
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
---
Certificate chain
0 s:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
i:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDQDCCAqmgAwIBAgIJAPqlHcMGI8LLMA0GCSqGSIb3DQEBBQUAMHQxHDAaBgNV
BAoTE0RvdmVjb3QgbWFpbCBzZXJ2ZXIxEjAQBgNVBAsTCWgxNDQwNjgyLjEiMCAG
A1UEAxMZaDE0NDA2ODIuc3RyYXRvc2VydmVyLm5ldDEcMBoGCSqGSIb3DQEJARYN

...

---
+OK Dovecot ready.</pre><p>Und schliesslich verschlüsselt mit SSL über den Port 995:</p><pre class="brush: plain; title: ; notranslate">openssl s_client -connect pop3.phpgangsta.de:995
CONNECTED(00000003)
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=18:self signed certificate
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
verify error:num=10:certificate has expired
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
depth=0 O = Dovecot mail server, OU = h1440682., CN = h1440682.stratoserver.net, emailAddress = root@hwn53662
notAfter=Dec  4 21:15:04 2009 GMT
verify return:1
---
Certificate chain
0 s:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
i:/O=Dovecot mail server/OU=h1440682./CN=h1440682.stratoserver.net/emailAddress=root@hwn53662
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDQDCCAqmgAwIBAgIJAPqlHcMGI8LLMA0GCSqGSIb3DQEBBQUAMHQxHDAaBgNV
BAoTE0RvdmVjb3QgbWFpbCBzZXJ2ZXIxEjAQBgNVBAsTCWgxNDQwNjgyLjEiMCAG
A1UEAxMZaDE0NDA2ODIuc3RyYXRvc2VydmVyLm5ldDEcMBoGCSqGSIb3DQEJARYN

...

---
+OK Dovecot ready.</pre><p>Gut, die Verbindung steht, nun müssen wir uns authentifizieren. Dazu gibt es verschiedene Möglichkeiten, hier die einfachste:</p><pre class="brush: plain; title: ; notranslate">USER xxxx@phpgangsta.de
+OK
PASS SicheresPasswort
+OK Logged in.</pre><p>Der Loginname und das Passwort werden einzeln um im Klartext an den Server geschickt. Solange TLS oder SSL bereits aktiviert sind ist das kein Sicherheitsproblem, sollte allerdings keine Verschlüsselung aktiviert sein sollte man für die Authentifizierung besser APOP nutzen (auch wenn das nicht 100% sicher ist):</p><p>http://de.wikipedia.org/wiki/APOP</p><pre class="brush: plain; title: ; notranslate">+OK POP3 server ready &lt;1896.697170952@phpgangsta.de&gt;
APOP xxx@phpgangsta.de c4c9334bac560ecc979e58001b3e22fb
+OK Logged in.</pre><p>Der zweite Parameter ist ein MD5-Hash, der aus dem Zeitstempel ( &lt;process-ID.timestamp@hostname&gt; ) und dem Klartextkennwort gebildet wird. Dies kann der Server dann überprüfen und den Login zulassen oder nicht.</p><p>Nach dem Login möchten wir wahrscheinlich eine Liste aller E-Mails haben. Eine vollständige Liste aller Nachrichtennummern und Größen gibt es mit dem Befehl</p><pre class="brush: plain; title: ; notranslate">LIST
+OK 7 messages:
1 1737
2 2333
3 1984
4 1788
5 4094
6 2693
7 2279
.</pre><p>Nur die Größe der 5. Nachricht fragt man so ab:</p><pre class="brush: plain; title: ; notranslate">LIST 5
+OK 5 4094</pre><p>Möchten wir nun eine E-Mail abrufen holen wir wie folgt die komplette 1. Nachricht:</p><pre class="brush: plain; title: ; notranslate">RETR 1
+OK 1737 octets
Return-Path: &lt;XXXX@domain.de&gt;
Delivered-To: xxx@phpgangsta.de
Received: from localhost (h1440682.stratoserver.net [127.0.0.1])
by h1440682.stratoserver.net (Postfix) with ESMTP id 0EBBAEC9A8F
for &lt;xxx@phpgangsta.de&gt;; Sun, 29 Nov 2009 11:14:26 +0000 (UTC)
Message-ID: &lt;4B125783.9050508@gmx.de&gt;
Date: Sun, 29 Nov 2009 12:14:11 +0100
From: Michael Kliewe &lt;XXXX@domain.de&gt;
User-Agent: Thunderbird 2.0.0.23 (Windows/20090812)
MIME-Version: 1.0
To: xxx@phpgangsta.de
Subject: test neues Konto
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

das sollte ankommen
.</pre><p>Wir können auch nur die Header abfragen:</p><pre class="brush: plain; title: ; notranslate">TOP 1 0
+OK
Return-Path: &lt;XXXX@domain.de&gt;
Delivered-To: xxx@phpgangsta.de
Received: from localhost (h1440682.stratoserver.net [127.0.0.1])
by h1440682.stratoserver.net (Postfix) with ESMTP id 0EBBAEC9A8F
for &lt;xxx@phpgangsta.de&gt;; Sun, 29 Nov 2009 11:14:26 +0000 (UTC)
Message-ID: &lt;4B125783.9050508@gmx.de&gt;
Date: Sun, 29 Nov 2009 12:14:11 +0100
From: Michael Kliewe &lt;XXXX@domain.de&gt;
User-Agent: Thunderbird 2.0.0.23 (Windows/20090812)
MIME-Version: 1.0
To: xxx@phpgangsta.de
Subject: test neues Konto
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

.</pre><p>Mit &#8220;TOP 1 10&#8243; könnten wir uns die Header plus die ersten 10 Zeilen der E-Mail geben lassen.</p><p>Möchten wir eine E-Mail löschen (weil wir sie gelesen bzw. heruntergeladen haben) markieren wir sie zur Löschung:</p><pre class="brush: plain; title: ; notranslate">DELE 1
+OK Marked to be deleted.</pre><p>Fragen wir nun erneut die Liste aller vorhandenen E-Mails ab erhalten wir:</p><pre class="brush: plain; title: ; notranslate">LIST
+OK 6 messages:
2 2333
3 1984
4 1788
5 4094
6 2693
7 2279
.</pre><p>Die erste Nachricht fehlt (wir haben sie ja zum Löschen markiert), aber bemerkenswert ist dass die fortlaufende Nummerierung nicht wiederhergestellt wurde, es gibt nun also eine Lücke. Sobald man sich ausloggt wird die zum Löschen markierte E-Mail wirklich gelöscht. Wenn man das nicht möchte und sie wiedergestellen möchte hilft ein Reset der Markierungen:</p><pre class="brush: plain; title: ; notranslate">RSET
+OK</pre><p>Möchte man eine eindeutige Kennung herausfinden geht das mit dem UIDL Kommando:</p><pre class="brush: plain; title: ; notranslate">UIDL 6
+OK 6 UID21-1259493142</pre><p>Eine vollständige Liste alle UIDs erhält man mittels</p><pre class="brush: plain; title: ; notranslate">UIDL
+OK
1 UID3-1259493142
2 UID4-1259493142
3 UID5-1259493142
4 UID7-1259493142
5 UID20-1259493142
6 UID21-1259493142
7 UID84-1259493142
.</pre><p>Wenn die Verbindung aufrecht erhalten werden soll müssen wir etwas gegen den drohenden Timeout machen, wir senden periodisch ein NOOP um dem Server zu sagen dass wir noch da sind:</p><pre class="brush: plain; title: ; notranslate">NOOP
+OK</pre><p>Ein kurzer Befehl um den aktuellen Status anzeigen zu lassen:</p><pre class="brush: plain; title: ; notranslate">STAT
+OK 7 16573</pre><p>Damit könnte man beispielsweise schnell prüfen ob neue E-Mails dazugekommen sind usw.</p><p>Soll die Verbindung getrennt werden loggen wir uns aus:</p><pre class="brush: plain; title: ; notranslate">QUIT
+OK Logging out, messages deleted.
Connection closed by foreign host.</pre><p>Tja, das war es schon wieder, POP3 ist ziemlich einfach, es gibt keine Ordner oder Flags wie in IMAP, deshalb ist die Kommandoübersicht recht kurz. Bis auf einige Sonderfälle sollte immer IMAP verwendet werden, dann kann man mit Ordner und Flags arbeiten, Dank IMAP IDLE kommen E-Mails in Echtzeit an usw.</p> <br/><br/><p>Ähnliche Artikel:</p><ol><li><a href='http://www.phpgangsta.de/das-imap-protokoll-im-detail-betrachtet' rel='bookmark' title='Das IMAP Protokoll im Detail betrachtet'>Das IMAP Protokoll im Detail betrachtet</a></li><li><a href='http://www.phpgangsta.de/das-smtp-protokoll-im-detail-betrachtet' rel='bookmark' title='Das SMTP Protokoll im Detail betrachtet'>Das SMTP Protokoll im Detail betrachtet</a></li></ol>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/das-pop3-protokoll-im-detail-betrachtet/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Das SMTP Protokoll im Detail betrachtet</title><link>http://www.phpgangsta.de/das-smtp-protokoll-im-detail-betrachtet</link> <comments>http://www.phpgangsta.de/das-smtp-protokoll-im-detail-betrachtet#comments</comments> <pubDate>Mon, 08 Aug 2011 07:38:10 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[Server-Software]]></category> <category><![CDATA[IMAP Telnet]]></category> <category><![CDATA[SMTP]]></category> <category><![CDATA[SMTP Befehle]]></category> <category><![CDATA[SMTP Protokoll]]></category> <category><![CDATA[Telnet]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=1158</guid> <description><![CDATA[Vor einem Jahr habe ich bereits das IMAP-Protokoll näher betrachtet, nun soll das SMTP Protokoll folgen. Jeder versendet und empfängt E-Mails, und viele von euch werden auch eigene Mailserver betreiben, es kann also nicht schaden das Protokoll näher zu kennen. SMTP steht für Simple Mail Transport Protocol, und genau das ist es auch: Simple. Mit [...]<br/><br/> Ähnliche Artikel:<ol><li><a href='http://www.phpgangsta.de/das-imap-protokoll-im-detail-betrachtet' rel='bookmark' title='Das IMAP Protokoll im Detail betrachtet'>Das IMAP Protokoll im Detail betrachtet</a></li></ol>]]></description> <content:encoded><![CDATA[<p><img class="alignright size-thumbnail wp-image-3241" title="mail" src="http://www.phpgangsta.de/wp-content/uploads/mail-150x131.png" alt="" width="150" height="131" />Vor einem Jahr habe ich bereits das <a href="http://www.phpgangsta.de/das-imap-protokoll-im-detail-betrachtet" target="_blank">IMAP-Protokoll näher betrachtet</a>, nun soll das <a href="http://tools.ietf.org/html/rfc2821" target="_blank">SMTP Protokoll</a> folgen. Jeder versendet und empfängt E-Mails, und viele von euch werden auch eigene Mailserver betreiben, es kann also nicht schaden das Protokoll näher zu kennen. SMTP steht für Simple Mail Transport Protocol, und genau das ist es auch: Simple. Mit einer Hand voll Befehlen kann man E-Mails auf den Weg bringen. SMTP wird von Mailservern gesprochen die E-Mails empfangen oder an andere Mailserver weitergeben, zur E-Mail-Abholung durch einen Client wird IMAP oder POP3 genutzt.</p><p>Nehmen wir erstmal den einfachsten Fall: Wir möchten eine E-Mail an meine E-Mail Adresse schicken. Dazu müssen wir zuerst herausfinden welcher Server für diese E-Mail-Adresse zuständig ist. Wir befragen den DNS-Server nach dem sogenannten MX-Eintrag (Mail Exchange) und erhalten den oder die Server, an die wir uns wenden müssen:</p><pre class="brush: plain; title: ; notranslate">dig -t MX phpgangsta.de +short
10 mail.phpgangsta.de.</pre><p>Hier könnten auch mehrere Ergebnisse erscheinen wenn ich mehrere Mailserver betreiben würde. Wir schauen also als nächstes, wer hinter mail.phpgangsta.de steckt:</p><pre class="brush: plain; title: ; notranslate">dig mail.phpgangsta.de +short
85.214.28.26</pre><p>In diesem Fall ist es mein Server mit der IP 85.214.28.26, wir müssen unsere E-Mail also dort abgeben. Der SMTP Port ist TCP 25, wohin wir uns ganz einfach mittels Telnet verbinden können:</p><pre class="brush: plain; title: ; notranslate">telnet 85.214.28.26 25
Trying 85.214.28.26...
Connected to 85.214.28.26.
Escape character is '^]'.
220 h1440682.stratoserver.net ESMTP Postfix (Debian/GNU)</pre><p>Der Server begrüßt uns mit seinem Namen und verrät auch gleichzeitig, dass er nicht nur SMTP spricht, sondern auch Extended SMTP (ESMTP). Mittlerweile sollten alle dieses neue Protokoll unterstützen, das 1995 eingeführt wurde um spezielle Fähigkeiten (Extensions) hinzuzufügen wie beispielsweise Authentifizierung. Vorher gab es die nicht, daran hatte wohl niemand gedacht früher *tzz*. Aber auch TLS ist erst mit ESMTP möglich, heutzutage gibt es auch wahrscheinlich keine Server mehr, die kein ESMTP anbieten.</p><p>Da der Server auch TLS unterstützt können wir uns auch verschlüsselt verbinden, indem wir erst eine normale Verbindung (wie oben) aufbauen und dann direkt mit dem STARTTLS Befehl in den verschlüsselten Modus wechseln. Da man das in Telnet schlecht eintippen kann nutzen wir den openssl-Client, der genau dies macht:</p><p><span id="more-1158"></span></p><pre class="brush: plain; title: ; notranslate">openssl s_client -starttls smtp -crlf -connect 85.214.28.26:587
CONNECTED(00000003)
...
...
---
250 HELP</pre><p>Wir sind also dran uns vorzustellen mit unseren Namen:</p><pre class="brush: plain; title: ; notranslate">HELO michael.client.de
250 h1440682.stratoserver.net</pre><p>HELO ist der alte Befehl, Hallo zu sagen. Damit schalten wir in den alten SMTP-Modus, was aber eigentlich niemand mehr möchte. Also versuchen wir es erstmal mit EHLO, der ESMTP-Variante. Sollte das fehlschlagen müssen wir auf HELO zurückfallen.</p><pre class="brush: plain; title: ; notranslate">EHLO michael.client.de
250-h1440682.stratoserver.net
250-PIPELINING
250-STARTTLS
250-SIZE 52428800
250-ETRN
250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 NTLM RPA
250-AUTH=PLAIN LOGIN DIGEST-MD5 CRAM-MD5 NTLM RPA
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN</pre><p>Ah, es geht, der Server antwortet mit all seinen Features und Modulen, die er unterstützt sowie der maximalen Größe einer E-Mail, die er annehmen wird.</p><p>Die Zahlen am Anfang jeder Antwort des Servers sind die SMTP-Statuscodes.</p><ul><li>1XX Mailserver hat die Anforderung akzeptiert, ist aber selbst noch nicht tätig geworden. Eine Bestätigungsmeldung ist erforderlich.</li><li>2XX Mailserver hat die Anforderung erfolgreich ohne Fehler ausgeführt.</li><li>3XX Mailserver hat die Anforderung verstanden, benötigt aber zur Verarbeitung weitere Informationen.</li><li>4XX Mailserver hat einen temporären Fehler festgestellt. Wenn die Anforderung ohne jegliche Änderung wiederholt wird, kann die Verarbeitung möglicherweise abgeschlossen werden.</li><li>5XX Mailserver hat einen fatalen Fehler festgestellt. Die Anforderung kann nicht verarbeitet werden.</li></ul><p>Der Server kann bei allen Befehlen Fehler zurückliefern, beispielsweise wenn wir einen ungültigen EHLO Befehl abgesendet haben, der Absender oder Empfänger nicht akzeptiert wird, oder der Server festgestellt hat dass die E-Mail Spam ist.</p><p>OK, wir haben Hallo gesagt, nun geht es mit der E-Mail los. Wir nennen zuerst den Absender der E-Mail:</p><pre class="brush: plain; title: ; notranslate">MAIL FROM: test@domain.de
250 2.1.0 Ok</pre><p>Als nächstes folgt der Empfänger der E-Mail:</p><pre class="brush: plain; title: ; notranslate">RCPT TO: XXX@phpgangsta.de
250 2.1.5 Ok</pre><p>und dann der Inhalt der E-Mail. Dieser besteht aus E-Mail-Headern und dem eigentlichen Inhalt. Ich möchte jetzt hier nicht auf E-Mail-Header eingehen, und auch nicht mehrteilige E-Mails, HTML-Emails, Anhänge usw erklären. Kommt vielleicht später <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> Wir beginnen mit dem DATA-Befehl, gefolgt vom eigentliche Inhalt. Wir werden angewiesen, das Ende mit einem Punkt in einer eigenen Zeile zu markieren. Hier erstmal eine ganz einfache Text-Email:</p><pre class="brush: plain; title: ; notranslate">DATA
354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;
From: bill@microsoft.com
To: empfaenger@domain.de
Subject: Testmail

Testmails sind toll, diese hier ist eine ganz einfache, ohne HTML, ohne Anhänge usw.
.
250 2.0.0 Ok: queued as 370DB1044028</pre><p>Hier ist schön zu sehen dass wir den From- und To-Header völlig frei festlegen können. Im E-Mail-Programm wird häufig nur dieser leicht fälschbare From-Header angezeigt. Dies ist ein großes Manko des Protokolls finde ich, denn nahezu jeder fällt auf so einen gefälschten Absender rein und erkennt nicht den wirklichen Absender. Das Problem der Absenderfälschung gänzlich zu beheben wird nicht einfach möglich sein, es gibt Ansätze (<a href="http://www.dkim.org/" target="_blank">DKIM</a>, <a href="http://de.wikipedia.org/wiki/Sender_Policy_Framework" target="_blank">SPF</a>), die aber auch nur partiell funktionieren.</p><p>Die E-Mail ist also angenommen worden, wir können uns abmelden mittels QUIT, oder aber die Verbindung aufrecht erhalten und zurücksetzen (RSET), um eine weitere E-Mail abzuliefern.</p><pre class="brush: plain; title: ; notranslate">quit
221 2.0.0 Bye
Connection closed by foreign host.</pre><p>Ein vollständiger Dialog zur Zustellung einer E-Mail sieht dann so aus:</p><pre class="brush: plain; title: ; notranslate">telnet 85.214.28.26 25
Trying 85.214.28.26...
Connected to 85.214.28.26.
Escape character is '^]'.
220 h1440682.stratoserver.net ESMTP Postfix (Debian/GNU)
EHLO michael.client.de
250-h1440682.stratoserver.net
250-PIPELINING
250-STARTTLS
250-SIZE 52428800
250-ETRN
250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 NTLM RPA
250-AUTH=PLAIN LOGIN DIGEST-MD5 CRAM-MD5 NTLM RPA
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM: test@domain.de
250 2.1.0 Ok
RCPT TO: XXX@phpgangsta.de
250 2.1.5 Ok
DATA
354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;
From: bill@microsoft.com
To: empfaenger@domain.de
Subject: Testmail

Testmails sind toll, diese hier ist eine ganz einfache, ohne HTML, ohne Anhänge usw.
.
250 2.0.0 Ok: queued as 370DB1044028
quit
221 2.0.0 Bye
Connection closed by foreign host.</pre><p>OK, E-Mail direkt an einen Mailserver zustellen können wir nun. Doch wie sieht es aus wenn wir die E-Mail dem Mailserver zur weiteren Zustellung übergeben wollen? Das hat mehrere Vorteile: Erstens wird unsere E-Mail, wenn sie vom Provider-Mailserver bzw. dem eigenen Mailserveer im Internet zugestellt wird, seltener als Spam deklariert (manche Mailserver nehmen gar keine E-Mails von dynamischen IP-Adressen an bzw. haben all diese auf Blacklists), und zweitens könnte es ja auch sein dass der Mailserver des Empfängers gerade offline ist, dann müßte man es nach einer Stunde, nach 4 Stunden usw. nochmal probieren (dafür gibt es Queues in allen Mailservern). Das lässt man doch lieber einen Mailserver machen.</p><p>Also, wie wollen uns bei unserem Mailserver via SMTP anmelden und ihm eine E-Mail zur weiteren Zustellung übergeben. Dazu müssen wir uns mit dem richtigen Server verbinden und uns authentifizieren. Das sind die sogenannten Postausgangsserver, die meistens smtp.domain.de heißen. Dazu haben wir direkt mehrere Möglichkeiten:</p><p>Die meisten (vernünftigen) Mailserver sind nicht nur via Port 25 sondern auch via Port 587 (Submission) bzw. via Port 465 (SSL) erreichbar. Um unsere E-Mail zur weiteren Zustellung abzuliefern verbinden wir uns mit dem eigentlich dafür vorgesehenen Port 587:</p><pre class="brush: plain; title: ; notranslate">telnet 85.214.28.26 587
Trying 85.214.28.26...
Connected to 85.214.28.26.
Escape character is '^]'.
220 h1440682.stratoserver.net ESMTP Postfix (Debian/GNU)</pre><p>Um die E-Mail nicht im Klartext übertragen zu müssen können wir wieder TLS nutzen (siehe oben) oder auch SSL:</p><pre class="brush: plain; title: ; notranslate">openssl s_client -crlf -connect 85.214.28.26:465
CONNECTED(00000003)
...
...
---
220 HELP</pre><p>Und nun sagen wir wieder brav EHLO:</p><pre class="brush: plain; title: ; notranslate">EHLO michael.client.de
 250-h1440682.stratoserver.net
 250-PIPELINING
 250-STARTTLS
 250-SIZE 52428800
 250-ETRN
 250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 NTLM RPA
 250-AUTH=PLAIN LOGIN DIGEST-MD5 CRAM-MD5 NTLM RPA
 250-ENHANCEDSTATUSCODES
 250-8BITMIME
 250 DSN</pre><p>Damit wir nun einen Empfänger definieren können der nicht auf diesem Mailserver beheimatet ist müssen wir uns erstmal authentifizieren. Dazu bietet der Mailserver die oben gelisteten Methoden. Da wir via TLS oder SSL verschlüsselt kommunizieren können wir eine unsichere Methode nehmen bei der wir den Usernamen und das Passwort nur via base64 kodieren. Sollten wir unverschlüsselt mit dem Server verbunden sein bietet es sich an DIGEST-MD5, CRAM-MD5 oder eine andere sichere Authentifizierungsmethode zu wählen.</p><p>Wir nehmen die einfachste: AUTH LOGIN. Dann müssen wir nacheinander den Benutzernamen und das Passwort übergeben, jeweils base64 kodiert:</p><pre class="brush: plain; title: ; notranslate">AUTH LOGIN
334 VXNlcm5hbWU6
aGFoYUBwaHBnYW5nc3RhLmRl
334 UGFzc3dvcmQ6
bWVpbnBhc3N3b3J0
235 2.7.0 Authentication successful</pre><p>Zwei kurze Zeilen helfen mir dabei immer:</p><pre class="brush: php; title: ; notranslate">php -r 'echo base64_encode(&quot;email@domain.de&quot;).&quot;\n&quot;;'
php -r 'echo base64_encode(&quot;GeheimPasswortHier&quot;).&quot;\n&quot;;'</pre><p>Alternativ dazu gibt es noch AUTH PLAIN, bei dem beides in einem Befehl übergeben wird, getrennt durch ein Null-Byte:</p><pre class="brush: plain; title: ; notranslate">auth plain AGVtYWlsQGRvbWFpbi5kZQBHZWhlaW1QYXNzd29ydEhpZXI=
235 2.7.0 Authentication successful</pre><p>&nbsp;</p><pre class="brush: php; title: ; notranslate">php -r 'echo base64_encode(&quot;&#92;&#48;email@domain.de&#92;&#48;GeheimPasswortHier&quot;).&quot;\n&quot;;'</pre><p>Das ältere Verfahren SMTP-after-POP wird immer seltener unterstützt, da war es nötig sich erstmal per POP3 zu authentifizieren, und dann hatte man ein Zeitfenster von beispielsweise 15 Minuten Zeit, E-Mails via SMTP zu verschicken. Das war ein Workaround aus der Zeit wo es noch kein ESMTP gab.</p><p>Gut, wir sind authentifiziert, und können nun genauso wie oben die E-Mail verschicken:</p><pre class="brush: plain; title: ; notranslate">MAIL FROM: test@domain.de
250 2.1.0 Ok
RCPT TO: irgendwen@dadraussen.de
250 2.1.5 Ok
DATA
354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;
From: test@domain.de
To: irgendwen@dadraussen.de
Subject: Testmail

Testmails sind toll, diese hier ist eine ganz einfache, ohne HTML, ohne Anhänge usw.
.
250 2.0.0 Ok: queued as 370DB1044028
quit
221 2.0.0 Bye
Connection closed by foreign host.</pre><p>Ich glaube mehr gibt es nicht an Grundlagen zu SMTP zu erzählen, <a href="http://smtpfilter.sourceforge.net/esmtp.html" target="_blank">alles weitere</a> ist technischer Schnickschnack den nur Mailserver untereinander brauchen <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p> <br/><br/><p>Ähnliche Artikel:</p><ol><li><a href='http://www.phpgangsta.de/das-imap-protokoll-im-detail-betrachtet' rel='bookmark' title='Das IMAP Protokoll im Detail betrachtet'>Das IMAP Protokoll im Detail betrachtet</a></li></ol>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/das-smtp-protokoll-im-detail-betrachtet/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Dieser Schlüssel zerstört sich in 30 Sekunden selbst</title><link>http://www.phpgangsta.de/dieser-schlussel-zerstort-sich-in-30-sekunden-selbst</link> <comments>http://www.phpgangsta.de/dieser-schlussel-zerstort-sich-in-30-sekunden-selbst#comments</comments> <pubDate>Mon, 01 Aug 2011 07:34:18 +0000</pubDate> <dc:creator>Oliver</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[Server-Software]]></category> <category><![CDATA[linux]]></category> <category><![CDATA[openssh]]></category> <category><![CDATA[Private Key]]></category> <category><![CDATA[Public Key]]></category> <category><![CDATA[Sicherheit]]></category> <category><![CDATA[SSH]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=3156</guid> <description><![CDATA[Gastartikel von Oliver Sperke. Ich bin 34 Jahre alt und seit 10 Jahren selbständiger Webentwickler. Mein Fokus liegt dabei auf der Erstellung, Beratung und Optimierung in den Bereichen High Performance, Usability und Sicherheit in den gängigsten Internetsprachen: PHP, HTML, Javascript und CSS. Nachdem ich ja in den letzten Wochen über den sicheren Umgang mit Passwörtern [...]<br/><br/> Ähnliche Artikel:<ol><li><a href='http://www.phpgangsta.de/der-download-der-sich-selbst-loscht' rel='bookmark' title='Der Download, der sich selbst löscht'>Der Download, der sich selbst löscht</a></li></ol>]]></description> <content:encoded><![CDATA[<p><em>Gastartikel von Oliver Sperke.</em></p><p><em>Ich bin 34 Jahre alt und seit 10 Jahren selbständiger Webentwickler. Mein Fokus liegt dabei auf der Erstellung, Beratung und Optimierung in den Bereichen High Performance, Usability und Sicherheit in den gängigsten Internetsprachen: PHP, HTML, Javascript und CSS.</em></p><p>Nachdem ich ja in den letzten Wochen über den <a href="http://www.phpgangsta.de/passwortmythen-oder-%E2%80%9Ewas-du-schon-immer-uber-passworter-wusstest-aber-nie-zu-sagen-wagtest%E2%80%9C">sicheren</a> <a href="http://www.phpgangsta.de/schoener-hashen-mit-bcrypt">Umgang</a> mit <a href="http://www.phpgangsta.de/tlsssl-fur-heimwerker">Passwörtern</a> in Webprojekten erzählt habe, soll es heute mal um etwas anderes gehen (aber trotzdem um das Thema Sicherheit). Wenn man oft auf fremden oder eigenen Servern arbeitet, kommt man an <a href="http://www.openssh.com/">OpenSSH</a> eigentlich nicht vorbei. Und wenn man dazu noch so faul ist wie ich (und vermutlich die meisten von Euch auch), hat man keine dutzenden Dateien mit Passwörtern, sondern wickelt die gesamten Loginvorgänge mit Hilfe von <a href="http://de.wikipedia.org/wiki/Public-Key-Authentifizierung">öffentlichen und privaten Schlüsseln</a> ab. Dieses Verfahren ist nicht nur bequem, es bietet auch zusätzliche Sicherheit, da man nicht in Versuchung kommt, einfache Passwörter zu verwenden. Ausserdem ist die eigene Passwortliste schon von Haus aus verschlüsselt.</p><p>Das Verfahren hat aber für einen Serverbetreiber Nachteile. Der öffentliche Schlüssel muss auf dem Server hinterlegt werden. Ausserdem muss man sobald der Zugang nicht mehr benötigt wird, nachsehen, ob ein Benutzer sich vielleicht eigene Schlüssel hinterlegt hat und natürlich muss man ihm den Zugang manuell sperren.</p><p><span id="more-3156"></span>Alle diese Vorgänge sind lästig und zeitaufwendig und bergen Gefahren, vor allem dann, wenn man die Zugänge von vielen Benutzern verwalten muss. Schnell hat man eine Zeile in der <a href="http://www.eng.cam.ac.uk/help/jpmg/ssh/authorized_keys_howto.html">„authorized_keys“</a> Datei für einen Benutzer übersehen und handelt sich damit dauerhaft ungebetene Gäste ein. Seit OpenSSH 5.6 gibt es nicht nur die Möglichkeit, öffentliche und private Schlüssel zu hinterlegen, sondern den öffentlichen Schlüssel zu signieren. Dieses Verfahren der Signierung oder Zertifizierung bietet uns gewaltige Vorteile.</p><p>Der Server kann bei einer Signierung erkennen, ob ein Schlüssel nur für einen gewissen Zeitraum gültig sein soll oder schon abgelaufen ist und ob gewisse Rechte, z. B. zum <a href="http://www.jfranken.de/homepages/johannes/vortraege/ssh2_inhalt.de.html#ToC1">X11 Forwarding</a> oder <a href="http://www.jfranken.de/homepages/johannes/vortraege/ssh2_inhalt.de.html#ToC9">Port Weiterleitung</a> erteilt wurden oder nicht. Ausserdem müssen wir die Public Keys der Nutzer nicht mehr hinterlegen und unser Privatekey ist quasi unangreifbar. Dieses Verfahren benötigt fertig eingerichtet nicht mal mehr einen Login auf dem Server zur Erstellung neuer Zugänge.</p><h2>Wichtiger Hinweis und Ausgangssituation</h2><p><strong>Lest bitte erst den ganzen Text, damit Ihr nicht in der Mitte stecken bleibt. Wenn Ihr nicht regelmäßig auf Linuxsystemen arbeitet, dann richtet euch eine virtuelle Maschine ein, die Ihr nach Lust und Laune kaputt konfigurieren könnt. Das Verfahren nutze ich selbst auf meinen Servern, wenn Ihr Euch trotzdem aussperrt, dann ist das nicht meine Schuld, bei mir geht es ja. Man kann das Verfahren auch auf <em>einem Rechner</em> testen.</strong></p><p><strong>Falls Euer Zielrechner nicht greifbar für Euch ist, also irgendwo im Rechenzentrum steht, lasst die Passwortauthentifizierung an und loggt Euch zusätzlich auf einer anderen Konsole ein. Lasst das Fenster offen. Sollte etwas schief gehen, könnt Ihr es in diesem Fenster immer noch reparieren. Diese Anleitung richtet sich eindeutig an erfahrende Nutzer und ist nichts für Hobbyadmins und „Menschen mit schwachem Herz“.</strong></p><p>Server und Client sind bei mir beide Linuxrechner &#8211; für Windows bin ich kein Fachmann. Da aber OpenSSH auch unter Windows arbeitet, dürfte die Konfiguration letzendlich in etwa die gleiche sein.</p><p>Alle Einstellungen sind lediglich Vorschläge und nicht verbindlich. Verbesserungen sind natürlich willkommen, eigenes Nachdenken erwünscht. Als Testsystem habe ich <a href="http://www.debian.org/">Debian Squeeze</a> auf dem Server und bei mir zu Hause <a href="https://www.archlinux.de/">ArchLinux</a>. Bei Debian muss der SSH Server aus dem <a href="http://packages.debian.org/unstable/">„unstable“ Zweig</a> installiert werden (libssl, openssh-server, openssh-client), da es dort noch kein aktuelles Paket in testing oder stable gibt. Als Mindestversion empfehle ich OpenSSH 5.8, Version 5.6 sollte aber theoretisch auch funktionieren.</p><p>Ich arbeite zunächst als root während der Einrichtung bis ich etwas anderes sage. Wer das nicht möchte, muss überall <code>sudo</code> vor die Befehle schreiben. Sollte noch kein SSH Server und/oder Client installiert sein, fangen wir damit an.</p><p><strong>Auf dem Server (root)</strong></p><pre class="brush: bash; title: ; notranslate">
apt-get install openssh-server openssh-client libssl
</pre><p><strong>Auf dem Client (root)</strong></p><pre class="brush: bash; title: ; notranslate">
apt-get install openssh-client
</pre><p>Nach kurzer Wartezeit ist unser SSH Server fertig eingerichtet und gestartet.</p><h2>Was werden wir tun?</h2><ol><li>Grundlegende (sichere) Konfiguration des SSH Dienstes</li><li>Sperren des SSH Login für root</li><li>Anlegen und Einrichten eines neuen Benutzers zum Login</li><li>Zugang für diesen Benutzer nur mit gültigem signiertem Schlüssel</li></ol><h2>Die Konfiguration</h2><p>Zunächst sichern wir die aktuelle Konfiguration. Dann editieren wir die sshd_config mit nano (joe, vi usw. gehen natürlich auch).</p><p><strong>Auf dem Server (root)</strong></p><pre class="brush: bash; title: ; notranslate">
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
nano /etc/ssh/sshd_config
</pre><p>Innerhalb der Datei ändere ich die Einstellungen unter dem Punkt <em>Authentification</em> auf die angegebenen Werte. die <em>LoginGraceTime</em> kann auf 10 Sekunden herunter gesetzt werden, da ein Zugriff mit Passwörtern nicht genutzt wird und meine Schlüssel vom <a href="http://en.wikipedia.org/wiki/Ssh-agent">ssh-agent</a> verwaltet werden. Den root Login verbiete ich, denn ich will es „Brute Forcern“ etwas schwerer machen. Die Einstellungen für <em>StrictModes</em>, <em>RSAAuthentication</em>, <em>PubkeyAuthentication</em> bleiben gleich. <em>PasswordAuthentication</em> setze ich hier schon auf no (siehe Hinweise). Wenn Ihr wollt, könnt Ihr auch mit <em>AllowUsers user1 user2</em> usw. eine „Whitelist“ für erlaubte Loginnamen fest legen. Das bietet aber auch nicht mehr Sicherheit &#8211; nur die Fehlermeldung ändert sich.</p><p>Die Werte für <em>AuthorizedKeysFile</em>, <em>AuthorizedPrincipalsFile</em> und <em>TrustedUserCAKeys</em> fügen wir hinzu. In der <em>AuthorizedKeysFile</em> stehen normalerweise die Publickeys der Benutzer. Da wir die aber hier nicht brauchen, ändern wir den Wert auf <code>/dev/null</code>. So kann sich kein Benutzer eigene Zugänge hinterlegen. <em>TrustedUserCAKeys</em> ist der öffentliche Teil unseres Zertifikats. In der <em>AuthorizedPrincipalsFile</em> stehen alle Benutzer, die in den Zertifikaten hinterlegt werden. Dazu später noch mehr.</p><pre class="brush: plain; title: ; notranslate">
# Authentication:
LoginGraceTime 10
PermitRootLogin no
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes

AuthorizedKeysFile /dev/null
TrustedUserCAKeys /etc/ssh/trusted_ca_keys
AuthorizedPrincipalsFile %h/.ssh/authorized_ca_user

PasswordAuthentication no
</pre><p>Die Einstellungen übernehmen wir mit einem SSH Neustart. Wenn Ihr Euch nicht sicher seid, wartet noch. Die Änderungen könnt Ihr jederzeit rückgängig machen, indem ihr die .bak Datei zurück kopiert und dann ssh neu startet.</p><p><strong>Auf dem Server (root)</strong></p><pre class="brush: bash; title: ; notranslate">
/etc/init.d/ssh restart
</pre><h2>Der authorisierte Benutzer</h2><p>Als nächstes legen wir einen neuen Benutzer an. Den nenne ich jetzt einfach mal login, weil er nur dafür da ist, sich auf dem Server anzumelden. Bevor Ihr versucht anonsphere.com zu brute forcen &#8211; da hab ich nen anderen Benutzer &#8211; ausserdem werde Ihr nach 3 Versuchen gebannt. <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> Die zweite Zeile ist optional. Ihr könnt natürlich auch ein Passwort für den Benutzer hinterlegen, aber ich habe keine Lust, dass jedesmal einzugeben. Wer sich als dieser Benutzer einloggen kann, könnte eh unbemerkt keylogger o. ä. installieren. Mir persönlich reicht der abgesicherte Zugang. Wenn der Benutzer eingeschränkt handeln soll, also nicht zum root werden darf, ändert den Befehl von -G users,admin auf -g users</p><p><strong>Auf dem Server (root)</strong></p><pre class="brush: bash; title: ; notranslate">
useradd -c &quot;Login&quot; -d /home/login -G users,admin -u 1003 -m -s /bin/bash login
passwd --delete login
</pre><h2>Der normale Schlüssel</h2><p>Auf Eurem Clientsystem erzeugen wir für unseren Benutzer einen Schlüssel, falls Ihr schon einen habt, springt zum nächsten <a href="#sig">Kapitel</a>.</p><p><strong>Auf dem Client (Benutzer)</strong></p><pre class="brush: bash; title: ; notranslate">
ssh-keygen -t rsa -b 4096 -f id_rsa
</pre><p>Verschiebt den private Schlüssel in den Ordner ~/.ssh/id_rsa. <strong>Der Publickey wird nicht auf dem Server hinterlegt!</strong></p><p><strong>Auf dem Client (Benutzer)</strong></p><pre class="brush: bash; title: ; notranslate">
mkdir ~/.ssh/
mv id_rsa ~/.ssh/id_rsa
</pre><h2 id="sig">Der signierte Schlüssel</h2><p>Zum Erstellen der Zertifikate brauchen wir noch ein Schlüsselpaar. Den Ablauf kennen wir ja schon. Den Inhalt des öffentlichen Schlüssel hinterlegen wir <strong>auf dem Server</strong> in der Datei <em>trusted_ca_keys</em>. Dann wechseln wir auf unseren Benutzer und hinterlegen die ID des Zertifikats („principal“), die erlaubt sein sollen &#8211; dieser muss nicht mit dem Benutzernamen übereinstimmen. Auf dem Server muss nur der Publickey des Zertifikats liegen.</p><p><strong>Auf dem Client oder Server (Benutzer)</strong></p><pre class="brush: bash; title: ; notranslate">
ssh-keygen -t rsa -b 4096 -f zertifikat_rsa
</pre><p><strong>Auf dem Server (root)</strong></p><pre class="brush: bash; title: ; notranslate">
cat zertifikat_rsa.pub &gt;&gt; /etc/ssh/trusted_ca_keys
su login
mkdir ~/.ssh/
echo &quot;oliver&quot; &gt;&gt; ~/.ssh/authorized_ca_user
</pre><p><strong>Die einzige wichtige Datei ist die <em>zertifikat_rsa</em>. Diese muss gesichert werden (auch mehrfach) und möglichst weit weg von direktem Zugriff (Container, USB Stick, etc.). Alle anderen Dateien sind uninteressant!</strong> Wir haben also jetzt unsere Vorbereitungen getroffen. Als letztes muss noch Euer Publickey (aus „Der normale Schlüssel“) signiert werden. Das macht ihr mit folgender Zeile. I ist der Name der Zertifizierung und steht später im <em>auth.log</em>. <code>n</code> ist der principal, also der Benutzername, für den das Zertifikat ausgestellt ist und der in der <em>authorized_ca_user</em> hinterlegt wurde.</p><pre class="brush: bash; title: ; notranslate">
ssh-keygen -s zertifikat_rsa -I MeinLogin -n oliver .ssh/id_rsa.pub
ssh-add .ssh/id_rsa
</pre><p>Falls Ihr den SSH Agent benutzt, fügt danach den Schlüssel hinzu mit <code>ssh-add .ssh/id_rsa</code>.</p><h2>Aufräumen</h2><p>Jetzt könnte es passiert sein, dass die Rechte nicht korrekt gesetzt wurden bei unseren Aktionen. Dieses Problem erledigen wir mit der beliebten „Holzhammermethode“, damit unser Setup sicher ist. Wir gehen zurück auf den root Account auf dem Server und setzen dann unsere Rechte.</p><p><strong>Auf dem Server (root)</strong></p><pre class="brush: bash; title: ; notranslate">
chown -R root:root /etc/ssh/*
chmod 600 /etc/ssh/*
</pre><p><strong>Auf dem Client (Benutzer)</strong></p><pre class="brush: bash; title: ; notranslate">
chmod 700 ~/.ssh
chmod 600 ~/.ssh/*
</pre><p>Der Login sollte nun funktionieren. Wenn nicht, gibt die Datei <em>/var/log/auth.log</em> (Client und Server) weitere Informationen. Falls da nichts brauchbares steht, erhöht in der <em>ssh_config/sshd_config</em> den <em>LogLevel</em> auf <em>DEBUG3</em>. Fast immer sind irgendwo die Rechte falsch. Wenn bis hier hin alles funktioniert, können wir jetzt ein zeitlich eingeschränktes Zertifikat erzeugen. Dafür benutzen wir diese Zeile.</p><p><strong>Auf dem Client (Benutzer)</strong></p><pre class="brush: bash; title: ; notranslate">
ssh-keygen -s zertifikat_rsa -I MeinLogin -n oliver -V +5m .ssh/id_rsa.pub
</pre><p>Der Zugang wäre damit fünf Minuten gültig. Probiert es aus! Meldet Euch auf dem Server an, meldet Euch ab und schaut, ob Ihr Euch nach 5 Minuten noch anmelden könnt. Wenn Ihr mit dem Prinzip warm geworden seid, könnt Ihr natürlich auch fremde Publickeys signieren. Der Befehl sieht dann z. B. so aus:</p><pre class="brush: bash; title: ; notranslate">
ssh-keygen -s zertifikat_rsa -I Zeitarbeiter -n zeitarbeiter -V +1d fremderPubkey.pub
</pre><p>Neben der Zeit könnt Ihr auch seine Rechte, wie Port- oder X11-Forwarding einschränken. Mehr Infos bekommt Ihr mit</p><pre class="brush: bash; title: ; notranslate">
man ssh-keygen
</pre><p>Auf dem Server müsst Ihr dann in der Datei <em>/home/login/authorized_ca_user</em> auf dem Server den Benutzer <em>zeitarbeiter</em> in einer neuen Zeile hinterlegen. Ihr könnt jede ID mehrfach verwenden. So könntet Ihr natürlich auch Signaturen vorher entwerten, indem Ihr einen verwendeten Priincipal löscht. Um einem neuem Benutzer Zugang zu erteilen, benötigt Ihr seinen Publickey. Diesen signiert Ihr mit der <em>zertifikat_rsa</em> und schickt ihm die <em>*-cert.pub</em> Datei zurück. Kein Login nötig!</p><h2>Was geht? Was geht nicht?</h2><p>Mit Hilfe der Signaturen ist es nun endlich möglich, Zugänge zu Servern zu erteilen, die nach einer gewissen Zeit selbst verfallen, ab einem gewissem Zeitpunkt gültig sind oder Aktionen verbieten, ohne in der sshd_config Änderungen vorzunehmen. Das Verfahren eignet sich u. a. für die Vergabe von Serverzugängen für Wartungsarbeiten an der Datenbank oder zur Einrichtung von Software, die vom Benutzer genutzt wird. Ausserdem natürlich auch für die sichere Vergabe von <a href="http://de.wikipedia.org/wiki/SSH_File_Transfer_Protocol">SFTP</a> oder <a href="http://de.wikipedia.org/wiki/Files_transferred_over_shell_protocol">FISH</a> Zugänge mit denen der Benutzer seine Dateien ändern kann. Wenn jemand für ein Jahr bezahlt und nicht verlängert, haben wir keine Arbeit mehr damit. Verlängert er den Zugang, können wir ihm einfach lokal ein neues Zertifikat generieren.</p><p>Der größte Vorteil ist aber, dass Euer Privatekey quasi nicht mehr kompromitiert werden kann. Ich benutze den RSA Schlüssel nur für meine Serverzugänge. Sollte er mir aus irgendwelchen Gründen gestohlen werden und das Passwort gleich dazu, benenne ich einfach den principal um und erzeuge mir ein neues Zertifikat. Meinen Privatekey kann sich derjenige dann ausdrucken und an die Wand hängen, weil der ist für den Zugang völlig unerheblich. Wichtig ist nur die <em>zertifikat_rsa</em>, die muss geschützt werden und diese liegt natürlich sicher in einer verschlüsselten Datei.</p><p>Als Einschränkung müssen wir allerdings hin nehmen, dass das Verfahren bisher nur in aktuellen OpenSSH Versionen integriert ist, was evtl. den Zugang durch Programme wie <a href="http://de.wikipedia.org/wiki/Putty">PuTTY</a> oder <a href="http://de.wikipedia.org/wiki/Winscp">WinSCP</a> erschwert. Für Windows habe ich generell noch nach keiner Lösung gesucht. Es kann also sein, dass es schon funktioniert, muss aber nicht &#8211; Infos bitte in die Kommentare. Unter Linux funktioniert das Verfahren mit allen Programmen, die auf der Basis von OpenSSH arbeiten, also eigentlich mit allen.</p><p><strong>Einen Hinweis noch</strong><br /> Falls Ihr auf eure Server <a href="http://www.fail2ban.org/wiki/index.php/Main_Page">fail2ban</a> einsetzt, müsst Ihr aus der Filterdatei für ssh die Zeile mit „Invalid Publickey“ entfernen oder auskommentieren, denn der ist durch den Verweis auf /dev/null natürlich immer falsch, auch wenn die Authentifizierung letzendlich erfolgreich ist (und ja, ich hatte beim ersten Mal auch nicht dran gedacht). In diesem Fall solltet Ihr auch eine Whitelist setzen, denn ansonsten werden Benutzer mit falschem Namen nicht immer gebannt.</p> <br/><br/><p>Ähnliche Artikel:</p><ol><li><a href='http://www.phpgangsta.de/der-download-der-sich-selbst-loscht' rel='bookmark' title='Der Download, der sich selbst löscht'>Der Download, der sich selbst löscht</a></li></ol>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/dieser-schlussel-zerstort-sich-in-30-sekunden-selbst/feed</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Screenshots von Webseiten erstellen mit PHP</title><link>http://www.phpgangsta.de/screenshots-von-webseiten-erstellen-mit-php</link> <comments>http://www.phpgangsta.de/screenshots-von-webseiten-erstellen-mit-php#comments</comments> <pubDate>Thu, 21 Jul 2011 06:01:01 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Screenshot]]></category> <category><![CDATA[Screenshots erstellen]]></category> <category><![CDATA[WebsiteToImage]]></category> <category><![CDATA[wkhtmltoimage]]></category> <category><![CDATA[wkhtmltopdf]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=2794</guid> <description><![CDATA[Einen einfachen manuellen Screenshot von einer Webseite zu erstellen ist einfach, brauche ich hier wohl nicht extra erläutern. Wenn man allerdings aus seiner PHP-Applikation Screenshots von Webseiten erstellen möchte oder keine Lust hat auf manuelles Zusammenkopieren weil die Webseite sehr lang oder breit ist, hilft das Projekt wkhtmltopdf. Dieses Kommandozeilentool gibt es für Windows, Linux [...]<br/><br/> Keine ähnlichen Artikel.]]></description> <content:encoded><![CDATA[<p>Einen einfachen manuellen Screenshot von einer Webseite zu erstellen ist einfach, brauche ich hier wohl nicht extra erläutern. Wenn man allerdings aus seiner PHP-Applikation Screenshots von Webseiten erstellen möchte oder keine Lust hat auf manuelles Zusammenkopieren weil die Webseite sehr lang oder breit ist, hilft das Projekt <a href="http://code.google.com/p/wkhtmltopdf/" target="_blank">wkhtmltopdf</a>. Dieses Kommandozeilentool gibt es für Windows, Linux und Mac, und es läuft auch auf Servern ohne grafische Oberfläche. Auf der Webseite des Projekts findet man sowohl wkhtmltopdf als auch wkhtmltoimage. wk steht dabei für die Webkit Render Engine, die aus einem gegebenen HTML-Input entweder ein PDF oder ein Bild (jpg, png, tiff) erstellt.</p><p>Ich werde hier zeigen wie man Bilder erstellt, die Installation ist einfach: Man lädt sich die passende Version herunter, in meinem Fall für einen Debian-Server ist das <a href="http://code.google.com/p/wkhtmltopdf/downloads/detail?name=wkhtmltoimage-0.10.0_rc2-static-i386.tar.bz2&amp;can=2&amp;q=">wkhtmltoimage-0.10.0_rc2-static-i386.tar.bz2</a> . Die darin enthaltene Datei kopiere ich nach /usr/local/bin , falls bei euch open_basedir aktiv ist muss es natürlich irgendwo in ein erlaubtes Verzeichnis.</p><pre class="brush: bash; title: ; notranslate">wget http://wkhtmltopdf.googlecode.com/files/wkhtmltoimage-0.10.0_rc2-static-i386.tar.bz2
tar -xjvf wkhtmltoimage-0.10.0_rc2-static-i386.tar.bz2
mv wkhtmltoimage-i386 /usr/local/bin/</pre><p>Ein erster kleiner Test von der Konsole:</p><pre class="brush: bash; title: ; notranslate">wkhtmltoimage-i386 http://www.phpgangsta.de phpgangsta.de.jpg</pre><p>Hier das Ergebnis (klicken für das Original Bild):</p><p><span id="more-2794"></span><a href="http://www.phpgangsta.de/wp-content/uploads/www.phpgangsta.de_1.jpg"><img class="alignnone size-full wp-image-3051" title="http://www.phpgangsta.de als Bild" src="http://www.phpgangsta.de/wp-content/uploads/www.phpgangsta.de_1.jpg" alt="" width="614" height="2268" /></a></p><p>Gar nicht schlecht! Schauen wir uns als nächstes den Aufruf aus PHP heraus an.</p><pre class="brush: php; title: ; notranslate">&lt;?
passthru('/usr/local/bin/wkhtmltoimage-i386 http://www.phpgangsta.de phpgangsta.de.jpg');</pre><p>So einfach kann es sein! Natürlich möchte man dies variabel machen, sodass man von jeder beliebigen Webseite Screenshots erstellen kann, und auch das Format oder die Qualität wählen kann. Bei der Arbeit mit Aufrufen wie passthru() oder auch shell_exec(), exec() etc. sollte man immer aufpassen dass man die übergebenen Parameter gut prüft und entschärft (<a href="http://de2.php.net/escapeshellcmd" target="_blank">escapeshellcmd</a> und <a href="http://de2.php.net/escapeshellarg" target="_blank">escapeshellarg</a>)</p><p>Auf dieser Webseite kann die Funktionalität übrigens getestet werden:</p><p><a href="http://screenshot.phpgangsta.de" target="_blank">http://screenshot.phpgangsta.de</a></p><p>Ich habe <a href="https://github.com/PHPGangsta/WebsiteToImage" target="_blank">auf GitHub die Klasse WebsiteToImage</a> angelegt mit der die Screenshoterstellung gekapselt und vereinfacht wird. Ich freue mich natürlich über weitere implementierte Features und Pull Requests!</p><p>Aktuell sieht die Klasse so aus:</p><pre class="brush: php; title: ; notranslate">&lt;?php

class WebsiteToImage
{
    const FORMAT_JPG  = 'jpg';
    const FORMAT_JPEG = 'jpeg';
    const FORMAT_PNG  = 'png';
    const FORMAT_TIF  = 'tif';
    const FORMAT_TIFF = 'tiff';

    protected $_programPath;
    protected $_outputFile;
    protected $_url;
    protected $_format = self::FORMAT_JPG;
    protected $_quality = 90;

    public function start()
    {
        $programPath = escapeshellcmd($this->_programPath);
        $outputFile  = escapeshellarg($this->_outputFile);
        $url         = escapeshellarg($this->_url);
        $format      = escapeshellarg($this->_format);
        $quality     = escapeshellarg($this->_quality);

        $command = "$programPath --format $format --quality $quality $url $outputFile";

        exec($command);
    }

    public function setOutputFile($outputFile)
    {
        clearstatcache();
        if (!is_writable(dirname($outputFile))) {
            throw new Exception('output file not writable');
        }
        
        $this->_outputFile = $outputFile;
        return $this;
    }

    public function getOutputFile()
    {
        return $this->_outputFile;
    }

    public function setProgramPath($programPath)
    {
        $this->_programPath = $programPath;
        return $this;
    }

    public function getProgramPath()
    {
        return $this->_programPath;
    }

    public function setFormat($format)
    {
        $this->_format = $format;
        return $this;
    }

    public function getFormat()
    {
        return $this->_format;
    }

    public function setQuality($quality)
    {
        $this->_quality = (int)$quality;
        return $this;
    }

    public function getQuality()
    {
        return $this->_quality;
    }

    public function setUrl($url)
    {
        $this->_url = $url;
        return $this;
    }

    public function getUrl()
    {
        return $this->_url;
    }
}</pre><p>Und so wird sie benutzt:</p><pre class="brush: php; title: ; notranslate">&lt;?php

require_once 'WebsiteToImage.php';

$websiteToImage = new WebsiteToImage();
$websiteToImage->setProgramPath('/usr/local/bin/wkhtmltoimage-i386')
               ->setOutputFile('www.phpgangsta.de.jpg')
               ->setQuality(70)
               ->setUrl('http://www.phpgangsta.de')
               ->start();

$websiteToImage->setFormat(WebsiteToImage::FORMAT_PNG)
               ->setOutputFile('www.phpgangsta.de.png')
               ->start();</pre><p>wkhtmltoimage hat viele interessante Funktionalitäten, beispielsweise kann man nur einen bestimmten Bereich ausschneiden, die Höhe und die Breite einstellen, die Qualität und das Format ändern. Aber es geht noch sehr viel mehr wie man unten sieht, man kann Javascript deaktivieren, Bilder auf der Webseite nicht laden, ein HTTP Authentifizierungspasswort angeben falls benötigt, einen Proxy einstellen, einen Zoomfaktor wählen und vieles mehr.</p><p>Hier die  &#8220;erweiterte Hilfe&#8221;:</p><pre class="brush: plain; title: ; notranslate">wkhtmltoimage-i386 -H
Name:
  wkhtmltoimage 0.10.0 rc2

Synopsis:
  wkhtmltoimage [OPTIONS]... &lt;input file&gt; &lt;output file&gt;

Description:
  Converts an HTML page into an image,

General Options:
      --allow &lt;path&gt;                  Allow the file or files from the specified
                                      folder to be loaded (repeatable)
      --checkbox-checked-svg &lt;path&gt;   Use this SVG file when rendering checked
                                      checkboxes
      --checkbox-svg &lt;path&gt;           Use this SVG file when rendering unchecked
                                      checkboxes
      --cookie &lt;name&gt; &lt;value&gt;         Set an additional cookie (repeatable)
      --cookie-jar &lt;path&gt;             Read and write cookies from and to the
                                      supplied cookie jar file
      --crop-h &lt;int&gt;                  Set height for croping
      --crop-w &lt;int&gt;                  Set width for croping
      --crop-x &lt;int&gt;                  Set x coordinate for croping
      --crop-y &lt;int&gt;                  Set y coordinate for croping
      --custom-header &lt;name&gt; &lt;value&gt;  Set an additional HTTP header (repeatable)
      --custom-header-propagation     Add HTTP headers specified by
                                      --custom-header for each resource request.
      --no-custom-header-propagation  Do not add HTTP headers specified by
                                      --custom-header for each resource request.
      --debug-javascript              Show javascript debugging output
      --no-debug-javascript           Do not show javascript debugging output
                                      (default)
      --encoding &lt;encoding&gt;           Set the default text encoding, for input
  -H, --extended-help                 Display more extensive help, detailing
                                      less common command switches
  -f, --format &lt;format&gt;               Output file format (default is jpg)
      --height &lt;int&gt;                  Set screen height (default is calculated
                                      from page content) (default 0)
  -h, --help                          Display help
      --htmldoc                       Output program html help
      --images                        Do load or print images (default)
      --no-images                     Do not load or print images
  -n, --disable-javascript            Do not allow web pages to run javascript
      --enable-javascript             Do allow web pages to run javascript
                                      (default)
      --javascript-delay &lt;msec&gt;       Wait some milliseconds for javascript
                                      finish (default 200)
      --load-error-handling &lt;handler&gt; Specify how to handle pages that fail to
                                      load: abort, ignore or skip (default
                                      abort)
      --disable-local-file-access     Do not allowed conversion of a local file
                                      to read in other local files, unless
                                      explecitily allowed with --allow
      --enable-local-file-access      Allowed conversion of a local file to read
                                      in other local files. (default)
      --manpage                       Output program man page
      --minimum-font-size &lt;int&gt;       Minimum font size
      --password &lt;password&gt;           HTTP Authentication password
      --disable-plugins               Disable installed plugins (default)
      --enable-plugins                Enable installed plugins (plugins will
                                      likely not work)
      --post &lt;name&gt; &lt;value&gt;           Add an additional post field (repeatable)
      --post-file &lt;name&gt; &lt;path&gt;       Post an additional file (repeatable)
  -p, --proxy &lt;proxy&gt;                 Use a proxy
      --quality &lt;int&gt;                 Output image quality (between 0 and 100)
                                      (default 94)
      --radiobutton-checked-svg &lt;path&gt; Use this SVG file when rendering checked
                                      radiobuttons
      --radiobutton-svg &lt;path&gt;        Use this SVG file when rendering unchecked
                                      radiobuttons
      --readme                        Output program readme
      --run-script &lt;js&gt;               Run this additional javascript after the
                                      page is done loading (repeatable)
  -0, --disable-smart-width           Use the specified width even if it is not
                                      large enough for the content
      --stop-slow-scripts             Stop slow running javascripts (default)
      --no-stop-slow-scripts          Do not Stop slow running javascripts
                                      (default)
      --transparent                   Make the background transparent in pngs
      --use-xserver                   Use the X server (some plugins and other
                                      stuff might not work without X11)
      --user-style-sheet &lt;url&gt;        Specify a user style sheet, to load with
                                      every page
      --username &lt;username&gt;           HTTP Authentication username
  -V, --version                       Output version information an exit
      --width &lt;int&gt;                   Set screen width (default is 1024)
                                      (default 1024)
      --window-status &lt;windowStatus&gt;  Wait until window.status is equal to this
                                      string before rendering page
      --zoom &lt;float&gt;                  Use this zoom factor (default 1)</pre><p>Es gibt auch das <a href="https://github.com/mreiferson/php-wkhtmltox" target="_blank">PHP-Binding Projekt php-wkhtmltox</a> für die C-Bibliothek libwkhtmltox, sodass man es als PHP-Extension nutzen kann (extension=phpwkhtmltox.so).</p> <br/><br/><p>Keine ähnlichen Artikel.</p>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/screenshots-von-webseiten-erstellen-mit-php/feed</wfw:commentRss> <slash:comments>29</slash:comments> </item> <item><title>Schöner hashen mit bcrypt</title><link>http://www.phpgangsta.de/schoener-hashen-mit-bcrypt</link> <comments>http://www.phpgangsta.de/schoener-hashen-mit-bcrypt#comments</comments> <pubDate>Mon, 18 Jul 2011 06:56:09 +0000</pubDate> <dc:creator>Oliver</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[bcrypt]]></category> <category><![CDATA[Hash]]></category> <category><![CDATA[Hashing]]></category> <category><![CDATA[Passwort]]></category> <category><![CDATA[Sicherheit]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=2946</guid> <description><![CDATA[Gastartikel von Oliver Sperke. Ich bin 34 Jahre alt und seit 10 Jahren selbständiger Webentwickler. Mein Fokus liegt dabei auf der Erstellung, Beratung und Optimierung in den Bereichen High Performance, Usability und Sicherheit in den gängisten Internetsprachen: PHP, HTML, Javascript und CSS. Bei meinem vorherigem Gastbeitrag wurde ich direkt im ersten Kommentar aus meiner heilen [...]<br/><br/> Keine ähnlichen Artikel.]]></description> <content:encoded><![CDATA[<p><em>Gastartikel von Oliver Sperke.</em></p><p><em>Ich bin 34 Jahre alt und seit 10 Jahren selbständiger Webentwickler. Mein Fokus liegt dabei auf der Erstellung, Beratung und Optimierung in den Bereichen High Performance, Usability und Sicherheit in den gängisten Internetsprachen: PHP, HTML, Javascript und CSS.</em></p><p>Bei meinem <a href="http://www.phpgangsta.de/passwortmythen-oder-%e2%80%9ewas-du-schon-immer-uber-passworter-wusstest-aber-nie-zu-sagen-wagtest%e2%80%9c">vorherigem Gastbeitrag</a> wurde ich direkt im ersten Kommentar aus meiner heilen Welt geworfen. Dort stand nämlich folgender „erschütternder Kommentar“ zu lesen:</p><blockquote><p>Das du Salting und Mehrfachhashing predigst, während der Rest der Welt schon einen Schritt weiter zu bcrypt geht… Traurig.</p></blockquote><p>Nun ja, dazu möchte ich drei Dinge sagen.</p><ol><li>Ich predige nicht (Ausnahme: „Es heißt Standard, verdammt, nicht <a href="http://www.google.de/?q=standart">Standart</a>!“).</li><li>Ach, wenn die Welt schon mal auf dem Stand des einfachen md5 wäre &#8230;</li><li>Bcrypt verdient einen eigenen Beitrag.</li></ol><p>Natürlich hatte der Autor völlig recht. Über Hashfunktionen im Web zu schreiben und bcrypt nicht zu erwähnen ist fast schon schändlich. Also <a href="http://www.usenix.org/events/usenix99/provos.html">bcrypt</a> ist eine Hashfunktion, die auf Langsamkeit optimiert wurde. Um genauer zu sein, es ist nicht mal ein richtiger Hashalgorithmus, sondern eine Blowfish Verschlüsselung, bei der am Ende „die Schlüssel weggeworfen werden“, daher lässt sich das Ergebnis nicht mehr entschlüsseln. bcrypt ist eine Weiterentwicklung der „<a href="http://en.wikipedia.org/wiki/Crypt_%28Unix%29#Traditional_DES-based_scheme">Traditional DES Scheme</a>“ Funktion aus der Unixwelt. Obwohl dieses Verfahren 30 Jahre lang (!) gute Dienste geleistet hat, stellen sich so langsam „Alterserscheinungen“ ein. Der Zahn der Zeit nagt auch hier in Form von gestiegener Rechenleistung.</p><h2>Kurze Rückschau</h2><p><span id="more-2946"></span>Hashalgorithmen wie md5 und die shaX sind auf Schnelligkeit optimiert. Das ist gut, wenn man prüfen will, ob der heruntergeladen Film auch wirklich korrekt übertragen wurde. Das ist auch gut, wenn man testen möchte, ob das SSL Zertifikat einer Webseite nicht verfälscht wurde. Das ist aber eher suboptimal, wenn man damit Passwörter speichern will. Wie schon im letzten Artikel erklärt und <a href="http://www.phpgangsta.de/passwortmythen-oder-%e2%80%9ewas-du-schon-immer-uber-passworter-wusstest-aber-nie-zu-sagen-wagtest%e2%80%9c#comments">ausgiebig diskutiert</a>, ist die gestiegene Rechenleistung auch ein Problem für die klassischen Hashfunktionen in Webanwendungen. Zwar kann man mit Salts, mehr Salts und Mehrfachhashes das Schlimmste verhindern, aber irgendwie ist das <a href="http://www.klamm.de/forum/f28/php-mysql-passwoerter-richtig-verschluesseln-251427.html">alles nicht so nachvollziehbar für jeden</a>. Kurz gesagt: „Das geht besser“.</p><h2>Was bcrypt kann</h2><p>Selbst wenn wir dafür sorgen, dass unsere Passwörter gut geschützt sind, können wir natürlich kaum verhindern, dass ein Benutzer trotzdem ein schwaches Passwort verwendet. Wenn es der Angreifer gezielt auf eine Person, z. B. den Admin abgesehen hat, wird die Situation noch schlimmer, denn bis <a href="http://www.phpgangsta.de/passwortmythen-oder-%e2%80%9ewas-du-schon-immer-uber-passworter-wusstest-aber-nie-zu-sagen-wagtest%e2%80%9c">10 Zeichen</a> kann man auch schon mal eine Brute Force Attacke für einen einzelnen Hash probieren. Deshalb sollten wir unserem <a href="http://de.wikipedia.org/wiki/Cracker_%28Computersicherheit%29">Cracker</a> das Leben grundsätzlich so schwer wie möglich machen.</p><p>Bcrypt bringt gewisse Vorkehrungen für genau diesen Fall mit. Der Algorithmus ist auch optimiert noch sehr langsam, und das ist gut so. Der Hash beinhaltet einen Wert für die Rundenanzahl, den sog. „Kostenfaktor“. Dies ist der Aufwand der bei der Berechnung betrieben werden muss. Jedem Hash kann zusätzlich ein individueller Salt zugeordnet werden. In PHP ist bcrypt über die <a href="http://de.php.net/manual/de/function.crypt.php">crypt()</a> Funktion seit Version 5.3 fest implementiert. Davor hing der Einsatz vom Betriebsystem ab.</p><h2>Was bcrypt nicht kann</h2><p>Bcrypt bringt einige schöne Fähigkeiten mit, die wir in der Webwelt wunderbar nutzen können. Allerdings gibt es einige Dinge, die designbedingt nicht vorgesehen sind. Dazu zählt ein geheimer Salt, den wir in unserer Anwendung hinterlegen können. Der Sinn resultiert aus der Überlegung, dass wenn ein Angreifer aus welchen Gründen auch immer auf die Datenbank zugreifen kann, er auch noch auf den Quelltext der Webanwendung zugreifen können muss. Im Zweifel entscheidet sich dort, ob unsere Passwörter weiter geschützt sind oder nicht.</p><p>Die zweite fehlende Funktion, ist die Möglichkeit Hashes von zusätzlichen Faktoren, wie der E-Mail Adresse (ersatzweise dem Benutzernamen oder die UserID) abhängig zu machen. Der Hintergrund ist etwas speziell. Nehmen wir mal an, ein Angreifer findet in unserer Webanwendung eine <a href="http://de.wikipedia.org/wiki/Cross-Site_Scripting">XSS Lücke</a>, mit denen er die Session eines Benutzers übernehmen kann. Was wäre das Schlimmste, was er tun kann? Richtig, er ändert das Passwort oder die E-Mail Adresse. Wie kann ich das am effektivsten verhindern? Ganz klar, ich muss ihn zwingen zur Überprüfung das alte Passwort einzugeben. Durch die Kopplung der Hashes an die E-Mail kann ich das gar nicht vergessen. Man könnte natürlich den Salt abhängig von der E-Mail machen, aber was ist wenn ein Benutzer mehrfach angemeldet ist? Brute Force Attacken werden mit jedem Ziel lohnenswerter.</p><h2>Vom Rein und Raus</h2><p>Ein ganz einfacher Hash ensteht so:</p><pre class="brush: php; title: ; notranslate">crypt ( 'Passwort', '$2a$04$EinSaltFuerDasPasswort' );</pre><p>Als Ausgabe ergibt sich:</p><pre>$2a$04$EinSaltFuerDasPasswore.oNHNUzZrs1V5tpdv/WJ64.DIyBV1kC</pre><p>Auf den ersten Blick ist das im Vergleich zu md5(&#8216;Passwort&#8217;) natürlich etwas verwirrend, aber dafür schreibe ich das ja hier. Im ersten Argument steht der zu hashende String. Das zweite Argument besteht aus drei Teilen, die je mit einem $ eingeleitet werden. Der erste Block bestimmt die verwendete Funktion. Die möglichen Werte könnt Ihr auf php.net nachschauen. Wir nutzen hier nur $2a für bcrypt.</p><p>Der zweite Block beschreibt die Anzahl der Runden, mit dem der Hash erstellt wird. Der Wert darf zwischen 04 und 31 liegen. Mit jeder Runde verdoppelt sich die Zeit zur Erstellung, das System ist also exponentiell. Wenn eine Runde etwa 1 ms dauert, dann dauern 31 Runden ca. 74 Minuten. Genug Luft nach oben also. Brauchbare Werte liegen derzeit bei etwa 08 bis 12, je nach eingesetzter Hardware und Geduld. Gibt man Zahlen ausserhalb des Bereichs an, wird *0 zurück gegeben.</p><p>Der dritte Block ist der individuelle Salt. Dieser darf aus Groß- und Kleinbuchstaben, Zahlen, sowie ./ bestehen. Tauchen andere Zeichen auf, wird ebenfalls *0 zurück gegeben. Die Eingabewerte müssen also gut gewählt sein. Weiterhin darf der Salt aus 128 Bits, also 21 1/2 Zeichen bestehen. Wen das verwundert, 21 Zeichen werden komplett dargestellt, beim letzten Zeichen werden die Hälfte der Bits verworfen. Deshalb wird aus &#8216;EinSaltFuerDasPasswort&#8217; im hash &#8216;EinSaltFuerDasPasswore&#8217;.</p><p>Die Ausgabe entspricht der Eingabe, gefolgt vom eigentlichem Hash. Jetzt kann man natürlich berechtigt fragen, was daran sicher sein soll, wenn da ja alles steht. Stimmt, aber genau dieses Verfahren ist gleichzeitig ein Vorteil.</p><h2>Einmal bcrypt &#8230;</h2><p>Ich erstelle der Einfachheit halber eine Funktion, mit der man die Eigenschaften von bcrypt richtig nutzen kann. Auch hier gilt wieder &#8211; nichts ist in Stein gemeisselt. Wenn Ihr Vorschläge habt, her damit. Die Funktionen nenne ich (besonders kreativ) bcrypt_encode und bcrypt_check.</p><pre class="brush: php; title: ; notranslate">function bcrypt_encode ( $password )
{
	return crypt ( $password, '$2a$04$EinSaltFuerDasPasswort' );
}</pre><p>Diese Funktion gibt uns einen ersten Anfang. Ein Aufruf von bcrypt(&#8216;Passwort&#8217;) gibt uns den o. g. Hash zurück. Die Saltfunktion nutzt natürlich überhaupt nichts, wenn man überall den gleichen Salt verwendet. Da der Salt in der Datenbank steht und daher nicht geheim ist, kann dieser <a href="http://de.wikipedia.org/wiki/Pseudozufall">pseudozufällig</a> sein kann. Folgendes Konstrukt ist also ausreichend.</p><pre class="brush: php; title: ; notranslate">$salt = substr ( str_shuffle ( './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ) , 0, 22 );</pre><p>Die Anzahl der Runden sollte variabel sein. Der Hintergrund ist ganz einfach. Manche Accounts sind wichtiger als andere. Wenn ich als Admin 3 Sekunden zum Login warten muss, dann stört mich das nicht. Einem Besucher diese Wartezeit zu erklären, könnte sich aber schwierig gestalten oder als technische Schwäche fehlinterpretiert werden. Als Bonbon kann man dem Besucher auch anbieten, die sichere Variante zu wählen. Ein Normalwert sollte festgelegt werden, aber mit der Möglichkeit zu abweichenden Werten. Übertragen auf unsere Funktion ergibt sich.</p><pre class="brush: php; title: ; notranslate">function bcrypt_encode( $password, $rounds='08' )
{
	$salt = substr ( str_shuffle ( './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ) , 0, 22 );
	return crypt ( $password, '$2a$' . $rounds . '$' . $salt );
}</pre><p>Zur Passwortspeicherung habe ich jetzt eigentlich alle Möglichkeiten von bcrypt ausgeschöpft. Mit jedem Aufruf wird ein neuer Hash mit einem anderem Salt erzeugt. Nur sicherer fühl ich mich jetzt nicht, denn genau wie oben schon erwähnt gebe ich dem Angreifer freiwillig alle Daten. Es ist natürlich besser als ein purer md5 hash, aber eher noch gut gemeint als gut gemacht.</p><p>Daher würde ich diese Funktion gerne erweitern. Wie bei unserem md5 Beispiel bringe ich zusätzlich einen Salt ein, der nur im Quelltext hinterlegt ist. Dieser muss vor dem ersten Aufruf der Funktion mit define(&#8216;SALT&#8217;, &#8216;beliebigerWert&#8217;) definiert werden. Ausserdem möchte ich, dass man bei einer Änderung der E-Mail Adresse das alte Passwort eingeben werden muss. In den Kommentaren zum letzten Beitrag hat ein Besucher <a href="http://www.phpgangsta.de/passwortmythen-oder-%E2%80%9Ewas-du-schon-immer-uber-passworter-wusstest-aber-nie-zu-sagen-wagtest%E2%80%9C#comment-19723">erwähnt</a>, dass das Einbringen eines Salt mit hash_hmac() sicherer wäre als einfaches voranstellen oder anhängen. Auch wenn ich die Bedenken in diesem speziellem Fall nur bedingt teile, da sich der individuelle Salt in jeder Zeile ändert und daher ein Angriff auf den systemweiten Salt sinnlos wäre, schaden kann es auch nicht und wenn wir schon einmal dran sind, klotzen wir mal richtig. <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p><p>Dazu erweitern wir zunächst einmal mit <a href="http://de.php.net/manual/de/function.str-pad.php">str_pad()</a> unseren String auf die viefachefache Länge des Passwortes, indem wir ihn mit dem sha1 hash der E-Mail Adresse davor und dahinter auffüllen. Ich nehme hier sha1, weil ich möchte, dass sich bei jeder E-Mail der Salt komplett ändert. Diesen String jagen wir dann durch <a href="http://de.php.net/manual/de/function.hash-hmac.php">hash_hmac()</a> mit unserem systemweiten Salt <a href="http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html">in Whirlpool</a> als Binärausgabe. Den entstandenen Zeichensalat verpacken wir mit bcrypt.</p><pre class="brush: php; title: ; notranslate">function bcrypt_encode ( $email, $password, $rounds='08' )
{
	$string = hash_hmac ( &quot;whirlpool&quot;, str_pad ( $password, strlen ( $password ) * 4, sha1 ( $email ), STR_PAD_BOTH ), SALT, true );
	$salt = substr ( str_shuffle ( './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ) , 0, 22 );
	return crypt ( $string, '$2a$' . $rounds . '$' . $salt );
}</pre><p>Ein Aufruf von</p><pre class="brush: php; title: ; notranslate">bcrypt_encode( 'oliver@anonsphere.com', 'Test-Null8Fünfzehn' );</pre><p>führt also zu diesen Ergebnissen:</p><pre class="brush: php; title: ; notranslate">// Passwort mit E-Mail auf vierfache Länge aufgefüllt
4e707693b984367edadf5a022867Test-Null8Fünfzehn4e707693b984367edadf5a022867e

// hash_hmac mit Whirlpool und systemweitem Salt (im Original binär)
b0492febbd81ef10387e2e7127295e09c197ff0cadf8ae5dc98182178f9e0891cf86b91abb1c723e0de510361cb67e1149460a687271672d77de439d7c572b57

// Verpackt mit bcrypt
$2a$08$jb8v67zmCNMO9dlX1tkVqOxGlhQkJNL45AvfpbEWvqXnGC8YcO7Hm</pre><p>Die Sicherheit dürfte nur schwer anzuzweifeln sein. <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p><h2>&#8230; und zurück</h2><p>Jetzt fehlt noch die Möglichkeit den gespeicherten Passworthash mit unserem Passwort zu vergleichen. Jetzt kommen wir zu dem Teil, wo bcrypt von nett, auf cool wechselt.<br /> <code></code></p><pre>$2a$08$jb8v67zmCNMO9dlX1tkVqOxGlhQkJNL45AvfpbEWvqXnGC8YcO7Hm</pre><p><code></code><br /> Schauen wir uns doch mal diesen Hash genauer an. Wir haben oben gesehen, der Hash besteht aus den Einstellungen und dem Ergebnis. Anders gesagt, der Hash liefert uns alles, was wir zum Berechnen brauchen. Dazu schreibe ich ihn mal anders, damit es klarer wird.<br /> <code></code></p><pre>Einstellungen: $2a$08$jb8v67zmCNMO9dlX1tkVqOx
         Hash: GlhQkJNL45AvfpbEWvqXnGC8YcO7Hm</pre><p><code></code><br /> Der erste Teil entspricht genau dem Code, den wir zur Erzeugung genutzt haben, daher muss auch bei korrekter E-Mail und Passwort und diesen Einstellungen unser Hash heraus kommen. Dass heißt, wenn der hinterlegte hash die Variable $stored hat, dann muss folgende Bedingung wahr sein.</p><pre class="brush: php; title: ; notranslate">crypt ( $string, substr ( $stored, 0, 30 ) ) == $stored;</pre><p>Oder übertragen in eine eigene Funktion.</p><pre class="brush: php; title: ; notranslate">function bcrypt_check ( $email, $password, $stored )
{
	$string = hash_hmac ( &quot;whirlpool&quot;, str_pad ( $password, strlen ( $password ) * 4, sha1 ( $email ), STR_PAD_BOTH ), SALT, true );
	return crypt ( $string, substr ( $stored, 0, 30 ) ) == $stored;
}</pre><p>Der Vorteil erschliesst sich erst auf den zweiten Blick. Während man bei der Umstellung von md5 auf sha1 oder von sha1 auf sha256 Probleme mit bestehenden Benutzerlogins bekommt, weil die alten Passwörter ungültig werden, nimmt uns bcrypt alle nötigen Workarounds ab. Bei der Prüfung ist es nämlich vollkommen egal, was als Ursprungswert an Runden und Salt hinterlegt wurde. Wenn ich irgendwann mal die Sicherheit erhöhen will oder auf einen schnelleren/langsameren Server umziehe, ändere ich den $rounds Wert und trotzdem funktionieren alte Logins weiter. Sobald aber die E-Mail oder das Passwort geändert wird, wird der neue Wert übernommen.</p><h2>Was noch zu sagen wäre</h2><p>Bcrypt ist eine schöne Sache, entbindet Euch aber keineswegs von zusätzlichen Sicherheitsüberlegungen. Wer zukunftsorientiert an ein neues Projekt geht oder wer schon beim letzten Artikel überlegt hat, ob seine Passwortspeicherung wirklich so sicher ist, wie er dachte, sollte überlegen, ob der Einsatz lohnt. Ein sicheres Verfahren deshalb abzulösen, ist aber auf jeden Fall unnötig.</p><p>Bleibt mir abschliessend nur noch <a href="http://www.gernothassknecht.de/">eins zu sagen</a>: „ES HEISST STANDARD!!11“.</p> <br/><br/><p>Keine ähnlichen Artikel.</p>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/schoener-hashen-mit-bcrypt/feed</wfw:commentRss> <slash:comments>45</slash:comments> </item> <item><title>Linkpool Nummer 16</title><link>http://www.phpgangsta.de/linkpool-nummer-16</link> <comments>http://www.phpgangsta.de/linkpool-nummer-16#comments</comments> <pubDate>Sun, 20 Mar 2011 11:52:33 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Lesepool]]></category> <category><![CDATA[Linkpool]]></category> <category><![CDATA[Links]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=2345</guid> <description><![CDATA[Interessante Einsichten, wie t3n.de gehostet wurde die letzten Jahre: Massenhosting, eigener Serverraum, Housing und nun Individualhosting: http://t3n.de/news/t3nde-gehostet-290436/ Hat jemand schon Erfahrungen mit diesem PHP Application Server? http://www.photon-project.com/ Interessante ZendCon Session Podcast Episode über die Memcached Extension: http://devzone.zend.com/article/13104-ZendCon-Sessions-Episode-040-Memcached-the-better-Memcache-interface Audio Mitschnitt + Präsentation von der Dutch PHP Conference 2010 über Datenbankversionierung: http://techportal.ibuildings.com/2011/03/01/dpcradio-database-version-control-without-pain/ Auch von der Dutch PHP [...]<br/><br/> Ähnliche Artikel:<ol><li><a href='http://www.phpgangsta.de/linkpool-nummer-11' rel='bookmark' title='Linkpool Nummer 11'>Linkpool Nummer 11</a></li><li><a href='http://www.phpgangsta.de/linkpool-nummer-14' rel='bookmark' title='Linkpool Nummer 14'>Linkpool Nummer 14</a></li><li><a href='http://www.phpgangsta.de/linkpool-nummer-5' rel='bookmark' title='Linkpool Nummer 5'>Linkpool Nummer 5</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Interessante Einsichten, wie t3n.de gehostet wurde die letzten Jahre: Massenhosting, eigener Serverraum, Housing und nun Individualhosting:</p><p><a href="http://t3n.de/news/t3nde-gehostet-290436/" target="_blank">http://t3n.de/news/t3nde-gehostet-290436/</a></p><p>Hat jemand schon Erfahrungen mit diesem PHP Application Server?</p><p><a href="http://www.photon-project.com/" target="_blank">http://www.photon-project.com/</a></p><p>Interessante ZendCon Session Podcast Episode über die Memcached Extension:</p><p><a href="http://devzone.zend.com/article/13104-ZendCon-Sessions-Episode-040-Memcached-the-better-Memcache-interface" target="_blank">http://devzone.zend.com/article/13104-ZendCon-Sessions-Episode-040-Memcached-the-better-Memcache-interface</a></p><p>Audio Mitschnitt + Präsentation von der Dutch PHP Conference 2010 über Datenbankversionierung:</p><p><a href="http://techportal.ibuildings.com/2011/03/01/dpcradio-database-version-control-without-pain/" target="_blank">http://techportal.ibuildings.com/2011/03/01/dpcradio-database-version-control-without-pain/</a></p><p>Auch von der Dutch PHP Conference 2010, Rob Allen über stressfreies Deployment:</p><p><a href="http://techportal.ibuildings.com/2010/11/09/dpcradio-stress-free-deployment/" target="_blank">http://techportal.ibuildings.com/2010/11/09/dpcradio-stress-free-deployment/</a></p><p>Sehr schöne Veranschaulichung der Geschwindigkeitsunterschiede zwischen L1 Cache, L2 Cache, RAM und Festplatte:</p><p><a href="http://twitpic.com/4a1eot/full" target="_blank">http://twitpic.com/4a1eot/full</a></p> <br/><br/><p>Ähnliche Artikel:</p><ol><li><a href='http://www.phpgangsta.de/linkpool-nummer-11' rel='bookmark' title='Linkpool Nummer 11'>Linkpool Nummer 11</a></li><li><a href='http://www.phpgangsta.de/linkpool-nummer-14' rel='bookmark' title='Linkpool Nummer 14'>Linkpool Nummer 14</a></li><li><a href='http://www.phpgangsta.de/linkpool-nummer-5' rel='bookmark' title='Linkpool Nummer 5'>Linkpool Nummer 5</a></li></ol>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/linkpool-nummer-16/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Test von Googles neuem Apache Modul mod_pagespeed</title><link>http://www.phpgangsta.de/test-von-googles-neuem-apache-modul-mod_pagespeed</link> <comments>http://www.phpgangsta.de/test-von-googles-neuem-apache-modul-mod_pagespeed#comments</comments> <pubDate>Thu, 04 Nov 2010 23:32:37 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[Server-Software]]></category> <category><![CDATA[apache]]></category> <category><![CDATA[Google]]></category> <category><![CDATA[mod_pagespeed]]></category> <category><![CDATA[performance]]></category> <category><![CDATA[speed]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=1818</guid> <description><![CDATA[Google kündigt an, die Welt applaudiert: Das neue Apache-Modul mod_pagespeed soll automatisch Webseiten schneller machen, ohne Aufwand und für jede Seite, eine bis zu 50% schnellere Webseite wird versprochen. Google selbst hat natürlich auch etwas davon: Wenn jede Webseite schneller abrufbar ist, können die Suchmaschinen-Spider schneller und mehr crawlen&#8230; Doch wenn man es selbst ausprobiert [...]<br/><br/> Keine ähnlichen Artikel.]]></description> <content:encoded><![CDATA[<p>Google kündigt an, die Welt applaudiert: Das neue <a href="http://code.google.com/intl/de-DE/speed/page-speed/docs/module.html" target="_blank">Apache-Modul mod_pagespeed</a> soll automatisch Webseiten schneller machen, ohne Aufwand und für jede Seite, eine bis zu 50% schnellere Webseite wird versprochen. Google selbst hat natürlich auch etwas davon: Wenn jede Webseite schneller abrufbar ist, können die Suchmaschinen-Spider schneller und mehr crawlen&#8230;</p><p>Doch wenn man es selbst ausprobiert sind die Ergebnisse ernüchternd. Ich habe heute Abend das Modul installiert und aktiviert (in unter 3 Minuten), und ein paar Messergebnisse mit <a href="https://addons.mozilla.org/de/firefox/addon/1843/" target="_blank">Firebug</a>, <a href="http://code.google.com/intl/de-DE/speed/page-speed/download.html" target="_blank">PageSpeed</a> und <a href="https://addons.mozilla.org/de/firefox/addon/5369/" target="_blank">YSlow</a> zusammengetragen.</p><p>Ergebnis: kein nennenswerter Geschwindigkeitsschub, teilweise sogar langsamer als vorher. Einige haben bei ersten Benchmarks das selbe Ergebnis wie ich erhalten, andere jedoch sprechen von 46% Verbesserung. Es scheint sehr davon abzuhängen wie die Seite aufgebaut ist und ob bereits Maßnahmen zur Verbesserung der Performance getroffen wurden.<br /> Außerdem habe ich auf meiner Seite nach der Aktivierung Probleme mit dem HTML-Validator gefunden die vorher nicht da waren, durch die &#8220;Verbesserungen&#8221; habe ich plötzlich ungültigen HTML-Code!</p><p>Hat jemand von Euch bereits Tests gemacht, was ist dabei herausgekommen?</p><p>==========================<br /> Die <a href="http://code.google.com/intl/de-DE/speed/page-speed/download.html" target="_blank">Installation unter Ubuntu</a> (32bit) ist denkbar einfach:<br /> <span id="more-1818"></span></p><pre class="brush: plain; title: ; notranslate">wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-beta_current_i386.deb
dpkg -i mod-pagespeed-beta_current_i386.deb
/etc/init.d/apache2 restart</pre><p>Danach kann man die Konfiguration anpassen:</p><pre class="brush: plain; title: ; notranslate">vi /etc/apache2/mods-enabled/pagespeed.conf</pre><p>Meine ersten Ergebnisse:</p><pre class="brush: plain; title: ; notranslate">Browser Cache deaktiviert

Ohne Pagespeed:
51 Requests
Firebug Netzwerk Tab: 4,64   3,79   3,5    3,8   3,81
PageSpeed		83/100
YSlow			81
Size			154,4KB

Standard Konfiguration
50 Requests
Firebug Netzwerk Tab: 4,69   5,13   5,91   4,99   6,3
PageSpeed		84/100
YSlow			82
Size			155,1KB

Fast alle Filter aktiviert:
50 Requests
Firebug Netzwerk Tab: 6,0    5,85   6,47   5,34   5,83
PageSpeed		83/100
YSlow			82
Size			154,9KB

===============================================================

Browser Cache aktiviert

Ohne Pagespeed:
18 Requests
Firebug Netzwerk Tab:  3,2     2,7    2,9    2,8    2,85
PageSpeed		80/100
YSlow			81
Complete Size		59,5KB
index size		12,3KB

Standard Konfiguration
18 Requests
Firebug Netzwerk Tab: 2,8    2,7     3,1    3,0    2,85
PageSpeed		80/100
YSlow			84
Complete Size		61,2KB
index size		14,0KB

Fast alle Filter aktiviert:
18 Requests
Firebug Netzwerk Tab: 3,4    3,6    3,4    3,1    3,7
PageSpeed		80/100
YSlow			84
Complete Size		61KB
index size		13,8KB</pre><br/><br/><p>Keine ähnlichen Artikel.</p>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/test-von-googles-neuem-apache-modul-mod_pagespeed/feed</wfw:commentRss> <slash:comments>17</slash:comments> </item> <item><title>PHP und HTTP AUTH bei 1und1 Webhosting</title><link>http://www.phpgangsta.de/php-und-http-auth-bei-1und1-webhosting</link> <comments>http://www.phpgangsta.de/php-und-http-auth-bei-1und1-webhosting#comments</comments> <pubDate>Sat, 06 Feb 2010 09:53:47 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Allgemein]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[1und1 Webhosting]]></category> <category><![CDATA[htaccess]]></category> <category><![CDATA[HTTP Authorization]]></category> <category><![CDATA[PHP_AUTH_PW]]></category> <category><![CDATA[PHP_AUTH_USER]]></category> <category><![CDATA[x-mapp-php5]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=891</guid> <description><![CDATA[Um das Zend Framework in der Webhosting-Umgebung bei 1und1 ans Laufen zu bekommen, gibt es ein paar Kleinigkeiten zu beachten: Als erstes muss man bei 1und1 in der .htaccess-Datei angeben welche PHP-Version man benutzen möchte. Dies macht man mit der Zeile Außerdem muß man noch die folgenden 2 Zeilen hinzufügen, sonst erhält man einen 500er [...]<br/><br/> Ähnliche Artikel:<ol><li><a href='http://www.phpgangsta.de/blog-url-struktur-geandert' rel='bookmark' title='Blog URL Struktur geändert'>Blog URL Struktur geändert</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Um das <a href="http://framework.zend.com/" target="_blank">Zend Framework</a> in der Webhosting-Umgebung bei 1und1 ans Laufen zu bekommen, gibt es ein paar Kleinigkeiten zu beachten:</p><p>Als erstes muss man bei 1und1 in der <a href="http://de.wikipedia.org/wiki/.htaccess" target="_blank">.htaccess-Datei</a> angeben <a href="http://faq.1and1.com/scripting_languages_supported/php/9.html" target="_blank">welche PHP-Version man benutzen möchte</a>. Dies macht man mit der Zeile</p><pre class="brush: plain; title: ; notranslate">AddType x-mapp-php5 .php</pre><p>Außerdem muß man noch die folgenden 2 Zeilen hinzufügen, sonst erhält man einen 500er Fehler:</p><pre class="brush: plain; title: ; notranslate">Options -MultiViews
RewriteBase /</pre><p>Die RewriteBase gilt es natürlich anzupassen falls das Projekt über einen anderen Pfad erreicht werden muss.</p><p>Da PHP bei 1und1 als CGI läuft, muß man für die <a href="http://de.wikipedia.org/wiki/HTTP-Authentifizierung" target="_blank">HTTP-Authentifizierung</a> auch noch einen kleinen Workaround einbauen:</p><pre class="brush: plain; title: ; notranslate">RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]</pre><p>Damit wird die Authentifizierungsinformation in die Variable $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] geschrieben. Das sieht dann ungefähr so aus:</p><pre class="brush: plain; title: ; notranslate">echo $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
//  Basic: d2lraTpwZWRpYQ==</pre><p>Das ist die Base64-Darstellung von &#8220;Username:Passwort&#8221;.</p><p>Die entgültige .htaccess sieht dann so aus:</p><pre class="brush: plain; title: ; notranslate">AddType x-mapp-php5 .php
Options -MultiViews

RewriteEngine On
RewriteBase /

# workaround for 1und1 php cgi mode
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]</pre><p>Und so kommt man an Username + Passwort heran:</p><pre class="brush: php; title: ; notranslate">if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
 list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)));
}</pre><br/><br/><p>Ähnliche Artikel:</p><ol><li><a href='http://www.phpgangsta.de/blog-url-struktur-geandert' rel='bookmark' title='Blog URL Struktur geändert'>Blog URL Struktur geändert</a></li></ol>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/php-und-http-auth-bei-1und1-webhosting/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>eMail-Postfächer synchronisieren mit imapsync</title><link>http://www.phpgangsta.de/email-postfacher-synchronisieren-mit-imapsync</link> <comments>http://www.phpgangsta.de/email-postfacher-synchronisieren-mit-imapsync#comments</comments> <pubDate>Mon, 21 Dec 2009 18:15:49 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[IMAP Konten]]></category> <category><![CDATA[imapsync]]></category> <category><![CDATA[Mail Backup]]></category> <category><![CDATA[Mails synchronisieren]]></category> <category><![CDATA[Postfächer]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=720</guid> <description><![CDATA[Einer der wenigen Artikel, die sich nicht um PHP drehen, aber trotzdem sehr interessant sind So häufig braucht es der Normalanwender nicht, aber wenn man mal seinen Email-Provider wechselt oder eine Kopie aller seiner Mails auf einem anderen Server haben möchte, gibt es nichts einfacheres als das imapsync-Script von Gilles Lamiral. imapsync ist ein Perl-Script, [...]<br/><br/> Keine ähnlichen Artikel.]]></description> <content:encoded><![CDATA[<p>Einer der wenigen Artikel, die sich nicht um PHP drehen, aber trotzdem sehr interessant sind <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p><p>So häufig braucht es der Normalanwender nicht, aber wenn man mal seinen Email-Provider wechselt oder eine Kopie aller seiner Mails auf einem anderen Server haben möchte, gibt es nichts einfacheres als das <a href="http://freshmeat.net/projects/imapsync/" target="_blank">imapsync</a>-Script von Gilles Lamiral.</p><p>imapsync ist ein Perl-Script, das unter Linux, Windows und Mac läuft und die Emails zweier IMAP-Konten abgleichen kann. Dabei kopiert es nicht nur die Emails selbst, sondern auch deren Flags und das Interne Datum der Mails. Jede Nachricht wird auch nur einmal kopiert, sodass möglichst wenig Datentransfer stattfindet. Es ist also sowohl für Backupzwecke als auch Migrationszwecke von großem Nutzen, denn es unterstützt eine Vielzahl von verschiedenen IMAP-Servern.</p><p>Wenn ich hier alle Optionen aufzählen würde, die das Script unterstützt, würde der Artikel sehr lang werden. Das lassen wir also schön bleiben, nur ein paar Stichworte seien verraten: Es unterstützt SSL, Ordner können übersprungen werden, man kann Quellordner auf andere Zielordner mappen, Mails können nach der Synchronisierung gelöscht werden (dann ist es eher ein Verschieben von Mails statt einer Synchronisierung), Mails die größer als ein Limit sind können übersprungen werden, nur Mails der letzten X Tage können synchronisiert werden usw usw.</p><p>Genug Informationen, um es mal auszuprobieren? Dann los:</p><pre class="brush: bash; title: ; notranslate">sudo apt-get install imapsync</pre><p>Schon ist es installiert und wir können anfangen zu synchronisieren. Erstmal machen wir einen Trockendurchlauf (&#8211;dry), es wird also nur simuliert:</p><pre class="brush: bash; title: ; notranslate">imapsync --dry --host1 10.0.0.2 --user1 &quot;mkliewe@mail.de&quot; --password1 &quot;Passwort1&quot; --host2 10.0.0.3 --user2 &quot;backup@mail.de&quot; --password2 &quot;Passwort2&quot;</pre><p>Die Ausgabe sieht dann beispielsweise so aus:</p><pre class="brush: bash; title: ; notranslate">$RCSfile: imapsync,v $ $Revision: 1.286 $ $Date: 2009/07/24 15:53:04 $
Here is a [linux] system (Linux xxxxx01 2.6.31-14-server #48-Ubuntu SMP Fri Oct 16 15:07:34 UTC 2009 x86_64)
with perl 5.10.0
Mail::IMAPClient  3.21
IO::Socket        1.30_01
IO::Socket::SSL
Digest::MD5       2.36_01
Digest::HMAC_MD5
Term::ReadKey
Date::Manip
 and the module Mail::IMAPClient version used here is 3.21
Command line used:
/usr/bin/imapsync --dry --host1 10.0.0.2 --user1 mkliewe@mail.de --password1 MASKED --host2 10.0.0.3 --user2 backup@mail.de --password2 MASKED
Turned ON syncinternaldates, will set the internal dates (arrival dates) on host2 same as host1.
TimeZone:[europe/berlin]
Will try to use CRAM-MD5 authentication on host1
Will try to use CRAM-MD5 authentication on host2
From imap server [10.0.0.2] port [143] user [mkliewe@mail.de]
To   imap server [10.0.0.3] port [143] user [backup@mail.de]
Banner: * OK mail.de Dovecot ready.
Host 10.0.0.2 says it has CAPABILITY for AUTHENTICATE CRAM-MD5
Success login on [10.0.0.2] with user [mkliewe@mail.de] auth [CRAM-MD5]
Banner: * OK mail.de Dovecot ready.
Host 10.0.0.3 says it has CAPABILITY for AUTHENTICATE CRAM-MD5
Success login on [10.0.0.3] with user [backup@mail.de] auth [CRAM-MD5]
host1: state Authenticated
host2: state Authenticated
From separator and prefix: [.][]
To   separator and prefix: [.][]
++++ Calculating sizes ++++
From Folder [INBOX]                             Size:     37258 Messages:     3
From Folder [Test2]                             Size:         0 Messages:     0
From Folder [Trash]                             Size:         0 Messages:     0
Total size: 37258
Total messages: 3
Time: 0 s
++++ Calculating sizes ++++
To   Folder [INBOX]                             Size:         0 Messages:     0
To   Folder [Test2]                            does not exist yet
To   Folder [Trash]                            does not exist yet
Total size: 0
Total messages: 0
Time: 0 s
++++ Listing folders ++++
From folders list: [INBOX] [Test2] [Trash]
To   folders list: [INBOX]
++++ Looping on each folder ++++
From Folder [INBOX]
To   Folder [INBOX]
++++ From [INBOX] Parse 1 ++++
++++ To   [INBOX] Parse 1 ++++
++++ Verifying [INBOX] -&gt; [INBOX] ++++
+ NO msg #1 [jM2q9dB8TAvtUZDi0mNMyQ:30262] in INBOX
+ Copying msg #1:30262 to folder INBOX
flags from: [$notjunk][&quot;21-Dec-2009 15:15:25 +0100&quot;]
+ NO msg #2 [0RLbKdGjywBv4mLEANRUtg:5553] in INBOX
+ Copying msg #2:5553 to folder INBOX
flags from: [$notjunk][&quot;21-Dec-2009 17:19:02 +0100&quot;]
+ NO msg #3 [ctDrRzmFgf4W2lUbu/KlBQ:1443] in INBOX
+ Copying msg #3:1443 to folder INBOX
flags from: [$notjunk][&quot;19-Dec-2009 19:34:30 +0100&quot;]
Time: 1 s
From Folder [Test2]
To   Folder [Test2]
To   Folder Test2 does not exist
Creating folder [Test2]
From Folder [Trash]
To   Folder [Trash]
To   Folder Trash does not exist
Creating folder [Trash]
++++ End looping on each folder ++++
++++ Statistics ++++
Time                   : 1 sec
Messages transferred   : 0 (could be 3 without dry mode)
Messages skipped       : 0
Total bytes transferred: 0
Total bytes skipped    : 0
Total bytes error      : 0
Detected 0 errors</pre><p>In diesem Fall gibt es also 3 Ordner auf dem Quellserver. Die Ordner &#8220;Trash&#8221; und &#8220;Test2&#8243; gibt es auf dem Zielserver noch nicht, sie würden also angelegt. Es existieren auch 3 Emails in der INBOX, die synchronisiert werden.</p><p>Wenn man den selben Befehl nochmal ohne &#8211;dry ausführt, dann wird wirklich synchroniert von host1 nach host2.</p><p>Um dann die Synchronisation stündlich zu wiederholen eignet sich ein Cronjob:</p><pre class="brush: bash; title: ; notranslate">sudo crontab -u root -e</pre><p>mit dem Inhalt</p><pre class="brush: plain; title: ; notranslate">0 * * * 1-5 /usr/local/bin/myimapsync.sh</pre><p>wobei in der myimapsync.sh natürlich der Befehl stehen sollte, beispielsweise:</p><pre class="brush: bash; title: ; notranslate">#!/bin/bash

imapsync --dry --host1 imap.domain.de --user1 &quot;user@domain.de&quot; --password1 &quot;Passwort1&quot; --host2 10.0.0.3 --user2 &quot;backup@domain.de&quot; --password2 &quot;Passwort2&quot; &gt;&gt; /var/log/myimapsync.log</pre><p>Hier für Administratoren noch ein kleines hilfreichen Script, welches mehrere Konten synchronisiert:</p><pre class="brush: bash; title: ; notranslate">#!/bin/bash

inputfile=&quot;/etc/imapsyncbatch.conf&quot;
host1=&quot;imap.domain.de&quot;
host2=&quot;10.0.0.3&quot;
logfile=&quot;/var/log/imapsyncbatch.log&quot;

if [ ! -f $inputfile ]
then
{
	echo &quot;The input file does not exist! Exiting...&quot; &gt;&gt; $logfile
	exit;
}
fi

date=`date +%X_-_%x`
echo &quot;$date IMAPSync started...&quot; &gt;&gt; $logfile

tr &quot;,&quot; &quot; &quot; &lt;$inputfile | while read u1 p1 u2 p2
do
	date=`date +%X_-_%x`
	echo &quot;$date Start Syncing User $u1 to $u2&quot; &gt;&gt; $logfile
	imapsync $1 --buffersize 8192000 --nosyncacls --syncinternaldates \
		--host1 $host1 --user1 &quot;$u1&quot; --password1 &quot;$p1&quot; --ssl1 --port1 993 \
		--host2 $host2 --user2 &quot;$u2&quot; --password2 &quot;$p2&quot; --ssl2 --port2 993 \
		--noauthmd5
	date=`date +%X_-_%x`
	echo &quot;$date Finished $u1 to $u2&quot; &gt;&gt; $logfile
done

date=`date +%X_-_%x`
echo &quot;$date IMAPSync Finished...&quot; &gt;&gt; $logfile
echo &quot;$date ------------------------------------&quot; &gt;&gt; $logfile</pre><p>wobei in der /etc/imapsyncbatch.conf die Zugangsdaten stehen:</p><pre class="brush: plain; title: ; notranslate">user1@domain.de,Passwort1,user2@domain.de,Passwort2
bernd@domain.de,PasswortBernd,backup@domain.de,PasswortBernd</pre><p>Falls mehrere Personen Zugriff auf diesen Rechner haben, sollte diese Datei gut geschützt werden (beispielsweise mit &#8220;sudo chmod 700 /etc/imapsyncbatch.conf&#8221;). Da das Script selbst keinen Root-Zugriff auf den Rechner braucht, kann man es auch mit einem normalen Benutzeraccount starten, dann muß allerdings der Lesezugriff auf die /etc/imapsyncbatch.conf und der Schreibzugriff auf /var/log/imapsyncbatch.log gewährleistet sein.</p> <br/><br/><p>Keine ähnlichen Artikel.</p>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/email-postfacher-synchronisieren-mit-imapsync/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Virtualisierung: ESXi ausprobieren auf dem Mac</title><link>http://www.phpgangsta.de/virtualisierung-esxi-ausprobieren-auf-dem-mac</link> <comments>http://www.phpgangsta.de/virtualisierung-esxi-ausprobieren-auf-dem-mac#comments</comments> <pubDate>Thu, 10 Dec 2009 16:08:15 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Allgemein]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[ESXi]]></category> <category><![CDATA[Hypervisor]]></category> <category><![CDATA[Virtualisierung]]></category> <category><![CDATA[VMWare]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=680</guid> <description><![CDATA[Wer sich mit Virtualisierung beschäftigt, kommt um VMWare nicht herum. VMWare Workstation haben sicherlich einige von euch schon ausprobiert, sobald es dann aber in Richtung &#8220;Server-Virtualisierung&#8221; geht wird die Luft schon dünner. Wenn man Virtualisierungssoftware (auch Hypervisor genannt) grob unterteilen möchte, gibt es 2 Arten: Hypervisor, die direkt auf der Hardware laufen (&#8220;bare metal&#8221;, also [...]<br/><br/> Keine ähnlichen Artikel.]]></description> <content:encoded><![CDATA[<p>Wer sich mit Virtualisierung beschäftigt, kommt um VMWare nicht herum. VMWare Workstation haben sicherlich einige von euch schon ausprobiert, sobald es dann aber in Richtung &#8220;Server-Virtualisierung&#8221; geht wird die Luft schon dünner.</p><p>Wenn man Virtualisierungssoftware (auch <a href="http://de.wikipedia.org/wiki/Hypervisor" target="_blank">Hypervisor</a> genannt) grob unterteilen möchte, gibt es 2 Arten:</p><ol><li>Hypervisor, die direkt auf der Hardware laufen (&#8220;bare metal&#8221;, also selbst eine Art Minibetriebssystem) und kein Host-Betriebssystem benötigen. Bekannte Produkte sind hier <a href="http://www.vmware.com/products/esx/" target="_blank">VMWare ESX</a>, der <a href="http://www.vmware.com/products/esxi/" target="_blank">kostenlose VMWare ESXi</a>, <a href="http://www.citrix.com/english/ps2/products/feature.asp?contentID=1686939" target="_blank">XenServer Hypervisor</a>, <a href="http://www.microsoft.com/servers/hyper-v-server/how-to-get.mspx" target="_blank">Microsofts Hyper-V</a>, Sie werden auch als &#8220;Type 1&#8243; oder &#8220;Native VM&#8221; bezeichnet.</li><li>Applikationen, die auf einem Betriebssystem installiert werden, und dann als Programm gestartet werden. Bekannte Vertreter sind da <a href="http://www.virtualbox.org/" target="_blank">Sun&#8217;s Open Source VirtualBox</a>, <a href="http://www.vmware.com/products/workstation/" target="_blank">VMWare Workstation/Server</a>, <a href="http://www.microsoft.com/windows/virtual-pc/" target="_blank">Microsoft Virtual PC</a>, <a href="http://www.linux-kvm.org/page/Main_Page" target="_blank">KVM</a>, <a href="http://user-mode-linux.sourceforge.net/" target="_blank">UML</a>, <a href="http://linux-vserver.org/" target="_blank">Linux VServer</a>, <a href="http://openvz.org/" target="_blank">OpenVZ</a>, <a href="http://www.parallels.com/de/products/pvc45/" target="_blank">Virtuozzo</a> und viele weitere. Sie werden auch als &#8220;Type 2&#8243; oder &#8220;Hosted VM&#8221; bezeichnet.</li></ol><p>In der zweiten Kategorie unterscheidet man dann zwischen &#8220;Full Virtualization&#8221; und &#8220;Paravirtualization&#8221;. Ersteres kann unveränderte Gäste starten, sprich jedes Betriebssystem auf dem Markt, während bei Paravirtualization das Gastbetriebssystem weiß, dass es virtualisiert wird und es angepasst sein muss an diese Situation, es geht also nicht mit jedem Betriebssystem.</p><p>Bei den Bare-Metal-Hypervisor gibt es natürlich Hardware-Einschränkungen, da sie direkt auf der Hardware laufen und nicht eine so große Treiber-Unterstützung mitbringen können wie moderne Windows- oder Linux-Betriebssysteme. Daher sollte man sich vorher informieren, ob beispielsweise ESXi auf seiner Hardware überhaupt läuft.</p><p>Um etwas mit ESXi zu testen, habe ich mir für zuhause mal einen USB-Stick erstellt mit der ESXi-Software drauf, und davon gebootet. Der Hypervisor bootete auch erfolgreich, jedoch bliebt er beim Laden der USB-Module stecken. Mein Mainboard (ein MSI 790FX GD70) wird also nicht unterstützt. Um trotzdem zu testen, startete ich es in der Firma mal testweise in VMWare Fusion. VMWare Fusion ist quasi das selbe wie VMWare Workstation, nur für Mac. Doch auch hier startete der Hypervisor nicht vernünftig, da ein Hypervisor innerhalb eines Hypervisors nicht unterstützt wird. Doch <a href="http://www.van-lieshout.com/2009/06/installing-esx-40-on-vmware-fusion/" target="_blank">Dank eines Blog-Artikels</a> habe ich es dennoch ans Laufen bekommen, und nun kann ich ESXi ausgiebig testen.</p><p>Ich habe also ein Mac OS X, darauf VMWare Fusion, darin wiederum ESXi installiert, und auf dem ESXi laufen dann weitere Betriebssysteme (aktuell ein Ubuntu 9.10 und Debian Lenny). Damit ich den ESXi administrieren kann, benötigt man VMWare vSphere, welches wiederum nur unter Windows läuft. Also habe ich unter Fusion noch eine Windows Virtual Machine laufen.</p><p>Ihr merkt schon, es macht Spass, soviele Betriebssysteme, teilweise verschachtelt, laufen zu lassen <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p> <br/><br/><p>Keine ähnlichen Artikel.</p>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/virtualisierung-esxi-ausprobieren-auf-dem-mac/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Zuhause im IPv6 Web surfen (Teil1: Ubuntu)</title><link>http://www.phpgangsta.de/zuhause-im-ipv6-web-surfen</link> <comments>http://www.phpgangsta.de/zuhause-im-ipv6-web-surfen#comments</comments> <pubDate>Tue, 17 Nov 2009 22:34:19 +0000</pubDate> <dc:creator>Michael Kliewe</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[DualStack]]></category> <category><![CDATA[gw6c]]></category> <category><![CDATA[IPv6]]></category> <category><![CDATA[IPv6-Tunnel]]></category> <category><![CDATA[Tunnelbroker]]></category> <category><![CDATA[Ubuntu]]></category><guid isPermaLink="false">http://www.phpgangsta.de/?p=570</guid> <description><![CDATA[Das neue Internet Protokoll in der Version 6 wird kommen, soviel ist sicher. Da es ein langsamer Umstieg ist, leben wir aktuell in einer zweigeteilten Welt: Der alten IPv4 Welt und der neuen IPv6 Welt. Einige Länder sind bei der Umstellung schneller, andere müssen noch mehr oder weniger dazu gezwungen werden. Ganz getrennt sind die [...]<br/><br/> Keine ähnlichen Artikel.]]></description> <content:encoded><![CDATA[<p>Das neue Internet Protokoll in der Version 6 wird kommen, soviel ist sicher. Da es ein langsamer Umstieg ist, leben wir aktuell in einer zweigeteilten Welt: Der alten IPv4 Welt und der neuen IPv6 Welt. Einige Länder sind bei der Umstellung schneller, andere müssen noch mehr oder weniger dazu gezwungen werden.</p><p>Ganz getrennt sind die beiden Welten jedoch nicht. Mit Hilfe von Tunnel-Protokollen und -Servern kann man zwischen den jeweiligen Netzen vermitteln.</p><p>Da die meisten von euch wohl noch IPv4 zuhause haben werden (kein großer deutscher Provider bietet aktuell IPv6 DSL-Anschlüsse an, es gibt nur ein paar kleinere), will ich hier kurz eine Anleitung schreiben, wie ich es zuhause nutze.</p><p>So sieht es vorher aus, wenn man noch keine IPv6 Verbindung hat (so sollte es bei euch auch aussehen):</p><pre class="brush: bash; title: ; notranslate">$ ping6 ipv6.google.com
connect: Network is unreachable</pre><p>(Diese komplette Anleitung ist für Linux/Ubuntu, <a href="http://www.phpgangsta.de/581" target="_blank">für Windows gibt es auch Software und eine Anleitung</a>, also einfach weiterlesen)</p><p><img class="alignnone size-full wp-image-571" title="without_ipv6" src="http://www.phpgangsta.de/wp-content/uploads/without_ipv6.png" alt="without_ipv6" width="648" height="588" /></p><p>Alles was wir brauchen ist eine Client-Software, die uns auf unserem Rechner hilft, ein Tunnel-Device zu erstellen, welches dann den IPv6-Traffic zum Tunnel-Server leitet. Ich habe zuhause die Software &#8220;gogoClient&#8221;(gw6c) genutzt, um mich mit einem kostenlosen IPv6 Tunnelbroker zu verbinden.</p><p>Es gibt verschiedene Möglichkeiten, je nach Betriebssystem, das grundlegende Vorgehen ist dabei: Download der Client Software und Starten der Sofware <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p><p>Und das müßt ihr dafür tun:</p><p>Ihr registriert euch kostenlos auf dieser Seite: <a href="http://gogonet.gogo6.com/" target="_blank">http://gogonet.gogo6.com/</a></p><p>Jedes Mitglied dort erhält nämlich die Möglichkeit, die Software herunterzuladen und eine IPv6-Adresse (bzw. ein Netz) zu erhalten. Unten in diesem Artikel gibt es noch einige interessante Links, die man sich durchlesen kann, falls man Probleme hat oder wissen möchte, was alles hinter dem Service steckt. Oder gar eine feste IPv6-Adresse haben möchte.</p><p>Nach der Registrierung kann man hier den Client herunterladen:</p><p><a href="http://gogonet.gogo6.com/page/download-1" target="_blank">http://gogonet.gogo6.com/page/download-1</a></p><p>Es gibt Versionen für Windows, Linux, *BSD, OpenWRT etc, alles was das Herz begehrt.</p><p>Nach dem Download entpackt man das entsprechende Archiv (Unter Windows startet man den Installer).</p><pre class="brush: bash; title: ; notranslate">$ tar -xzvf gw6c-linux.tar.gz
gw6c/
gw6c/template/
gw6c/template/README
gw6c/template/linux.sh
gw6c/bin/
gw6c/bin/gw6c.conf
gw6c/bin/gw6c
gw6c/bin/gw6c.conf.sample
gw6c/man/
gw6c/man/man5/
gw6c/man/man5/gw6c.conf.5
gw6c/man/man8/
gw6c/man/man8/gw6c.8</pre><p>In meinem Fall mußte ich nur noch eine kleine Einstellung in der gw6c/bin/gw6c.conf machen, nämlich den Pfad korrekt angeben, wohin ich gw6c entpackt habe:</p><pre class="brush: bash; title: ; notranslate">gw6_dir=/usr/local/gw6c</pre><p>Danach einfach starten via</p><pre class="brush: bash; title: ; notranslate">sudo /usr/local/gw6c/bin/gw6c</pre><p>Dann sollte der Tunnel aufgebaut sein:</p><pre class="brush: bash; title: ; notranslate">$ ifconfig tun
tun       Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet6 addr: 2001:5c0:1000:a::539/128 Scope:Global
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1280  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:1032 (1.0 KB)  TX bytes:608 (608.0 B)</pre><p>Falls das nicht der Fall ist, kann man das Logging aktivieren, indem man in der gw6c.conf die folgenden Einstellungen abändert:</p><pre class="brush: bash; title: ; notranslate">log_file=3
log_filename=gw6c.log</pre><p>Sobald nun also der Tunnel aufgebaut ist, können wir IPv6 nutzen:</p><pre class="brush: bash; title: ; notranslate">$ ping6 ipv6.google.com
PING ipv6.google.com(fx-in-x68.1e100.net) 56 data bytes
64 bytes from fx-in-x68.1e100.net: icmp_seq=1 ttl=56 time=42.3 ms
64 bytes from fx-in-x68.1e100.net: icmp_seq=2 ttl=56 time=44.8 ms
64 bytes from fx-in-x68.1e100.net: icmp_seq=3 ttl=56 time=44.4 ms
64 bytes from fx-in-x68.1e100.net: icmp_seq=4 ttl=56 time=48.3 ms
64 bytes from fx-in-x68.1e100.net: icmp_seq=5 ttl=56 time=43.6 ms</pre><pre class="brush: bash; title: ; notranslate">$ host ipv6.google.com

ipv6.google.com is an alias for ipv6.l.google.com.
ipv6.l.google.com has IPv6 address 2001:4860:a003::68</pre><pre class="brush: bash; title: ; notranslate">whois 2001:4860:a003::68

OrgName:    Google Inc.
OrgID:      GOGL
Address:    1600 Amphitheatre Parkway
City:       Mountain View
StateProv:  CA
PostalCode: 94043
Country:    US

NetRange:   2001:4860:0000:0000:0000:0000:0000:0000 - 2001:4860:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
CIDR:       2001:4860:0000:0000:0000:0000:0000:0000/32
OriginAS:   AS15169
NetName:    GOOGLE-IPV6</pre><p>Oder im Firefox:</p><p><img class="alignnone size-full wp-image-572" title="with_ipv6" src="http://www.phpgangsta.de/wp-content/uploads/with_ipv6.png" alt="with_ipv6" width="648" height="588" /></p><p>Ihr surft nun also transparent in beiden Netzen. Falls eine Adresse ins IPv6 führt, wird es über gogo6 geroutet, bei IPv4 bleibt alles beim alten.</p><p>Man kann nun auch noch bei gogo6 den Freenet6 Tunnel Service nutzen und eine feste IPv6 Adresse bekommen. Dazu mußt man sich <a href="http://gogonet.gogo6.com/page/freenet6-registration" target="_blank">auf einer Seite registrieren</a>, und mit diesen Registrierungsdaten die gw6c.conf anpassen. Und schon hat man eine statische IPv6 Adresse, unter der man auch seinen Rechner zuhause erreichen kann und Dienste anbieten kann.</p><p><a href="http://www.phpgangsta.de/581" target="_blank">Für Windows gibt es hier die Anleitung mit vielen Screenshots</a> <img src='http://www.phpgangsta.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p><p>Weitere Seiten, die man mit IPv6 Zugangn besuchen kann:</p><p><a href="http://www.six.heise.de" target="_blank">http://www.six.heise.de</a></p><p><a href="http://www.ipv6.bieringer.de" target="_blank">http://www.ipv6.bieringer.de</a> (mit Informationen über die eigene IPv6-Adresse)</p><p><a href="http://www.kame.net" target="_blank">http://www.kame.net</a> Die tanzende IPv6-Schildkröte aus Japan</p><p><strong>ACHTUNG: Mit einem solchen Tunnel erhaltet ihr eine öffentliche IPv6-Adresse. Ihr umgeht damit euren Router/NAT und seid direkt aus dem Internet erreichbar. Achtet also darauf, welche Dienste ihr ins Internet zur Verfügung stellt! Eventuell müßt ihr eine lokale Firewall installieren/konfigurieren, damit ihr nicht zu einer Spam-Drohne werdet oder gar schlimmeres. Achtet auf Freigaben, lokale Entwickler-Webserver etc etc.</strong></p><p>=======================================================</p><p>Interessante Kurzvideos über ping6, traceroute6, whois usw: <a href="http://ipv6.he.net/presentations.php" target="_blank">http://ipv6.he.net/presentations.php</a></p><p><a href="http://gogonet.gogo6.com/page/freenet6-tunnelbroker" target="_blank">http://gogonet.gogo6.com/page/freenet6-tunnelbroker</a></p><p><a href="http://gogonet.gogo6.com/page/help-center" target="_blank">http://gogonet.gogo6.com/page/help-center</a></p><p><a href="http://gogonet.gogo6.com/page/service-status" target="_blank">http://gogonet.gogo6.com/page/service-status</a></p><p>Diese Anleitung sieht einfacher aus, hat bei mir aber nicht funktioniert: <a href="http://unquietwiki.blogspot.com/2009/10/go-go-dancing-on-internet-ipv6-anyway.html" target="_blank">http://unquietwiki.blogspot.com/2009/10/go-go-dancing-on-internet-ipv6-anyway.html</a></p> <br/><br/><p>Keine ähnlichen Artikel.</p>]]></content:encoded> <wfw:commentRss>http://www.phpgangsta.de/zuhause-im-ipv6-web-surfen/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: basic
Database Caching 2/118 queries in 4.894 seconds using disk: basic
Object Caching 3514/3713 objects using disk: basic

Served from: www.phpgangsta.de @ 2012-02-04 13:28:51 -->
