프로그램/mysql

mysql 외부 접속이 안될때.

(주)CKBcorp., 2013. 7. 24. 02:37
반응형


아아....이걸 하려고 세시간 ~ 여섯시간 정도를 쓴 거 같아.

결론은 어처구니 없는 게 원인이었다.


혹시 나같은 사람이 또 있을까 싶어, 증상과 해결책을 기록한다.

아래 글에서,

 domainname.co.kr 은 서버의 도메인 네임을 의미한다.

123.456.789.0 은 서버의 ip 를 의미한다.

987.654.321.0 은 외부 단말의 ip 를 의미한다.


----------------------------------------------------------


환경1 : LAMP ( Linux + Apache + MySql + PHP )

환경2 : 딱히 설정같은거 바꾼 거 없고, 최초 설치 그대로 손 안댄 상태에서 외부 접속을 시도.


현상 : 외부 접속 안됨. 로컬에서는 mysql 이 잘 붙는데, 외부에서 못 붙는다. 

증상은

1. 로컬에서 #mysql -h localhost -u root 됨.

2. 로컬에서 #mysql -h domainname.co.kr -u root 됨.

3. 로컬에서 #mysql -h 123.456.789.0 -u root 됨.

4. 외부에서 $mysql -h domainname.co.kr -u root 안됨.

5. 로컬에서 #mysql -h 123.456.789.0 -u root 안됨.


메시지 : 외부에서 $mysql -h 123.456.789.0 -u root

ERROR 1045 (28000): Access denied for user 'root'@'987.654.321.0' (using password: NO)


상태 : mysql 의 root 패스워드를 딱히 설정하지 않았다.



추측 : "mysql 외부 접속" 찾아봄

시도 : 

1. 

로컬에서 

mysql> GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY 'password';

mysql> FLUSH PRIVILEGES;

으로 mysql 에서 모든 디비에 접근할 수 있는 권한 변경.

2. 외부에서

# mysql -h domainname.co.kr -u root 안됨.


추측 : 혹시 권한 설정이 적용 안 된 거 아닐까?

로컬에서 

mysql> use mysql;

mysql> select host,user from user;

결과:

+---------------------+------+

| host                | user |

+---------------------+------+

| %                   | root | 

| 127.0.0.1           | root | 

| domainname.co.kr |      | 

| domainname.co.kr | root | 

| localhost           |      | 

| localhost           | root | 

+---------------------+------+

6 rows in set (0.00 sec)

적용 이상무. '%' 가 있으니 접근 권한 설정은 된거임.


추측 : 혹시 mysql 에서 외부 접속 막도록 설정된 거 아닐까?

로컬에서 

$vi /etc/my.cnf      <----- mysql 설정파일.

결과:

"bind-address" 의 설정이 없다. 

해설 : 원래, mysql 은 DB의 권한 설정에서 "외부  아이피/도메인이 접속할 수 있도록 접속 권한을 설정" 하는 기능과 별개로 mysql 설정 파일에서 "접속 가능 아이피/도메인" 을 설정할 수 있다. 즉, 접속 가능/불가능 여부를 설정하는 곳이 두 곳이 있는 셈.

근데, 이 때 설정 파일에서 접속 가능 아이피/도메인을 설정하는 항목이 바로 "bind-address" 인데, 이게 mysql 버전에 따라 "bind-address=localhost" 로 되어 있는 경우가 있다.

이 경우에 접근이 가능한 것은 localhost 뿐이므로, 만일 해당 항목이 있다면 지워야 한다("#bind-address=localhost" 와 같이 변경.)

근데 내 경우엔 해당 항목 자체가 없었음. 


추측 : 혹시 bind-address 항목을 명시적으로 설정해 주어야 하지 않을까?

로컬에서 

$vi /etc/my.cnf 에 

bind-address=0.0.0.0

bind-address=123.456.789.0

bind-address=987.654.321.0

를 차례대로 추가.

결과: 다 안됨.


추측 : 방화벽 막혔는지 확인

시도 :

인터넷에서 iptables 를 찾아서 방화벽 정책 확인

#iptables -L                         <-------- root 권한만 실행가능.

결과 : 

# iptables -L

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         


Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         


Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination         


Chain fail2ban-SSH (1 references)

target     prot opt source               destination         


딱히 막힌 정책 없음.


추측 : 혹시 포트가 막혔나?

시도 : telnet 으로 mysql 포트(3306) 확인

1. 로컬에서 $telnet localhost 3306

mysql 에 접속됨

2. 외부에서 telnet localhost 3306

mysql 에 접속됨

-> Windows 7에서 telnet 설치 방법

"제어판 > 프로그램 > Windows 기능 사용/사용 안 함 > 텔넷 클라이언트"


추측 : 혹시 database 를 지정하지 않아서 그럴까?

시도 : 

외부에서 $mysql -h 123.456.789.0 -u root -p test   ( 데이터베이스 이름을 명시적으로 지정 )

결과 : Enter password:

pwd 를 입력하는 메시지로 변경

root 패스워드는 입력 안했는데, 엔터치면 실패.


시도 : 

로컬에서 

mysql> GRANT ALL PRIVILEGES ON *.* TO test계정@'%' IDENTIFIED BY 'test암호';

외부에서 

$mysql -h 123.456.789.0 -u test계정 -p 데이터베이스명   ( 데이터베이스 이름을 명시적으로 지정 )

결과 : Enter password:test암호

접속성공.


결론 : 

외부에서 접속하려면 명시적으로 데이터베이스 이름을 써 줘야 된다.

외부에서 접속하려면 암호가 설정된 계정만 이용 가능.


자세한 내용은 

http://kldp.org/node/26673

http://kldp.org/node/31596

http://www.i-swear.com/148

http://nasurada.tistory.com/126


참조.


또다른 결론 :

"root" , "admin", "administrator" 라는 아이디를 쓰는 모든 계정의 암호는 반드시 설정하는 게 정신건강상 좋다. 그게 진리임.


씨바. 내 6시간.

 


반응형