Организация проверки подписей PGP

Материал из DvoWiki
Перейти к: навигация, поиск

Организация проверки PGP подписей

Введение

В данной статье рассматривается применение GnuPG для проерки электронных подписей в электронной почте. Также будут рассмотрены вопросы установки сервера ключей (keyserver) работающего через LDAP. В конце рассмотрен вариант проверки входящей почты для RT.

Установка GnuPG

Для gentoo linux:

USE="ldap nls doc" emerge -v gnupg

Ключ ldap необходим для поддержки связи с сервером ключей.

Для получение руководства по использованию возможно испльзовть мануал man gnupg.

Развёртывание сервера ключей

Для развёртывания сервера ключей понадобится работающая инсталяция openldap. Для того чтобы openldap смог выступать в качестве сервера ключей необходимо добавить в файл настроек slap.conf ссылки на схему pgp-keyserver.schema. Скачать эту схему и прочие данные для OpenLDAP сервера ключей можно по адресу ftp://ftp.dvo.ru/pub/openldap_pgp_keyserver/. Ниже предложен вариант настройки slapd.conf:

#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#

include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/rfc2307bis.schema

include         /etc/openldap/schema/pgp-keyserver.schema
 
# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral       ldap://root.openldap.org 

pidfile         /var/run/slapd/slapd.pid
argsfile        /var/run/slapd/slapd.args

# Load dynamic backend modules:
modulepath      /usr/lib/openldap/modules
# moduleload    back_ldap.la
# moduleload    back_meta.la
# moduleload    back_monitor.la
# moduleload    back_perl.la

# Sample security restrictions
#       Require integrity protection (prevent hijacking)
#       Require 112-bit (3DES or better) encryption for updates
#       Require 63-bit encryption for simple bind
#security ssf=112 update_ssf=112 simple_bind=64
 
allow bind_anon_dn

# required for anonymous writes by PGP
# uncomment if you use user authentication 
allow update_anon

loglevel 256

# base may be read by anybody
access to dn.base=""
        by * read

# schemas may be read by anybody
access to dn="cn=Subschema"
        by * read

# userPassword may be written only by users themselves
access to attr="userPassword"
        by self write
        by * auth

# let PGP discover the keystore base DN
access to dn="cn=pgpServerInfo,dc=EXAMPLE,dc=COM"
        by * read

# -----------------------------------------------------------------

# Select either anonymous OR user authentication
# by commenting out the unwanted method.

#
# Anonymous (be sure to uncomment update_anon above)
#

# PGP keystore: only localhost may write, anyone can read
access to dn.subtree="ou=PGP Keys,dc=EXAMPLE,dc=COM"
        by peername.ip=127.0.0.1 write
        by * read

#
# User authentication:
#

## let PGP users change their passwords
#access to dn.regex="^uid=([^,]+),ou=PGP Users,dc=EXAMPLE,dc=COM$"
#       by self write
#       by * none
#
## PGP keystore: only users of "ou=PGP Users,dc=EXAMPLE,dc=COM" may write
#access to dn.subtree="ou=PGP Keys,dc=EXAMPLE,dc=COM"
#       by dn.regex="^uid=([^,]+),ou=PGP Users,dc=EXAMPLE,dc=COM$" write
#        by * read
#

# -----------------------------------------------------------------

# deny any other access
access to * by * none

# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn.  (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!

#######################################################################
# BDB database definitions
#######################################################################

database        bdb
checkpoint      1024    5
cachesize       10000
sizelimit       unlimited
timelimit       3600

suffix          "dc=EXAMPLE,dc=COM
rootdn          "cn=Manager,dc=EXAMPLE,dc=COM"

# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw          {SSHA}QfYckKX2j3mTsBpEsQ3LLIYcnlLCXYEX

# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory       /var/lib/ldap

# Indices to maintain
index objectClass eq
index pgpCertID,pgpKeyID,pgpKeyType,pgpUserID,pgpKeyCreateTime sub,eq
index pgpSignerID,pgpSubKeyID,pgpKeySize,pgpKeyExpireTime sub,eq
index pgpDisabled,pgpRevoked eq

#TLSCACertificateFile   /etc/openldap/ssl/certs/ca.pem
#TLSCertificateFile     /etc/openldap/ssl/certs/ldap.pem
#TLSCertificateKeyFile  /etc/openldap/ssl/keys/ldap.key
#TLSCipherSuite         HIGH:MEDIUM:-SSLv2:+SSLv3
#TLSVerifyClient        try 

# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw          {SSHA}QfYckKX2j3mTsBpEsQ3LLIYcnlLCXYEX

# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory       /var/lib/ldap

# Indices to maintain
index objectClass eq
index pgpCertID,pgpKeyID,pgpKeyType,pgpUserID,pgpKeyCreateTime sub,eq
index pgpSignerID,pgpSubKeyID,pgpKeySize,pgpKeyExpireTime sub,eq
index pgpDisabled,pgpRevoked eq

После добавления схемы и конфигурирования slapd.conf необходимо создать в LDAP примерно следующее дерево:

dc=EXAMPLE,dc=COM

 |
 +----cn=Manager
 +----cn=PGPServerInfo
 +----ou=PGP Keys
 |    +---pgpCertID=...
 |    +---pgpCertID=...
 +----ou=PGP Users
      +---uid=...
      +---uid=...

Это дерево можно создать либо при помощи phpldapadmin, либо посредством ldif файла:

# add with: ldapadd -x -W -h localhost -D "cn=Manager,dc=EXAMPLE,dc=COM" < example.ldif

dn: dc=EXAMPLE,dc=COM
dc: EXAMPLE
objectClass: domain
objectClass: top

dn: cn=Manager,dc=EXAMPLE,dc=COM
cn: Manager
sn: Manager
objectClass: person
objectClass: top

dn: ou=PGP Keys,dc=EXAMPLE,dc=COM
objectclass: organizationalUnit
ou: PGP Keys

dn: cn=PGPServerInfo,dc=EXAMPLE,dc=COM
cn: PGPServerInfo
objectclass: pgpserverinfo
pgpSoftware: OpenLDAP
pgpVersion: 2.2.27
pgpBaseKeyspaceDN: ou=PGP Keys,dc=EXAMPLE,dc=COM

dn: ou=PGP Users,dc=EXAMPLE,dc=COM
objectclass: organizationalUnit
ou: PGP Users

Подобную операцию можно провести и при добавлении пользователей:

# add with: ldapadd -x -h localhost -W -D "cn=Manager,dc=EXAMPLE,dc=COM" < pgpusers.ldif

dn: uid=user1,ou=PGP Users,dc=EXAMPLE,dc=COM
objectClass: inetOrgPerson
objectClass: uidObject
uid: user1
# password is 'user1'. Use slappasswd(8) to create a new
# one and replace the string here!
userPassword: {SSHA}sLbxdJt53SZvU9BMRSSmdD78vfiSoPHR
sn: lastname
cn: Test User 1


Конфигурирование GnuPG для работы с сервером ключей

Для работы с сервером ключей возможно использовать два варианта. Первый, задавать параметры сервера ключей непосредственно при вызове gpg (подробности можно найти в мануале). Второй вариант прописать сервер ключей в файле настроек. В стандартной конфигурации этот файл находится в домашней директории пользователя ~/.gnupg/gpg.conf.

Пример конфигурирования gpg, для работы с сервером ключей ldap.

keyserver ldap://keyserver.example.com
keyserver-options binddn="cn=Manager,dc=example,dc=com"
keyserver-options bindpw=secret
keyserver-options basedn="ou=PGP Keys,dc=example,dc=com"
keyserver-options auto-key-retrieve

Вышеприведённая конфигурация работает с сервером keyserver.example.com по протоколу ldap, от имени пользователя Manager. Очень важно здесь указать basedn, программа кладет и получает ключи непосредственно под этим base dn.

Интеграция проверки писем в сетевые сервисы

Для интеграции фильтраиции писем для сетевых сервисов (например RT), предполагается использование промежуточных скриптов. Принцип действия скрипта заключается в следующем:

  1. перехват письма, направленного к сервису
  2. проверка подписи письма с использованием сервера ключей (то есть публичный ключ отправителя должен присутствовать на сервере ключей)
  3. если письмо правильно подписано передать его сервису получателю.

Перенаправление можно оганизовать с помощью подобного sh скрипта (назовём его mail-filter.sh)

#!/bin/bash
/var/some/path/mail_pgp_verify_02.pl --conf /var/lib/gnupg/ |/var/aanother/path/service --arguments

Для перенаправления письма на вход этого скрипта необходимо поправить /etc/mail/aliases добавив алиас для конкретного адреса

corresponding: "|/var/lalala/mail-filter.sh"

При этом не надо забывать зделать ссылку на /var/lalala/mail-filter.sh в /usr/adm/sm.bin/, и набрать newaliases.

Дополнительные замечания

Стоит отметить тот факт, что sendmail может работать от пользователей которые не имеют shell и домашнюю директорию (Например daemon). В этом случае, для того чтобы производить верификацию писем с использованием gnugpg необходимо создать дополнительного пользователя для работы с gpg. Далее скрипты валидации запускать от имени этого пользователя используя sudo -u name_of_user. Конфигурационные файлы для этого пользователя будут находиться в $USER_HOME/.gnupg/.

Также на до поправить /etc/suduers. $ visudo -f /etc/sudoers

daemon    ALL=(somegpguser) NOPASSWD:/some/path/to/youre/script/mail_pgp_verify.pl