Running fetchmail with SSL support
This HowTo describes how to configure fetchmail with SSL support.
Contents |
Required packages
- openssl
- unzip
- perl
- fetchmail
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;
}