Sturbi's Home

  • Gallery
  • Modellflug
  • Datenschutz
  • Impressum

Blog

  • Allgemein (14)
    • Sprüche (6)
  • Angeln (2)
  • Computer (25)
    • Linux (16)
      • Nagios (5)
      • Nginx (4)
      • Postfix (3)
      • Subversion (1)
    • VMware (3)
    • Windows (9)
      • Powershell (8)
  • Fotografie (26)
  • Reise (8)
    • Hawaii (4)
    • Irland (1)
    • USA (5)
Wenn du etwas so machst,
wie du es seit zehn Jahren gemacht hast,
dann sind die Chancen groß,
daß du es falsch machst.

Charles F. Kettering amerikanischer Ingenieur * 29.08.1876, † 25.11.1958

Limit Postfix E-Mails pro Stunde

26. Juli 2012 by Sturbi Kategorie: Linux, Nagios, Postfix

Nachdem aus dem OTRS in der Nacht 25.000 E-Mails versand wurden, hatte uns unser Provider vorübergehend auf seinen Relay Servern blacklistet.
Um solche nächtliche Überraschungen künftig zu vermeiden, habe ich einen Policy Server für Postfix geschrieben. Dieser wird auf dem ausgehenden Mail Relay eingebunden und gibt nach 750 E-Mails pro Stunde dem Exchange DEFER zurück gibt, worauf dieser die Mails in seiner Queue behält.

Der Policy Server liest aus der Datei /tmp/postfix-counter den aktuellen Count und den Timestamp des letzten Counterreset. Ist der Timestamp älter als eine Stunde, wird der Counter auf 1 gesetzt, sonst um 1 erhöht und wieder in die Datei zurückgeschrieben.

Zur Überwachung habe ich einen einfachen Nagios Check geschrieben, welcher den Counter ausliest, die Anzahl Mails prüft und als Performancedaten ausgibt. Die enstandenen PNP Graphen sehen dann wie Sägezähne aus.

Im Postfix wird das Ganze in der main.cf eingebunden.

smtpd_recipient_restrictions = permit_mynetworks check_policy_service inet:127.0.0.1:8895 reject_unauth_destination

 

#! /usr/bin/perl -W
# based on sample from Postfix Page

use strict;
use Errno;
use IO::Select;
use IO::File;

my $fds;
my $flog;
my $conffile;
my %times = ();
my $maxcount = 750; # max mail per hour

sub init_sockets;

# initialize anything (database etc)
sub init() {
  $fds = IO::Select->new() or die "unable to create IO::Select object\n";
  init_sockets('inet:127.0.0.1:8895');
  use IO::File;
  $flog = IO::File->new("/tmp/smtpd-policy.log", 'a');
}

init();

sub request($;$) {
  my ($attr,$sock) = @_;
  my $act = 'DUNNO';
  my $now = time;

  open(FILE, "/tmp/postfix-counter");

  while(<FILE>){
    chomp($_);
    my ($key, $val) = split(/:/, $_);
      $times{$key} = $val;
    }

  close(FILE);  

  if ($times{'1htime'} + 3600 > $now){
    if ($times{'1hcount'} < $maxcount){
      my $tmp = $times{'1hcount'};
      $tmp = $tmp + 1;
      $times{'1hcount'} = $tmp;
      $act = 'OK';
      $times{'now'} = $now;
    }else{
      $act = 'DEFER to many mail';
      $times{'now'} = $now;
    }
  }else{
    $times{'1htime'} = $now;
    $times{'1hcount'} = 1;
    $act = 'OK';
    $times{'now'} = $now;
  }

  open(FILE, ">/tmp/postfix-counter");
  for my $key ( keys %times ) {
    my $value = $times{$key};
    print FILE "$key:$value\n";
  }

  close(FILE);

  if (defined $flog) {
    $flog->print("request:");
    $flog->print(" $_=$attr->{$_}") foreach keys %$attr;
    $flog->print(" action=$act\n");
    $flog->flush;
  }
  $act;
}

sub request_cb($) {
  my $s = shift;
  my $r = ${*$s}{attrs} || ( ${*$s}{attrs} = {} );
  for(;;) {
    $_ = $s->getline;
    unless (defined $_) {
      $fds->remove($s) unless $!{EAGAIN};
      return;
    }
    if (/^([a-zA-Z_]+)=([^\r\n]*)\r?\n$/) { $r->{$1} = $2; }
    elsif (/^\r?\n$/) { last; }
    else { $r->{error} = 1; }
  }
  ${*$s}{attrs} = undef;
  my $act;
  if ($r->{error}) { $act = 'ERROR unknown request line'; }
  elsif (!exists($r->{request}) ||
         $r->{request} ne 'smtpd_access_policy') {
    $act = 'ERROR required request attribute is not present';
  }
  else {
    $act = request($r);
    unless (defined $act) {
      $fds->remove($s);
      return;
    }
  }
  $s->print("action=$act\n\n") or $fds->remove($s);
}

sub accept_cb($) {
  my $ls = shift;
  my $s = $ls->accept;
  if ($s) {
    $s->blocking(0);
    ${*$s}{cb} = \&request_cb;
    $fds->add($s);
  }
}

sub init_sockets {
  foreach my $sock ( @_ ) {
    my $s;
    if ($sock =~ /^inet:([^:]+:.+)$/i) {
      use IO::Socket::INET;
      $s = IO::Socket::INET->new(
        LocalAddr => $1,
        Proto => 'tcp',
        Type => SOCK_STREAM,
        Listen => 5,
        ReuseAddr => 1,
      );
    }
    elsif ($sock =~ /^unix:(.+)$/) {
      use IO::Socket::UNIX;
      unlink $1;
      $s = IO::Socket::UNIX->new(
        Type => SOCK_STREAM,
        Local => $1,
        Listen => 5,
      );
    }
    else {
      die "invalid listening point specification: $sock\n";
    }
    die "unable to create listening socket for $sock: $!\n" unless $s;
    $s->blocking(0);
    ${*$s}{cb} = \&accept_cb;
    $fds->add($s);
  }
}

for(;;) {
  foreach my $s ( $fds->can_read() ) {
    &{${*$s}{cb}}($s);
  }
}

 

Exchange Message Header cleanup in Postfix

19. Juli 2012 by Sturbi Kategorie: Linux, Postfix, Windows

Wer sich mal den Header seiner ausgehenden E-Mail angesehen hat, wird vielleicht mit Schrecken festgestellt haben, das Exchange Server dort etwas zu gesprächig sind.
Da man für eine DKIM Signatur am besten noch ein ausgehendes Relay zwischen Exchange und Internet schaltet, kann man mit Postfix sehr schnell für Abhilfe schaffen.
Die DKIM Signatur erfolgt nach der Verarbeitung der „header_checks“, wir können hier also noch beliebig ändern.

Zuerst ersetze ich die „Received“ Zeile der Übertragung vom Exchange Server an das Postfix Relay mit einem Eintrag von localhost. Hier kann man auch einen beliebigen anderen MTA z.B. Exim eintragen. Er sollte nur nicht zu fantasievoll sein, Antispam Systeme sind nachtragend. Das gilt auch für die unbedingt richtige Syntax! (MessageID und Uhrzeit)

Dann werden alle X-Header mit Verweisen auf interne IP Adressen gelöscht.

Zuletzt lösche ich noch X-Header mit Verweisen auf den User-Agent, Antivirus und Antispam und wer sich da sonst noch einträgt.
Benutzt man z.B. OTRS, sollte man hier unbedingt den X-Header mit der Software Versionsnummer löschen, aber den X-Header mit der Ticketnummer lassen.

zum testen legt man sich ein Mailkonto bei hotmail an und schaut sich dort den Quelltext der E-Mail an.

 

header_checks = pcre:/etc/postfix/header_checks

 

/^Received: from exchange.intern.sturbi.de (.*) with ESMTP id ([A-F[:digit:]]+)(.*)/    REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1]) by [127.0.0.1] (Postfix) with ESMTP id $2 $3
/^Received: (.*)192\.168/       IGNORE
/^Received: (.*)10\.0/  IGNORE
/^Received: (.*)172\./  IGNORE
/^X-Virus/ IGNORE
/^X-Mailer/ IGNORE
/^User-Agent/ IGNORE
/^X-MS-Has-Attach/ IGNORE
/^X-MS-TNEF-Correlator/ IGNORE
/^X-OLX-Disclaimer/ IGNORE
/^X-Powered-BY: OTRS/ IGNORE
/^X-Virus/              IGNORE
/^X-Mailer/             IGNORE
/^User-Agent/           IGNORE
/^X-MS/      IGNORE
/^x-originating-ip/      IGNORE

Pimp my Powershell Environment

19. Juli 2012 by Sturbi Kategorie: Powershell, Windows

Hier einmal meine Microsoft.PowerShell_profile.ps1

Wichtig ist mir vor allem, das die Powershell schnell startet. Also möglicht wenige Module laden.
Zum schnellen Nachladen der einzelnen Module habe ich die Aufrufe in Funktionen verpackt, welche sich über „load-XXX“ aufrufen lassen.(siehe Script loads.ps1)
Das Quest Active Directory  wird standardmäßig geladen. Bits benötigt kaum Zeit zum laden und ich benutze es gern um Downloads durchzuführen.

Meine lokalen Scripte lege ich im Ordner $lib ab.

Als Editor verwende ich überwiegend Notepad++, welcher über den alias e aufgerufen wird.

Um über die Command Line Dateien via scp zu kopieren benutze ich das Client Pack von VanDyke.
Meine SSH Verbindungen rufe ich über Funktionen im Script ssh.ps1 auf. An Stelle von SecureCRT kann man auch mit Putty arbeiten.

Mit den Funktionen „big“ und „small“ kann ich schnell die Konsole in ihrer Größe verändern, ohne die Maus zu bemühen.

Add-PSSnapin Quest.ActiveRoles.ADManagement
Import-Module BitsTransfer

$lib = "C:\data\PowerShell\lib\"

set-alias -Name vi -Value "C:\Program Files (x86)\Vim\vim73\vim.exe" -Force
set-alias -Name Edit-File -Value "C:\Program Files (x86)\Notepad++\notepad++.exe" -Force
set-alias -Name e -Value "C:\Program Files (x86)\Notepad++\notepad++.exe" -Force

Set-Alias -Name scp -Value "C:\Program Files\VanDyke Software\ClientPack\vcp" -Force
Set-Alias -Name ssh -Value "C:\Program Files\VanDyke Software\ClientPack\vsh" -Force

. "C:\data\PowerShell\lib\ssh.ps1"
. "C:\data\PowerShell\lib\loads.ps1"

$env:PSModulePath = "$env:PSModulePath;C:\data\powershell\Modules\"

function global:prompt {
    # our theme
    $cdelim = [ConsoleColor]::DarkCyan
    $chost = [ConsoleColor]::Green
    $cloc = [ConsoleColor]::Cyan

    write-host "$([char]0x0A7) " -n -f $cloc
    write-host ([net.dns]::GetHostName()) -n -f $chost
    write-host ' {' -n -f $cdelim
    # write-host (shorten-path (pwd).Path) -n -f $cloc
	write-host (pwd).Path -n -f $cloc
    write-host '}'  -f $cdelim
	Write-Host ":~#" -NoNewline -ForegroundColor $cdelim
    return ' '
}

function big(){

$pshost = get-host
$pswindow = $pshost.ui.rawui

$newsize = $pswindow.buffersize
$newsize.height = 3000
$newsize.width = 180
$pswindow.buffersize = $newsize

$newsize = $pswindow.windowsize
$newsize.height = 80
$newsize.width = 180
$pswindow.windowsize = $newsize
}

function small(){

$pshost = get-host
$pswindow = $pshost.ui.rawui

$newsize = $pswindow.windowsize
$newsize.height = 24
$newsize.width = 80
$pswindow.windowsize = $newsize

$newsize = $pswindow.buffersize
$newsize.height = 24
$newsize.width = 80
$pswindow.buffersize = $newsize
}

function load-PowerTabe()
{
	Import-Module "PowerTab" -ArgumentList "C:\data\powershell\Modules\PowerTab\PowerTabConfig.xml"
	$PowerTabConfig.DefaultHandler = "Intellisense"
	$PowerTabConfig.DoubleBorder = $False
}

function load-PSCX()
{
	Import-Module Pscx
}

function load-Exchange()
{
	. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto
}

function load-Sharepoint()
{
	$ver = $host | select version
	if ($ver.Version.Major -gt 1)  {$Host.Runspace.ThreadOptions = "ReuseThread"}
	Add-PsSnapin Microsoft.SharePoint.PowerShell
	Set-location $home
}

function load-SQL()
{
	$ErrorActionPreference = "Stop"

	$sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"

	if (Get-ChildItem $sqlpsreg -ErrorAction "SilentlyContinue")
	{
		throw "SQL Server Provider for Windows PowerShell is not installed."
	}
	else
	{
		$item = Get-ItemProperty $sqlpsreg
		$sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)
	}

	#
	# Set mandatory variables for the SQL Server provider
	#
	Set-Variable -scope Global -name SqlServerMaximumChildItems -Value 0
	Set-Variable -scope Global -name SqlServerConnectionTimeout -Value 30
	Set-Variable -scope Global -name SqlServerIncludeSystemObjects -Value $false
	Set-Variable -scope Global -name SqlServerMaximumTabCompletion -Value 1000

	#
	# Load the snapins, type data, format data
	#
	Push-Location
	cd $sqlpsPath
	Add-PSSnapin SqlServerCmdletSnapin100
	Add-PSSnapin SqlServerProviderSnapin100
	Update-TypeData -PrependPath SQLProvider.Types.ps1xml 
	# update-FormatData -prependpath SQLProvider.Format.ps1xml 
	Pop-Location

	#
	# Loads the SQL Server Management Objects (SMO)
	#

	$ErrorActionPreference = "Stop"

	$sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"

	if (Get-ChildItem $sqlpsreg -ErrorAction "SilentlyContinue")
	{
		throw "SQL Server Provider for Windows PowerShell is not installed."
	}
	else
	{
		$item = Get-ItemProperty $sqlpsreg
		$sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)
	}

	$assemblylist = 
	"Microsoft.SqlServer.Management.Common",
	"Microsoft.SqlServer.Smo",
	"Microsoft.SqlServer.Dmf ",
	"Microsoft.SqlServer.Instapi ",
	"Microsoft.SqlServer.SqlWmiManagement ",
	"Microsoft.SqlServer.ConnectionInfo ",
	"Microsoft.SqlServer.SmoExtended ",
	"Microsoft.SqlServer.SqlTDiagM ",
	"Microsoft.SqlServer.SString ",
	"Microsoft.SqlServer.Management.RegisteredServers ",
	"Microsoft.SqlServer.Management.Sdk.Sfc ",
	"Microsoft.SqlServer.SqlEnum ",
	"Microsoft.SqlServer.RegSvrEnum ",
	"Microsoft.SqlServer.WmiEnum ",
	"Microsoft.SqlServer.ServiceBrokerEnum ",
	"Microsoft.SqlServer.ConnectionInfoExtended ",
	"Microsoft.SqlServer.Management.Collector ",
	"Microsoft.SqlServer.Management.CollectorEnum",
	"Microsoft.SqlServer.Management.Dac",
	"Microsoft.SqlServer.Management.DacEnum",
	"Microsoft.SqlServer.Management.Utility"

	foreach ($asm in $assemblylist)
	{
		$asm = [Reflection.Assembly]::LoadWithPartialName($asm)
	}

	Push-Location
	cd $sqlpsPath
	update-FormatData -prependpath SQLProvider.Format.ps1xml 
	Pop-Location

}

function load-VMWare()
{
	# Adds the base cmdlets
	Add-PSSnapin VMware.VimAutomation.Core
	# Add the following if you want to do things with Update Manager
	Add-PSSnapin VMware.VumAutomation
	# This script adds some helper functions and sets the appearance. You can pick and choose parts of this file for a fully custom appearance.
	# . "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-VIToolkitEnvironment.ps1"

	. "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1"
	Connect-VIServer -Server vcenter
}

function load-EQL()
{
	Import-Module -name "C:\Program Files\EqualLogic\bin\EqlPSTools.dll"
}

function telnet-switch-iscsi-1{
	& "C:\Program Files\VanDyke Software\Clients\SecureCRT.exe" /T /TELNET 192.168.9.221
}

function ssh-hermes{
	& "C:\Program Files\VanDyke Software\Clients\SecureCRT.exe" /T /SSH2 wutz@10.0.10.5
}

function ssh-hermine{
	& "C:\Program Files\VanDyke Software\Clients\SecureCRT.exe" /T /SSH2 wutz@hermine
}

 

 

 

 

Sommerwetter

9. Juli 2012 by Sturbi Kategorie: Fotografie

es hat mal wieder geregnet …

5097
5113
5116
5126

Reiher und Haubentaucher

8. April 2012 by Sturbi Kategorie: Fotografie

Mein Ostersonntag Spaziergang brachte mich wieder an den See, nachzusehen, was die Haubentaucher machen. Viel verwertbares ist nicht dabei entstanden, aber eine schöne Studie eines zufällig vorbeifliegenden Reihers.

5077
5062
5061

Spitzmaus

8. April 2012 by Sturbi Kategorie: Fotografie

Meine Katze hatte mal wieder eine Maus auf den Hof gebracht. Aber irgendwie war es anders. Kein hochwerfen, hinterherspringen, rumrennen und belauern! Sie saß in 2 Metern Abstand und beäugte ihr „Opfer“. Also die Kammera mitnehmen und mal nachsehen. Größer als eine Maus und kleiner als eine Ratte. Aber ängstlich quitschen, in einer extremen Lautstärke, so das die Katze weglief, konnte sie. Opa hatte mir mal erzählt, das Spitzmäuse den Katzen nicht schmecken, weshalb sie diese nicht fressen. Da grad keine akute Gefahr für die Maus bestand (die Katze war ins Haus zu ihrem Fressnapf geflüchtet), schnell in der Google Bildersuche nach Spitzmaus gesucht, dann noch etwas über sie recherchiert und festgelegt, das sie gerettet wird. Also wieder raus und die Kleine vorsichtig auf eine große Schaufel bugsiert und im Garten unter einem Strauch frei gelassen. (Katze war immer noch am Fressnapf!) Hoffentlich war sie gesund und überlebt das Abenteuer.

http://de.wikipedia.org/wiki/Spitzmaus

5036
  • « Vorherige Seite
  • 1
  • …
  • 5
  • 6
  • 7
  • 8
  • 9
  • …
  • 11
  • Nächste Seite »

© 2025 · Sturbi's Home