Jak zajistit, aby se nám k databázi připojovali jen správní lidé ze správného místa?
10.3.2006 06:00 | Petr Zajíc | přečteno 20979×
Co můžeme udělat pro nastavení zabezpečení databáze MySQL v praxi a
jak na to jít? O tom bude řeč v dnešním díle seriálu. Zpočátku se Vám
možná bude zdát celá problematika dosti spletitá, ale nakonec zjistíte,
že celý systém je velmi logický a přehledný. Takže, vzhůru na věc!
Veškerá oprávnění jsou v MySQL uložena ve zvláštní databázi, která
se jmenuje mysql. V ní je pět tabulek, které s oprávněním tak či onak
souvisejí. MySQL při požadavku na provedení nějaké operace tyto
tabulky dotazuje, a podle výsledku se rozhodne, zda dané oprávnění
přidělí či nikoli. Těmito pěti tabulkami jsou:
a v zásadě se dá říci, že se s jejich obsahem dá za určitých
okolností manipulovat přímo. Abychom to celé trochu zjednodušili,
vynecháme z dobrých důvodů tabulku host a budeme se věnovat zbylým
čtyřem. Pro experimenty je dobré v tomto případě mít k dispozici
testovací server s administrátorským přístupem.
MySQL provádí v podstatě dvojí ověřování. První se nazývá ověření při připojení a stanovuje
kdo se odkud smí nebo nesmí k našemu serveru připojit. Pokud to projde
nastupuje druhá
fáze, nazývaná ověření při požadavku.
Ta poskytuje uživatelům ověřeným při připojení práva pro konkrétní akce
na serveru (jako je třeba vkládání dat do tabulek).
Pozn.: V těchto dvou věcech je
podstatný rozdíl. Je klidně možné nakonfigurovat správu uživatelů tak,
aby se někdo mohl připojit, ale potom nemohl provést prakticky žádnou
myslitelnou akci na serveru.
Tady platí, že pro ověření při připojení se používají údaje, které jsou uloženy v tabulce user. Pokud jste přihlášen jako superuživatel, můžete si je prohlédnout pomocí
use mysql;
select * from user;
nebo ještě stručněji - protože nás v tuto chvíli zajímají pouze tři pole - pomocí něčeho jako
select host, user,
password from user;
Jak asi tušíte, ověření při připojení zjišťuje, zda daný uživatel se
smí připojit z daného hostitele - a zda přitom použil správné heslo.
Pokud je všechno v pořádku, pustí MySQL uživatele dál. Pokud ne,
skončíte při přihlašování chybou ve stylu:
ERROR 1045 (28000):
Access denied for user 'xxx'@'host' (using password: NO)
Do tabulky user může superuživatel (nebo jiný uživatel, pokud má k tomu práva) zapisovat přímo. Můžete tak například založit uživatele franta s heslem atnarf, který bude smět přistupovat k serveru z hostitele 192.168.0.100. První, co Vás asi napadne je provést to pomocí INSERT prostě takto:
insert into user (user,
host, password) values ('franta','192.168.0.100','atnarf');
To nebude fungovat! Důvodem je, že MySQL neukládá hesla ve sloupci password jako prostý text, ale - zjednodušeně řečeno - ukládá jejich hash. Ten lze vytovřit pomocí MySQL funkce PASSWORD, takže vylepšená verze příkazu pro vložení do tabulky user by mohla znít nějak takto (nesprávně založeného uživatele jsem odstranil):
delete from user where
user = 'franta' and host = '192.168.0.100' and password = 'atnarf';
insert into user (user, host, password) values
('franta','192.168.0.100',password('atnarf'));
Jestliže si to vyzkoušíte, zjistíte pravděpodobně, že to zase nebude fungovat. Důvodem je tentokrát mechanismus, jakým MySQL obsluhuje mezipaměť. Je třeba přikázat databázi, aby nový obsah tabulky user zapsala na disk. To provedete pomocí příkazu flush:
flush privileges;
K čemu dojde? MySQL vyprázdní cache a znovunačte oprávnění. V našem
případě i s nově založeným uživatelem, který se od této chvíle smí se
svým heslem připojit ze stroje 192.168.0.100.
K celému mechanismu bych si dovolil několik poznámek:
Prozradím rovnou, že přímá modifikace systémových tabulek s oprávněními není jediná možnost, jak tato oprávnění spravovat. Přesto je velmi rozumné vědět, že to můžete provést. Činnosti přidávání uživatelů však můžeme udělat mnohem jednodušeji pomocí vestavěného SQL příkazu GRANT. Než bych pracně vysvětloval, jak takový příkaz funguje uvedu příklad. Stejného efektu, kterého jsme předtím dosáhli ručním vyplněním tabulky user lze pomocí GRANT dosáhnout takto:
GRANT USAGE ON *.* TO
franta@'192.168.0.100' IDENTIFIED by 'atnarf';
Použití GRANT je mnohem pružnější než přímý zápis do tabulek s
oprávněními nejméně z následujících důvodů:
Bude dobré si říci, že svoje oprávnění (a leckdy i oprávnění ostatních) můžete zkontrolovat příkazem SHOW GRANTS:
show grants;
show grants for 'franta'@'192.168.0.100';
Tím jsme zhruba dokončili ověřování při připojení a příště se
podíváme na to, jak zajistit a spravovat oprávnění při
požadavku.