MySQL 사용자를 만들 때 호스트에 % 사용


93

내 MySQL 데이터베이스에는 appuser와 support라는 두 명의 사용자가 필요합니다.
응용 프로그램 개발자 중 한 명이 이러한 사용자를 위해 4 개의 계정을 만들어야한다고 주장합니다.

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

제 삶을 위해 왜 그가 우리에게 이것이 필요하다고 생각하는지 알 수 없습니다. 와일드 카드를 호스트로 사용하지 않고 'localhost'를 처리하지 않습니까?

어떤 아이디어?

(여기서 MySQL 5.5 사용)

답변:


106

localhost이것은 MySQL에서 특별합니다. 이것은 TCP / IP 소켓이 아닌 UNIX 소켓 (또는 Windows에서는 명명 된 파이프)을 통한 연결을 의미합니다. %호스트로 사용 localhost하면는 포함되지 않으므로 명시 적으로 지정해야합니다.


어떤 버전입니까? MySQL 5.5.35에서 "%"는 localhost 와도 일치합니다.
depquid

4
"localhost"는 로컬 소켓을 통해 연결될뿐만 아니라 127.0.0.1 (소켓을 사용하지 않음)은 %와 일치하지 않고 대신 localhost도 일치합니다. 오늘 haproxy 설치로 확인했습니다.
Phillipp 2014

33

@nos가이 질문에 대한 현재 허용 된 답변의 의견에서 지적했듯이 허용 된 답변이 잘못되었습니다.

예를 이용하여 차분 존재 %localhost소켓 대신 표준 TCP / IP 접속의 접속을 통해 사용자 계정 호스트에 연결할 때이.

의 호스트 값은 소켓에 대해 %포함되지 않으므로 localhost해당 방법을 사용하여 연결하려는 경우 지정해야합니다.


16

그냥 테스트 해 봅시다.

수퍼 유저로 연결 한 다음 :

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 도메인 소켓에 연결하려면 (즉, 파일 시스템 항목에 의해 이름이 지정된 I / O 파이프 /var/run/mysqld/mysqld.sock) 명령 줄에서이를 실행합니다 ( --protocol옵션을 사용하여 이중 확인).

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

위의 내용은 "user comes from localhost"와 일치하지만 확실히 "user comes from 127.0.0.1"과는 일치하지 않을 것으로 예상합니다.

대신 "127.0.0.1"에서 서버에 연결하려면 명령 줄에서 실행하십시오.

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

를 생략 --protocol=TCP하면 mysql명령은 여전히 ​​Unix 도메인 소켓을 사용하려고 시도합니다. 다음과 같이 말할 수도 있습니다.

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프로세스에 전달되도록 환경에 설정됩니다. )

의심스러운 경우 확인

연결이 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;
  • 소켓을 사용하여 연결 : FAILURE
  • 127.0.0.1에서 연결 : 실패

사례 1 : 호스트 = '%'

update user set host='%' where user='foo'; flush privileges;
  • 소켓을 사용하여 연결 : 확인
  • 127.0.0.1에서 연결 : 확인

사례 2 : 호스트 = 'localhost'

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

동작은 다양 하며 이는 분명히에 따라 다릅니다 skip-name-resolve. 설정된 경우 localhost로그에 따라가있는 행 이 무시됩니다. 다음은 오류 로그에서 볼 수 있습니다. "--skip-name-resolve 모드에서 무시 된 ''user '항목'root @ localhost '." . 이것은 Unix 도메인 소켓을 통한 연결이 없음을 의미합니다. 그러나 이것은 경험적으로 사실이 아닙니다. localhost이제는 Unix 도메인 소켓 만 의미하며 더 이상 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;
  • 소켓을 사용하여 연결 : FAILURE
  • 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;
  • 소켓을 사용하여 연결 : FAILURE
  • 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)

Edge Case A : 호스트 = '0.0.0.0'

update user set host='0.0.0.0' where user='foo';flush privileges;
  • 소켓을 사용하여 연결 : FAILURE
  • 127.0.0.1에서 연결 : 실패

Edge Case B : 호스트 = '255.255.255.255'

update user set host='255.255.255.255' where user='foo';flush privileges;
  • 소켓을 사용하여 연결 : FAILURE
  • 127.0.0.1에서 연결 : 실패

Edge Case 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;
  • 소켓을 사용하여 연결 : FAILURE
  • 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
이것은 코드를 이해할 필요없이 나머지 대답이 실제로 말하는 것을 명확하게하는 결론이 필요합니다.
Prometheus

7

user@'%'localhost에서 연결 하려면 mysql -h192.168.0.1 -uuser -p.


5

지금까지 제공된 답변과 약간 다른 답변을 제공하겠습니다.

users 테이블에 localhost의 익명 사용자에 대한 행이있는 경우 ''@'localhost'이는 와일드 카드 host를 사용하는 사용자보다 더 구체적으로 처리됩니다 'user'@'%'. 이것이 또한 제공해야하는 이유 'user'@'localhost'입니다.

이 페이지 하단에서 자세한 설명을 볼 수 있습니다 .


5

백분율 기호는 원격 및 로컬 연결을 포함한 모든 호스트를 의미합니다.

localhost는 로컬 연결 만 허용합니다.

(시작하려면 데이터베이스에 대한 원격 연결이 필요하지 않은 경우 appuser @ '%'사용자를 즉시 ​​제거 할 수 있습니다.)

네, 겹칩니다 만 ...

... 두 유형의 계정을 모두 설정하는 이유가 있습니다. 이는 mysql 문서 ( http://dev.mysql.com/doc/refman/5.7/en/adding-users.html )에 설명되어 있습니다.

localhost에 익명의 사용자가있는 경우 다음을 사용하여 찾을 수 있습니다.

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

사용자 appuser @ '%'(그리고 appuser @ 'localhost'가 아님) 만 생성하면 appuser mysql 사용자가 로컬 호스트에서 연결할 때 익명 사용자 계정이 사용됩니다 (appuser @보다 우선합니다. '%' 사용자).

그리고 이것에 대한 수정은 (추측 할 수 있듯이) appuser @ 'localhost'(로컬 호스트 익명 사용자보다 더 구체적이며 appuser가 로컬 호스트에서 연결하는 경우에 사용됨)를 만드는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.