MySQL उपयोगकर्ता बनाते समय होस्ट के लिए% का उपयोग करना


93

मेरे MySQL डेटाबेस को दो उपयोगकर्ताओं की आवश्यकता है: ऐप्यूसर और समर्थन।
एप्लिकेशन डेवलपर्स में से एक जोर देकर कहता है कि मैं इन उपयोगकर्ताओं के लिए चार खाते बनाता हूं:

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

मेरे जीवन के लिए मैं यह नहीं जान सकता कि वह सोचता है कि हमें इसकी आवश्यकता है। होस्ट 'लोकलहोस्ट' की देखभाल के रूप में वाइल्डकार्ड का उपयोग नहीं करेगा?

कोई विचार?

(यहाँ MySQL 5.5 का उपयोग करके)

जवाबों:


106

localhostMySQL में विशेष है, इसका मतलब एक टीसीपी / आईपी सॉकेट के विपरीत UNIX सॉकेट (या विंडोज पर नामित पाइप, मेरा मानना ​​है) पर एक कनेक्शन है। %मेजबान के रूप में उपयोग करना शामिल नहीं है localhost, इसलिए इसे स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है।


किस संस्करण में? MySQL 5.5.35 में, "%" लोकलहोस्ट से भी मेल खाता है।
पदावनत करें

4
न केवल "लोकलहोस्ट" स्थानीय सॉकेट के माध्यम से कनेक्ट होता है, 127.0.0.1 (जो सॉकेट का उपयोग नहीं करता है)% से मेल नहीं खाता, लेकिन इसके बजाय लोकलहोस्ट भी। देखा कि आज एक haproxy स्थापना के साथ।
फिलिप

33

जैसा कि @nos ने इस प्रश्न के वर्तमान में स्वीकृत उत्तर की टिप्पणियों में बताया है, स्वीकृत उत्तर गलत है।

हाँ, वहाँ का उपयोग कर के बीच एक अंतर है %और localhostजब जोड़ने के माध्यम से एक सॉकेट एक मानक टीसीपी / आईपी कनेक्ट करने के बजाय कनेक्ट उपयोगकर्ता खाता मेजबान के लिए।

एक होस्ट मान सॉकेट के लिए %शामिल नहीं है localhostऔर इस प्रकार निर्दिष्ट किया जाना चाहिए यदि आप उस पद्धति का उपयोग करके कनेक्ट करना चाहते हैं।


15

चलो बस परीक्षण करते हैं।

सुपरयुसर के रूप में कनेक्ट करें, और फिर:

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

और फिर

USE mysql;

सेट अप

परीक्षण के लिए fooपासवर्ड वाला उपयोगकर्ता बनाएं bar:

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

जुडिये

यूनिक्स डोमेन सॉकेट (यानी I / O पाइप जिसे फाइलसिस्टम प्रविष्टि /var/run/mysqld/mysqld.sockया कुछ इस तरह नाम दिया गया है ) से कनेक्ट करने के लिए , इसे कमांड लाइन पर चलाएं ( --protocolविकल्प का उपयोग निश्चित रूप से सुनिश्चित करने के लिए करें)

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

एक को उम्मीद है कि उपरोक्त मैच "उपयोगकर्ता लोकलहोस्ट से आता है" लेकिन निश्चित रूप से "उपयोगकर्ता 127.0.0.1 से नहीं आता है"।

इसके बजाय "127.0.0.1" से सर्वर से कनेक्ट करने के लिए, इसे कमांड लाइन पर चलाएं

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

यदि आप बाहर निकलते हैं --protocol=TCP, तोmysql कमांड यूनिक्स डोमेन सॉकेट का उपयोग करने का प्रयास करेगा। तुम भी कह सकते हो:

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

एक लाइन में दो कनेक्शन के प्रयास:

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"

(पासवर्ड वातावरण में सेट किया गया है ताकि इसे mysqlप्रक्रिया में पारित किया जाए )

संदेह के मामले में सत्यापन

वास्तव में जांचें कि क्या कनेक्शन टीसीपी / आईपी सॉकेट या यूनिक्स डोमेन सॉकेट से गुजरता है

  1. के उत्पादन की जांच करके mysql क्लाइंट प्रक्रिया का PID प्राप्त करें ps faux
  2. भागना lsof -n -p<yourpid>

आप कुछ इस तरह देखेंगे:

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

या

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

इसलिए:

केस 0: होस्ट = '10 .10.10.10 '(अशक्त परीक्षण)

update user set host='10.10.10.10' where user='foo'; flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: विफलता
  • 127.0.0.1 से कनेक्ट करें: विफलता

केस 1: होस्ट = '%'

update user set host='%' where user='foo'; flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: ठीक है
  • 127.0.0.1 से कनेक्ट करें: ठीक है

केस 2: होस्ट = 'लोकलहोस्ट'

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

व्यवहार भिन्न होता है और यह स्पष्ट रूप से निर्भर करता है skip-name-resolve। यदि सेट किया जाता है, localhostतो लॉग के अनुसार लाइनों को अनदेखा किया जाता है। निम्नलिखित त्रुटि लॉग में देखा जा सकता है: "- उपयोगकर्ता 'प्रविष्टि' रूट @ localhost 'को --skip-name- रिज़ॉल्यूशन मोड में अनदेखा किया गया है।" । इसका मतलब है यूनिक्स डोमेन सॉकेट के माध्यम से कनेक्ट नहीं करना। लेकिन यह आनुभविक रूप से मामला नहीं है। localhostअब इसका मतलब केवल यूनिक्स डोमेन सॉकेट है, और यह 127.0.0.1 से मेल नहीं खाता है।

skip-name-resolve बंद है:

  • सॉकेट का उपयोग करके कनेक्ट करें: ठीक है
  • 127.0.0.1 से कनेक्ट करें: ठीक है

skip-name-resolve चालू है:

  • सॉकेट का उपयोग करके कनेक्ट करें: ठीक है
  • 127.0.0.1 से कनेक्ट करें: विफलता

केस 3: मेजबान = '127.0.0.1'

update user set host='127.0.0.1' where user='foo';flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: विफलता
  • 127.0.0.1 से कनेक्ट करें: ठीक है

केस 4: मेजबान = ''

update user set host='' where user='foo';flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: ठीक है
  • 127.0.0.1 से कनेक्ट करें: ठीक है

( MySQL 5.7: 6.2.4 एक्सेस कंट्रोल, स्टेज 1: कनेक्शन सत्यापन के अनुसार , खाली स्ट्रिंग '' का अर्थ "किसी भी मेजबान" से है लेकिन '%' के बाद क्रमबद्ध होता है। )

केस 5: मेजबान = '192.168.0.1' (अतिरिक्त परीक्षण)

('192.168.0.1' मेरी मशीन के IP पतों में से एक है, आपके मामले में उचित रूप से बदला गया है)

update user set host='192.168.0.1' where user='foo';flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: विफलता
  • 127.0.0.1 से कनेक्ट करें: विफलता

परंतु

  • कनेक्ट का उपयोग कर mysql -pbar -ufoo -h192.168.0.1: ठीक है ()

उत्तरार्द्ध क्योंकि यह वास्तव में टीसीपी कनेक्शन से आ रहा है 192.168.0.1, जैसा कि पता चला lsof:

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

एज केस ए: होस्ट = '0.0.0.0'

update user set host='0.0.0.0' where user='foo';flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: विफलता
  • 127.0.0.1 से कनेक्ट करें: विफलता

एज केस B: होस्ट = '255.255.255.255'

update user set host='255.255.255.255' where user='foo';flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: विफलता
  • 127.0.0.1 से कनेक्ट करें: विफलता

एज केस सी: होस्ट = '127.0.0.2'

(127.0.0.2 RFC6890 में परिभाषित 127.0.0.1 के बराबर पूरी तरह से वैध लूपबैक पता है )

update user set host='127.0.0.2' where user='foo';flush privileges;
  • सॉकेट का उपयोग करके कनेक्ट करें: विफलता
  • 127.0.0.1 से कनेक्ट करें: विफलता

दिलचस्प बात यह है:

  • mysql -pbar -ufoo -h127.0.0.2से जोड़ता है 127.0.0.1और विफल है
  • mysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2 ठीक है

साफ - सफाई

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

परिशिष्ट

यह देखने के लिए कि mysql.userतालिका में वास्तव में क्या है , जो अनुमति तालिकाओं में से एक है, उपयोग करें:

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;

यह देता है:

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

इसी तरह तालिका के लिए 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
इसके लिए एक निष्कर्ष की आवश्यकता है जो यह स्पष्ट करता है कि शेष उत्तर वास्तव में कोड को समझने की आवश्यकता के बिना क्या कह रहा है।
प्रोमेथियस

7

यदि आप user@'%'लोकलहोस्ट उपयोग से कनेक्ट करना चाहते हैं mysql -h192.168.0.1 -uuser -p


5

अब तक प्रदान किए गए लोगों को थोड़ा अलग जवाब देने के लिए जा रहे हैं।

यदि आपकी उपयोगकर्ता तालिका में लोकलहोस्ट से अनाम उपयोगकर्ता के लिए एक पंक्ति है ''@'localhost'तो इसे वाइल्डकार्ड के साथ आपके उपयोगकर्ता की तुलना में अधिक विशिष्ट माना जाएगा 'user'@'%'। यही कारण है कि यह भी प्रदान करना आवश्यक है 'user'@'localhost'

आप इस पृष्ठ के निचले भाग में इसे और अधिक विस्तार से देख सकते हैं ।


5

प्रतिशत प्रतीक का अर्थ है: दूरस्थ और स्थानीय कनेक्शन सहित कोई भी होस्ट।

लोकलहोस्ट केवल स्थानीय कनेक्शन की अनुमति देता है।

(इसलिए शुरू करने के लिए, यदि आपको अपने डेटाबेस के लिए दूरस्थ कनेक्शन की आवश्यकता नहीं है, तो आप appuser @ '%' से तुरंत छुटकारा पा सकते हैं)

तो, हाँ, वे अतिव्यापी हैं, लेकिन ...

... दोनों प्रकार के खातों को सेट करने का एक कारण है, यह mysql डॉक्स में बताया गया है: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html

यदि आपके पास अपने लोकलहोस्ट पर एक अनाम उपयोगकर्ता है, जिसे आप यहाँ देख सकते हैं:

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

और यदि आप केवल उपयोगकर्ता appuser @ '%' (और आप appuser @ 'localhost') नहीं बनाते हैं, तो जब appuser mysql उपयोगकर्ता स्थानीय होस्ट से जोड़ता है, तो अनाम उपयोगकर्ता खाते का उपयोग किया जाता है (यह आपके appuser @ पर पूर्वाग्रह है) '%' उपयोगकर्ता)।

और इसके लिए फिक्स है (जैसा कि कोई अनुमान लगा सकता है) appuser @ 'localhost' बनाने के लिए (जो कि अधिक विशिष्ट है कि स्थानीय होस्ट अनाम उपयोगकर्ता और यदि आपका ऐप्यूसर लोकलहोस्ट से कनेक्ट होता है) का उपयोग किया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.