Наш VPS настроен таким образом, что все базы данных доступны из любого домена через localhost и имя пользователя / пароль / имя базы данных.
Это обычная настройка или должен быть какой-то способ «заключить в тюрьму» каждого пользователя, чтобы он не мог получить доступ к другим базам данных на локальном хосте?
Спасибо, Марк
Как упоминает Калеб, при настройке MySQL, как и в других системах, лучше всего использовать систему с минимально необходимыми привилегиями - если разные приложения не связаны между собой, у них мало причин для доступа к базам данных друг друга. . Если некоторые являются связанных, то они должны быть предоставлены конкретный, ограниченный привилегии для таблиц, к которым им нужен доступ в другой базе данных, но не более.
Я предполагаю, что когда вы говорите
доступен из любого домена через localhost
вы имеете в виду, что вы используете установку Apache с несколькими доменами (или аналогичную), это означает, что все ваши приложения работают на одном компьютере, и, таким образом, с точки зрения MySQL каждый пользователь является 'username'@'localhost'
user, поэтому вы ограничены указанием пользователей по имени пользователя.
Важно отметить, что из-за того, как работают разрешения MySQL, в ситуации, когда у вас есть удаленные пользователи, которые 'user1'@'abc.example.com'
на самом деле совершенно другой пользователь к 'user1'@'xyz.example.com'
или 'user1'@'localhost'
несмотря на совместное использование имени пользователя, которое значительно увеличивает вашу гибкость в настройке разрешений (или делает вещи очень запутанными, в зависимости от вашей точки зрения). Это аргумент в пользу запуска сервера базы данных на другой виртуальной машине, если вы можете - хотя, конечно, это не обязательно.
Обычный, простой в использовании (и небезопасный) метод добавления пользователей базы данных, как правило, выглядит примерно так:
GRANT ALL ON *.* TO `user1`@`localhost`;
который просто дает этому пользователю GLOBAL
привилегии делать что-либо с любой базой данных.
Это плохо как по очевидным, так и по другим не столь очевидным причинам. *.*
включает mysql
сама база данных - это позволяет вам делать что-нибудь вам нравится с другими пользователями, настройками и т. д., и этого следует избегать. В ALL
часть заявления предоставляет все привилегии, доступные в GLOBAL
область действия - это означает, что они могут делать такие вещи, как SHOW PROCESSLIST
и KILL <query-id>
. Это может показаться прекрасным («зачем они вообще это сделали?»), Но опять же, как отмечает Калеб, если приложение скомпрометировано, пользователь базы данных, с которым оно соединяется, будет пользователем, которого злоумышленник «использует» против вас.
Простое улучшение вышеизложенного - назначить привилегии с помощью такого оператора для каждой базы данных:
GRANT ALL ON `user1_database`.* TO `user1`@`localhost`;
Это дает все DATABASE
уровень привилегий для user1
на user1_database
- это важно, так как исключает всех сильных мира сего. GLOBAL
перечисленные выше привилегии, поэтому теперь пользователь может, в худшем случае, удалить свою базу данных.
Еще одним улучшением этого метода является создание как минимум двух пользователей для каждого приложения. Один с GRANT ALL
в базе данных (для администрирования), а другой будет использоваться самим веб-приложением, которое имеет только необходимые ему привилегии и только для объектов, к которым ему нужен доступ. Очевидно, что это довольно большая дополнительная работа, когда вы вносите изменения и дополнительное тестирование, но при правильном выполнении это может значительно снизить возможный ущерб в случае взлома системы.
У меня часто бывает стандартный пользователь, а другой - с _www
суффикс для веб-приложения.
Вы можете упростить часть этого, используя привилегии подстановочных знаков MySQL, и иметь пользователей, которые могут создавать свои собственные базы данных (соответствующие определенному шаблону) и
-- Create a user that has ALL privileges on databases beginning with 'user1_'
-- This is our application admin user
-- it can create any database that matches the pattern
GRANT ALL ON `user1\_%`.* TO `user1`@`localhost`;
-- Create a "safe" version of this user with just the ability to modify data
-- This is a generic approach and could be applied at object level per-database
GRANT SELECT, INSERT, UPDATE, DELETE ON `user1\_%`.* TO `user1_www`@`localhost`;
Способ создания пользователя-администратора в этом примере является распространенным методом в общей среде - он позволяет пользователям создавать базы данных без назначения каких-либо GLOBAL
привилегии, чтобы они не могли видеть базы данных других пользователей.
Вы должны использовать более тонкие привилегии с помощью таблицы привилегий MySQL, чтобы каждое приложение (или даже компонент приложения) имело доступ только к базам данных или таблицам, которые необходимы для его работы. Это уменьшит потенциальные проблемы с нарушениями конфиденциальности, уменьшит ущерб в случае нарушения безопасности и даже поможет выявить ошибки в вашем программном обеспечении во время тестирования.
Как упоминают @simon и @caleb, глобальные разрешения обычно назначаются, но это не является хорошей практикой, я использую этот `` макрос '' (который я сколотил на основе другого сообщения о serverfault или SO, не может запомните, какой из них ') для привилегий:
SET @usr = '\'username\'@\'localhost\'';
SET @pwd = '\'longpassword\'';
SET @db = 'database';
set @query = CONCAT('revoke all privileges on *.* from ', @usr);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;
set @query = CONCAT('drop user ', @usr);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;
set @query = CONCAT('create user ', @usr, ' identified by ', @pwd);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;
set @obj = CONCAT(@db, '.tablename');SET @query = CONCAT('GRANT select ON ', @obj, ' TO ', @usr, ' identified by ', @pwd);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;
удаление строк revoke, drop и create и изменение имени таблицы и привилегий по мере необходимости. Это позволяет, как предлагает @caleb, создавать мелкие привилегии с минимумом хлопот.