Running fetchmail with SSL support

From OpenFSG
Jump to: navigation, search

This HowTo describes how to configure fetchmail with SSL support.

Contents

Required packages


installing required packages

Using ipkg makes installing the required packages very easy

install openssl

ipkg install openssl

install perl

ipkg install perl

install unzip

ipkg install unzip

install fetchmail

ipkg install fetchmail


edit fetchmail configuration

open /opt/etc/fetchmailrc and insert the following

poll pop.gmx.net
proto apop
port 995
user yourname@gmx.de
password secret
is LOCALUSERNAME
ssl
sslproto tls1
sslcertpath /usr/share/ssl/certs
sslfingerprint 'BA:03:AC:50:A9:A0:C7:AF:1E:79:3A:B7:C0:E7:19:5E'
sslcertck

get fingerprint from your mail provider

Run the following command and copy ssl fingerprint to file /opt/etc/fetchmailrc (fetchmail should not run as deamon) see tips & tricks at the end of this HowTo how to stop fetchmail

/opt/bin/fetchmail -v -p PROTOCOLL -u USERNAME MAILSERVER | grep -i fingerprint

here is an example

/opt/bin/fetchmail -v -p pop3 -u nobody@gmx.de pop.gmx.net | grep -i fingerprint


get root certificate

Run the following commands

cd /tmp
wget https://www.verisign.com/support/thawte-roots.zip > thawte-root.zip
unzip thawte-root.zip
cd ./ Thawte\ Server\ Roots
openssl x509 -in ThawtePremiumServerCA.cer -inform DER -outform PEM  > thawte.pem
mkdir /usr/share/ssl
mkdir /usr/share/ssl/certs
cp ./thawte.pem /usr/share/ssl/certs

ger provider certificate

The following command gets certificate of gmx (should work for other providers aswell)... some providers make the certificates available for download (e.g. web.de --> trustcenter.web.de)

echo "quit" | openssl s_client -connect pop.gmx.net:995 -showcerts | sed -ne '/BEGIN/,/END/p' > /usr/share/ssl/certs/gmx.de.pem

enable certificates for fetchmail

To make certificates available for fetchmail you need c_rehash (see end of this Howto) go to directory /usr/share/ssl/certs

cd /usr/share/ssl/certs

create new file c_rehash and paste code from the end of this HowTo

cd /usr/share/ssl/certs
./c_rehash ./

now there should be some symlinks available.

ls -rtl /usr/share/ssl/certs

should show some symlinks


Tips and tricks

stopping fetchmail

if you are not able to stop fetchmail using startup script with stop parameter you have to kill fetchmail

ps -ef | grep -i fetchmail
kill PID
#!/opt/bin/perl


# Perl c_rehash script, scan all files in a directory
# and add symbolic links to their hash values.

my $openssl;

#my $dir = "/usr/lib/ssl";
my $dir = "/opt/share/openssl";
if(defined $ENV{OPENSSL}) {
	$openssl = $ENV{OPENSSL};
} else {
	$openssl = "openssl";
	$ENV{OPENSSL} = $openssl;
}

$ENV{PATH} .= ":$dir/bin\n";
if(! -x $openssl) {
	my $found = 0;
	foreach (split /:/, $ENV{PATH}) {
		if(-x "$_/$openssl") {
			$found = 1;
			last;
		}	
	}
	if($found == 0) {
		print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n";
		exit 0;
	}
}

if(@ARGV) {
	@dirlist = @ARGV;
} elsif($ENV{SSL_CERT_DIR}) {
	@dirlist = split /:/, $ENV{SSL_CERT_DIR};
} else {
	$dirlist[0] = "$dir/certs";
}


foreach (@dirlist) {
	if(-d $_ and -w $_) {
		hash_dir($_);
		print $_;
		print "\n";
	}
}

sub hash_dir {
	my %hashlist;
	print "Doing $_[0]\n";
	chdir $_[0];
	opendir(DIR, ".");
	my @flist = readdir(DIR);
	# Delete any existing symbolic links
	foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
		if(-l $_) {
			unlink $_;
		}
	}
	closedir DIR;
	FILE: foreach $fname (grep {/\.pem$|\.crt$/} @flist) {
		# Check to see if certificates and/or CRLs present.
		my ($cert, $crl) = check_file($fname);
		if(!$cert && !$crl) {
			($cert, $crl) = check_file("$openssl x509 -in \"$fname\" -inform der  -outform pem | ");
			if(!$cert && !$crl) {
				print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
				next;
			}
		}
		link_hash_cert($fname) if($cert);
		link_hash_crl($fname) if($crl);
	}
}

sub check_file {
	my ($is_cert, $is_crl) = (0,0);
	my $fname = $_[0];
	open IN, $fname;
	while(<IN>) {
		if(/^-----BEGIN (.*)-----/) {
			my $hdr = $1;
			if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
				$is_cert = 1;
				last if($is_crl);
			} elsif($hdr eq "X509 CRL") {
				$is_crl = 1;
				last if($is_cert);
			}
		}
	}
	close IN;
	return ($is_cert, $is_crl);
}


# Link a certificate to its subject name hash value, each hash is of
# the form <hash>.<n> where n is an integer. If the hash value already exists
# then we need to up the value of n, unless its a duplicate in which
# case we skip the link. We check for duplicates by comparing the
# certificate fingerprints

sub link_hash_cert {
		my $fname = $_[0];
		$fname =~ s/'/'\\''/g;
		my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in '$fname'`;
		if(!$hash || !fprint) {
			($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in '$fname' -inform der`;
		}
		chomp $hash;
		chomp $fprint;
		$fprint =~ s/^.*=//;
		$fprint =~ tr/://d;
		my $suffix = 0;
		# Search for an unused hash filename
		while(exists $hashlist{"$hash.$suffix"}) {
			# Hash matches: if fingerprint matches its a duplicate cert
			if($hashlist{"$hash.$suffix"} eq $fprint) {
				print STDERR "WARNING: Skipping duplicate certificate $fname\n";
				return;
			}
			$suffix++;
		}
		$hash .= ".$suffix";
		print "$fname => $hash\n";
		$symlink_exists=eval {symlink("",""); 1};
		if ($symlink_exists) {
			symlink $fname, $hash;
		} else {
			system ("cp", $fname, $hash);
		}
		$hashlist{$hash} = $fprint;
}

# Same as above except for a CRL. CRL links are of the form <hash>.r<n>

sub link_hash_crl {
		my $fname = $_[0];
		$fname =~ s/'/'\\''/g;
		my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
		chomp $hash;
		chomp $fprint;
		$fprint =~ s/^.*=//;
		$fprint =~ tr/://d;
		my $suffix = 0;
		# Search for an unused hash filename
		while(exists $hashlist{"$hash.r$suffix"}) {
			# Hash matches: if fingerprint matches its a duplicate cert
			if($hashlist{"$hash.r$suffix"} eq $fprint) {
				print STDERR "WARNING: Skipping duplicate CRL $fname\n";
				return;
			}
			$suffix++;
		}
		$hash .= ".r$suffix";
		print "$fname => $hash\n";
		$symlink_exists=eval {symlink("",""); 1};
		if ($symlink_exists) {
			symlink $fname, $hash;
		} else {
			system ("cp", $fname, $hash);
		}
		$hashlist{$hash} = $fprint;
}

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox