programing tip

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

itbloger 2020. 10. 10. 09:41
반응형

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


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

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

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

어떤 아이디어?

(여기서 MySQL 5.5 사용)


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


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

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

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


그냥 테스트 해보자.

수퍼 유저로 연결 한 다음 :

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에서 연결 : 확인

(According to MySQL 5.7: 6.2.4 Access Control, Stage 1: Connection Verification, The empty string '' also means “any host” but sorts after '%'. )

Case 5: Host = '192.168.0.1' (extra test)

('192.168.0.1' is one of my machine's IP addresses, change appropriately in your case)

update user set host='192.168.0.1' where user='foo';flush privileges;
  • Connect using socket: FAILURE
  • Connect from 127.0.0.1: FAILURE

but

  • Connect using mysql -pbar -ufoo -h192.168.0.1: OK (!)

The latter because this is actually TCP connection coming from 192.168.0.1, as revealed by lsof:

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

Edge Case A: Host = '0.0.0.0'

update user set host='0.0.0.0' where user='foo';flush privileges;
  • Connect using socket: FAILURE
  • Connect from 127.0.0.1: FAILURE

Edge Case B: Host = '255.255.255.255'

update user set host='255.255.255.255' where user='foo';flush privileges;
  • Connect using socket: FAILURE
  • Connect from 127.0.0.1: FAILURE

Edge Case C: Host = '127.0.0.2'

(127.0.0.2 is perfectly valid loopback address equivalent to 127.0.0.1 as defined in RFC6890)

update user set host='127.0.0.2' where user='foo';flush privileges;
  • Connect using socket: FAILURE
  • Connect from 127.0.0.1: FAILURE

Interestingly:

  • mysql -pbar -ufoo -h127.0.0.2 connects from 127.0.0.1 and is FAILURE
  • mysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2 is OK

Cleanup

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

Addendum

To see what is actually in the mysql.user table, which is one of the permission tables, use:

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;

this gives:

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

Similarly for table 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;

If you want connect to user@'%' from localhost use mysql -h192.168.0.1 -uuser -p.


Going to provide a slightly different answer to those provided so far.

If you have a row for an anonymous user from localhost in your users table ''@'localhost' then this will be treated as more specific than your user with wildcard'd host 'user'@'%'. This is why it is necessary to also provide 'user'@'localhost'.

You can see this explained in more detail at the bottom of this page.


The percent symbol means: any host, including remote and local connections.

The localhost allows only local connections.

(so to start off, if you don't need remote connections to your database, you can get rid of the appuser@'%' user right away)

So, yes, they are overlapping, but...

...there is a reason for setting both types of accounts, this is explained in the mysql docs: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html.

If you have an have an anonymous user on your localhost, which you can spot with:

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

and if you just create the user appuser@'%' (and you not the appuser@'localhost'), then when the appuser mysql user connects from the local host, the anonymous user account is used (it has precedence over your appuser@'%' user).

And the fix for this is (as one can guess) to create the appuser@'localhost' (which is more specific that the local host anonymous user and will be used if your appuser connects from the localhost).

참고URL : https://stackoverflow.com/questions/10823854/using-for-host-when-creating-a-mysql-user

반응형