MySQL kullanıcısı oluştururken ana bilgisayar için% kullanma


93

MySQL veritabanımın iki kullanıcıya ihtiyacı var: uygulama kullanıcısı ve destek.
Uygulama geliştiricilerinden biri bu kullanıcılar için dört hesap oluşturmam konusunda ısrar ediyor:

appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'

Hayatım boyunca neden buna ihtiyacımız olduğunu düşündüğünü anlayamıyorum. Ev sahibi 'localhost' ile ilgilenirken joker karakteri kullanmak olmaz mı?

Herhangi bir fikir?

(Burada MySQL 5.5 kullanarak)

Yanıtlar:


106

localhostMySQL'de özeldir, TCP / IP soketinin aksine bir UNIX soketi (veya Windows'ta adlandırılmış kanallar) üzerinden bir bağlantı anlamına gelir. Kullanılması %konak içermez olarak localhost, açıkça belirtmek için dolayısıyla ihtiyaç.


Hangi versiyonda? MySQL 5.5.35'te "%" de localhost ile eşleşir.
depquid

4
Yalnızca "localhost" yerel soket yoluyla bağlanmakla kalmaz, 127.0.0.1 (soketi kullanmaz)% ile eşleşmez, bunun yerine localhost da eşleşmez. Bunu bugün bir haproksi kurulumuyla gördüm.
Phillipp

33

Bu soruya şu anda kabul edilen cevabın yorumlarında @nos'un da belirttiği gibi kabul edilen cevap yanlıştır.

Evet, standart bir TCP / IP bağlantısı yerine bir soket bağlantısı yoluyla bağlanırken kullanıcı hesabı ana bilgisayarı kullanmak %ve kullanmak arasında bir fark vardır localhost.

Ana bilgisayar değeri soketleri %içermez localhostve bu nedenle, bu yöntemi kullanarak bağlanmak istiyorsanız belirtilmelidir.


16

Hadi test edelim.

Süper kullanıcı olarak bağlanın ve ardından:

SHOW VARIABLES LIKE "%version%"; 
+-------------------------+------------------------------+ 
| Variable_name           | Value                        | 
+-------------------------+------------------------------+ 
| version                 | 10.0.23-MariaDB-0+deb8u1-log | 

ve sonra

USE mysql;

Kurmak

Test için fooşifreli bir kullanıcı oluşturun bar:

CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;

Bağlan

Unix Etki Alanı Soketine bağlanmak için (yani dosya sistemi girişiyle /var/run/mysqld/mysqld.sockveya benzeri bir şekilde adlandırılan G / Ç borusu ), bunu komut satırında çalıştırın ( --protocoliki kez emin olmak için seçeneği kullanın)

mysql -pbar -ufoo
mysql -pbar -ufoo --protocol=SOCKET

Biri, yukarıdaki "kullanıcı localhost'tan geliyor" ile eşleşmesini bekler, ancak kesinlikle "kullanıcı 127.0.0.1'den geliyor" ile eşleşmez.

Bunun yerine "127.0.0.1" üzerinden sunucuya bağlanmak için bunu komut satırından çalıştırın

mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP

Dışarıda bırakırsanız --protocol=TCP, mysqlkomut yine de Unix alan soketini kullanmayı deneyecektir. Ayrıca şunu da söyleyebilirsiniz:

mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1

Tek hatta iki bağlantı denemesi:

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"

(işleme geçirilmesi için şifre ortamda belirlenir mysql)

Şüphe Durumunda Doğrulama

Bağlantının bir TCP / IP soketi veya bir Unix Alan soketi üzerinden gidip gitmediğini gerçekten kontrol etmek için

  1. mysql istemci sürecinin PID'sini çıktılarını inceleyerek elde edin. ps faux
  2. koş lsof -n -p<yourpid>.

Şunun gibi bir şey göreceksiniz:

mysql [PID] quux 3u IPv4 [code] 0t0 TCP 127.0.0.1:[port]->127.0.0.1:mysql (ESTABLISHED)

veya

mysql [PID] quux 3u unix [code] 0t0 [code] socket

Yani:

Durum 0: Ana Bilgisayar = '10 .10.10.10 '(boş test)

update user set host='10.10.10.10' where user='foo'; flush privileges;
  • Soket kullanarak bağlayın: HATA
  • 127.0.0.1'den bağlan: HATA

Durum 1: Ana Bilgisayar = '%'

update user set host='%' where user='foo'; flush privileges;
  • Soketi kullanarak bağlayın: Tamam
  • 127.0.0.1'den bağlanın: Tamam

Durum 2: Ana Bilgisayar = 'localhost'

update user set host='localhost' where user='foo';flush privileges;

Davranış değişir ve bu görünüşe göre buna bağlıdır skip-name-resolve. Ayarlanırsa, ile satırların localhostgünlüğe göre yok sayılmasına neden olur . Hata günlüğünde aşağıdakiler görülebilir: "'kullanıcı' girişi 'root @ localhost' --skip-name-solution modunda yok sayıldı." . Bu, Unix Etki Alanı Soketi aracılığıyla bağlanmanın olmadığı anlamına gelir. Ancak bu, ampirik olarak durum böyle değil. localhostartık YALNIZCA Unix Domain Socket anlamına geliyor ve artık 127.0.0.1 ile eşleşmiyor.

skip-name-resolve kapalı:

  • Soketi kullanarak bağlayın: Tamam
  • 127.0.0.1'den bağlanın: Tamam

skip-name-resolve açık:

  • Soketi kullanarak bağlayın: Tamam
  • 127.0.0.1'den bağlan: HATA

Durum 3: Ana Bilgisayar = '127.0.0.1'

update user set host='127.0.0.1' where user='foo';flush privileges;
  • Soket kullanarak bağlayın: HATA
  • 127.0.0.1'den bağlanın: Tamam

Durum 4: Ana Bilgisayar = ''

update user set host='' where user='foo';flush privileges;
  • Soketi kullanarak bağlayın: Tamam
  • 127.0.0.1'den bağlanın: Tamam

( MySQL 5.7: 6.2.4'e göre Erişim Kontrolü, Aşama 1: Bağlantı Doğrulama , Boş dize '' aynı zamanda "herhangi bir ana bilgisayar" anlamına gelir ancak "%" den sonra sıralanır. )

Durum 5: Ana Bilgisayar = '192.168.0.1' (ekstra test)

('192.168.0.1' makinemin IP adreslerinden biridir, sizin durumunuza uygun şekilde değiştirin)

update user set host='192.168.0.1' where user='foo';flush privileges;
  • Soket kullanarak bağlayın: HATA
  • 127.0.0.1'den bağlan: HATA

fakat

  • Şunu kullanarak bağlanın mysql -pbar -ufoo -h192.168.0.1: Tamam (!)

Bu aslında gelen TCP bağlantısı olduğu için ikinci 192.168.0.1ortaya koyduğu gibi, lsof:

TCP 192.168.0.1:37059->192.168.0.1:mysql (ESTABLISHED)

Uç Durum A: Ana Bilgisayar = '0.0.0.0'

update user set host='0.0.0.0' where user='foo';flush privileges;
  • Soket kullanarak bağlayın: HATA
  • 127.0.0.1'den bağlan: HATA

Edge Case B: Ana Bilgisayar = '255.255.255.255'

update user set host='255.255.255.255' where user='foo';flush privileges;
  • Soket kullanarak bağlayın: HATA
  • 127.0.0.1'den bağlan: HATA

Uç Durum C: Ana Bilgisayar = '127.0.0.2'

(127.0.0.2, RFC6890'da tanımlandığı gibi 127.0.0.1'e eşdeğer mükemmel şekilde geçerli geri döngü adresidir )

update user set host='127.0.0.2' where user='foo';flush privileges;
  • Soket kullanarak bağlayın: HATA
  • 127.0.0.1'den bağlan: HATA

İlginç bir şekilde:

  • mysql -pbar -ufoo -h127.0.0.2BAĞLANIR 127.0.0.1ve BAŞARISIZ
  • mysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2 tamam

Temizlemek

delete from user where user='foo';flush privileges;

Ek

mysql.userİzin tablolarından biri olan tabloda gerçekte ne olduğunu görmek için şunu kullanın:

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;

bu şunu verir:

+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+
    | password | user     | host      | su | gr | selock | modif | ria | views | funcs | replic | admin  |
    +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+
    | *E8D46   | foo      |           | N  | N  | NN     | NNNNN | NNN | NNN   | NNNNN | NN     | NNNNNN |

Benzer şekilde tablo için 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;

6
Bu, kodu anlamaya gerek kalmadan yanıtın geri kalanının gerçekte ne söylediğini netleştiren bir sonuca ihtiyaç duyar.
Prometheus

7

user@'%'Localhost kullanımından bağlanmak istiyorsanız mysql -h192.168.0.1 -uuser -p.


5

Şimdiye kadar verilenlere biraz farklı bir cevap verecek.

Kullanıcılar tablonuzda localhost'tan anonim bir kullanıcı için bir satırınız varsa, ''@'localhost'bu, joker karakterli ana makineye sahip kullanıcınızdan daha özel kabul edilecektir 'user'@'%'. Bu yüzden sağlamak da gereklidir 'user'@'localhost'.

Bunun daha ayrıntılı olarak bu sayfanın altında açıklandığını görebilirsiniz .


5

Yüzde sembolü şu anlama gelir: uzak ve yerel bağlantılar dahil herhangi bir ana bilgisayar.

Localhost yalnızca yerel bağlantılara izin verir.

(bu nedenle, veritabanınıza uzaktan bağlantıya ihtiyacınız yoksa, appuser @ '%' kullanıcısından hemen kurtulabilirsiniz)

Yani, evet, örtüşüyorlar, ama ...

... her iki tür hesabı da ayarlamanın bir nedeni vardır, bu mysql belgelerinde açıklanmıştır: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html .

Localhost'unuzda anonim bir kullanıcınız varsa, bunu tespit edebilirsiniz:

select Host from mysql.user where User='' and Host='localhost';

ve eğer appuser @ '%' kullanıcısını oluşturursanız (ve appuser @ 'localhost' değil), appuser mysql kullanıcısı yerel ana bilgisayardan bağlandığında , anonim kullanıcı hesabı kullanılır (appuser @ 'nize göre önceliğe sahiptir. '%' kullanıcı).

Ve bunun düzeltmesi (tahmin edilebileceği gibi) appuser @ 'localhost'u oluşturmaktır (bu, yerel anonim kullanıcıdan daha spesifiktir ve uygulayıcınız localhost'tan bağlanırsa kullanılacaktır).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.