MySQLユーザーを作成するときにホストに%を使用する


93

私のMySQLデータベースには、appuserとsupportの2人のユーザーが必要です。
アプリケーション開発者の1人は、これらのユーザー用に4つのアカウントを作成すると主張しています。

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

私の人生では、なぜ彼が私たちにこれが必要だと思っているのか理解できません。ホストが「localhost」を処理するので、ワイルドカードを使用しませんか?

何か案は?

(ここではMySQL 5.5を使用しています)

回答:


106

localhostこれはMySQLで特別なことであり、TCP / IPソケットではなく、UNIXソケット(またはWindowsでは名前付きパイプ)を介した接続を意味します。%ホストとしての使用にはが含まれていないlocalhostため、明示的に指定する必要があります。


どのバージョンで?MySQL 5.5.35では、「%」はローカルホストにも一致します。
depquid 2014

4
「localhost」はローカルソケットを介して接続するだけでなく、127.0.0.1(ソケットを使用しない)は%と一致しませんが、代わりにlocalhostも一致します。今日はhaproxyのインストールでそれを見ました。
フィリップ2014

33

@nosがこの質問に対する現在受け入れられている回答のコメントで指摘しているように、受け入れられた回答は正しくありません。

はい、標準のTCP / IP接続の代わりにソケット接続を介して接続する場合、ユーザーアカウントホストの使用%と使用には違いがあり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;

接続する

Unixドメインソケット(つまり、ファイルシステムエントリ/var/run/mysqld/mysqld.sockなどによって名前が付けられたI / Oパイプ)に接続するには、コマンドラインでこれを実行し--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=TCPmysqlコマンドはUnixドメインソケットを使用しようとします。あなたはまた言うことができます:

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

1行での2つの接続試行:

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プロセスに渡されるように環境で設定されます)

疑わしい場合の検証

接続がTCP / IPソケットまたはUnixドメインソケットのどちらを経由するかを実際に確認するには

  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 '(nullテスト)

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;
  • ソケットを使用して接続:OK
  • 127.0.0.1から接続:OK

ケース2:ホスト= 'localhost'

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

動作はさまざまで、これは明らかにに依存しskip-name-resolveます。設定されている場合localhost、ログに従って行が無視されます。エラーログには次の内容が表示されます。「「user」エントリ「root @ localhost」は--skip-name-resolveモードでは無視されます。」。これは、Unixドメインソケットを介して接続しないことを意味します。しかし、これは経験的には当てはまりません。localhost現在はUnixドメインソケットのみを意味し、127.0.0.1とは一致しなくなりました。

skip-name-resolve オフです:

  • ソケットを使用して接続:OK
  • 127.0.0.1から接続:OK

skip-name-resolve オンになっています:

  • ソケットを使用して接続:OK
  • 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から接続:OK

ケース4:ホスト= ''

update user set host='' where user='foo';flush privileges;
  • ソケットを使用して接続:OK
  • 127.0.0.1から接続:OK

MySQL 5.7:6.2.4アクセス制御、ステージ1:接続検証によると空の文字列 ''も「任意のホスト」を意味しますが、「%」の後にソートされます。

ケース5:ホスト= '192.168.0.1'(追加テスト)

(「192.168.0.1」は私のマシンのIPアドレスの1つです。あなたの場合は適切に変更してください)

update user set host='192.168.0.1' where user='foo';flush privileges;
  • ソケットを使用して接続します:失敗
  • 127.0.0.1から接続:失敗

だが

  • 使用して接続mysql -pbar -ufoo -h192.168.0.1:OK(!)

これは実際にから来るTCP接続であるため、後者192.168.0.1によって明らかにされるように、lsof

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

エッジケースA:ホスト= '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から接続:失敗

エッジケースC:ホスト= '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権限テーブルの1つであるテーブルに実際に何があるかを確認するには、次を使用します。

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の匿名ユーザーの行がある場合''@'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'を作成することです(これはローカルホストの匿名ユーザーよりも具体的であり、appuserがlocalhostから接続する場合に使用されます)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.