Intro

내부망 서버에서 웹을 하나를 열었다. 선배분이 서버에서 테스트 글을 썼는데 삭제 권한이 없었다. 장난으로 안지워주겠다고 하니, 서버의 SQL에 직접 접속해 글을 지우려고 시도를 했다. 하지만 여기서 만난 에러.

1
ERROR 1130 (00000) Host '000.000.000.000' is not allowed to connect to this MySQL server



왜 접속할 수 없을까?

에러메세지를 직역하면 “호스트 000.000.000.000’은 이 MySQL server에 접속 허용이 되지 않았습니다.” 이다. 즉, 접속할 수 있는 권한이 없다는 것.

그런데 웹을 연 내 기억으로는 이 서버에 내부망의 사람이 접속할 수 없도록 따로 정책을 정한 적은 없는데.. 도대체 왜 접속할 수 없는 걸까?

관련해서는 인프라를 담당하시는 선배분께 그 답을 들을 수 있었다.

MySQL 의 기본 접속 정책

데이터베이스는 기본적으로 외부의 접속을 막아야 한다. 데이터베이스가 외부의 접속을 막지 않는다면, 외부에서 해당 서버의 데이터베이스에 접속하고, 데이터베이스의 내용을 자신의 입맛대로 수정하거나, 없는 정보를 만들어 부당한 이득을 취하는 등의 “해킹”이 가능해지는 것이다.

왜 접속이 안되는걸까?

MySQL은 디폴트로 3306 포트로 통신을 한다. 그러므로 우선 3306 포트를 포트포워딩하는 등의 인바운드 규칙 조정을 통해 외부의 접근을 허용할 수 있다.

하지만 포트에 접근할 수 있도록 3306 포트가 열려있더라도 DB의 허락이 없다면 데이터베이스에 접속할 수는 없다. 이 부분은 MySQL의 “계정”과 연관이 있다.

쉽게 이해할 수 있도록 MySQL에서 계정을 만드는 예시를 들어본다.

1
2
3
CREATE USER '사용자명'@'localhost' IDENTIFIED BY '비밀번호';

GRANT ALL PRIVILEAGES ON 'DB명' to '사용자명'@'localhost';

이는 ‘사용자명’ 이라는 DB 접속 계정을 만들고, 특정 DB에 대한 모든 권한을 주는 명령어이다.

여기서 주목할 부분은 '사용자명'@'localhost'.

사용자명 at 뒤에 localhost가 붙어있다. 즉, 본 호스트(SQL이 실행되는 호스트)에 있는 ‘사용자명’ 이라는 계정에 DB 권한을 부여한 것이다.

예를 들어 SQL이 존재하는 서버 주소를 ‘111.111.1.1’ 이라고 가정해보자. 내외부에서 접속을 시도하면 아래와 같이 된다.

1
2
3
4
5
6
7
8
9
10
11
12
# 111.111.1.1 에서 접속시

mysql -u 사용자명 -p
>>> 접속 성공
use DB
>>> Database changed


# 외부(222.222.2.2)에서 접속시

mysql -u 사용자명 -h 111.111.1.1 --prot 3306
>>> ERROR 1130 (00000) Host '111.111.1.1' is not allowed to connect to this MySQL server

SQL이 있는 동일 호스트에서 접속하는 건 가능하지만, 외부에서 동일한 계정으로 접속했을 때에는 접속이 거부된다.
SQL 입장에서 봤을 때 두 계정은 다른 계정이며, 외부에서 접근하는 계정은 없는 계정이기 때문이다.

1
2
3
4
# SQL 입장에서 봤을 

내부에서 접속을 시도하는 사용자 : 사용자명@localhost
외부에서 접속을 시도하는 사용자 : 사용자명@222.222.2.2

사용자명@localhost는 있는 계정이지만, 사용자명@222.222.2.2 는 없는 계정이다.



그러면 어떻게 외부 접속을 허용할까?

이러한 DB 접속에 대한 기본 정책은 보안을 위해 가장 기본적이고 강력한 방법이다.
그런데, 경우에 따라서는 외부 접속을 허용해야 할 때가 있다.

그런 경우엔 (눈치 챘겠지만) 외부 IP 계정을 만들어주면 된다.

(1) 먼저 외부 접속에 대해 포트 접근 허용을 해주고(포트포워딩)
(2) 아래와 같이 외부 IP 계정을 만들어준다.

1
CREATE USER '사용자명'@'222.222.2.2' IDENTIFIED BY '비밀번호'

이렇게 만들어진 계정은 ‘222.222.2.2’ IP를 가진 머신에서 본 DB에 접속할 수 있게 하는 계정이 된다.
위에서 설명한 것과 같이 222.222.2.2 IP가 아닌 다른 IP에서 이 계정을 쓰면, 당연히 접속은 불가능하다.

모든 IP에서 접근할 수 있게 허용할 수 있을까?

권장되지는 않지만, 모든 IP에서 DB에 접근할 수 있도록 설정할 수도 있다.
다시 한 번 말하지만, 권장되지 않는다.

1
2
3
4
5
6
7
8
9
(1) MySQL 설정 파일 "my.cnf"  찾아 열어줍니다.  
 파일은 보통 mysql 설치된 디렉토리, 혹은 DB 저장되는 디렉토리에 있습니다.  

(2) bind-address 값을 '0.0.0.0' 으로 설정합니다.  
디폴트로는 localhost 되어있을 겁니다. 이걸 모든 IP 뜻하는 0.0.0.0으로 바꿔줍니다.  

(3) my.ncf 파일을 저장하고 닫은 , MySQL 서버를 다시 시작합니다.
- 리눅스라면 service mysql restart
- 윈도우라면 net start mysql

혹은 특정 네트워크 그룹에서 접속할 수 있도록도 할 수 있습니다.

1
2
3
4
5
6
7
# 유저를 만들어줄 때 (create user)

CREATE USER '유저명'@'123.123.0.*' IDENTIFIED '비밀번호';
--> *을 통해 123.123.0에 속한 네트워크 장비는 '유저명'으로 접속 가능

CREATE USER '유저명'@'%' IDENTIFIED '비밀번호';
--> 모든 IP에서 '유저명'으로 접속 가능



Reference

https://kimyhcj.tistory.com/entry/MySQL-%EC%99%B8%EB%B6%80-%EC%A0%91%EC%86%8D-ERROR-1130-00000-Host-xxxx-is-not-allowed-to-connect-to-this-MySQL-server
https://binshuuuu.tistory.com/214
https://cjh5414.github.io/mysql-create-user/
https://mommoo.tistory.com/93