아아....이걸 하려고 세시간 ~ 여섯시간 정도를 쓴 거 같아.
결론은 어처구니 없는 게 원인이었다.
혹시 나같은 사람이 또 있을까 싶어, 증상과 해결책을 기록한다.
아래 글에서,
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://nasurada.tistory.com/126
참조.
또다른 결론 :
"root" , "admin", "administrator" 라는 아이디를 쓰는 모든 계정의 암호는 반드시 설정하는 게 정신건강상 좋다. 그게 진리임.
씨바. 내 6시간.
'프로그램 > mysql' 카테고리의 다른 글
Linux 에서 C 컴파일용 mysql library + header file 구하기. (0) | 2013.08.05 |
---|---|
Linux + C/C++ + Mysql 예제 (0) | 2013.07.31 |
MySql 로 접속할 때 "Authentication with old password no longer supported, use 4.1 style password" (2) | 2013.07.25 |
printf 에서 동적 변수 지정. (0) | 2011.11.16 |
mysql 에서는 alter 의 문법이 다르다. (0) | 2011.11.16 |