Сегодняшняя заметка есть небольшая шпаргалка для самого себя, как настроить базовую безопасность для сервисов комплекта LAMP на Ubuntu Xenial Server. К примеру обезопасить подключение к MySQL только тем пользователям у которых есть соответствующие SSL сертификаты дабы ни кто попало мог подключиться к систему. Но я не спорю что это не полный список, а лишь малая часть по защите системы. Я в повседневности и в своих проектах использую только самолично настроенное на VPS, а не только сервис в пользование. Я доверяю только себе и своему опыту. Ладно начну пожалуй…
Шаг №1:
ekzorchik@srv-xenial:~$ sudo tasksel install lamp-server
New password for the MySQL "root" user: 712mbddr@
Repeat password for the MySQL "root" user: 712mbddr@
ekzorchik@srv-xenial:~$ sudo apache2 -v
Server version: Apache/2.4.18 (Ubuntu)
ekzorchik@srv-xenial:~$ sudo php --version
PHP 7.0.22-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.22-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies
ekzorchik@srv-xenial:~$ mysql --version
mysql Ver 14.14 Distrib 5.7.19, for Linux (x86_64) using EditLine wrapper
Шаг №2:
ekzorchik@srv-xenial:~$ sudo mysql_secure_installation
Enter password for user root: 712mbddr@
Press y|Y for Yes, any other key for No: N (если указать y|Y то запуститься сценарий валидации пароля)
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Шаг №3:
По умолчанию сервис ожидает подключения к MySQL только локально, если в Ваших проектах нужно чтобы можно было подключаться с удаленных системе, то:
ekzorchik@srv-xenial:~$ ip r | awk '{print $9}'
10.9.9.129
ekzorchik@srv-xenial:~$ sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
#bind-address = 127.0.0.1
bind-address = 0.0.0.0
Шаг №4:
Для настройки шифрования передаваемых данных между этой системой и удаленной нужно использовать шифрование:
ekzorchik@srv-xenial:~$ sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
require_secure_transport = ON
ekzorchik@srv-xenial:~$ 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'
После проверяю, а создались ли файлы ключей:
ekzorchik@srv-xenial:~$ sudo find /var/lib/mysql -name '*.pem' -ls
Шаг №5:
Копирую клиентские ключи на удаленную систему:
ekzorchik@srv-xenial:~$ sudo scp /var/lib/mysql/ca.pem aollo@10.9.9.254:/home/aollo
ekzorchik@srv-xenial:~$ sudo scp /var/lib/mysql/client-cert.pem aollo@10.9.9.254:/home/aollo
ekzorchik@srv-xenial:~$ sudo scp /var/lib/mysql/client-key.pem aollo@10.9.9.254:/home/aollo
затем на удаленной системе:
aollo@work:~$ mkdir ~/client-ssl
aollo@work:~$ sudo mv client-*.pem ~/client-ssl/
aollo@work:~$ sudo mv ca.pem ~/client-ssl/
ekzorchik@srv-xenial:~$ sudo service mysql restart
ekzorchik@srv-xenial:~$ sudo netstat -tulpn | grep mysqld
tcp 0 0 10.9.9.129:3306 0.0.0.0:* LISTEN 13064/mysqld
(если бы параметр bind_address не был бы изменен, то значилось только 127.0.0.1:3306)
Шаг №6:
Т.к. ранее я запретил удаленное подключение под учетной записью root сервиса mysql на системе Ubuntu 16.04 (Ubuntu Xenial), то значит нужно создать пользователя и дать ему права под которым можно будет подключиться с удаленной системы:
ekzorchik@srv-xenial:~$ mysql -u root -p712mbddr@
Отобразить текущую политику установки паролей для пользователей mysql:
mysql> show variables like 'validate_password%';
+--------------------------------------+--------+
| Variable_name | Value |
+--------------------------------------+--------+
| validate_password_check_user_name | OFF |
| validate_password_dictionary_file | |
| validate_password_length | 8 |
| validate_password_mixed_case_count | 1 |
| validate_password_number_count | 1 |
| validate_password_policy | MEDIUM |
| validate_password_special_char_count | 1 |
+--------------------------------------+--------+
7 rows in set (0.01 sec)
mysql> use mysql
mysql> create user 'ekzorchik'@'%' identified by 'Aa1234567@!' require x509;
Query OK, 0 rows affected (0.00 sec)
На заметку: а можно принудительно задать уже после, что данный пользователь может подключаться только с использованием SSL или только если у него есть публичный ключ x509:
mysql> alter user 'ekzorchik'@'%' require ssl;
mysql> alter user 'ekzorchik'@'%' require x509
отменить использование SSL:
mysql> alter user 'ekzorchik'@'%';
mysql> grant all privileges on *.* to 'ekzorchik'@'%';
→ по сути это еще один администратор, но правильнее указывать на конкретную базу данных собственного администратора.
mysql> flush privileges;
mysql> 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)
На заметку: Если переменные have_openssl и have_ssl помечены как DISABLED. Это означает, что функциональность SSL собран в сервере, но еще не включена, у меня значения YES значит все включено.
Шаг №7:
Отобразить заведенных пользователей в сервисе MySQL:
ekzorchik@srv-xenial:~$ mysql -u root -p712mbddr@
mysql> use mysql;
mysql> select User,Host from mysql.user;
mysql> drop user 'test'@'%'; (или что у Вас написано)
mysql> flush privileges;
Проверить текущее состоянии подключения к сессии можно:
mysql> \s
Current user: root@localhost
SSL: Not in use
Connection: Localhost via UNIX socket
mysql> quit
Bye
На заметку: если в bind-address = указан IP, то можно при создании пользователя использовать символ процента как звездочка при использовании всех комбинации соответствующего октета, так и просто со всех адресов: 'user'@'%'
Шаг №8:
Проверяю, а могу ли я теперь с удаленной системы (Ubuntu Trusty Desktop amd64 Gnome Classic) подключиться к этой где развернут сервис mysql (Ubuntu 16.03, Ubuntu Xenial Server):
aollo@work:~$ sudo apt-get install mysql-client -y
aollo@work:~$ mysql --version
mysql Ver 14.14 Distrib 5.5.57, for debian-linux-gnu (x86_64) using readline 6.3
aollo@work:~$ mysql -u ekzorchik -pAa1234567@! -h 10.9.9.129
ERROR 1045 (28000): Access denied for user 'ekzorchik'@'10.9.9.254' (using password: YES)
А если указать файлы клиентских сертификатов которые я скопировал с серверной части на эту систему:
aollo@work:~$ mysql -u ekzorchik -pAa1234567@! -h 10.9.9.129 --ssl=ca=~/client-ssl/ca.pem --ssl-cert=~/client-ssl/client-cert.pem --ssl-key=~/client-ssl/client-key.pem
mysql> \s
--------------
mysql Ver 14.14 Distrib 5.5.57, for debian-linux-gnu (x86_64) using readline 6.3
Connection id: 11
Current database:
Current user: ekzorchik@10.9.9.254
SSL: Cipher in use is DHE-RSA-AES256-SHA
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.7.19-0ubuntu0.16.04.1 (Ubuntu)
Protocol version: 10
Connection: 10.9.9.129 via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 37 min 1 sec
Threads: 2 Questions: 44 Slow queries: 0 Opens: 140 Flush tables: 1 Open tables: 52 Queries per second avg: 0.019
Шаг №9:
Дабы в строке подключения не указывать месторасположение файлов SSL, можно один раз добавить в клиентскую настройку и после подключение уже будет само заниматься что и откуда подставлять:
aollo@work:~$ sudo nano /etc/mysql/my.cnf
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
ssl-ca = /home/aollo/client-ssl/ca.pem
ssl-cert = /home/aollo/client-ssl/client-cert.pem
ssl-key = /home/aollo/client-ssl/client-key.pem
aollo@work:~$ mysql -u ekzorchik -pAa1234567@! -h 10.9.9.129
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 5.7.19-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Работает. Теперь подключение к сервису MySQL есть только у пользователей у которых есть файлы SSL.
Шаг №10:
После не забывает добавить/включить правило на удаленное подключение к серверу в брандмауэере:
ekzorchik@srv-xenial:~$ sudo ufw allow mysql
ekzorchik@srv-xenial:~$ sudo ufw status
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
3306 ALLOW Anywhere
Шаг №11:
Теперь настройки по безопасности Apache2:
ekzorchik@srv-xenial:~$ sudo rm /etc/apache2/sites-available/000-default.conf
ekzorchik@srv-xenial:~$ sudo rm /etc/apache2/sites-available/default-ssl.conf
ekzorchik@srv-xenial:~$ sudo rm /etc/apache2/sites-enabled/000-default.conf
ekzorchik@srv-xenial:~$ sudo nano /etc/apache2/conf-enabled/security.conf
ServerTokens Prod
ServerSignature Off
TraceEnable Off
ekzorchik@srv-xenial:~$ sudo rm /var/www/html/index.html
ekzorchik@srv-xenial:~$ sudo ufw allow http
Rule added
- Использовать безопасный доступ к сайту задействовав https префикс, не важно самоподписанный сертификат или купленный лицензионный.
- Установить ModSecurity для защиты Apache2
- Установить модуль mod_evasive Для защиты от Ddos атак
- Поставить брандмауэр ufw с политикой все запрещено кроме разрешенного
Указывать все возможные способы защиты сервисов и приводить их вот здесь я считаю излишним, каждый должен прийти самим что и как ему закрывать и настраивать безопасность, а не действовать по шаблону. Ведь то что опубликовано в интернете не есть 100% защита, а лишь меры на что обратить внимание при защите. Важно все настраивать самим и учиться при этом, как я к примеру. На этом у меня всё, с уважением автор блога Олло Александр aka ekzorchik.