В нашей команде появилась необходимость организовать хранение и подключения в общую базу. Устали от ситуации, что каждый делает свой конфиг.
Будем делать общую базу на Centos 7 + MariaDB.
Хоть и запись получилась, как портянка, но в ней ничего сложного и трудного. Правда, пришлось повозиться, т.к. продукт ещё сыроватый, в документации встречаются косяки.
Содержание
Подготовка Centos
Обновления и пару утилит
Вся статья делается на голом Centos’e и вся настройка производиться с 0. Поэтому нам надо подготовить сервер.
Начинаем с обновления системы.
1 | sudo yum update |
Так же я сразу добавляю mc, уж очень мне нравится :)
1 | yum install mc -y |
Ещё я себе ставлю Nano т.к. просто привык к нему во времена учёбы.
1 | yum install nano -y |
Установка MariaDB
Для того, чтобы поставить последнею версию нам надо добавить официальный репозиторий. Переходим на сайт разработчика. Выбираем нужные параметры и получаем готовый код. Нам осталось только подключить репозиторий.
Создаем файл MariaDB.repo по пути /etc/yum.repos.d/
1 | nano /etc/yum.repos.d/MariaDB.repo |
И вставляем в него код, который даёт нам разработчик.
1 2 3 4 5 6 7 | # MariaDB 10.4 CentOS repository list - created 2021-01-26 20:00 UTC # http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.4/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1 |
У меня были какие-то проблемы с установкой версии 10.5, поэтому я поставить 10.4
Запускаем установку.
1 | yum install MariaDB-server MariaDB-client |
После установки запускаем и добавляем в автозагрузку
1 2 | systemctl start mariadb systemctl enable mariadb |
Проверяем, что всё стартануло.
1 | systemctl status mariadb |
Примерный вывод.
1 2 3 4 5 6 7 8 9 10 11 | mariadb.service - MariaDB 10.4.17 database server Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/mariadb.service.d └─migrated-from-my.cnf-settings.conf Active: active (running) since Tue 2021-01-26 20:04:41 UTC; 1min 2s ago Docs: man:mysqld(8) https://mariadb.com/kb/en/library/systemd/ Main PID: 27630 (mysqld) Status: "Taking your SQL requests now..." CGroup: /system.slice/mariadb.service └─27630 /usr/sbin/mysqld |
Дальше нам необходимо настроить базовую защиту. Выполняем команду:
1 | mysql_secure_installation |
- Задать пароль для пользователя root (по умолчанию его нет)1234567891011121314151617181920212223242526272829NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDBSERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!In order to log into MariaDB to secure it, we'll need the currentpassword for the root user. If you've just installed MariaDB, andhaven't set the root password yet, you should just press enter here.Enter current password for root (enter for none):OK, successfully used password, moving on...Setting the root password or using the unix_socket ensures that nobodycan log into the MariaDB root user without the proper authorisation.You already have your root account protected, so you can safely answer 'n'.Switch to unix_socket authentication [Y/n] yEnabled successfully!Reloading privilege tables..... Success!You already have your root account protected, so you can safely answer 'n'.Change the root password? [Y/n] yNew password:Re-enter new password:Password updated successfully!Reloading privilege tables..... Success!
- Удаляем анонимных пользователей12Remove anonymous users? [Y/n] y... Success!
- Запрещаем удаленный вход под root’ом12345Normally, root should only be allowed to connect from 'localhost'. Thisensures that someone cannot guess at the root password from the network.Disallow root login remotely? [Y/n] y... Success!
- Удаляем тестовые таблицы123456789By default, MariaDB comes with a database named 'test' that anyone canaccess. This is also intended only for testing, and should be removedbefore moving into a production environment.Remove test database and access to it? [Y/n] y- Dropping test database...... Success!- Removing privileges on test database...... Success!
- Обновляем таблицу привилегий12345Reloading the privilege tables will ensure that all changes made so farwill take effect immediately.Reload privilege tables now? [Y/n] y... Success!
После выполнения этих шагов должно выйти сообщение о том, всё прошло удачно.
1 2 3 4 5 6 | Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB! |
И небольшой тюнинг работы MariaDB, взятая с просторов интернета, которая мне очень нравится. Также в этом конфиге исправлена проблема с кодировкой.
Кириллица превращалась в вопросительные знаки.
1 | nano /etc/my.cnf |
И приводим к виду
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | [mysqld] local-infile=0 datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 max_allowed_packet = 128M sql_mode = "" log-error = /var/log/mysql-error.log # Cache parameters query_cache_size = 16M table_open_cache = 4096 thread_cache_size = 16 key_buffer_size = 8M thread_stack = 256K join_buffer_size = 2M sort_buffer_size = 2M # Parameters for temporary tables tmpdir = /tmp max_heap_table_size = 32M tmp_table_size = 32M # InnoDB parameters innodb_file_per_table innodb_buffer_pool_size = 32M innodb_flush_log_at_trx_commit = 2 innodb_flush_method = O_DIRECT innodb_use_native_aio = 0 transaction-isolation = READ-COMMITTED character-set-server = utf8 collation-server = utf8_unicode_ci init-connect = "SET NAMES utf8 COLLATE utf8_unicode_ci" skip-name-resolve [mysqldump] quick quote-names max_allowed_packet = 128M default-character-set = utf8 [mysql] [isamchk] key_buffer = 16M [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid [client] default-character-set=utf8 |
Перезапускаем MariaDB.
1 | systemctl restart mysql |
Установка PhpMyAdmin
Для удобства администрирования базы поставим phpmyadmin. Он не обязателен, всё можно сделать из консоли. Ну и, конечно, нам нужен веб-сервер, возьмём Apache и php поставим, куда без него? :)
Установим Apache
1 | sudo yum install httpd -y |
После установки включаем Apache
1 | sudo systemctl start httpd.service |
Переходим по адресу http://ip-адрес-сервера/. Примерная картинка:
Установим php
1 | sudo yum install php php-mysql -y |
Перезапускаем Apache, чтобы он заработал с php.
1 | sudo systemctl restart httpd.service |
Устанавливаем сам phpmyadmin
1 | yum install phpmyadmin -y |
Сделаем бэкап оригинального конфига.
1 | cp /etc/httpd/conf.d/phpMyAdmin.conf /etc/httpd/conf.d/phpMyAdmin.conf.backup |
В стандартном конфиге подключения к phpmyadmin разрешены только с localhost или же 127.0.0.1, надо это поправить. Открываем конфиг и приводим к виду.
1 | nano /etc/httpd/conf.d/phpMyAdmin.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | Alias /phpMyAdmin /usr/share/phpMyAdmin Alias /phpmyadmin /usr/share/phpMyAdmin <Directory /usr/share/phpMyAdmin/> AddDefaultCharset UTF-8 Require all granted </Directory> <Directory /usr/share/phpMyAdmin/setup/> Require all granted </Directory> <Directory /usr/share/phpMyAdmin/libraries/> Order Deny,Allow Deny from All Allow from None </Directory> <Directory /usr/share/phpMyAdmin/setup/lib/> Order Deny,Allow Deny from All Allow from None </Directory> <Directory /usr/share/phpMyAdmin/setup/frames/> Order Deny,Allow Deny from All Allow from None </Directory> |
После этого перезапускаем Apache.
1 | systemctl restart httpd |
И пробуем зайти http://ip-адрес-сервера/phpmyadmin
Создание базы
Логинимся на phpmyadmin. Переходим в «Создать БД». Заполняем поля:
Имя: mRemoteNG
Кодировка: urf8_general_ci
Далее переходим в раздел SQL и копируем скрипт, который ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `tblCons` -- DROP TABLE IF EXISTS `tblCons`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `tblCons` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `ConstantID` varchar(128) DEFAULT NULL, `PositionID` int(11) NOT NULL, `ParentID` varchar(128) DEFAULT NULL, `LastChange` datetime NOT NULL, `Name` varchar(128) NOT NULL, `Type` varchar(32) NOT NULL, `Expanded` tinyint(1) NOT NULL, `Description` varchar(1024) DEFAULT NULL, `Icon` varchar(128) NOT NULL, `Panel` varchar(128) NOT NULL, `Username` varchar(512) DEFAULT NULL, `DomainName` varchar(512) DEFAULT NULL, `Password` varchar(1024) DEFAULT NULL, `Hostname` varchar(512) DEFAULT NULL, `Protocol` varchar(32) NOT NULL, `PuttySession` varchar(128) DEFAULT NULL, `Port` int(11) NOT NULL, `ConnectToConsole` tinyint(1) NOT NULL, `UseCredSsp` tinyint(1) NOT NULL, `RenderingEngine` varchar(10) DEFAULT NULL, `ICAEncryptionStrength` varchar(32) NOT NULL, `RDPAuthenticationLevel` varchar(32) NOT NULL, `RDPMinutesToIdleTimeout` int(11) NOT NULL, `RDPAlertIdleTimeout` tinyint(1) NOT NULL, `Colors` varchar(32) NOT NULL, `Resolution` varchar(32) NOT NULL, `DisplayWallpaper` tinyint(1) NOT NULL, `DisplayThemes` tinyint(1) NOT NULL, `EnableFontSmoothing` tinyint(1) NOT NULL, `EnableDesktopComposition` tinyint(1) NOT NULL, `CacheBitmaps` tinyint(1) NOT NULL, `RedirectDiskDrives` tinyint(1) NOT NULL, `RedirectPorts` tinyint(1) NOT NULL, `RedirectPrinters` tinyint(1) NOT NULL, `RedirectSmartCards` tinyint(1) NOT NULL, `RedirectSound` varchar(64) NOT NULL, `SoundQuality` varchar(20) NOT NULL, `RedirectAudioCapture` tinyint(1) NOT NULL, `RedirectKeys` tinyint(1) NOT NULL, `Connected` tinyint(1) NOT NULL, `PreExtApp` varchar(256) DEFAULT NULL, `PostExtApp` varchar(256) DEFAULT NULL, `MacAddress` varchar(32) DEFAULT NULL, `UserField` varchar(256) DEFAULT NULL, `ExtApp` varchar(256) DEFAULT NULL, `VNCCompression` varchar(10) DEFAULT NULL, `VNCEncoding` varchar(20) DEFAULT NULL, `VNCAuthMode` varchar(10) DEFAULT NULL, `VNCProxyType` varchar(20) DEFAULT NULL, `VNCProxyIP` varchar(128) DEFAULT NULL, `VNCProxyPort` int(11) DEFAULT NULL, `VNCProxyUsername` varchar(512) DEFAULT NULL, `VNCProxyPassword` varchar(1024) DEFAULT NULL, `VNCColors` varchar(10) DEFAULT NULL, `VNCSmartSizeMode` varchar(20) DEFAULT NULL, `VNCViewOnly` tinyint(1) NOT NULL, `RDGatewayUsageMethod` varchar(32) NOT NULL, `RDGatewayHostname` varchar(512) DEFAULT NULL, `RDGatewayUseConnectionCredentials` varchar(32) NOT NULL, `RDGatewayUsername` varchar(512) DEFAULT NULL, `RDGatewayPassword` varchar(1024) DEFAULT NULL, `RDGatewayDomain` varchar(512) DEFAULT NULL, `InheritCacheBitmaps` tinyint(1) NOT NULL, `InheritColors` tinyint(1) NOT NULL, `InheritDescription` tinyint(1) NOT NULL, `InheritDisplayThemes` tinyint(1) NOT NULL, `InheritDisplayWallpaper` tinyint(1) NOT NULL, `InheritEnableFontSmoothing` tinyint(1) NOT NULL, `InheritEnableDesktopComposition` tinyint(1) NOT NULL, `InheritDomain` tinyint(1) NOT NULL, `InheritIcon` tinyint(1) NOT NULL, `InheritPanel` tinyint(1) NOT NULL, `InheritPassword` tinyint(1) NOT NULL, `InheritPort` tinyint(1) NOT NULL, `InheritProtocol` tinyint(1) NOT NULL, `InheritPuttySession` tinyint(1) NOT NULL, `InheritRedirectDiskDrives` tinyint(1) NOT NULL, `InheritRedirectKeys` tinyint(1) NOT NULL, `InheritRedirectPorts` tinyint(1) NOT NULL, `InheritRedirectPrinters` tinyint(1) NOT NULL, `InheritRedirectSmartCards` tinyint(1) NOT NULL, `InheritRedirectSound` tinyint(1) NOT NULL, `InheritSoundQuality` tinyint(1) NOT NULL, `InheritRedirectAudioCapture` tinyint(1) NOT NULL, `InheritResolution` tinyint(1) NOT NULL, `InheritUseConsoleSession` tinyint(1) NOT NULL, `InheritUseCredSsp` tinyint(1) NOT NULL, `InheritRenderingEngine` tinyint(1) NOT NULL, `InheritICAEncryptionStrength` tinyint(1) NOT NULL, `InheritRDPAuthenticationLevel` tinyint(1) NOT NULL, `InheritRDPMinutesToIdleTimeout` tinyint(1) NOT NULL, `InheritRDPAlertIdleTimeout` tinyint(1) NOT NULL, `InheritUsername` tinyint(1) NOT NULL, `InheritPreExtApp` tinyint(1) NOT NULL, `InheritPostExtApp` tinyint(1) NOT NULL, `InheritMacAddress` tinyint(1) NOT NULL, `InheritUserField` tinyint(1) NOT NULL, `InheritExtApp` tinyint(1) NOT NULL, `InheritVNCCompression` tinyint(1) NOT NULL, `InheritVNCEncoding` tinyint(1) NOT NULL, `InheritVNCAuthMode` tinyint(1) NOT NULL, `InheritVNCProxyType` tinyint(1) NOT NULL, `InheritVNCProxyIP` tinyint(1) NOT NULL, `InheritVNCProxyPort` tinyint(1) NOT NULL, `InheritVNCProxyUsername` tinyint(1) NOT NULL, `InheritVNCProxyPassword` tinyint(1) NOT NULL, `InheritVNCColors` tinyint(1) NOT NULL, `InheritVNCSmartSizeMode` tinyint(1) NOT NULL, `InheritVNCViewOnly` tinyint(1) NOT NULL, `InheritRDGatewayUsageMethod` tinyint(1) NOT NULL, `InheritRDGatewayHostname` tinyint(1) NOT NULL, `InheritRDGatewayUseConnectionCredentials` tinyint(1) NOT NULL, `InheritRDGatewayUsername` tinyint(1) NOT NULL, `InheritRDGatewayPassword` tinyint(1) NOT NULL, `InheritRDGatewayDomain` tinyint(1) NOT NULL, `LoadBalanceInfo` varchar(1024) DEFAULT NULL, `AutomaticResize` tinyint(1) NOT NULL DEFAULT 1, `InheritLoadBalanceInfo` tinyint(1) NOT NULL DEFAULT 0, `InheritAutomaticResize` tinyint(1) NOT NULL DEFAULT 0, `RedirectClipboard` tinyint(1) NOT NULL DEFAULT 1, `InheritRedirectClipboard` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=3324 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tblRoot` -- DROP TABLE IF EXISTS `tblRoot`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `tblRoot` ( `Name` varchar(2048) NOT NULL, `Export` tinyint(1) NOT NULL, `Protected` varchar(4048) NOT NULL, `ConfVersion` double NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tblUpdate` -- DROP TABLE IF EXISTS `tblUpdate`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `tblUpdate` ( `LastUpdate` datetime(3) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; |
Если всё прошло хорошо, вы увидите вот такой вывод.
Создание пользователя
База есть. Теперь нужен пользователь под которым будем логиниться на сервер. Переходим в раздел привилегии и создаём нового.
Заполняем поля. Имя, разрешенные IP с которых можно подключаться, пароль, привилегии.
Настройка подключения
Я всё настраивал под версию v1.77.0 portable. Переходим на страницу загрузки на сайте разработчика.
Распаковываем в любое место. И запускаем.
Переходим во вкладку инструменты.
Открываем SQL-Server, отмечаем чек бокс на «Использовать SQL-Server для загрузки и сохранения подключения». Заполняем данные от базы, которые мы настраивали на предыдущих шагах.
Проверяем подключение. Если всё хорошо — нажимаем «Да».
И первым делом, чтобы понять, что всё заработало корректно — надо создать первое подключение. Если что-то пойдет не так, то все проблемы будут высыпаться в левом нижнем углу на вкладке «Уведомления».
Безопасность
Что касается безопасности — тут, как и ожидалось, сыровато, но присутствует.
Если заглянуть в базу, то все пароли зашифрованы. Мы видим в базе лишь отпечатки.
Если попытаться сделать экспорт файла подключений и заглянуть в XML-файл — там тоже самое. Но везде видны логины, ip:порт и другая информация. То есть в базе шифруется лишь пароль.
Не лишним будет поставить на сам сервер поставить fail2ban, выключить phpmyadmin и настроить какой-нибудь FireWall.
Шифрование и пароль
На файл подключения можно поставить пароль. Тогда, даже если сделать экспорт и импорт файла в виде XML, то выдаст ошибку. Пароль можно поставить так:
И при входе мы будем видеть запрос на пароль:
Если после установки пароля попробовать выгрузить xml и загрузить обратно, то программа выдаст ошибку, что ей не прочитать файл.
Разграничение прав
Про разграничение прав и речи нет. Группа пользователей всегда одна: все всё видят. Так что, если стоит задача — одним дать доступы сюда, вторым только сюда, то это можно сделать только через MySQL. Либо создавать несколько баз. Других способов я не нашел.
Результат
Пришлось потратить немного времени и сил, чтобы это все заработало хотя бы в виде MVP. На данный момент мы у себя будем запускать это в боевую среду и активно использовать.
Траблшут
Везде отключен буфер обмена
По умолчанию для всех и вся проброс буфера обмена отключен. Если вы перенесили свой рабочий конфиг, то эти значения перепишет. Чтобы не ковыряться руками — зайдем в phpmyadmin, выбираем базу mRemoteNG, таблицу tblCons, делаем SQL-запрос:
1 | UPDATE `tblCons` SET `RedirectClipboard`='1'; |