Baza danych MySQL potrzebuje dwóch użytkowników: appuser i support.
Jeden z twórców aplikacji nalega, abym utworzył cztery konta dla tych użytkowników:
appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'
Na całe życie nie mogę zrozumieć, dlaczego sądzi, że tego potrzebujemy. Czy użycie symbolu wieloznacznego jako hosta nie zajmie się „hostem lokalnym”?
Jakieś pomysły?
(Używając MySQL 5.5 tutaj)
Jak @nos zauważył w komentarzach do aktualnie zaakceptowanej odpowiedzi na to pytanie, przyjęta odpowiedź jest nieprawidłowa.
Tak, istnieje różnica między korzystaniem z hosta konta użytkownika
%
a korzystaniemlocalhost
z hosta konta użytkownika w przypadku łączenia się przez gniazdo zamiast standardowego połączenia TCP / IP.Wartość hosta
%
nie obejmujelocalhost
gniazd i dlatego musi zostać określona, jeśli chcesz łączyć się przy użyciu tej metody.źródło
Po prostu przetestujmy.
Połącz się jako superużytkownik, a następnie:
SHOW VARIABLES LIKE "%version%"; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | version | 10.0.23-MariaDB-0+deb8u1-log |
i wtedy
USE mysql;
Ustawiać
Utwórz użytkownika
foo
z hasłembar
do testowania:CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;
Połączyć
Aby połączyć się z Unix Domain Socket (tj. Potokiem I / O, który jest nazwany przez wpis systemu plików
/var/run/mysqld/mysqld.sock
lub coś podobnego), uruchom to w wierszu poleceń (użyj--protocol
opcji, aby upewnić się podwójnie)mysql -pbar -ufoo mysql -pbar -ufoo --protocol=SOCKET
Można się spodziewać, że powyższe dopasowanie „użytkownik pochodzi z hosta lokalnego”, ale z pewnością nie „użytkownik pochodzi z 127.0.0.1”.
Aby zamiast tego połączyć się z serwerem z „127.0.0.1”, uruchom to w wierszu poleceń
mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP
Jeśli pominiesz
--protocol=TCP
,mysql
polecenie nadal będzie próbowało użyć gniazda domeny Unix. Możesz też powiedzieć:mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1
Dwie próby połączenia w jednej linii:
export MYSQL_PWD=bar; \ mysql -ufoo --protocol=SOCKET --execute="SELECT 1"; \ mysql -ufoo --bind-address=127.0.0.1 --host=127.0.0.1 --execute="SELECT 1"
(hasło jest ustawione w środowisku, tak aby było przekazywane do
mysql
procesu)Weryfikacja w przypadku wątpliwości
Aby naprawdę sprawdzić, czy połączenie przechodzi przez gniazdo TCP / IP lub gniazdo domeny Unix
ps faux
lsof -n -p<yourpid>
.Zobaczysz coś takiego:
lub
Więc:
Przypadek 0: Host = „10 .10.10.10” (test zerowy)
update user set host='10.10.10.10' where user='foo'; flush privileges;
Przypadek 1: Host = „%”
update user set host='%' where user='foo'; flush privileges;
Przypadek 2: Host = 'localhost'
update user set host='localhost' where user='foo';flush privileges;
Zachowanie jest różne i najwyraźniej zależy od tego
skip-name-resolve
. Jeśli jest ustawiona, powodujelocalhost
ignorowanie wierszy z zgodnie z dziennikiem. W dzienniku błędów można zobaczyć następujące informacje: „Wpis„ użytkownika ”„ root @ localhost ”został zignorowany w trybie --skip-name-solution.” . Oznacza to brak łączenia się przez gniazdo domeny Unix. Ale empirycznie tak nie jest.localhost
teraz oznacza TYLKO Unix Domain Socket i już nie pasuje do 127.0.0.1.skip-name-resolve
jest wyłączony:skip-name-resolve
jest włączony:Przypadek 3: Host = „127.0.0.1”
update user set host='127.0.0.1' where user='foo';flush privileges;
Przypadek 4: Host = ''
update user set host='' where user='foo';flush privileges;
(Zgodnie z MySQL 5.7: 6.2.4 Kontrola dostępu, etap 1: weryfikacja połączenia , pusty ciąg „” oznacza również „dowolny host”, ale sortuje po „%” ).
Przypadek 5: Host = „192.168.0.1” (dodatkowy test)
(„192.168.0.1” to jeden z adresów IP mojego komputera, zmień odpowiednio w swoim przypadku)
update user set host='192.168.0.1' where user='foo';flush privileges;
ale
mysql -pbar -ufoo -h192.168.0.1
: OK (!)To drugie, ponieważ jest to w rzeczywistości połączenie TCP
192.168.0.1
, jak ujawnionolsof
:Przypadek skrajny A: Host = „0.0.0.0”
update user set host='0.0.0.0' where user='foo';flush privileges;
Przypadek krawędzi B: Host = „255.255.255.255”
update user set host='255.255.255.255' where user='foo';flush privileges;
Edge Case C: Host = „127.0.0.2”
(127.0.0.2 to doskonale poprawny adres sprzężenia zwrotnego odpowiadający 127.0.0.1 zdefiniowanemu w RFC6890 )
update user set host='127.0.0.2' where user='foo';flush privileges;
Co ciekawe:
mysql -pbar -ufoo -h127.0.0.2
łączy się z127.0.0.1
i jest FAILUREmysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2
jest OKSprzątać
delete from user where user='foo';flush privileges;
Uzupełnienie
Aby zobaczyć, co faktycznie znajduje się w
mysql.user
tabeli, która jest jedną z tabel uprawnień, użyj:SELECT SUBSTR(password,1,6) as password, user, host, Super_priv AS su, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) AS funcs, CONCAT(Repl_slave_priv, Repl_client_priv) AS replic, CONCAT(Shutdown_priv, Process_priv, File_priv, Show_db_priv, Reload_priv, Create_user_priv) AS admin FROM user ORDER BY user, host;
to daje:
+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | password | user | host | su | gr | selock | modif | ria | views | funcs | replic | admin | +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | *E8D46 | foo | | N | N | NN | NNNNN | NNN | NNN | NNNNN | NN | NNNNNN |
Podobnie dla tabeli
mysql.db
:SELECT host,db,user, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv) AS funcs FROM db ORDER BY user, db, host;
źródło
Jeśli chcesz połączyć się
user@'%'
z localhost użyjmysql -h192.168.0.1 -uuser -p
.źródło
Zamierzam udzielić nieco innej odpowiedzi niż dotychczas.
Jeśli masz wiersz dla anonimowego użytkownika z hosta lokalnego w tabeli użytkowników,
''@'localhost'
będzie to traktowane jako bardziej szczegółowe niż twój użytkownik z hostem z symbolem wieloznacznym'user'@'%'
. Dlatego konieczne jest również zapewnienie'user'@'localhost'
.Możesz zobaczyć to wyjaśnione bardziej szczegółowo na dole tej strony .
źródło
Symbol procentu oznacza: dowolny host, w tym połączenia zdalne i lokalne.
Lokalny host zezwala tylko na połączenia lokalne.
(więc na początek, jeśli nie potrzebujesz zdalnych połączeń z bazą danych, możesz od razu pozbyć się użytkownika appuser @ '%')
Więc tak, pokrywają się, ale ...
... istnieje powód dla ustawienia obu typów kont, jest to wyjaśnione w dokumentacji mysql: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html .
Jeśli masz anonimowego użytkownika na swoim hoście lokalnym, którego możesz rozpoznać za pomocą:
select Host from mysql.user where User='' and Host='localhost';
a jeśli po prostu utworzysz appuser użytkownika @ '%' (a nie jesteś appuser @ 'localhost'), to gdy użytkownik appuser mysql łączy się z lokalnego hosta, używane jest konto anonimowego użytkownika (ma pierwszeństwo przed twoim appuser @ „%” użytkownika).
Rozwiązaniem tego problemu jest (jak można się domyślić) utworzenie appuser @ 'localhost' (co jest bardziej szczegółowe niż anonimowy użytkownik lokalnego hosta i będzie używany, jeśli appuser połączy się z localhost).
źródło