3. Настройка TLS (Transport Layer Security)
В наши дни использование TLS является практически обязательным. TLS реализует защитные функции конфиденциальности и целостности данных, а так же служит для поддержки аутентификации LDAP с использованием механизма SASL EXTERNAL. TLS определён в RFC4346. Для настройки TLS на сервере нам понадобятся SSL сертификат и ключ. Сертификат должен быть подписан доверенным удостоверяющим центром (УЦ, Certificate Authority, CA) или собственным удостоверяющим центром (на основе самоподписанного, self-signed, сертификата), если используется в тестовых целях. С помощью OpenSSL мы создадим импровизированный удостоверяющий центр и затем настроим TLS. Прямая цитата из Википедии:
Сертификаты, как правило, используются для обмена зашифрованными данными в больших сетях. Криптосистема с открытым ключом решает проблему обмена секретными ключами между участниками безопасного обмена, однако не решает проблему доверия к открытым ключам. Предположим, что Алиса, желая получать зашифрованные сообщения, генерирует пару ключей, один из которых (открытый) она публикует каким-либо образом. Любой, кто желает отправить ей конфиденциальное сообщение, имеет возможность зашифровать его этим ключом, и быть уверенным, что только она (так как только она обладает соответствующим секретным ключом) сможет это сообщение прочесть. Однако описанная схема ничем не может помешать злоумышленнику Давиду создать пару ключей, и опубликовать свой открытый ключ, выдав его за ключ Алисы. В таком случае Давид сможет расшифровывать и читать, по крайней мере, ту часть сообщений, предназначенных Алисе, которые были по ошибке зашифрованы его открытым ключом. Идея сертификата — это наличие третьей стороны, которой доверяют две другие стороны информационного обмена. Предполагается, что таких третьих сторон немного, и их открытые ключи всем известны каким-либо способом, например, хранятся в операционной системе или публикуются в журналах. Таким образом, подлог открытого ключа третьей стороны легко выявляется. Если Алиса сформирует сертификат со своим публичным ключом, и этот сертификат будет подписан третьей стороной (например, Трентом), любой, доверяющий Тренту, сможет удостовериться в подлинности открытого ключа Алисы. В централизованной инфраструктуре в роли Трента выступает удостоверяющий центр. В сетях доверия Трент может быть любым пользователем, и следует ли доверять этому пользователю, удостоверившему ключ Алисы, решает сам отправитель сообщения.
3.1 Удостоверяющий центр на основе самоподписанного сертификата с помощью OpenSSL
Где работаем: ldap-srv Итак, мы создаём централизованную инфраструктуру открытых ключей (PKI) в миниатюре. Для этого сформируем пару закрытый ключ/корневой сертификат удостоверяющего центра. Причём сертификат будет подписан этим же закрытым ключом (т. е. станет самоподписанным). Затем сгенерируем новый закрытый ключ для нашей службы каталогов и создадим для неё сертификат, подписанный закрытым ключом нашего удостоверяющего центра. При этом клиенские рабочие станции должны знать только корневой сертификат. Используя его они могут установить безопасное соединение с любым сервером, который имеет закрытый ключ и соответствующий ему сертификат, подписанный нашим УЦ. Такие пары (ключ/сертификат) можно создавать для множества задач. Например, в разделе, посвященном репликации, мы создадим второй сервер каталогов, которому тоже понадобится такая пара. Удостоверяющий центр желательно разворачивать на отдельной машине, не имеющей подключения к сети, но для простоты примера мы проделаем всю работу на ldap-srv.example.com. Создадим каталог для нашего удостоверяющего центра (CA) и установим безопасные права доступа. Затем зададим значение umask таким, чтобы вновь создаваемые файлы имели права доступа чтения и записи только для создавшего их пользователя:
# mkdir /root/CA # chmod u=rwx,g=,o= /root/CA # cd /root/CA # umask 066
В конфигурационном файле /etc/ssl/openssl.cnf в секции [ CA_default ] для удобства поменяем значение директивы dir = ./demoCA на dir = ./ . В этом же разделе директивой default_days задаётся срок действия выпускаемых сертификатов. Можете поменять её значение по своему усмотрению. Файлы index.txt и serial будут играть роль своеобразной базы данных, чтобы отслеживать статус выпущенных закрытых ключей и сертификатов. Создадим структуру каталогов и файлов для своего удостоверяющего центра:
# mkdir certs crl newcerts private # chmod 700 private # touch index.txt # echo 1000 > serial
Сгенерируем закрытый ключ удостоверяющего центра (длиной 4096 бит). Он должен хранится особенно бережно. Поэтому мы защитим его при помощи шифра AES. Вам будет предложено ввести пароль для доступа к новому закрытому ключу. Запомните его и не потеряйте. Это последний рубеж защиты от злоумышленника. Без пароля выпустить новые сертификаты не получится.
# openssl genrsa -aes256 -out private/rootca.key 4096
Изменим права доступа к новому ключу, чтобы ненароком его не стереть:
# chmod 400 private/rootca.key
Откройте конфигурационный файл OpenSSL (openssl.cnf) и найдите секции [ usr_cert ] и [ v3_ca ] . Убедитесь, что в них присутствуют следующие директивы:
[ usr_cert ]# Эти расширения будут добавлены при подписывании запроса нашим УЦ.basicConstraints=CA:FALSEkeyUsage = nonRepudiation, digitalSignature, keyEnciphermentnsComment = "OpenSSL Generated Certificate"subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid,issuer[ v3_ca ]# Расширения для типового УЦsubjectKeyIdentifier=hashauthorityKeyIdentifier=keyid:always,issuerbasicConstraints = CA:truekeyUsage = cRLSign, keyCertSign
Сейчас мы можем выпустить корневой сертификат удостоверяющего центра, подписав его закрытым ключом rootca.key. Так как это сертификат УЦ, используем расширение v3_ca :
# openssl req -sha256 -new -x509 -days 3650 -extensions v3_ca \ -key private/rootca.key -out certs/rootca.crt \ -subj /C=RU/ST=Moscow/L=Moscow/O=ExampleInc/OU=ITdept/CN=ca-server/emailAddress=support@example.com # chmod 444 certs/rootca.crt
В качестве алгоритма хэширования мы используем SHA-2 (подвид SHA-256). Стоимость атаки на SHA-1 стремительно падает, а о практическом применении новоявленного SHA-3 говорить пока рано. Почему мы выбрали именно SHA-256, а не SHA-512? С сертификатом, использующим SHA-512, Вы сможете запустить демон slapd, но не сможете к нему подключиться. Увидите лишь такую многозначную ошибку:
can't connect: A TLS packet with unexpected length was received.
- C — Country Name (страна) — RU
- ST — State or Province Name (штат или провинция) — Moscow
- L — Locality Name (город) — Moscow
- O — Organization Name (наименование организации) — ExampleInc
- OU — Organizational Unit Name (наименование подразделения) — ITdept
- CN — Common Name (имя субъекта или FQDN сервера) — ca-server
- emailAddress — Email Address (адрес электронной почты) — support@example.com
Можем посмотреть содержимое сертификата следующей командой:
# openssl x509 -in certs/rootca.crt -noout -text
Удостоверяющий центр готов к выпуску сертификатов.
3.2 Выпуск сертификата для сервера службы каталогов
Где работаем: ldap-srv
Как правило, закрытые ключи клиентов УЦ не должны хранится в самом УЦ. Клиент может сам сформировать ключевую пару и прислать в УЦ лишь запрос на подпись (Certificate Signing Request, CSR). Запрос содержит открытый ключ. Однако мы будем создавать все ключи и хранить их в одном месте. В организации, которая серьёзно подходит к проблемам безопасности такой процесс работы может быть неприемлемым.
Продолжаем в том же каталоге /root/CA. Создадим закрытый ключ для сервера службы каталогов:
# openssl genrsa -out private/ldap-srv.example.com.key 4096 # chmod 400 private/ldap-srv.example.com.key
Сгенерируем запрос на подпись сертификата. Наименование организации (ExampleInc) должно совпадать с наименованием в корневом сертификате УЦ. В качестве Common Name укажем FQDN нашего сервера:
# openssl req -sha256 -new \ -key private/ldap-srv.example.com.key -out certs/ldap-srv.example.com.csr \ -subj /C=RU/ST=Moscow/L=Moscow/O=ExampleInc/OU=ITdept/CN=ldap-srv.example.com/emailAddress=support@example.com
Следующим шагом должно быть подписание запроса CSR существующим доверенным удостоверяющим центром (например, VeriSign) в обмен на деньги. Но нам не хочется платить за эту услугу, или у нас нет своего (корпоративного) CA, или это просто тестовая конфигурация, а может нам просто всё равно. Поэтому мы подпишем его с помощью своего собственного CA:
# openssl ca -extensions usr_cert -notext -md sha256 \ -keyfile private/rootca.key -cert certs/rootca.crt \ -in certs/ldap-srv.example.com.csr -out certs/ldap-srv.example.com.crt # chmod 444 certs/ldap-srv.example.com.crt
Создадим каталог для ключевой информации нашего сервера и поместим туда получившиеся у нас файлы:
# mkdir /etc/ldap/ssl # chown openldap:openldap /etc/ldap/ssl # chmod 0500 /etc/ldap/ssl # cp certs/ldap-srv.example.com.crt private/ldap-srv.example.com.key /etc/ldap/ssl
Установим права доступа для ключевой информации:
# chown openldap:openldap /etc/ldap/ssl/ # chmod 0400 /etc/ldap/ssl/
Поместим корневой сертификат в каталог с сертификатами операционной системы и зададим для него права доступа:
# cp certs/rootca.crt /etc/ssl/certs/ # chmod 0644 /etc/ssl/certs/rootca.crt
В заключение можем удалить запрос CSR, он нам больше не нужен:
# rm -rf certs/ldap-srv.example.com.csr
Каталог /root/CA теперь выполняет роль удостоверяющего центра. Аналогичным образом его можно создать на другой машине, тогда надо будет копировать секретные ключи и подписанные сертификаты по сети с помощью scp или через съёмный носитель. Неплохой идеей будет хранить этот каталог на отдельном носителе и монтировать его только для выпуска новых сертификатов. Сам носитель можно, например, положить в сейф. Процесс создания новых пар ключ-сертификат в будущем будет состоять из трёх этапов:
- Генерация секретного ключа и запроса на подписание сертификата;
- Подписание сертификата с помощью закрытого ключа нашего CA (rootca.key);
- Перемещение новых секретного ключа и подписанного сертификата в каталоги, где они будут использоваться.
3.3 Настройка конфигурации TLS
Где работаем: ldap-srv
Вернёмся во временный каталог:
$ cd ~/ldap
Создадим LDIF-файл 3.2-tls-config.ldif для внесения в каталог конфигурации TLS и запишем в него:
dn: cn=configadd: olcTLSVerifyClientolcTLSVerifyClient: never-add: olcTLSCertificateFileolcTLSCertificateFile: /etc/ldap/ssl/ldap-srv.example.com.crt-add: olcTLSCertificateKeyFileolcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv.example.com.key-add: olcTLSCACertificateFileolcTLSCACertificateFile: /etc/ssl/certs/rootca.crt
Этими записи говорят демону slapd, где лежит его сертификат и ключ, где лежит корневой сертификат УЦ и что от клиентов требовать наличие сертификата не нужно. Чтобы окончательно всё запутать, мы могли бы создать сертификаты для всех клиентов. В реальной жизни такая аутентификация клиента принесёт небольшое усиление защиты за счёт большого увеличения работы по сопровождению всех этих сертификатов. Тем более далее в этом руководстве мы опишем механизмы аутентификации Kerberos.
Загрузим конфигурацию TLS в наш каталог:
# ldapmodify -QY EXTERNAL -H ldapi:/// -f 3.2-tls-config.ldif modifying entry "cn=config"
Теперь наш сервер OpenLDAP должен поддерживать расширения TLS. Перепроверим, что всё в порядке:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i tls olcTLSCertificateFile: /etc/ldap/ssl/ldap-srv.example.com.crt olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv.example.com.key olcTLSCACertificateFile: /etc/ssl/certs/rootca.crt olcTLSVerifyClient: never
Вновь отредактируем конфигурационный файл /etc/ldap/ldap.conf и включим поддержку TLS:
BASE dc=example,dc=comURI ldap://ldap-srv.example.comTLS_CACERT /etc/ssl/certs/rootca.crtTLS_REQCERT demandTIMELIMIT 15TIMEOUT 20
Обычно для конфигурации cn=config перезагрузка службы не требуется, но чтобы созданная нами ключевая информация подхватилась, придётся это сделать:
# service slapd restart * Stopping OpenLDAP slapd [ OK ] * Starting OpenLDAP slapd [ OK ]
Проверьте соединение с сервером с использованием TLS (модификатор -ZZ ). На этот раз мы выполним запрос с использованием DN нашего администратора:
$ ldapsearch -xZZLLLWD cn=admin,dc=example,dc=com -b cn=config -s base Enter LDAP Password: dn: cn=config objectClass: olcGlobal cn: config olcArgsFile: /var/run/slapd/slapd.args olcPidFile: /var/run/slapd/slapd.pid olcTLSCACertificateFile: /etc/ssl/certs/rootca.crt olcTLSCertificateFile: /etc/ldap/ssl/ldap-srv.example.com.crt olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv.example.com.key olcTLSVerifyClient: never
Обратите внимание, что в запросе ldapsearch нам не пришлось указывать имя хоста ( -H ldap://ldap-srv.example.com ). Всё потому что оно указано в файле /etc/ldap/ldap.conf. Что касается TLS, то во время инициирования соединения клиент (на данном этапе клиентский запрос выполняет сам сервер) получает от сервера его подписанный сертификат (ldap-srv.example.com.crt). Клиент может ничего не знать о сервере, но у него есть сертификат CA (rootca.crt), с помощью которого и проверяется сервер.
3.4 Создание CRL и отзыв сертификатов
Где работаем: ldap-srv
Сертификаты не вечны. Во-первых при создании задаётся его срок действия. При этом частота обновления сертификатов — баланс между безопасностью и удобством. Во-вторых он может быть скомпрометирован, если скомпрометирован его закрытый ключ. Как во втором случае оповестить субъектов доступа, что сертификат более не действителен? Для этого и служит Certificate Revocation List (CRL). Он представляет собой список серийных номеров отозванных сертификатов, подписанный УЦ, который их выпустил.
Вернёмся в каталог удостоверяющего центра:
# cd /root/CA
Прежде чем мы сможем сгенерировать CRL, надо создать файл crlnumber. Он нужен openssl, чтобы отслеживать номер следующего CRL:
# echo 1000 > crlnumber
В стандартной конфигурации openssl использует CRL V1. Раскомментируйте строку
crl_extensions = crl_ext
в /etc/ssl/openssl.cnf, чтобы переключиться на CRL V2. Это хорошая идея, за исключением тех случаев, когда надо использовать именно CRL V1 (например, при использовании сильно устаревшего браузера). Создаём CRL:
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -gencrl -out crl/rootca.crl
Посмотреть результат можно так:
# openssl crl -in crl/rootca.crl -text
Предположим, что закрытый ключ сервера ldap-srv был скомпрометирован. Чтобы оповестить об этом клиентские машины, надо отозвать сертификат этого сервера, создать CRL, а затем — распространить CRL среди клиентов.
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -revoke certs/ldap-srv.example.com.crt
Заглянем в index.txt. Начало записи с нашим сертификатом теперь изменилось с V на R :
# cat index.txt R 160116072355Z 150119081313Z 1000 unknown /C=RU/ST=Moscow/O=ExampleInc/OU=ITdept/CN=ldap-srv.example.com/emailAddress=support@example.com
Обратите внимание, что копии новых сертификатов так же содержатся в каталоге newcerts. При этом имя файла содержит серийный номер сертификата. Когда отзываете сертификаты, вместо файлов в каталоге certs Вы можете пользоваться каталогом newcerts. Результат будет идентичен. Например:
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -revoke newcerts/1000.pem
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -gencrl -out crl/rootca.crl
Взглянём на содержимое CRL:
# openssl crl -in crl/rootca.crl -text
Вы должны увидеть нечто подобное:
. Revoked Certificates: Serial Number: 1000 Revocation Date: .
Поместим CRL в каталог, где его увидит клиентское ПО:
# cp crl/rootca.crl /etc/ssl
Осталось только распространить этот CRL среди клиентов. Мы делаем это простым путём — копированием файлов по сети вручную.
Где работаем: ldap-client
На каждой клиентской машине надо будет запустиь:
# scp user@ldap-srv.example.com:/etc/ssl/certs/rootca.crt /etc/ssl/certs # scp user@ldap-srv.example.com:/etc/ssl/rootca.crl /etc/ssl/
Настроим клиентскую конфигурацию в /etc/ldap/ldap.conf и укажем, где хранится CRL:
BASE dc=example,dc=comURI ldap://ldap-srv.example.comTLS_CACERT /etc/ssl/certs/rootca.crtTLS_REQCERT demandTLS_CRLFILE /etc/ssl/rootca.crlTIMELIMIT 15TIMEOUT 20
И попробуем получить доступ к серверу каталогов:
$ ldapsearch -xZZLLLWD cn=admin,dc=example,dc=com -b cn=config -s base dn ldap_start_tls: Connect error (-11) additional info: (unknown error code)
Наш CRL работает. Но к slapd теперь не подключиться. Надо выпустить новый сертификат для сервера.
Где работаем: ldap-srv
Сделаем это простой последовательностью команд. Мы повторяем пройденное, комментарии излишни:
# cd /root/CA # openssl genrsa -out private/ldap-srv.example.com.key 4096 # chmod 400 private/ldap-srv.example.com.key # openssl req -sha256 -new \ -key private/ldap-srv.example.com.key -out certs/ldap-srv.example.com.csr \ -subj /C=RU/ST=Moscow/L=Moscow/O=ExampleInc/OU=ITdept/CN=ldap-srv.example.com/emailAddress=support@example.com # openssl ca -extensions usr_cert -notext -md sha256 \ -keyfile private/rootca.key -cert certs/rootca.crt \ -in certs/ldap-srv.example.com.csr -out certs/ldap-srv.example.com.crt # chmod 444 certs/ldap-srv.example.com.crt # cp certs/ldap-srv.example.com.crt private/ldap-srv.example.com.key /etc/ldap/ssl # chown openldap:openldap /etc/ldap/ssl/ # chmod 0400 /etc/ldap/ssl/
Перезупустим демон slapd и убедимся, что к серверу можно подключиться:
# service slapd restart $ ldapsearch -xZZLLLWD cn=admin,dc=example,dc=com -b cn=config -s base dn Enter LDAP Password: dn: cn=config
В целом по отзыву сертификатов. Иногда в реальных условиях лучше применить другой подход. Намного удобней, когда клиентские машины самостоятельно выясняют у сервера, действителен конкретный сертификат или нет. В выпускаемые сертификаты можно вносить запись CRL Distribution Points . Она заставит клиентов самих периодически скачивать новый CRL. Или можно использовать OCSP. Но эта тема выходит за рамки данного руководства.
OpenLDAP и Ubuntu на практике > Настройка TLS (Transport Layer Security)
Pro-LDAP.ru 2015 г. Последнее изменение страницы — 3 мая 2015 г. Вопросы и предложения принимаются на форуме проекта.
Использование SSL/TLS на vsftpd (Ubuntu)
Предупреждение: FTP по своей сути небезопасен! В большинстве случаев рекомендуется использовать SFTP вместо FTP.
Раньше FTP (или File Transfer Protocol – протокол передачи файлов) был очень популярным способом обмена файлами между локальным и удаленным компьютерами. Тем не менее, он небезопасен, потому его использование подвергает компьютер определенному риску.
При необходимости использовать именно FTP (вместо более безопасного SFTP, который для передачи файлов использует протокол SSH) его можно несколько обезопасить при помощи SSL.
Данное руководство демонстрирует, как настроить vsftpd для использования SSL-сертификатов на сервере Ubuntu 12.04.
Установка vsftpd
Сервер vsftpd можно получить из репозиториев Ubuntu по умолчанию. Чтобы установить его, наберите:
sudo apt-get install vsftpd
Теперь vsftpd установлен, можно приступить к его настройке.
Настройка основных функций
По умолчанию конфигурационный файл находится в /etc/vsftpd.conf. Откройте его с привилегиями root:
sudo nano /etc/vsftpd.conf
Отключите возможность входа в систему анонимно: найдите параметр anonymous_enable и измените его значение на “NO”:
Затем нужно позволить вход пользователям, использующим локальные файлы аутентификации, так как анонимный доступ отключен. Раскомментируйте данную строку:
Чтобы разрешить пользователям вносить изменения в файловую систему, раскомментируйте параметр:
Кроме того, необходимо раскомментировать опцию chroot_local_user, чтобы ограничить пользователей их домашними каталогами:
Сохраните изменения и закройте файл.
Создание FTP-пользователя
Поскольку vsftpd защищает все jail-ы chroot, chroot не должен принадлежать пользователю и не должен иметь право на изменение. Поэтому удобнее всего создать отдельного пользователя для работы с FTP.
Для этого наберите:
sudo adduser ftpuser
Установите пароль; на остальные извещения можно нажать ENTER. Теперь нужно передать root -привилегии домашнему каталогу пользователя ftpuser.
sudo chown root:root /home/ftpuser
Внутри этого домашнего каталога создайте отдельный каталог, в который можно выгрузить файлы. Затем передайте этот каталог пользователю FTP:
sudo mkdir /home/ftpuser/files
sudo chown ftpuser:ftpuser /home/ftpuser/files
Теперь можно установить (незащищенное) соединение как ftpuser и выгрузить файлы в каталог files.
Настройка SSL для работы с vsftpd
Теперь нужно создать сертификаты SSL, чтобы использовать их с vsftpd. Это делается так:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem
Это создаст сертификат, действительный на протяжении года. Он будет размещен в каталоге /etc/ssl/private/, который нужно добавить в конфигурационный файл.
Внесение SSL в конфигурации Vsftpd
Откройте конфигурационный файл с привилегиями root:
sudo nano /etc/vsftpd.conf
В нижней части файла найдите строку, соответствующую только что созданному сертификату SSL:
Под этой строкой нужно внести дополнительную информацию об SSL.
При создании сертификата ключевой файл и сертификат были помещены в один файл, поэтому можно указать строку закрытого ключа:
Затем нужно внести следующие строки, которые ограничат доступ клиентов к TLS.
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
Затем нужно настроить сервер на использование TLS (преемник SSL):
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
Чтобы расширить конфигурационный файл, необходимо внести дополнительные опции:
Сохранив изменения, закройте файл.
Затем перезапустите сервер, чтоб активировать внесенные изменения:
sudo service vsftpd restart
Подключение к серверу через FileZilla
Современные клиенты FTP могут использовать механизмы шифрования SSL и TLS. Ниже будет продемонстрировано, как установить подключение с помощью FileZilla (используя поперечные платформы).
Слева на конфигурационной панели найдите и нажмите кнопку, которая открывает “Site Manager”.
Затем нажмите на кнопку “New Site” в правом нижнем углу появившегося окна.
Введите IP-адрес. В поле “Encryption” разверните меню и выберите “Require explicit FTP over TLS”.
В поле “Logon Type” выберите “Ask for password”. В поле “User” укажите ранее созданного пользователя ftp.
Затем нажмите “Connect” в нижней части интерфейса, после чего введите пароль пользователя ftp.
На данном этапе нужно будет принять TLS-сертификат.
Готово! Теперь соединение с сервером с помощью механизма шифрования TLS/SSL установлено.
Итоги
Инструкции данного руководства помогут повысить защиту FTP; тем не менее, FTP по-прежнему имеет некоторые уязвимости при установлении соединения. Если это возможно, некоторые операции лучше выполнять по SFTP. В любом случае, при работе с FTP настоятельно рекомендуется использовать TLS/SSL.
Форум русскоязычного сообщества Ubuntu
Страница сгенерирована за 0.102 секунд. Запросов: 25.
- Сайт
- Об Ubuntu
- Скачать Ubuntu
- Семейство Ubuntu
- Новости
- Форум
- Помощь
- Правила
- Документация
- Пользовательская документация
- Официальная документация
- Семейство Ubuntu
- Материалы для загрузки
- Совместимость с оборудованием
- RSS лента
- Сообщество
- Наши проекты
- Местные сообщества
- Перевод Ubuntu
- Тестирование
- RSS лента
© 2012 Ubuntu-ru — Русскоязычное сообщество Ubuntu Linux.
© 2012 Canonical Ltd. Ubuntu и Canonical являются зарегистрированными торговыми знаками Canonical Ltd.
Настройка SSL/TLS для MySQL в Ubuntu 18.04
MySQL – самая популярная в мире реляционная система управления базами данных с открытым исходным кодом. Современные пакетные менеджеры упрощают запуск MySQL, однако после установки следует выполнить дополнительную настройку СУБД. В частности, это касается безопасности данных.
По умолчанию MySQL принимает только локальные соединения. Прежде чем настроить поддержку удалённых соединений, очень важно позаботиться о безопасности. Данный мануал поможет настроить MySQL на сервере Ubuntu 18.04 для поддержки удалённых соединений с помощью шифрования SSL/TLS.
Требования
Для работы вам понадобятся два сервера Ubuntu 18.04 (первый будет использоваться в качестве сервера MySQL, второй – в качестве клиента).
- Пользователь с доступом к sudo на каждом сервере.
- На сервере MySQL нужно серверное программное обеспечение СУБД. Инструкции по установке можно найти в мануале Установка MySQL в Ubuntu 18.04 (разделы 1-3). Также нужно обязательно создать root-пользователя MySQL с парольной аутентификацией. Это необходимо для подключения MySQL через TCP, а не по Unix сокету.
1: Проверка состояния SSL/TLS
Примечание: Этот раздел нужно выполнить на сервере MySQL.
Подключитесь к серверу MySQL и проверьте текущее состояние SSL/TLS.
Запустите сессию root-пользователя MySQL. Опция –р запрашивает пароль для входа. Опция –h позволяет указать хост, к которому нужно подключиться. В данном случае это loopback-интерфейс IPv4, или localhost. С его помощью клиент будет подключаться к TCP вместо локального сокета. MySQL пытается установить соединение через файл сокета Unix по умолчанию. Как правило, это быстрее и безопаснее, так как эти соединения можно создавать только локально и они не должны проходить все проверки и операции маршрутизации, которые проходят соединения TCP. Но TCP позволяет проверить статус SSL:
mysql -u root -p -h 127.0.0.1
По запросу введите root-пароль MySQL, после чего откроется интерактивная сессия.
Запросите состояние переменных SSL/TLS:
SHOW VARIABLES LIKE ‘%ssl%’;
+—————+———-+
| Variable_name | Value |
+—————+———-+
| have_openssl | DISABLED |
| have_ssl | DISABLED |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | |
+—————+———-+
9 rows in set (0.01 sec)
Переменные have_openssl и have_ssl отключены (отмечены DISABLED). Это значит, что сервер поддерживает функции SSL, но пока что шифрование не включено.
Проверьте состояние текущего соединения:
\s
—————
mysql Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using EditLine wrapper
Connection id: 9
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: »
Using delimiter: ;
Server version: 5.7.26-0ubuntu0.18.04.1 (Ubuntu)
Protocol version: 10
Connection: 127.0.0.1 via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 40 min 11 sec
Threads: 1 Questions: 33 Slow queries: 0 Opens: 113 Flush tables: 1 Open tables: 106 Queries per second avg: 0.013
—————
На данный момент подключение не использует SSL даже несмотря на то, что это TCP соединение.
Закройте текущую сессию:
2: Генерирование SSL/TLS-сертификатов и ключей
Примечание: Данный раздел также нужно выполнить на сервере MySQL.
Чтобы включить поддержку SSL в MySQL, сначала нужно создать соответствующий сертификат и ключ. Утилита mysql_ssl_rsa_setup, которая поставляется вместе с MySQL 5.7+, позволяет ускорить этот процесс. Версия MySQL, которую вы установили перед началом работы, поставляется с этой утилитой.
Процесс MySQL должен иметь возможность прочитать сгенерированные файлы, поэтому в качестве владельца этих файлов нужно указать пользователя mysql:
sudo mysql_ssl_rsa_setup —uid=mysql
При этом появится такой вывод:
Generating a 2048 bit RSA private key
.+++
. +++
writing new private key to ‘ca-key.pem’
——
Generating a 2048 bit RSA private key
. +++
. +++
writing new private key to ‘server-key.pem’
——
Generating a 2048 bit RSA private key
. +++
. +++
writing new private key to ‘client-key.pem’
——
Файлы будут созданы в каталоге данных MySQL, /var/lib/mysql. Проверьте созданные файлы:
sudo find /var/lib/mysql -name ‘*.pem’ -ls
258930 4 -rw-r—r— 1 mysql mysql 1107 May 3 16:43 /var/lib/mysql/client-cert.pem
258919 4 -rw-r—r— 1 mysql mysql 451 May 3 16:43 /var/lib/mysql/public_key.pem
258925 4 -rw——- 1 mysql mysql 1675 May 3 16:43 /var/lib/mysql/server-key.pem
258927 4 -rw-r—r— 1 mysql mysql 1107 May 3 16:43 /var/lib/mysql/server-cert.pem
258922 4 -rw——- 1 mysql mysql 1675 May 3 16:43 /var/lib/mysql/ca-key.pem
258928 4 -rw——- 1 mysql mysql 1675 May 3 16:43 /var/lib/mysql/client-key.pem
258924 4 -rw-r—r— 1 mysql mysql 1107 May 3 16:43 /var/lib/mysql/ca.pem
258918 4 -rw——- 1 mysql mysql 1679 May 3 16:43 /var/lib/mysql/private_key.pem
Эти файлы – ключи и сертификаты для центра сертификации (название файла начинается с «ca»), а также для сервера и клиента MySQL (файлы с названиями server и client соответственно). Файлы private_key.pem и public_key.pem используются MySQL для безопасной передачи паролей вне SSL.
3: Включение SSL на сервере MySQL
Современные версии MySQL при запуске сервера ищут файлы сертификатов в каталоге данных MySQL. Поэтому для включения поддержки SSL не нужно изменять конфигурацию MySQL.
Достаточно просто перезапустить сервис:
sudo systemctl restart mysql
После перезапуска откройте сессию MySQL. Клиент MySQL автоматически попытается подключиться через SSL, если сервер поддерживает такие изменения.
mysql -u root -p -h 127.0.0.1
Попробуйте снова запросить состояние переменных SSL, обратите внимание на значения переменных, которые имеют отношение к SSL:
SHOW VARIABLES LIKE ‘%ssl%’;
+—————+——————+
| Variable_name | Value |
+—————+——————+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | ca.pem |
| ssl_capath | |
| ssl_cert | server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | server-key.pem |
+—————+——————+
9 rows in set (0.00 sec)
Теперь вместо DISABLED переменные have_openssl и have_ssl имеют значение YES. Кроме того, теперь переменные ssl_ca, ssl_cert и ssl_key содержат имена соответствующих файлов.
Снова введите команду:
\s
—————
. . .
SSL: Cipher in use is DHE-RSA-AES256-SHA
. . .
Connection: 127.0.0.1 via TCP/IP
. . .
—————
На этот раз отображается специальный SSL-шифр, а это значит, что SSL используется для защиты соединения.
Вернитесь в оболочку:
Теперь сервер поддерживает шифрование данных.
4: Настройка защищенных подключений для удаленных клиентов
Теперь, когда сервер поддерживает SSL, можно начать настройку безопасного удаленного доступа. Для этого необходимо:
- Настроить удаленные подключения только по SSL.
- Настроить MySQL для прослушивания публичного интерфейса.
- Настроить брандмауэр для поддержки внешних подключений.
На данный момент сервер MySQL поддерживает SSL подключения от клиентов. Но он также поддерживает и незашифрованные удалённые соединения, а это опасно.
Чтобы исправить это, нужно включить опцию require_secure_transport, которая ограничивает удаленные соединения и поддерживает только SSL или соединения по локальному сокету Unix. Поскольку сокеты доступны только внутренним подключениям сервера, единственным способом подключения, доступным для удаленных пользователей, будет SSL.
Чтобы включить эту опцию, откройте файл /etc/mysql/my.cnf в текстовом редакторе:
sudo nano /etc/mysql/my.cnf
В файле вы увидите две директивы !includedir для ссылки на дополнительные конфигурационные файлы. Нужно разместить свои настройки под этими строками, чтобы они переопределяли конфликтующие настройки.
Создайте раздел [mysqld], чтобы определить процесс MySQL. Добавьте директиву require_secure_transport со значением ON.
. . .
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld] # Require clients to connect either using SSL
# or through a local socket file
require_secure_transport = ON
По умолчанию MySQL прослушивает только соединения, поступающие от 127.0.0.1. Это означает, что MySQL прослушивает только соединения от компьютера, на котором установлен сервер MySQL.
Чтобы разрешить MySQL прослушивать внешние подключения, вы должны настроить его на прослушивание подключений по внешнему IP-адресу. Чтобы сделать это, вы можете добавить параметр bind-address и указать 0.0.0.0 (IP-адрес, который представляет все IP-адреса). По сути, это заставит MySQL прослушивать соединения на каждом интерфейсе.
. . .
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld] # Require clients to connect either using SSL
# or through a local socket file
require_secure_transport = ON
bind-address = 0.0.0.0
Примечание: В качестве альтернативы вы можете установить внешний IP-адрес сервера MySQL. Но вам нужно будет обновить файл my.cnf, если вы перенесете свою базу данных на другой компьютер.
Сохраните и закройте файл.
Затем перезапустите MySQL, чтобы применить новые настройки:
sudo systemctl restart mysql
Убедитесь, что MySQL прослушивает 0.0.0.0 вместо 127.0.0.1.
sudo netstat -plunt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 13317/mysqld
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1293/sshd
tcp6 0 0 . 22 . * LISTEN 1293/sshd
Как видите, теперь MySQL прослушивает 0.0.0.0, а значит, поддерживает соединения на всех интерфейсах.
Теперь нужно открыть MySQL в брандмауэре ufw.
sudo ufw allow mysql
Rule added
Rule added (v6)
5: Настройка удаленного пользователя MySQL
Теперь сервер MySQL прослушивает удаленные соединения, но в настоящее время нет пользователей, которые могли бы подключаться с внешних машин.
Откройте сессию root-пользователя MySQL, чтобы создать удаленного пользователя:
Создайте нового удалённого пользователя с помощью команды CREATE USER (здесь мы назовем его mysql_user).
Используйте IP-адрес клиентского компьютера в качестве хоста нового пользователя, чтобы ограничить подключение к этой машине, замените password паролем вашего пользователя.
На случай если опция require_secure_transport будет отключена, добавьте REQUIRE SSL, чтобы ограничить пользователя только SSL-соединениями.
CREATE USER ‘mysql_user’@’your_mysql_client_IP’ IDENTIFIED BY ‘password’ REQUIRE SSL;
Затем предоставьте пользователю права на необходимые базы данных или таблицы. Для примера создайте базу данных example и передайте новому пользователю права на неё:
CREATE DATABASE example;
GRANT ALL ON example.* TO ‘mysql_user’@’your_mysql_client_IP’;
Затем очистите привилегии, чтобы обновить настройки БД:
Закройте оболочку MySQL:
Теперь нужно попробовать создать удаленное соединение.
Примечание: Дальнейшие действия нужно выполнить на клиенте MySQL.
Чтобы подтвердить, что вы можете успешно подключиться к MySQL, вам необходимо установить пакет mysql-client на клиент MySQL.
Подключитесь к клиенту MySQL:
Обновите индекс локальных пакетов:
sudo apt update
sudo apt install mysql-client
По запросу нажмите Enter.
Теперь убедитесь, что можете создать удалённое подключение к серверу. Опция –u указывает удалённого пользователя, -h задаёт IP-адрес MySQL.
mysql -u mysql_user -p -h your_mysql_server_IP
Предоставьте пароль указанного в команде пользователя, после чего вы подключитесь к удалённому серверу.
Убедитесь, что подключение шифруется:
\s
—————
. . .
SSL: Cipher in use is DHE-RSA-AES256-SHA
. . .
Connection: your_mysql_server_IP via TCP/IP
. . .
—————
Вернитесь в оболочку системы:
Вы подтвердили, что можете подключиться к MySQL через SSL. Однако вы еще не убедились, что сервер MySQL сбрасывает небезопасные соединения. Чтобы проверить это, попробуйте подключиться еще раз, но на этот раз добавьте к команде login опцию –ssl-mode=disabled. Она позволит команде попытаться создать незашифрованное соединение:
mysql -u mysql_user -p -h mysql_server_IP —ssl-mode=disabled
После запроса пароля соединение будет сброшено:
ERROR 1045 (28000): Access denied for user ‘mysql_user’@’mysql_server_IP’ (using password: YES)
Как видите, сервером поддерживаются только SSL-соединения, а незашифрованные соединения сбрасываются.
На данный момент сервер MySQL поддерживает безопасные удалённые подключения. В целом, этого достаточно для безопасности данных, но есть и некоторые дополнительные рекомендации, которые можно использовать.
6: Настройка валидации подключений MySQL (опционально)
В настоящее время сервер MySQL использует SSL-сертификат, подписанный сгенерированным на локальной машине центром сертификации (CA). Сертификата сервера и пары ключей будет достаточно для шифрования входящих соединений.
ЦС может также подтвердить подлинность сервера или клиента, но на данный момент эта функция не используется. Создайте сертификат CA и ключи для клиентов, и тогда обе стороны смогут предоставить сертификаты, подписанные доверенным центром и подтверждающие их подлинность. Это предотвратит подделку соединений вредоносными серверами.
Чтобы настроить проверку подлинности, нужно:
- Передать соответствующие файлы SSL на клиентский компьютер.
- Создать конфигурационный файл клиента.
- Откорректировать параметры удаленного пользователя и настроить запрос доверенного сертификата.
Примечание: Процесс передачи сертификатов и клиентского ключа клиенту MySQL, описанный далее, включает отображение содержимого каждого файла с помощью команды cat, копирование этого содержимого в буфер обмена и вставку его в новый файл на клиентской машине. Эти файлы можно скопировать напрямую с помощью таких программ, как scp или sftp, но для этого необходимо настроить для обоих серверов ключи SSH, чтобы они могли обмениваться данными.
Наша цель – свести к минимуму количество возможных путей подключения к вашему серверу MySQL. Описанный ниже процесс немного более трудоемкий, чем прямая передача файлов, но он безопасен и не требует SSH-соединения между двумя компьютерами.
В домашнем каталоге создайте каталог для хранения сертификатов, client-ssl.
Ключ сертификата нужно хранить в секрете. Ограничьте доступ к каталогу, в котором хранится ключ.
chmod 700 ~/client-ssl
Теперь права доступа есть только у текущего пользователя.
Перейдите на сервер MySQL и отобразите содержимое следующего файла:
sudo cat /var/lib/mysql/ca.pem
——BEGIN CERTIFICATE——
. . .
——END CERTIFICATE——
Скопируйте весь результат (включая строки BEGIN CERTIFICATE и END CERTIFICATE).
Вернитесь на клиентскую машину MySQL, создайте файл в каталоге для сертификатов:
Вставьте в него скопированный сертификат. Сохраните и закройте файл.
Вернитесь на сервер MySQL и отобразите содержимое этого файла:
sudo cat /var/lib/mysql/client-cert.pem
——BEGIN CERTIFICATE——
. . .
——END CERTIFICATE——
Снова скопируйте весь результат (включая строки BEGIN CERTIFICATE и END CERTIFICATE).
Перейдите на клиентскую машину MySQL и создайте файл в каталоге для сертификатов:
Вставьте в него скопированный сертификат. Сохраните и закройте файл.
Снова вернитесь на сервер MySQL и отобразите содержимое следующего файла:
sudo cat /var/lib/mysql/client-key.pem
——BEGIN RSA PRIVATE KEY——
. . .
——END RSA PRIVATE KEY——
Скопируйте полученный результат, включая строки BEGIN CERTIFICATE и END CERTIFICATE.
Вернитесь на клиент MySQL, создайте файл в этом каталоге:
В этот файл вставьте скопированные данные, сохраните и закройте файл.
В настоящее время клиент MySQL имеет все необходимые файлы сертификата, которые можно использовать при подключении к серверу. Однако сервер еще не поддерживает сертификаты клиента.
Перейдите на сервер MySQL. Откройте сессию пользователя root в MySQL:
Измените параметры удалённого пользователя. Вместо REQUIRE SSL укажите REQUIRE X509. Теперь кроме обязательного SSL-соединения сервер будет запрашивать у удалённого пользователя сертификат, подписанный ЦС, которому доверяет сервер MySQL.
Чтобы изменить параметры пользователя, введите:
ALTER USER ‘mysql_user’@’mysql_client_IP’ REQUIRE X509;
Вернитесь в стандартную оболочку:
Теперь нужно убедиться, что сервер запрашивает сертификат у клиента.
Перейдите на клиент MySQL и попробуйте создать соединение без сертификата.
mysql -u mysql_user -p -h mysql_server_IP
ERROR 1045 (28000): Access denied for user ‘mysql_user’@’mysql_client_IP’ (using password: YES)
Как и ожидалось, без сертификата клиент не сможет создать удалённое подключение.
Теперь добавьте в команду опции –ssl-ca, –ssl-cert и –ssl-key, в которых нужно указать путь к соответствующим файлам:
mysql -u mysql_user -p -h mysql_server_IP —ssl-ca=~/client-ssl/ca.pem —ssl-cert=~/client-ssl/client-cert.pem —ssl-key=~/client-ssl/client-key.pem
Сервер должен принять такое подключение. Закройте MySQL:
Чтобы не перечислять файлы сертификатов при каждом подключении, можно создать простой конфигурационный файл клиента MySQL.
Подключитесь к клиенту MySQL. Откройте домашний каталог и создайте в нём скрытый файл ~/.my.cnf:
Добавьте в файл раздел [client]. В нём можно указать опции ssl-ca, ssl-cert и ssl-key со всеми путями к соответствующим файлам.
[client] ssl-ca = ~/client-ssl/ca.pem
ssl-cert = ~/client-ssl/client-cert.pem
ssl-key = ~/client-ssl/client-key.pem
Опция ssl-ca проверяет сертификат сервера MySQL и подтверждает, что он подписан ЦС, которому можно доверять.
Опции ssl-cert и ssl-key указывают пути к файлам, которые позволяют подтвердить подлинность сертификата.
Сохраните и закройте файл.
Попробуйте подключиться к серверу MySQL, не добавляя в команду опции –ssl-ca, –ssl-cert и –ssl-key.
mysql -u remote_user -p -h mysql_server_ip
Теперь клиент и сервер могут подтвердить свою подлинность.