На Хабре есть несколько статей по rsyslog, но не нашлось ни одной, описывающей, как настроить взаимодействие клиента и сервера через защищенное соединение. Попробую исправить этот момент.
Допустим, у нас есть несколько серверов, имеющих доступ в интернет и не имеющих какой-то приватной сети между собой. В один прекрасный момент нам надоедает лазать на каждый их них по очереди и мы решаем настроить централизованный сервер логов. Так как данные будут передаваться через интернет, необходимо их защитить, передавая их через TLS.
В качестве подопытных у нас выступают машинки с CentOS 6.7, тренироваться мы будем с rsyslog 7.x. rsyslog server (rslserver) у нас будет называться server.com, а rsyslog client (rslclient) — example.com.
Установка
Ставить rsyslog будем с их оффициального репозитория (http://www.rsyslog.com/rhelcentos-rpms/).
Сервер
wget http://rpms.adiscon.com/v7-stable/rsyslog.repo -O /etc/yum.repos.d/rsyslog.repo
yum install gnutls-utils rsyslog rsyslog-gnutls
mv /etc/rsyslog.conf.rpmnew /etc/rsyslog.conf #в случае если что-то правили до этого, надо будет перенести изменения
service rsyslog restart
less /var/log/messages #проверяем что rsyslog запустился без ошибок
Клиент
wget http://rpms.adiscon.com/v7-stable/rsyslog.repo -O /etc/yum.repos.d/rsyslog.repo
yum install rsyslog rsyslog-gnutls #gnutls-utils на клиенте не нужен
mv /etc/rsyslog.conf.rpmnew /etc/rsyslog.conf #в случае если что-то правили до этого, надо будет перенести изменения
service rsyslog restart
less /var/log/messages #проверяем что rsyslog запустился без ошибок
Настройка
Генерация сертификатов
Самая муторная часть. Нам необходимо сгенерировать пару ключей CA и по запросу+паре ключей для сервера и для каждого клиента. Все секьюрно. Для безопасности генерацию стоит делать не на сервере/клиенте, а на отдельной машине.
CA
Сердце нашей безопасности. Генерируем private key:
[root@sysadmin ~]# certtool --generate-privkey --outfile ca-key.pem
Generating a 2048 bit RSA private key...
Генерируем самоподписанный сертификат:
[root@sysadmin ~]# certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca.pem
Generating a self signed certificate...
Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
Country name (2 chars): RU
Organization name: myorg
Organizational unit name:
Locality name:
State or province name:
Common name: cacert
UID:
This field should not be used in new certificates.
E-mail:
Enter the certificate's serial number in decimal (default: 1395159808):
Activation/Expiration time.
The certificate will expire in (days): 3650
Extensions.
Does the certificate belong to an authority? (y/N): y
Path length constraint (decimal, -1 for no constraint):
Is this a TLS web client certificate? (y/N):
Is this also a TLS web server certificate? (y/N):
Enter the e-mail of the subject of the certificate: email@admin.com
Will the certificate be used to sign other certificates? (y/N): y
Will the certificate be used to sign CRLs? (y/N):
Will the certificate be used to sign code? (y/N):
Will the certificate be used to sign OCSP requests? (y/N):
Will the certificate be used for time stamping? (y/N):
Enter the URI of the CRL distribution point:
X.509 Certificate Information:
[...]
Is the above information ok? (Y/N): y
Signing certificate...
[root@sysadmin ~]# ls -l
total 136
-rw------- 1 root root 1675 Mar 18 11:12 ca-key.pem
-rw-r--r-- 1 root root 1318 Mar 18 12:24 ca.pem
[root@sysadmin ~]#
Не забываем что с помощью ca-key.pem злоумышленник может запросто подменить сертификат на свой, поэтому хранить его нужно в безопасном месте.
Сервер
Генерируем private key для rsyslog сервера:
[root@sysadmin ~]# certtool --generate-privkey --outfile rslserver-key.pem --bits 2048
Generating a 2048 bit RSA private key...
Генерируем certificate request. Rsyslog проверяет авторизацию по полю сертификата X509/name, так что в сommon name лучше указывать FQDN хоста.
[root@sysadmin ~]# certtool --generate-request --load-privkey rslserver-key.pem --outfile request.pem
Generating a PKCS #10 certificate request...
Country name (2 chars): RU
Organization name: myorg
Organizational unit name:
Locality name:
State or province name:
Common name: server.com
UID:
Enter a dnsName of the subject of the certificate: server.com
Enter a dnsName of the subject of the certificate:
Enter the IP address of the subject of the certificate:
Enter the e-mail of the subject of the certificate:
Enter a challenge password:
Does the certificate belong to an authority? (y/N): n
Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N):
Will the certificate be used for encryption (RSA ciphersuites)? (y/N):
Is this a TLS web client certificate? (y/N): y
Is this also a TLS web server certificate? (y/N): y
Генерируем сертификат из request'а.
[root@sysadmin ~]# certtool --generate-certificate --load-request request.pem --outfile rslserver-cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem
Generating a signed certificate...
Enter the certificate's serial number in decimal (default: 1395162401):
Activation/Expiration time.
The certificate will expire in (days): 3650
Extensions.
Do you want to honour the extensions from the request? (y/N):
Does the certificate belong to an authority? (y/N): n
Is this a TLS web client certificate? (y/N): y
Is this also a TLS web server certificate? (y/N): y
Enter a dnsName of the subject of the certificate: server.com
Enter a dnsName of the subject of the certificate:
Enter the IP address of the subject of the certificate:
Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N):
Will the certificate be used for encryption (RSA ciphersuites)? (y/N):
X.509 Certificate Information:
[...]
Is the above information ok? (Y/N): y
Signing certificate...
[root@sysadmin ~]# rm -f request.pem
Теоретически, можно использовать wildcards в common name и dns name, генерируя один сертификат сразу для нескольких хостов, но лучше этого не делать. После генерации сертификата request можно удалить.
Клиент
Для клиента все шаги те же, что и для сервера: генерируем ключ, затем запрос, затем сертификат. Естественно, имена файлов нужно заменить с rslserver на rslclient, а common name/dns name — с server.com на example.com.
Копируем файлы
Пакет для CentOS создает директорию /etc/pki/rsyslog/, которой грех не воспользоваться. Копируем на сервер файлы ca.pem, rslserver-cert.pem, rslserver-key.pem, а на клиента файлы ca.pem, rslclient-cert.pem, rslclient-key.pem.
Получаем что-то вроде:
[root@server.com]# ls -l1 /etc/pki/rsyslog/
-rw-r--r-- 1 root root 1172 Feb 8 20:19 ca.pem
-rw-r--r-- 1 root root 1294 Feb 8 21:13 rslserver-cert.pem
-rw-r--r-- 1 root root 1675 Feb 8 21:11 rslserver-key.pem
[root@example.com]# ls -l1 /etc/pki/rsyslog/
-rw-r--r-- 1 root root 1172 Feb 8 20:21 ca.pem
-rw-r--r-- 1 root root 1273 Feb 8 20:21 rslclient-cert.pem
-rw------- 1 root root 1675 Feb 8 20:21 rslclient-key.pem
Конфиги
Сервер
Добавляем в начало /etc/rsyslog.conf, сразу после загрузки модулей imuxsock и imklog:
################### REMOTE LOGGING BEGIN #########################
# Increase the amount of open files rsyslog is allowed, which includes open tcp sockets
# This is important if there are many clients.
# http://www.rsyslog.com/doc/rsconf1_maxopenfiles.html
$MaxOpenFiles 2048
# make gtls driver the default
$DefaultNetstreamDriver gtls
# certificate files generated on RHEL6 and stored in /root
$DefaultNetstreamDriverCAFile /etc/pki/rsyslog/ca.pem
$DefaultNetstreamDriverCertFile /etc/pki/rsyslog/rslserver-cert.pem
$DefaultNetstreamDriverKeyFile /etc/pki/rsyslog/rslserver-key.pem
# Provides TCP syslog reception
# for parameters see http://www.rsyslog.com/doc/imtcp.html
module(load="imtcp"
MaxSessions="2000"
StreamDriver.mode="1"
StreamDriver.authmode="x509/name"
PermittedPeer="example.com"
)
input(type="imtcp" port="10514" name="tcp-tls")
################### REMOTE LOGGING END #########################
Из названий директив вроде все понятно: увеличиваем лимит открытых файлов, указываем что поток идет через TLS, показываем на ключи для его расшифровки, а затем передаем поток в модуль imtcp, который проверяет авторизацию по полю x509/name, сравнивая с разрешенным пиром.
Если мы хотим складывать логи с каждого клиента в отдельный файл, то в конце /etc/rsyslog.conf (или в каком-то из файлов в /etc/rsyslog.d) нам надо указать rsyslog соответствующие параметры:
# This one is the template to generate the log filename dynamically, depending on the client's hostname.
$template FileForRemote,"/var/log/remote/%fromhost%/syslog.log"
if ($inputname contains "tcp-tls") then
{
?FileForRemote
stop
}
Тут все просто. Сначала мы задаем динамический шаблон имени файла, и затем записываем в эти файлы все, что приходит из «tcp-tls» (имя задано выше в input). После того как мы создали запись, мы прекращаем обработку данного сообщения (директива stop), чтобы она не попала в «общий котел».
Клиент
На клиенте все еще проще. В файле /etc/rsyslog.d/tls.conf указываем, что сетевой поток надо гнать через TLS с такими-то сертификатами, проверяя x509/name на соответствие заданному. Последняя строчка указывает, что по сети, через протокол TCP (@@) на адрес server.com мы шлем только записи от ядра (kern).
# make gtls driver the default
$DefaultNetstreamDriver gtls
# certificate files
$DefaultNetstreamDriverCAFile /etc/pki/rsyslog/ca.pem
$DefaultNetstreamDriverCertFile /etc/pki/rsyslog/rslreverb-cert.pem
$DefaultNetstreamDriverKeyFile /etc/pki/rsyslog/rslreverb-key.pem
#### GLOBAL DIRECTIVES ####
# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# gtls Network Stream Driver
# x509/name - certificate validation and subject name authentication
# http://www.rsyslog.com/doc/ns_gtls.html
$ActionSendStreamDriverAuthMode x509/name
$ActionSendStreamDriverPermittedPeer server.com
$ActionSendStreamDriverMode 1 # run driver in TLS-only mode
kern.* @@server.com:10514
Собственно и все. Не забудьте открыть порты на фаерволе и перезапустить rsyslog на сервере и клиенте. В подготовке руководства использовалась официальная документация rsyslog и запись из блога Kristian Reese.
Автор: strangeman