Datenhaufen zu IT und Elektronik.

Autor: kernel-error (Seite 26 von 47)

Google schaut in die E-Mails seiner gmail Nutzer!

Google schaut in die E-Mails seiner gmail Nutzer, wertet den Inhalt aus und zeigt dem Nutzer dann maßgeschneiderte Werbung…. OK, ist jetzt nichts Neues! Nun hat Google aber bekanntgegeben dass sie zumindest keine Schüler mehr in dieser Form abschnorcheln will.

Zu lesen ist es hier: http://googleenterprise.blogspot.de/2014/04/protecting-students-with-google-apps.html

Toll, oder? Super… Alle freuen sich… O_o ALLE FREUEN SICH! Leute, schlaft ihr alle? Google durchsucht, nach eigenen Angaben, keine E-Mail Accounts von Schülern mehr und SCHÜTZT sie somit vor Werbung welche zu E-Mail Inhalten passt!!!!!

Das ist so als wenn der Postbote die Briefe liest und immer direkt das passende Werbeprospekt beilegt. Warum freuen sich alle? Ich verstehe es nicht, tut mir leid!

AOL macht jetzt auch Mailinglisten „kaputt“ / DMARC

Das gefällt mir laughing… Nachdem nun Yahoo die Eier hatte einfach mal ihre DMARC Policy „scharf“ (reject) zu schalten und sich so viel Schimpfe von aller Welt dafür eingesammelt hat und beschuldigt wurde die Mailinglisten „kaputt“ zu machen…. Tja, da zieht AOL nun in gewisser Weise nach: http://postmaster-blog.aol.com/2014/04/22/aol-mail-updates-dmarc-policy-to-reject/

AOL hat nämlich gerade ein tierisches Spam-Problem. Also jetzt nicht direkt, eher haben andere das Problem, es betrifft AOL nur in soweit das deren Absenderdomain dafür missbraucht wird. Die Spam E-Mails sehen also so aus als wenn sie von AOL kommen. AOL hat nun also ihre DMARC Policy scharf geschaltet um das Problem damit etwas eindämmen zu können. Ob nun wohl so langsam Google und Microsoft ebenfalls nachziehen? Inzwischen sollten die Admins der Mailinglisten ja schon mal „warm“ gelaufen sein tongue-out

Mailgraph: Erweiterung der Grafiken um SPF, DMARC und DKIM

Zu allem Monitoring sind grafische Auswertungen eine feine Sache um auf einen kurzen Blick zu erkennen ob sich etwas „positiv“ oder eher „negativ“ entwickelt. Eine sehr simple Lösung ist dabei mailgraph von David Schweikert. Um kleinere Mailserver im Auge zu behalten oder Änderungen an Testsystemen zu bewundern setzte ich es gerne ein.

Als ich mich vor einiger Zeit mit SPF / DKIM und DMARC beschäftigt habe, interessiere mich natürlich wie viele der E-Mails im Schnitt signiert sind, wie oft ein Test fehlschlägt und somit vermeintliche Werbung abgewehrt hat usw. usw… Ich habe mir dann zu beginn die Maillogs per egrep vorgenommen. Reichte für eine erste Übersicht. Irgendwann wollte ich mehr und habe begonnen mir mailgraph (Version 1.14) so zu erweitern das er mir genau diese Informationen anzeigt. Ich habe zwar einen spf-patch für mailgraph gefunden, nur wollte ich ja noch mehr.

Vor kurzem habe ich einen kleinen Vortrag zum Thema DMARC gehalten und dabei die Graphen auf einem der Testsysteme gezeigt. Da es ungewöhnlich viele Rückfragen dazu gab (wie, woher…) habe ich versprochen die Erweiterung online zu stellen!

Auf einem normalen Debian System müssen nur die beiden Dateien /usr/sbin/mailgraph sowie /usr/lib/cgi-bin/mailgraph.cgi durch die folgenden ersetzt werden. Wie immer bitte selbst denkend und nach vorheriger Sicherung tongue-out. Davon abgesehen das ich kein Programmierer bin, nehme ich Verbesserungsvorschläge sehr gerne an!

Dabei ist es ausgelegt für Postfix mit postfix-policyd-spf, opendkim und opendmarc

Beispiel…

Hier die bekannte Grafik der insg. empfangenen und versendeten E-Mails aus der letzten Woche.

Direkt gefolgt von der grafischen Auswertung der zurückgewiesenen, verseuchten usw… Mails.

Der folgende Graph zeigt den Anteil der E-Mails bei denen es keinen SPF Schutz der Domain gibt (SPF none), der SPF Check fehlgeschlagen ist (SPF fail) und selbstverständlich wo der SPF Check erfolgreich (SPF pass) war.

Gleiches gilt für den folgenden Graphen, wobei es sich hier auf DMARC bezieht.

Zu guter Letzte der Graph zu DKIM.


Download

Ich habe dafür zwei Patchfiles erstellt und diese lassen sich hier herunterladen: mailgraph-dmarc-spf-dkim.patch.tar.gz

/usr/sbin/mailgraph.patch

*** mailgraph	2012-06-17 00:00:00.000000000 +0200
--- mailgraph	2014-04-24 08:59:58.964977886 +0200
***************
*** 4,9 ****
--- 4,10 ----
  # copyright (c) 2000-2007 ETH Zurich
  # copyright (c) 2000-2007 David Schweikert <david@schweikert.ch>
  # released under the GNU General Public License
+ # with dkim-, dmarc, spf-patch Sebastian van de Meer <kernel-error@kernel-error.de>
  
  ######## Parse::Syslog 1.09 (automatically embedded) ########
  package Parse::Syslog;
***************
*** 382,388 ****
  my $rrd_greylist = "mailgraph_greylist.rrd";
  my $year;
  my $this_minute;
! my %sum = ( sent => 0, received => 0, bounced => 0, rejected => 0, virus => 0, spam => 0, greylisted => 0, delayed => 0);
  my $rrd_inited=0;
  
  my %opt = ();
--- 383,389 ----
  my $rrd_greylist = "mailgraph_greylist.rrd";
  my $year;
  my $this_minute;
! my %sum = ( sent => 0, received => 0, bounced => 0, rejected => 0, spfnone => 0, spffail => 0, spfpass => 0, dmarcnone => 0, dmarcfail => 0, dmarcpass => 0, dkimnone => 0, dkimfail => 0, dkimpass => 0, virus => 0, spam => 0, greylisted => 0, delayed => 0);
  my $rrd_inited=0;
  
  my %opt = ();
***************
*** 396,401 ****
--- 397,411 ----
  sub event_rejected($);
  sub event_virus($);
  sub event_spam($);
+ sub event_spfnone($);
+ sub event_spffail($);
+ sub event_spfpass($);
+ sub event_dmarcnone($);
+ sub event_dmarcfail($);
+ sub event_dmarcpass($);
+ sub event_dkimnone($);
+ sub event_dkimfail($);
+ sub event_dkimpass($);
  sub event_greylisted($);
  sub event_delayed($);
  sub init_rrd($);
***************
*** 533,538 ****
--- 543,557 ----
  				'DS:recv:ABSOLUTE:'.($rrdstep*2).':0:U',
  				'DS:bounced:ABSOLUTE:'.($rrdstep*2).':0:U',
  				'DS:rejected:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:spfnone:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:spffail:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:spfpass:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:dmarcnone:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:dmarcfail:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:dmarcpass:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:dkimnone:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:dkimfail:ABSOLUTE:'.($rrdstep*2).':0:U',
+ 				'DS:dkimpass:ABSOLUTE:'.($rrdstep*2).':0:U',
  				"RRA:AVERAGE:0.5:$day_steps:$realrows",   # day
  				"RRA:AVERAGE:0.5:$week_steps:$realrows",  # week
  				"RRA:AVERAGE:0.5:$month_steps:$realrows", # month
***************
*** 614,619 ****
--- 633,649 ----
  				event($time, 'bounced');
  			}
  		}
+ 	  elsif ($prog eq 'policy-spf') {
+ 	    if ($text =~ /Received-SPF: none/) {
+ 	      event($time, 'spfnone');
+ 	    }
+ 	    elsif($text =~ /Received-SPF: pass/) {
+ 				event($time, 'spfpass');
+ 			}
+ 	    elsif($text =~ /Received-SPF:/) {
+ 				event($time, 'spffail');
+ 			}
+ 	  }
  		elsif($prog eq 'local') {
  			if($text =~ /\bstatus=bounced\b/) {
  				event($time, 'bounced');
***************
*** 862,867 ****
--- 892,919 ----
  			event($time, 'virus');
  		}
  	}
+ 	elsif ($prog eq 'opendmarc') {
+ 		if ($text =~ /pass/) {
+ 			event($time, 'dmarcpass');
+ 		}
+ 		elsif($text =~ /none/) {
+ 			event($time, 'dmarcnone');
+ 		}
+ 		elsif($text =~ /fail/) {
+ 			event($time, 'dmarcfail');
+ 		}
+ 	}
+ 	elsif ($prog eq 'opendkim') {
+ 		if ($text =~ /DKIM verification successful/) {
+ 			event($time, 'dkimpass');
+ 		}
+ 		elsif($text =~ /no signature data/) {
+ 			event($time, 'dkimnone');
+ 		}
+ 		elsif($text =~ /bad signature data/) {
+ 			event($time, 'dkimfail');
+ 		}
+ 	}	
  	elsif($prog eq 'avmilter') {
  		# AntiVir Milter
  		if($text =~ /^Alert!/) {
***************
*** 918,931 ****
  	return 1 if $m == $this_minute;
  	return 0 if $m < $this_minute;
  
! 	print "update $this_minute:$sum{sent}:$sum{received}:$sum{bounced}:$sum{rejected}:$sum{virus}:$sum{spam}:$sum{greylisted}:$sum{delayed}\n" if $opt{verbose};
! 	RRDs::update $rrd, "$this_minute:$sum{sent}:$sum{received}:$sum{bounced}:$sum{rejected}" unless $opt{'no-mail-rrd'};
  	RRDs::update $rrd_virus, "$this_minute:$sum{virus}:$sum{spam}" unless $opt{'no-virus-rrd'};
  	RRDs::update $rrd_greylist, "$this_minute:$sum{greylisted}:$sum{delayed}" unless $opt{'no-greylist-rrd'};
  	if($m > $this_minute+$rrdstep) {
  		for(my $sm=$this_minute+$rrdstep;$sm<$m;$sm+=$rrdstep) {
! 			print "update $sm:0:0:0:0:0:0:0:0 (SKIP)\n" if $opt{verbose};
! 			RRDs::update $rrd, "$sm:0:0:0:0" unless $opt{'no-mail-rrd'};
  			RRDs::update $rrd_virus, "$sm:0:0" unless $opt{'no-virus-rrd'};
  			RRDs::update $rrd_greylist, "$sm:0:0" unless $opt{'no-greylist-rrd'};
  		}
--- 970,983 ----
  	return 1 if $m == $this_minute;
  	return 0 if $m < $this_minute;
  
! 	print "update $this_minute:$sum{sent}:$sum{received}:$sum{bounced}:$sum{rejected}:$sum{spfnone}:$sum{spffail}:$sum{spfpass}:$sum{dmarcnone}:$sum{dmarcfail}:$sum{dmarcpass}:$sum{dkimnone}:$sum{dkimfail}:$sum{dkimpass}:$sum{virus}:$sum{spam}:$sum{greylisted}:$sum{delayed}\n" if $opt{verbose};
! 	RRDs::update $rrd, "$this_minute:$sum{sent}:$sum{received}:$sum{bounced}:$sum{rejected}:$sum{spfnone}:$sum{spffail}:$sum{spfpass}:$sum{dmarcnone}:$sum{dmarcfail}:$sum{dmarcpass}:$sum{dkimnone}:$sum{dkimfail}:$sum{dkimpass}" unless $opt{'no-mail-rrd'};
  	RRDs::update $rrd_virus, "$this_minute:$sum{virus}:$sum{spam}" unless $opt{'no-virus-rrd'};
  	RRDs::update $rrd_greylist, "$this_minute:$sum{greylisted}:$sum{delayed}" unless $opt{'no-greylist-rrd'};
  	if($m > $this_minute+$rrdstep) {
  		for(my $sm=$this_minute+$rrdstep;$sm<$m;$sm+=$rrdstep) {
! 			print "update $sm:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0 (SKIP)\n" if $opt{verbose};
! 			RRDs::update $rrd, "$sm:0:0:0:0:0:0:0:0:0:0:0:0:0" unless $opt{'no-mail-rrd'};
  			RRDs::update $rrd_virus, "$sm:0:0" unless $opt{'no-virus-rrd'};
  			RRDs::update $rrd_greylist, "$sm:0:0" unless $opt{'no-greylist-rrd'};
  		}
***************
*** 935,940 ****
--- 987,1001 ----
  	$sum{received}=0;
  	$sum{bounced}=0;
  	$sum{rejected}=0;
+ 	$sum{spfnone}=0;
+ 	$sum{spffail}=0;
+ 	$sum{spfpass}=0;
+ 	$sum{dmarcnone}=0;
+ 	$sum{dmarcfail}=0;
+ 	$sum{dmarcpass}=0;
+ 	$sum{dkimnone}=0;
+ 	$sum{dkimfail}=0;
+ 	$sum{dkimpass}=0;
  	$sum{virus}=0;
  	$sum{spam}=0;
  	$sum{greylisted}=0;

/usr/lib/cgi-bin/mailgraph.cgi.patch

*** mailgraph.cgi	2012-06-17 00:00:00.000000000 +0200
--- mailgraph.cgi	2014-04-24 09:03:11.917988368 +0200
***************
*** 4,9 ****
--- 4,10 ----
  # copyright (c) 2000-2007 ETH Zurich
  # copyright (c) 2000-2007 David Schweikert <david@schweikert.ch>
  # released under the GNU General Public License
+ # with dkim-, dmarc, spf-patch Sebastian van de Meer <kernel-error@kernel-error.de>
  
  use RRDs;
  use POSIX qw(uname);
***************
*** 15,21 ****
--- 16,25 ----
  my $xpoints = 540;
  my $points_per_sample = 3;
  my $ypoints = 160;
+ my $ypoints_spf = 96;
  my $ypoints_err = 96;
+ my $ypoints_dmarc = 96;
+ my $ypoints_dkim = 96;
  my $ypoints_grey = 96;
  my $rrd = '/var/lib/mailgraph/mailgraph.rrd'; # path to where the RRD database is
  my $rrd_virus = '/var/lib/mailgraph/mailgraph_virus.rrd'; # path to where the Virus RRD database is
***************
*** 32,37 ****
--- 36,50 ----
  	sent       => '000099', # rrggbb in hex
  	received   => '009900',
  	rejected   => 'AA0000',
+ 	spfnone    => '000AAA',
+ 	spffail    => '12FF0A',
+ 	spfpass    => 'D15400',
+ 	dmarcnone  => 'FFFF00',
+ 	dmarcfail  => 'FF00EA',
+ 	dmarcpass  => '00FFD5',
+ 	dkimnone   => '3013EC',
+ 	dkimfail   => '006B3A',
+ 	dkimpass   => '491503',
  	bounced    => '000000',
  	virus      => 'DDBB00',
  	spam       => '999999',
***************
*** 154,159 ****
--- 167,292 ----
  	);
  }
  
+ sub graph_spf($)
+ {
+ 	my ($range, $file) = @_;
+ 	my $step = $range*$points_per_sample/$xpoints;
+ 	rrd_graph($range, $file, $ypoints_spf,
+ 		"DEF:spfpass=$rrd:spfpass:AVERAGE",
+ 		"DEF:mspfpass=$rrd:spfpass:MAX",
+ 		"CDEF:rspfpass=spfpass,60,*",
+ 		"CDEF:dspfpass=spfpass,UN,0,spfpass,IF,$step,*",
+ 		"CDEF:sspfpass=PREV,UN,dspfpass,PREV,IF,dspfpass,+",
+ 		"CDEF:rmspfpass=mspfpass,60,*",
+ 		"AREA:rspfpass#$color{spfpass}:SPF pass",
+ 		'GPRINT:sspfpass:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rspfpass:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmspfpass:MAX:max\: %4.0lf msgs/min\l',
+ 	
+ 		"DEF:spfnone=$rrd:spfnone:AVERAGE",
+ 		"DEF:mspfnone=$rrd:spfnone:MAX",
+ 		"CDEF:rspfnone=spfnone,60,*",
+ 		"CDEF:dspfnone=spfnone,UN,0,spfnone,IF,$step,*",
+ 		"CDEF:sspfnone=PREV,UN,dspfnone,PREV,IF,dspfnone,+",
+ 		"CDEF:rmspfnone=mspfnone,60,*",
+ 		"STACK:rspfnone#$color{spfnone}:SPF none",
+ 		'GPRINT:sspfnone:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rspfnone:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmspfnone:MAX:max\: %4.0lf msgs/min\l',
+ 
+ 		"DEF:spffail=$rrd:spffail:AVERAGE",
+ 		"DEF:mspffail=$rrd:spffail:MAX",
+ 		"CDEF:rspffail=spffail,60,*",
+ 		"CDEF:dspffail=spffail,UN,0,spffail,IF,$step,*",
+ 		"CDEF:sspffail=PREV,UN,dspffail,PREV,IF,dspffail,+",
+ 		"CDEF:rmspffail=mspffail,60,*",
+ 		"LINE2:rspffail#$color{spffail}:SPF fail",
+ 		'GPRINT:sspffail:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rspffail:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmspffail:MAX:max\: %4.0lf msgs/min\l',
+ 	);
+ }
+ 
+ sub graph_dmarc($)
+ {
+ 	my ($range, $file) = @_;
+ 	my $step = $range*$points_per_sample/$xpoints;
+ 	rrd_graph($range, $file, $ypoints_dmarc,
+ 		"DEF:dmarcpass=$rrd:dmarcpass:AVERAGE",
+ 		"DEF:mdmarcpass=$rrd:dmarcpass:MAX",
+ 		"CDEF:rdmarcpass=dmarcpass,60,*",
+ 		"CDEF:ddmarcpass=dmarcpass,UN,0,dmarcpass,IF,$step,*",
+ 		"CDEF:sdmarcpass=PREV,UN,ddmarcpass,PREV,IF,ddmarcpass,+",
+ 		"CDEF:rmdmarcpass=mdmarcpass,60,*",
+ 		"AREA:rdmarcpass#$color{dmarcpass}:DMARC pass",
+ 		'GPRINT:sdmarcpass:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rdmarcpass:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmdmarcpass:MAX:max\: %4.0lf msgs/min\l',
+ 		
+ 		"DEF:dmarcnone=$rrd:dmarcnone:AVERAGE",
+ 		"DEF:mdmarcnone=$rrd:dmarcnone:MAX",
+ 		"CDEF:rdmarcnone=dmarcnone,60,*",
+ 		"CDEF:ddmarcnone=dmarcnone,UN,0,dmarcnone,IF,$step,*",
+ 		"CDEF:sdmarcnone=PREV,UN,ddmarcnone,PREV,IF,ddmarcnone,+",
+ 		"CDEF:rmdmarcnone=mdmarcnone,60,*",
+ 		"STACK:rdmarcnone#$color{dmarcnone}:DMARC none",
+ 		'GPRINT:sdmarcnone:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rdmarcnone:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmdmarcnone:MAX:max\: %4.0lf msgs/min\l',
+ 
+ 		"DEF:dmarcfail=$rrd:dmarcfail:AVERAGE",
+ 		"DEF:mdmarcfail=$rrd:dmarcfail:MAX",
+ 		"CDEF:rdmarcfail=dmarcfail,60,*",
+ 		"CDEF:ddmarcfail=dmarcfail,UN,0,dmarcfail,IF,$step,*",
+ 		"CDEF:sdmarcfail=PREV,UN,ddmarcfail,PREV,IF,ddmarcfail,+",
+ 		"CDEF:rmdmarcfail=mdmarcfail,60,*",
+ 		"LINE2:rdmarcfail#$color{dmarcfail}:DMARC fail",
+ 		'GPRINT:sdmarcfail:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rdmarcfail:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmdmarcfail:MAX:max\: %4.0lf msgs/min\l',
+ 	);
+ }
+ 
+ sub graph_dkim($)
+ {
+ 	my ($range, $file) = @_;
+ 	my $step = $range*$points_per_sample/$xpoints;
+ 	rrd_graph($range, $file, $ypoints_dkim,
+ 		"DEF:dkimpass=$rrd:dkimpass:AVERAGE",
+ 		"DEF:mdkimpass=$rrd:dkimpass:MAX",
+ 		"CDEF:rdkimpass=dkimpass,60,*",
+ 		"CDEF:ddkimpass=dkimpass,UN,0,dkimpass,IF,$step,*",
+ 		"CDEF:sdkimpass=PREV,UN,ddkimpass,PREV,IF,ddkimpass,+",
+ 		"CDEF:rmdkimpass=mdkimpass,60,*",
+ 		"AREA:rdkimpass#$color{dkimpass}:DKIM pass",
+ 		'GPRINT:sdkimpass:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rdkimpass:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmdkimpass:MAX:max\: %4.0lf msgs/min\l',
+ 		
+ 		"DEF:dkimnone=$rrd:dkimnone:AVERAGE",
+ 		"DEF:mdkimnone=$rrd:dkimnone:MAX",
+ 		"CDEF:rdkimnone=dkimnone,60,*",
+ 		"CDEF:ddkimnone=dkimnone,UN,0,dkimnone,IF,$step,*",
+ 		"CDEF:sdkimnone=PREV,UN,ddkimnone,PREV,IF,ddkimnone,+",
+ 		"CDEF:rmdkimnone=mdkimnone,60,*",
+ 		"STACK:rdkimnone#$color{dkimnone}:DKIM none",
+ 		'GPRINT:sdkimnone:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rdkimnone:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmdkimnone:MAX:max\: %4.0lf msgs/min\l',
+ 
+ 		"DEF:dkimfail=$rrd:dkimfail:AVERAGE",
+ 		"DEF:mdkimfail=$rrd:dkimfail:MAX",
+ 		"CDEF:rdkimfail=dkimfail,60,*",
+ 		"CDEF:ddkimfail=dkimfail,UN,0,dkimfail,IF,$step,*",
+ 		"CDEF:sdkimfail=PREV,UN,ddkimfail,PREV,IF,ddkimfail,+",
+ 		"CDEF:rmdkimfail=mdkimfail,60,*",
+ 		"LINE2:rdkimfail#$color{dkimfail}:DKIM fail",
+ 		'GPRINT:sdkimfail:MAX:total\: %8.0lf msgs',
+ 		'GPRINT:rdkimfail:AVERAGE:avg\: %5.2lf msgs/min',
+ 		'GPRINT:rmdkimfail:MAX:max\: %4.0lf msgs/min\l',
+ 	);
+ }
+ 
  sub graph_grey($)
  {
  	my ($range, $file) = @_;
***************
*** 235,240 ****
--- 368,376 ----
  		print "<h2 id=\"G$n\">$graphs[$n]{title}</h2>\n";
  		print "<p><img src=\"$scriptname?${n}-n\" alt=\"mailgraph\"/><br/>\n";
  		print "<img src=\"$scriptname?${n}-e\" alt=\"mailgraph\"/></p>\n";
+ 		print "<img src=\"$scriptname?${n}-s\" alt=\"mailgraph\"/></p>\n";
+ 		print "<img src=\"$scriptname?${n}-d\" alt=\"mailgraph\"/></p>\n";
+ 		print "<img src=\"$scriptname?${n}-k\" alt=\"mailgraph\"/></p>\n";
  		print "<img src=\"$scriptname?${n}-g\" alt=\"mailgraph\"/></p>\n";
  	}
  
***************
*** 285,290 ****
--- 421,441 ----
  			graph_err($graphs[$1]{seconds}, $file);
  			send_image($file);
  		}
+ 		elsif($img =~ /^(\d+)-s$/) {
+ 			my $file = "$tmp_dir/$uri/mailgraph_$1_spf.png";
+ 			graph_spf($graphs[$1]{seconds}, $file);
+ 			send_image($file);
+ 		}
+ 		elsif($img =~ /^(\d+)-d$/) {
+ 			my $file = "$tmp_dir/$uri/mailgraph_$1_dmarc.png";
+ 			graph_dmarc($graphs[$1]{seconds}, $file);
+ 			send_image($file);
+ 		}
+ 		elsif($img =~ /^(\d+)-k$/) {
+ 			my $file = "$tmp_dir/$uri/mailgraph_$1_dkim.png";
+ 			graph_dkim($graphs[$1]{seconds}, $file);
+ 			send_image($file);
+ 		}
  		elsif($img =~ /^(\d+)-g$/) {
  			my $file = "$tmp_dir/$uri/mailgraph_$1_grey.png";
  			graph_grey($graphs[$1]{seconds}, $file);

Bei Fragen… Wie immer Fragen 🙂


09-08-2014 Update

Ich habe noch einen Patch erstellt um die Auswertung von DNSSEC DANE im Zusammenhang mit Postfix zu visualisieren. Dieses findet sich hier: mailgraph Graphen um DANE erweitern

Bei Interesse erstelle ich vielleicht noch einen großen Patch, welcher beides beinhaltet.

systemd und ntp

Man ist das hässlich… Da sitze ich hier an einem Sabayon System und bekomme keine saubere Uhrzeit. Zwar sollte ntpd.service beim Start die Uhrzeit abgleichen.. Der Dienst verkackt aber seinen Starten, weil er „noch“ kein Netzwerk hat. Dabei ist sogar hinterlegt dass es er erst nach dem Netzwerkmanager startet, denn noch scheint der Netzwerkmanager so schnell keine Verbindung zu bekommen. Der initiale Abgleich vom ntpd.service schlägt daher fehlt, der Dienst bleibt aus und es probiert es auch später nicht mehr. Grütze..

$ systemctl --failed
UNIT            LOAD   ACTIVE SUB    DESCRIPTION
ntpdate.service loaded failed failed Set time via NTP using ntpdate

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

1 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

Ich lasse jetzt mal das Bughunting und setzte einfach auf chrony 😀 Nur für Zeitsync ist das ok für mich!

$ equo search chrony
╠  @@ Suche...
╠      @@ Paket: net-misc/chrony-1.29.1 Branch: 5, [sabayonlinux.org] 
╠          Verfügbar:      Version: 1.29.1 ~ tag: NoTag ~ Version: 0
╠          Installiert:    Version: Nicht installiert ~ tag: n/a ~ Version: n/a
╠          Slot:           0
╠          Homepage:       http://chrony.tuxfamily.org/ 
╠          Beschreibung:   NTP client and server programs 
╠          Lizenz:         GPL-2
╠   Schlüsselwörter:  chrony
╠   Gefunden:         1 Eintrag

Gefunde und dann  installieren….

$ equo install chrony
╠  @@ Berechne Abhängigkeiten...
╠  ## [N] [sabayonlinux.org] dev-libs/libedit-20130712.3.1|0
╠  ## [N] [sabayonlinux.org] net-misc/chrony-1.29.1|0
╠  @@ Pakete die installiert/aktualisiert/entfernt werden müssen: 2
╠  @@ Pakete die entfernt werden müssen: 0
╠  @@ Download Größe: 413.1kB
╠  @@ Benutzter Festplattenspeicher: 715.6kB
╠  @@ Du brauchst zumindest: 1.5MB freien Speicherplatz
╠  ::: >>>  (1/1) 2 Pakete
╠    ## downloaden: 2 Pakete
╠    ## ( mirror #1 ) [dev-libs:libedit-20130712.3.1.3556f679066ec7d787573f08ac74ef24922243b2~0.tbz2] @ http://na.mirror.garr.it
╠    ## ( mirror #1 ) [net-misc:chrony-1.29.1.98ee02f66d56c49e1fdc4d713b2cea5ff23d775e~0.tbz2] @ http://na.mirror.garr.it
╠   ## Sammeldownload: 2 Artikel
╠    # [1] na.mirror.garr.it => dev-libs:libedit-20130712.3.1.3556f679066ec7d787573f08ac74ef24922243b2~0.tbz2
╠    # [2] na.mirror.garr.it => net-misc:chrony-1.29.1.98ee02f66d56c49e1fdc4d713b2cea5ff23d775e~0.tbz2
╠    ## Überprüfe Paketprüfsumme...
╠    ## Überprüfe Paketprüfsumme...
╠       : [net-misc:chrony-1.29.1.98ee02f66d56c49e1fdc4d713b2cea5ff23d775e~0.tbz2] GPG validated
╠       : [dev-libs:libedit-20130712.3.1.3556f679066ec7d787573f08ac74ef24922243b2~0.tbz2] GPG validated
╠       : [net-misc:chrony-1.29.1.98ee02f66d56c49e1fdc4d713b2cea5ff23d775e~0.tbz2] SHA1 validated
╠       : SHA256 deaktiviert
╠       : [dev-libs:libedit-20130712.3.1.3556f679066ec7d787573f08ac74ef24922243b2~0.tbz2] SHA1 validated
╠       : SHA512 deaktiviert
╠       : SHA256 deaktiviert
╠       : SHA512 deaktiviert
╠    ## ( mirror #1 ) [dev-libs:libedit-20130712.3.1.3556f679066ec7d787573f08ac74ef24922243b2~0.tbz2] erfolgreich @ http://na.mirror.garr.it
╠    ## ( mirror #1 ) [net-misc:chrony-1.29.1.98ee02f66d56c49e1fdc4d713b2cea5ff23d775e~0.tbz2] erfolgreich @ http://na.mirror.garr.it
╠    ##  angehäufte Transferrate: 658.3kB/Sekunde
╠  +++ >>>  (1/2) dev-libs/libedit-20130712.3.1
╠    ## Entpacke: dev-libs:libedit-20130712.3.1.3556f679066ec7d787573f08ac74ef24922243b2~0.tbz2
╠    ## Installiere Paket: dev-libs/libedit-20130712.3.1
╠    ## [BSD replacement for libreadline.]
╠    ## Updating installed packages repository: dev-libs/libedit-20130712.3.1
>>> Regenerating /etc/ld.so.cache...
╠    ## Aufräumen: dev-libs/libedit-20130712.3.1
╠  +++ >>>  (2/2) net-misc/chrony-1.29.1
╠    ## Entpacke: net-misc:chrony-1.29.1.98ee02f66d56c49e1fdc4d713b2cea5ff23d775e~0.tbz2
╠    ## Installiere Paket: net-misc/chrony-1.29.1
╠    ## [NTP client and server programs]
╠    ## Updating installed packages repository: net-misc/chrony-1.29.1
╠    ## Aufräumen: net-misc/chrony-1.29.1
╠  @@ Installation vollständig.
╠  @@ No configuration files to update.

Beim Boot soll er in Zukunft gestartet werden!

$ systemctl enable chronyd.service
ln -s '/usr/lib64/systemd/system/chronyd.service' '/etc/systemd/system/multi-user.target.wants/chronyd.service'

Och ja, am besten sollte der Dienst direkt gestartet werde…

$ systemctl start chronyd.service

Bevor ich es vergesse, den hässlichen ntpd.service will ich beim Start nicht mehr sehen!

$ systemctl disable ntpd.service

DMARC Milter und Postfix auf Debian 7 Wheezy

Über DMARC selbst habe ich ja schon etwas geschrieben. Selbst eine DMARC Policy zu veröffentlichen und sich um die eingehenden Reports zu kümmern ebenfalls. Heute soll es nun darum gehen, mit seinem Postfix auf einem Debian 7 die DMARC Policys der Absender zu Prüfen und zu berücksichtigen.

Es gibt bereits einen fertigen Milter für DMARC. Dieser findet sich leider nicht im aktuellen stable Zweig eines Debian 7.4 Wheezy. Nun könnte man auf einen Backport zurückgreifen…. So etwas kann einem aber schon mal das System etwas mehr „umdrehen“ als man wirklich möchte. Nur für den openDMARC Milter ist das nicht nötig.

Die Installation ist sehr einfach und im folgenden beschrieben. Dabei gehe ich von einem funktionsfähigen Postfix, SPF und DKIM Filter aus. Für dieses Setup setzte ich auf postgrey sowie  postfix-policyd-spf-perl. Denn der openDMARC Milter „verlässt“ sich darauf, das diese Programme bereits die richtigen Informationen in die Mailheader geschrieben haben.

ACHTUNG
Wer zum Beispiel AMaViS als smtpd_proxy_filter einsetzte, wird feststellen dass es nie zum openDMARC Milter kommt. Das liegt daran, dass die Milter an einer Stelle kommen, an welcher die E-Mail nie mehr vorbei kommt, wenn sie einmal durch einen smtpd_proxy_filter gelaufen sind. Hier kann man nun also abwarten bis DMARC nicht mehr als Milter arbeitet oder AMaViS als content_filter einsetzten tongue-out.

Wie immer ist es eine Beschreibung die den Einstieg erleichtern soll und keine „so ist es perfekt“ Beschreibung. Nun also los…

Zuerst den openDMARC Milter direkt von der Projektseite herunterladen.

http://sourceforge.net/projects/opendmarc/

Für das spätere Kompilieren braucht man in jedem Fall die Entwicklerpakete für libmilter, daher installiere ich sie zuerst.

$ apt-get install libmilter-dev

Dann packen wir mal den Download aus..

$ tar xvzf opendmarc-1.2.0.tar.gz

Ins Verzeichnis wechseln und wie gewohnt kompilieren. Ich setzte dabei einfach mal das Prefix auf /usr, damit am Ende nicht alles unter /usr/local/ liegt. Bitte selbstdenkend nachmachen 🙂

$ ./configure --prefix=/usr
$ make && make install

Der Milter sollte aus Sicherheitsgründen nicht als root laufen, daher lege ich dafür einen Benutzer opendmarc an und lege seine Heimat direkt ins spätere „Arbeitsverzeichnis“. Als zweites werden die Rechte gesetzt, damit der Benutzer in seinem Zuhause arbeiten kann.

$ adduser --quiet --system --group --home /var/run/opendmarc opendmarc
$ chown opendmarc:opendmarc /var/run/opendmarc

Man sieht schon, ich versuche mich nahe am Debian Default zu orientieren. Das soll so weiter gehen um spätere Upgrades zu erleichtern und es muss nichts „Neue“ erfunden werden.. Wie im testing Zweig und beim openDKIM Milter wird der zu verwendende Socket/Port… in der Konfigurationsdatei /etc/default/opendmarc gesetzt. Das spätere INIT-Script wird diese Konfigurationsdatei einfach beim Start des Milters, in die eigentliche Konfigurationsdatei, inkludieren. Also:

$ SOCKET="inet:8893@localhost"' > /etc/default/opendmarc

Das INIT-Script greife ich mir aus dem Testing Zweig des kommenden Debian 8…

$ vi /etc/init.d/opendmarc   
#! /bin/sh
#
### BEGIN INIT INFO
# Provides:             opendmarc
# Required-Start:       $syslog $time $local_fs $remote_fs $named $network
# Required-Stop:        $syslog $time $local_fs $remote_fs
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    Start the OpenDMARC service
# Description:          Enable DMAR verification and reporting provided by OpenDMARC
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/opendmarc
NAME=opendmarc
DESC="OpenDMARC"
RUNDIR=/var/run/$NAME
USER=opendmarc
GROUP=opendmarc
SOCKET=local:$RUNDIR/$NAME.sock
PIDFILE=$RUNDIR/$NAME.pid

# How long to wait for the process to die on stop/restart
stoptimeout=5

test -x $DAEMON || exit 0

# Include LSB provided init functions
. /lib/lsb/init-functions

# Include opendkim defaults if available
if [ -f /etc/default/opendmarc ] ; then
        . /etc/default/opendmarc
fi

if [ -f /etc/opendmarc.conf ]; then
        CONFIG_SOCKET=`awk '$1 == "Socket" { print $2 }' /etc/opendmarc.conf`
fi

# This can be set via Socket option in config file, so it's not required
if [ -n "$SOCKET" -a -z "$CONFIG_SOCKET" ]; then
        DAEMON_OPTS="-p $SOCKET $DAEMON_OPTS"
fi

DAEMON_OPTS="-c /etc/opendmarc.conf -u $USER -P $PIDFILE $DAEMON_OPTS"

start() {
        # Create the run directory if it doesn't exist
        if [ ! -d "$RUNDIR" ]; then
                install -o "$USER" -g "$GROUP" -m 755 -d "$RUNDIR" || return 2
                [ -x /sbin/restorecon ] && /sbin/restorecon "$RUNDIR"
        fi
        # Clean up stale sockets
        if [ -f "$PIDFILE" ]; then
                pid=`cat $PIDFILE`
                if ! ps -C "$DAEMON" -s "$pid" >/dev/null; then
                        rm "$PIDFILE"
                        TMPSOCKET=""
                        if [ -n "$SOCKET" ]; then
                                TMPSOCKET="$SOCKET"
                        elif [ -n "$CONFIG_SOCKET" ]; then
                                TMPSOCKET="$CONFIG_SOCKET"
                        fi
                        if [ -n "$TMPSOCKET" ]; then
                                # UNIX sockets may be specified with or without the
                                # local: prefix; handle both
                                t=`echo $SOCKET | cut -d: -f1`
                                s=`echo $SOCKET | cut -d: -f2`
                                if [ -e "$s" -a -S "$s" ]; then
                                        if [ "$t" = "$s" -o "$t" = "local" ]; then
                                                rm "$s"
                                        fi
                                fi
                        fi
                fi
        fi
        start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec "$DAEMON" --test -- $DAEMON_OPTS || return 1
        start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec "$DAEMON" -- $DAEMON_OPTS || return 2
}

stop() {
        start-stop-daemon --stop --retry "$stoptimeout" --exec "$DAEMON"
        [ "$?" = 2 ] && return 2
}

reload() {
        start-stop-daemon --stop --signal USR1 --exec "$DAEMON"
}

status() {
    local pidfile daemon name status

    pidfile=
    OPTIND=1
    while getopts p: opt ; do
        case "$opt" in
            p)  pidfile="$OPTARG";;
        esac
    done
    shift $(($OPTIND - 1))

    if [ -n "$pidfile" ]; then
        pidfile="-p $pidfile"
    fi
    daemon="$1"
    name="$2"

    status="0"
    pidofproc $pidfile $daemon >/dev/null || status="$?"
    if [ "$status" = 0 ]; then
        log_success_msg "$name is running"
        return 0
    else
        log_failure_msg "$name is not running"
        return $status
    fi
}

case "$1" in
  start)
        echo -n "Starting $DESC: "
        start
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        stop
        echo "$NAME."
        ;;
  restart)
        echo -n "Restarting $DESC: "
        stop
        start
        echo "$NAME."
        ;;
  reload|force-reload)
        echo -n "Restarting $DESC: "
        reload
        echo "$NAME."
        ;;
  status)
        status $DAEMON $NAME
        ;;
  *)
        N=/etc/init.d/$NAME
        echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
        exit 1
        ;;
esac

exit 0

Dieses nur noch an die richtige Stelle schieben, als ausführbar marken und bei jedem Booten mit starten lassen.

$ cp /pfad/opendmarc /etc/init.d/opendmarc
$ chmod +x /etc/init.d/opendmarc
$ update-rc.d opendmarc defaults

Das war schon fast das Schwerste… Jetzt kopiere ich die mitgelieferte Beispielkonfigurationsdatei für openDMARC nach /etc/.

$ cp /usr/share/doc/opendmarc/opendmarc.conf.sample /etc/

Diese passe ich nun wie folgt an:

$ vi /etc/opendmarc.conf
# This is a basic configuration that can easily be adapted to suit a standard
# installation. For more advanced options, see opendkim.conf(5) and/or
# /usr/share/doc/opendmarc/examples/opendmarc.conf.sample.

##  AuthservID (string)
##      defaults to MTA name
#
AuthservID smtp.kernel-error.de

##  BaseDirectory (string)
##      default (none)
##
##  If set, instructs the filter to change to the specified directory using
##  chdir(2) before doing anything else.  This means any files referenced
##  elsewhere in the configuration file can be specified relative to this
##  directory.  It's also useful for arranging that any crash dumps will be
##  saved to a specific location.
#
# BaseDirectory /var/run/opendmarc

##  ChangeRootDirectory (string)
##      default (none)
##
##  Requests that the operating system change the effective root directory of
##  the process to the one specified here prior to beginning execution.
##  chroot(2) requires superuser access.  A warning will be generated if
##  UserID is not also set.
# 
# ChangeRootDirectory /var/chroot/opendmarc

##  ForensicReports { true | false }
##      default "false"
##
# ForensicReports false

##  IgnoreHosts path
##      default (internal)
##
# IgnoreHosts /usr/local/etc/opendmarc/ignore.hosts

##  IgnoreMailFrom domain[,...]
##      default (none)
##
# IgnoreMailFrom example.com

##  PidFile path
##      default (none)
##
##  Specifies the path to a file that should be created at process start
##  containing the process ID.
##
#
PidFile /var/run/opendmarc.pid

##  RejectFailures { true | false }
##      default "false"
##
RejectFailures false

##  Socket socketspec
##      default (none)
##
##  Specifies the socket that should be established by the filter to receive
##  connections from sendmail(8) in order to provide service.  socketspec is
##  in one of two forms: local:path, which creates a UNIX domain socket at
##  the specified path, or inet:port[@host] or inet6:port[@host] which creates
##  a TCP socket on the specified port for the appropriate protocol family.
##  If the host is not given as either a hostname or an IP address, the
##  socket will be listening on all interfaces.  This option is mandatory
##  either in the configuration file or on the command line.  If an IP
##  address is used, it must be enclosed in square brackets.
#
#Socket inet:8893@localhost

##  SoftwareHeader { true | false }
##      default "false"
##
##  Causes the filter to add a "DMARC-Filter" header field indicating the
##  presence of this filter in the path of the message from injection to
##  delivery.  The product's name, version, and the job ID are included in
##  the header field's contents.
#
SoftwareHeader true

##  Syslog { true | false }
##      default "false"
##
##  Log via calls to syslog(3) any interesting activity.
#
Syslog true

##  SyslogFacility facility-name
##      default "mail"
##
##  Log via calls to syslog(3) using the named facility.  The facility names
##  are the same as the ones allowed in syslog.conf(5).
#
# SyslogFacility mail

##  TemporaryDirectory path
##      default /var/tmp
##
##  Specifies the directory in which temporary files should be written.
#
# TemporaryDirectory /var/tmp

##  TrustedAuthservIDs string
##      default HOSTNAME
##
##  Specifies one or more "authserv-id" values to trust as relaying true
##  upstream DKIM and SPF results.  The default is to use the name of
##  the MTA processing the message.  To specify a list, separate each entry
##  with a comma.  The key word "HOSTNAME" will be replaced by the name of
##  the host running the filter as reported by the gethostname(3) function.
#
# TrustedAuthservIDs d


##  UMask mask
##      default (none)
##
##  Requests a specific permissions mask to be used for file creation.  This
##  only really applies to creation of the socket when Socket specifies a
##  UNIX domain socket, and to the HistoryFile and PidFile (if any); temporary
##  files are normally created by the mkstemp(3) function that enforces a
##  specific file mode on creation regardless of the process umask.  See
##  umask(2) for more information.
#
UMask 0002

##  UserID user[:group]
##      default (none)
##
##  Attempts to become the specified userid before starting operations.
##  The process will be assigned all of the groups and primary group ID of
##  the named userid unless an alternate group is specified.
#
UserID opendmarc

CopyFailuresTo postmaster@kernel-error.de
ForensicReports true
ForensicReportsBcc postmaster@kernel-error.de
ForensicReportsSentBy postmaster@kernel-error.de
HistoryFile /var/run/opendmarc/opendmarc.dat
MilterDebug 0

Nach der Konfiguration sollte sich der Milter bereits starten lassen. Das mache ich nun mal und kontrolliere ob er läuft!

$ /etc/init.d/opendmarc start
$ netstat -ltnp | grep :8893
tcp        0      0 127.0.0.1:8893          0.0.0.0:*               LISTEN      15974/opendmarc

Es muss nur noch Postfix darüber informiert werden, dass der Milter genutzt werden soll. Ich erweitere also einfach die folgenden Optionen. Dabei sollte der DMARC-Milter natürlich als letztes stehen:

$ vi /etc/postfix/main.cf
smtpd_milters = inet:127.0.0.1:54321, inet:localhost:8893
non_smtpd_milters = inet:127.0.0.1:54321, inet:localhost:8893

Ich sag es ja, die grobe Konfiguration ist erstmal extrem einfach. Nun geht es nach dem Testen an einen Feinschliff und eine saubere Konfiguration. Tja…. Noch Fragen? Dann fragen 🙂

Die Mail Header In-Reply-To und Message-ID

LEUTE… am 13 August 1982 wurde von einem Herrn David H. Crocker das RFC 733 überarbeitet. Somit wurde das RFC 733 ersetzt durch das RFC 822.

In diesem nun knapp 32 Jahre alten Dokument wurden die Mailheader In-Reply-To und Message-ID definiert. Warum ich das schreibe? Ganz einfach… Weil es noch nicht bei allen angekommen zu sein scheint, was jetzt nicht böse zu verstehen ist!

Ich möchte es daher einmal kurz erklären. Sollte ich jemanden auf diesen Eintrag verweisen, also bitte lesen smile

Wenn ich eine E-Mail an Klaus schreibe, dann erhält meine E-Mail automatisch eine einmalige Message-ID. Diese landet dann, für den Anwender unsichtbar im Mailheader. Antwortet Klaus nun auf diese E-Mail, bekommt seine Antwort natürlich ebenfalls eine MessageID, zusätzlich wird noch das Feld In-Reply-To gefolgt von der MessageID der Nachricht auf welche er gerade geantwortet hat in die E-Mail Header geschrieben.

Was bringt dieses? Nun, viele E-Mail Clients (japp Outlook seit ein paar Jahren auch) können E-Mail Nachrichten in der Form eines Gesprächsverlaufes anzeigen. Selbst wenn sich Betreff oder E-Mail-Inhalt komplett ändern. Dieses macht einem nicht nur das nachträgliche Verfolgen der E-Mail Kommunikation einfacher, sondern erleichtert einem extrem die Übersicht zu behalten. Da die E-Mail ja an eine völlig falsche Stelle einsortiert wird.

Alles funktioniert perfekt bis zu dem Moment in welchem jemand in einem völlig anderem Zusammenhang auf eine E-Mail antwortet. Also irgendeine alte E-Mail heraussuchen, auf antworten klicken, Betreff und Hinhalt löschen und eine „neue“ E-Mail schreiben. Das verbrennt nicht nur die Übersicht, sondern sorgt dafür das E-Mails sehr spät oder überhaupt nicht gelesen/beantwortet werden.

Habe ich dich auf diesen Text verwiesen, dann möchte ich dich (aus dem genannten Grund) mit Nachdruck darum bitte, mit bei neuen Themen eine neue E-Mail zu schreiben. Alle anderen nehmen es bitte als Information auf!

Für Detail bitte im RFC 822 besonders den Punkt 4.6.2.  IN-REPLY-TO lesen: http://www.ietf.org/rfc/rfc0822.txt und natürlich RTFM beim eigenen MUA betreiben. Bei Fragen, einfach fragen wink

Kennwortgenerator

Bei mir ist mal wieder die Frage angekommen, wie man denn seine Kennwörter wählen sollte. Ich habe wieder auf das Programm pwgen hingewiesen. Das ist ein kleiner Password-Generator für die Bash/Konsole.

Warum ein Kennwort Generator? Nun ja, Software dieser Art hat aus meiner Sicht ein paar Vorteile…

So hindert man seinen eigenen Schweinehund daran immer das gleiche Kennwort zu benutzen. Das ist ja bekanntlich mehr als gefährlich, denn wenn bei irgendeinem Anbieter mal wieder ein Sicherheitsloch ausgenutzt wurde, ja dann ist das Kennwort schon in den „falschen Händen“, meist zusammen mit der E-Mail Adresse. Fast überall kann man sich mit der Kombination E-Mail Adresse/Kennwort anmelden. Ist es immer gleich, kann sich der Mensch mit den „falschen Händen“ direkt überall anmelden. Daher sollte es ein eigenes Kennwort für jeden Dienst geben. Dabei ist ein: SuperTollesKennwort.Dienstname besser als nichts… Nur so schlau dieses zu probieren ist im Zweifel der Mensch mit den „falschen Händen“ ebenfalls. Will man es auf die Spitze treiben legt man sogar für jeden Dienst eine eigene E-Mail Adresse an. Dann hat der Angreifer nicht nur kein einheitliches Kennwort, sondern auch keine einheitliche E-Mail Adresse. Zurück zu pwgen…

Als weiteren Vorteil sehe ich dass die erstellten Kennwörter „zufällig“ sind (es macht natürlich einen guten Kennwort Generator aus, dass er immer zufällige Kennwörter rechnet laughing). Einem selbst gehen schnell die Zufälle aus. Selbst wenn man immer nur auf der Tastatur hämmert, werden sie sich ähneln.

Zudem lässt sich pwgen gut in Scripten verwursten um direkt beim anlegen von Accounts schöne initiale Kennwörter zu generieren. Es wäre ja schön blöde immer die gleichen Kennwörter für neue Kunden zu vergeben. tongue-out

Nun wollen wir mal ein paar Kennwörter würfeln. Der folgende Aufruf sollte viele Kennwörter mit Groß-/Kleinschreibung, 8 Zeichen und Ziffern erstellen:

$ pwgen 
Puo7aone AG2aicho me0Ohn7t aiSeth7K aeb2Nah0 oGh1ohra iengahD0 ra4Aeboh
oNga5ooj doh0saeM eeMaiCo1 aeDoo8we IeXae1ah OoVael8h Soh7aera Ohnge6yi
aiH0quae ieSo7ohY noo4xe8E sheh5eeF uiChoh7e Aing2fae ieJii4to aeGu7tof
quooB9Be Ou1Onie4 Eeb9giep Chei8oob Yieh2yuz Naugh0be phai4aXe ohc7Ahw9
aiM0aiwo EiGhi9fu eiC2Xohk raiB0eu9 MuwuK5le Aicheew8 UDeo2eig xaig3Oph
kii0ER9E uKaig7uv ooha3Die Ahhoo5ba aTh7dook aeGh9mai Iewae8ig Shahye6s
Jieshie2 MooSa7th Tahj0dei tohb7Oto Ocahm7bi Ake5nah6 Boh7aung ThooV4ir
noo6Equ5 AhGhuz8i dotie8uN tae7Chai Mual8oaD ooP9IeQu aeg5Iido HahKie6u
Me8ahsei Ahg5ohpe Soh9ucol Eix1OoFa Ahleex9m ahch4Ahk Taev8Shi neu9Vei4
aiLoo5qu eiW2eiNg Zae8ooyu Eeng7koo ieZees1a tho1Chei bohh3ENe ooVeezu1
weeb4Ain daeMi8iR yohNg5iW Oogu1ac4 UFae3Fie kaiT5aak Wa6tie1u pheiw3Ye
Iyae4aef Shoh1aij pheong0K Toer8quu kohGu9Ta ceiChei0 iePh6she Taigh6mu
ooH0xair aGemai4i Zohdiah5 aesai2Oo uchohk7G ohxah9Oo AhJair1v thee6Io0
cah1kieG ieCh6cah Fi0aegeo ShiePee9 ooPafei2 oB4ohcho yoiPhu8I AiJ7beaM
Reexai7u AiCahj0s aePhai7E xaer6Uos ath4gi0U ieNgoo0i Ohfeech6 weet4Voo
iu8Dafis doo6Agee te7Hah7U oox3Eeri Eezas2th Eeyeer5g afiTah9K oot9aiCh
eiFaiNg9 Ooquahn9 jaiJah4z eo7oChai suph2Cau Tiebah1U uH0ohth0 uiS6iew0
Ej9iMee3 Phie4Ohh Iet7Aes1 pheiGh9r Jae3joh0 EiPh1iey Xo4Seejo ieque6Ci
booV4iex ieCae1Ee BaiMie8a waed6Fi1 Og5Ahth3 eiX4voph oopooQu1 phu0Xa3u
keishi0S Otievi4o ceeGh8Ee uthooZ6o Faed2sob udahG0Da Soh5aid1 reuze3Ne

So viele Kennwörter benötigt man normalerweise nicht. Ein einziges Kennwort mit Groß-/Kleinschreibung, 8 Zeichen und ohne Ziffern (dann kann es sich ein Anwender meist besser merken) generiert sich mit folgendem Aufruf:

$ pwgen -1 -0
chaisaeM

Soll es einmal sicher werden erstellt der folgende Aufruf ein Kennwort mit Groß-/Kleinschreibung, 14 Zeichen, Ziffern, Symbolen und der deaktivierten pronounceable Funktion von pwgen. Die pronounceable (aussprechbar) Funktion von pwgen sorgt sonst dafür das die Kennwörter besser zu merken sind. Dieses macht es natürlich etwas weniger zufällig.

$ pwgen -1 -s -y 14
SKf|.k.]m}o'Q3

Man sieht schon, solche Ausgaben lassen sich sehr gut in irgendwelchen Scripten nutzen! Wie immer bringen die man-pages noch mehr Beispiele und Informationen mit. Also bitte RTFM….

 $ man pwgen

 Ńoch Fragen? Dann fragen sealed

Einmal mit Profis: Einblick in die Welt der Experten

Ich habe heute, wenn auch etwas angeschlagen, wieder vor einem System gestanden welches von einem „selbsternannten“ Profi eingerichtet wurde. Dabei gab es Fehler die ich jetzt nicht näher ausführen kann, denn noch ist es mal wieder Zeit für einen ordentlichen double facepalm!

Nur falls sich jemand wundert warum ich in den nächsten Tagen dauerkopfschüttelnd herumlaufe. Jetzt glaubt bitte nicht dass ich fehlerfrei bin. Ganz sicher nicht!

« Ältere Beiträge Neuere Beiträge »

© 2025 -=Kernel-Error=-

Theme von Anders NorénHoch ↑