Первый:
Сценарий: я пытаюсь создать простое решение для мониторинга, чтобы следить за некоторыми аспектами набора из сотни или около того машин, находящихся под моим контролем (и, вероятно, их число в ближайшем будущем увеличится); От меня требуется иметь возможность создавать отчеты для системы безопасности, например, предоставлять им версии пакетов, чтобы доказать, что недавно обнаруженные уязвимости были исправлены на x из y машин.
Я мог бы получить эту информацию в реальном времени с помощью Ansible et al, но а) нет гарантии, что все машины будут подключены в любой момент времени, и б) инструменты управления могут дать мне текущий статус, но не обязательно исторические данные, которые мне могут понадобиться докладывать. Таким образом, с моей точки зрения, решение - это база данных, в которой могут храниться записи для каждой системы; когда система обновляется, мы добавляем новую запись в базу данных, указывающую на изменение, и затем я могу вывести ее позже.
Для этого мы используем базу данных MySQL. В настоящее время у нас есть простая, базовая установка MySQL с созданным небольшим набором таблиц и определенным одним пользователем без полномочий root. Список пользователей, определенный в MySQL:
select user, host, authentication_string from mysql.user;
+-------------+-----------+-------------------------------------------+
| user | host | authentication_string |
+-------------+-----------+-------------------------------------------+
| root | localhost | *D971D136A477A4C205AEF706... |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDT... |
| pkg_manager | localhost | *E91158E2E26F343D6639E4BD... |
+-------------+-----------+-------------------------------------------+
Таким образом, нет пустых строковых имен пользователей.
Рассматриваемая проблемная учетная запись - это учетная запись pkg_manager. Предоставьте разрешения на это:
mysql> show grants for 'pkg_manager'@'localhost';
+-------------------------------------------------------------------------------------+
| Grants for pkg_manager@localhost |
+-------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'pkg_manager'@'localhost' |
| GRANT SELECT, INSERT ON `panopticon`.`package` TO 'pkg_manager'@'localhost' |
| GRANT SELECT, INSERT ON `panopticon`.`package_history` TO 'pkg_manager'@'localhost' |
+-------------------------------------------------------------------------------------+
Учетная запись pkg_manager подключается без проблем, используя командную строку, например:
[~]$ mysql -u pkg_manager -p --database=panopticon
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.13 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, 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>
Однако мне нужно разрешить автоматическому инструменту входить в базу данных (он будет извлекать список систем, которые в настоящее время не обновлены, проверять, какие из них в настоящее время подключены, а затем отправлять обновления для них и записывать каждую успешное обновление.) Инструмент будет написан на Python, и я отключил коннектор Python 2.1.3.
Мы создали файл options.cnf для инструмента и сохранили его в ограниченном каталоге (изначально root: root 0700, в настоящее время:. Начальные тесты открытия соединения в python через соединитель с помощью:
connection = mysql.connector.connect(option_files='/path/to/options.cnf')
привело к ошибке 1045, сообщение SQLState 28000. (На самом деле, сначала было несколько других вещей, в основном связанных с указанием пути к сокету. Однако они очищены, и мы знаем, что они не мешают, потому что теперь журнал MySQL сообщает о неудачных попытках подключения.)
Мы знаем, что это частично работает, потому что полная информация об ошибке 1045: «Доступ запрещен для пользователя 'pkg_manager' @ 'localhost' (с использованием пароля: ДА)». Таким образом, он читает файл параметров, идентифицирует учетную запись pkg_manager и видит запись пароля в файле (если пароль отсутствует, конец сообщения становится «(с использованием пароля: НЕТ)».
Затем мы попытались упростить проблему, используя тот же файл параметров и создав в нем клиентский раздел, указав все те же поля, которые присутствуют в разделе connector_python. Это тоже не удалось:
mysql --defaults-file="/path/to/options.cnf"
Однако мы знали, что учетная запись работает, когда вручную указывали данные для входа в командную строку, как показано выше.
После многих часов поиска пользовательского опыта с ошибками входа в систему мы решили попробовать гибридный подход - вход в командную строку с использованием файла --defaults, но также с указанием -p, чтобы заставить нас ввести пароль в командной строке:
[~]$ mysql --defaults-file="/etc/pkg_manager/db_info/options.cnf" -p
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
Итак, мы знаем, что остальная информация, представленная в файле настроек, верна. Простой запуск mysql --print-defaults (чтобы определить, есть ли в списке поиска пути какие-либо другие файлы параметров, которые могут мешать) приводит к нулевым параметрам запуска в списке, поэтому нет других вариантов, которые могли бы помешать.
И на этом я в значительной степени застрял. Официальная документация MySQL прямо заявляет, что вы можете хранить пароли в незашифрованном виде в файле параметров в дополнение к зашифрованному локальному файлу входа в систему: http://dev.mysql.com/doc/refman/5.7/en/password-security-user.html
Но очевидно, что это не работает. Я просмотрел список переменных файла конфигурации, которые можно установить, и не вижу ничего, что могло бы помешать аутентификации пароля из файла параметров. Я увеличил регистрацию ошибок до 3, но никаких подробностей о проблемах с подключением не представлено, кроме однострочного примечания, указывающего на то, что попытка подключения от 'pkg_manager' @ 'localhost' была отклонена.
Пока не забыл, вот файл параметров (без пароля):
1 # Options file for pkg_manager, easy way to "securely" store database login info.
2 [connector_python]
3 user="pkg_manager"
4 password="*********"
5 database="panopticon"
6 host="localhost"
7 unix_socket="/var/lib/mysql/mysql.sock"
8
9 [client]
10 user="pkg_manager"
11 password="*********"
12 database="panopticon"
13 host="localhost"
14 socket="/var/lib/mysql/mysql.sock"
А вот файл /etc/my.cnf:
1 # For advice on how to change settings please see
2 # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
3
4 [mysqld]
5 #
6 # Remove leading # and set to the amount of RAM for the most important data
7 # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
8 # innodb_buffer_pool_size = 128M
9 #
10 # Remove leading # to turn on a very important data integrity option: logging
11 # changes to the binary log between backups.
12 # log_bin
13 #
14 # Remove leading # to set options mainly useful for reporting servers.
15 # The server defaults are faster for transactions and fast SELECTs.
16 # Adjust sizes as needed, experiment to find the optimal values.
17 # join_buffer_size = 128M
18 # sort_buffer_size = 2M
19 # read_rnd_buffer_size = 2M
20 datadir=/data/panopticon
21 socket=/var/lib/mysql/mysql.sock
22
23 skip-networking
24
25 # Disabling symbolic-links is recommended to prevent assorted security risks
26 symbolic-links=0
27
28 log-error=/var/log/mysqld.log
29 log_error_verbosity=3
30 general-log=1
31 general_log_file=/var/log/mysql_general.log
32 pid-file=/var/run/mysqld/mysqld.pid
Наконец-то у меня появилась возможность потратить еще несколько часов на изучение проблемы, и я нашел решение. Как я понял, это очень просто, но это также противоречит советам, опубликованным на нескольких форумах пользователей и даже в справочной документации MySQL.
Если мой пароль сохранен в файле опций в кавычках, он не сможет подключиться. Когда я удаляю кавычки из пароля, он подключается. В итоге я просмотрел код соединителя Python, прежде чем понял это, в основном потому, что я пытался удалить кавычки в пароле ранее, но из-за немного другой проблемы, а затем в моем сознании эти две проблемы немного смешались.
Я заметил, просматривая код соединителя Python, что могу напрямую создать экземпляр парсера файла параметров, поэтому я попробовал (передав путь к моему файлу параметров в качестве параметра). Когда я это сделал, я увидел, что все параметры, включая пароль, были импортированы в состояние парсера с любыми цитатами, которые у них были в файле. Однако ни на одном этапе после этого не были предприняты шаги по удалению кавычек из пароля (по крайней мере, что я видел), поэтому кажется вероятным, что, когда соединитель открывает файл параметров с анализатором, кавычки включаются и передаются в сервер для аутентификации как часть пароля.
Скорее всего, я приму это как отчет об ошибке для разработчиков MySQL, так как все остальные варианты отлично работают с кавычками.