Это решение отлично сработало. Это немного стар, но не было никаких проблем с ним. https://www.w3.org/2004/07/pgp-whitelist.html
Требования
Чтобы настроить эту систему белого списка, вам необходимо:
рабочая среда procmail, настроенная для фильтрации входящей электронной почты на том же компьютере, что и procmail, реализация PGP; мы предполагаем, что с этого момента это gnupg, но система должна быть адаптирована для других клиентов, а также набора ключей человека, которому вы доверяете, импортированного в вашу среду PGP; с помощью gnupg вы импортировали бы ключ, используя gpg --recv-key key_id, при условии, что у вас есть настроенный сервер PGP для получения ключей из раздела «Настройка»
Система, которую мы настраиваем, выполняет следующие действия:
для любого полученного письма он проверяет, находится ли отправитель, указанный в заголовке From, в нашем доверенном списке (.pgp-whitelist), если он есть, он проверяет, подписано ли письмо и, если да, правильно ли оно (с сценарий mailverify), если он есть, он добавляет заголовок X-Whitelist: Yes, убедившись, что входящая почта не имеет такого заголовка. Сценарий mailverify, используемый для проверки, можно загрузить с общедоступного сервера W3C CVS. Здесь вам нужно будет изменить вызов вашего PGP-клиента, если он не вызывается как gpg.
Предполагается, что белый список .pgp находится в вашем домашнем каталоге; измените путь в переменной PGP_WHITELIST ниже, если это не так. Его содержимое представляет собой список адресов электронной почты (по одному на строку), которым вы доверяете и хотите быть в белом списке, если вы получаете от них подписанные письма.
Соответствующие правила procmail для добавления в файл конфигурации .procmailrc приведены ниже; они должны быть добавлены перед настройкой для идентификации спама, если вы также используете procmail.
# .procmailrc - Check whitelist PGP_WHITELIST=$HOME/.pgp-whitelist #looking from spam, but blessing sender from my white list # by setting a X-Whitelist header # First, removing fake headers :0 fwh * ^X-Whitelist | formail -IX-Whitelist # checking for people with a trusted PGP key FROM=`formail -XFrom: | formail -r -xTo: | tr -d ' '` PGP_OK=`$HOME/mailverify 1>/dev/null && echo 1` :0 * ? egrep -q "$FROM" $PGP_WHITELIST * ? test -n "$PGP_OK" { :0 fwh | formail -a"X-Whitelist: Yes" :0: $MAILDIR/good/ } :0 fwh * !^X-Whitelist: Yes { :0: $MAILDIR/bounce/ }
Скрипт Perl, который проверяет почту. Твик папок MAILDIR соответственно.
#!/usr/bin/env perl # File Name: mailverify # Maintainer: Moshe Kaminsky <kaminsky@math.huji.ac.il> # Original Date: September 30, 2003 # Last Update: September 30, 2003 # http://mirror.hamakor.org.il/archives/linux-il/att-5615/mailverify ########################################################### use warnings; use integer; BEGIN { our $VERSION = 0.1; # analyze command line use Getopt::Long qw(:config gnu_getopt); use Pod::Usage; our $opt_help; our $opt_man; our $opt_version; our $Gpg; our $Tolerant; GetOptions('gpg=s' => \$Gpg, 'tolerant!' => \$Tolerant, 'help', 'version', 'man'); pod2usage(1) if $opt_help; pod2usage(-verbose => 2) if $opt_man; print "$0 version $VERSION\n" and exit if $opt_version; $Gpg = '/usr/bin/gpg --batch --verify' unless $Gpg; } use File::Temp qw( tempfile ); my $PrevField = ''; # process the header while (<>) { next if /^From /o; last if /^$/o; if (/^([\w-]+): (.*)$/o) { $Header{$1} = $2; $PrevField = $1; } else { $Header{$PrevField} .= $_; } } # check that the message is signed $Str = $Header{'Content-Type'}; @Parts = split /;\s+/, $Str if $Str; if (not $Str or $Parts[0] ne 'multipart/signed') { # the message is not multipart/signed, but might still be cleartext # signed. Depending on --tolerant, we may pass the rest of the message to # gpg directly print "Message not signed\n" and exit -1 unless $Tolerant; open GPG, "|$Gpg" or die "Can't open pipe to gpg ($Gpg): $!"; print GPG <>; close GPG; exit $? >> 8; } # the boundary string signals the boundary between two attachments $Boundary = $1 if $Parts[3] =~ /^boundary="(.*)"$/o; # go to the start of the message while (<>) { last if $_ eq "--$Boundary\n"; } # read the message, excluding the last (empty) line while (<>) { last if $_ eq "--$Boundary\n"; push @Message, $_; } pop @Message; # read the sig while (<>) { last if /^-----BEGIN PGP SIGNATURE-----$/o; } { do { push @Sig, $_; last if /^-----END PGP SIGNATURE-----$/o; } while (<>); }; # here comes the funny part: replace \n by \r\n $_ = join '', @Message; s/(?<!\r)\n/\r\n/g; # write everything to files my ($MsgFH, $MsgFile) = tempfile; print $MsgFH $_; my $SigFile = "$MsgFile.asc"; open SIGFH, ">$SigFile" or die "can't open $SigFile: $!"; print SIGFH @Sig; close $MsgFH; close SIGFH; # run gpg print `$Gpg $SigFile`; # clean up unlink $MsgFile, $SigFile; # exit with the status of gpg exit $? >> 8; __DATA__ # start of POD =head1 NAME mailverify - verify the pgp signature of a mime signed mail message =head1 SYNOPSIS B<mailverify> B<--help>|B<--man>|B<--version> B<mailverify> [B<--gpg=I<gpg command>>] [B<--(no)tolerant>] [I<mail file>] =head1 OPTIONS =over 4 =item B<--gpg=I<gpg command>> The command to run to do the actual checking. The default is S<C</usr/local/bin/gpg --batch --verify>>. It is called with one argument, which is the name of the file containing the signature. If B<--tolerant> is used, it may also be called with the whole message on the standard input. =item B<--(no)tolerant> Normally (with B<--notolerant>), if the Content-Type is not C<multipart/signed>, B<mailverify> decides that the message is not signed, and exits with status -1. With this switch, the message is passed to I<gpg> (or whatever was specified with the B<--gpg> option) as is. This way, clearsigned messages can be verified with the same command. =item B<--help> Give a short usage message and exit with status 1 =item B<--man> Give the full description and exit with status 1 =item B<--version> Print a line with the program name and exit with status 0 =back =head1 ARGUMENTS If an argument is given, it is treated a file containing an e-mail message to verify, but more common is to read the message from stdin. =head1 DESCRIPTION This script verifies the pgp signature of files whose signature appears as an attachment (Content-Type C<multipart/signed>). If B<--tolerant> is used, it will also verify clearsigned messages. The usage is basically to pipe the mail to this program. =head1 EXIT STATUS If the message is not of type C<multipart/signed>, and B<--tolerant> is not given, the exit status is -1. In any other case, it is the exit status of the I<gpg> command. =head1 SEE ALSO I<gpg(1)> =head1 BUGS Probably plenty, since I don't read any RFCs. Works with all cases I checked, though. =head1 AUTHOR Moshe Kaminsky <kaminsky@math.huji.ac.il> - Copyright (c) 2003 =head1 LICENSE This program is free software. You may copy or redistribute it under the same terms as Perl itself. =cut
Слава Моше.