1. 程式人生 > >MySQL5.7開啟遠端訪問及Ubuntu18.04防火牆3306埠

MySQL5.7開啟遠端訪問及Ubuntu18.04防火牆3306埠

在虛擬機器中安裝了Ubuntu18.04,MySQL5.7。系統預設的root等只能在本地訪問,host被限制為localhost,為了進行Java程式測試,本地eclipse訪問虛擬機器的資料庫,避免使用者管理混亂,特意新建一資料庫和使用者。

新建資料庫ttmsg,使用者ub64,開啟ub64使用者遠端訪問的過程。

--新建資料庫ttmsg

mysql> CREATE DATABASE ttmsg;
Query OK, 1 row affected (0.00 sec)

--新建使用者ub64,和登陸密碼,設定訪問限制為%,允許遠端訪問。
mysql> CREATE USER 'ub64'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec)

--給新建的使用者ub64訪問資料庫ttmsg的所有許可權
mysql> grant all privileges on ttmsg.* to 'ub64'@'%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)

--重新整理許可權列表,這樣就可以用ub64使用者登陸了
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

--新建資料表,開始測試。
mysql> CREATE TABLE Student(
    ->    ID   INT NOT NULL AUTO_INCREMENT,
    ->    NAME VARCHAR(20) NOT NULL,
    ->    AGE  INT NOT NULL,
    ->    PRIMARY KEY (ID)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+-----------------+
| Tables_in_ttmsg |
+-----------------+
| Student         |
+-----------------+
1 row in set (0.00 sec)

在eclipse中除錯java程式,嘗試往Student表中插入資料,報錯了。

------Records Creation--------
Exception in thread "main" org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:612)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:862)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:917)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:927)
	at com.tutorialspoint.StudentJDBCTemplate.create(StudentJDBCTemplate.java:14)
	at com.tutorialspoint.MainApp.main(MainApp.java:13)
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

好吧,檢查報錯說遠端JDBC建立失敗,沒連上。檢查一下MySQL是不是沒有開通對外的3306埠過濾,導致外部地址無法訪問呢,通過netstat命令,檢查3306埠,果然只有一個127.0.0.1:3306的監聽埠。

[email protected]:~$ netstat -ntpl
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:23              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:27017           0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 ::1:6010                :::*                    LISTEN      -

懷疑是否配置mysqld.cnf檔案,檢查bind-address的設定值問題。

vim /etc/mysql/mysql.conf.d/mysqld.cnf

#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 127.0.0.1

好吧,把bind-address修改成0.0.0.0,無限制,重啟mysql服務。重新檢查netstat,3306埠的訪問已經有所有來源地址的監聽了。

bind-address            = 0.0.0.0

[email protected]:~$ service mysql restart
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'mysql.service'.
Authenticating as: ub64-1804-1 (ub64)
Password:
==== AUTHENTICATION COMPLETE ===
[email protected]:~$ netstat -ntpl
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:23              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:27017           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 ::1:6010                :::*                    LISTEN      -

繼續程式程式碼測試,重新跑資料庫訪問程式。額(⊙﹏⊙),又出錯了,還是一樣的報錯資訊,還是沒有建立連線。

------Records Creation--------
Exception in thread "main" org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:612)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:862)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:917)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:927)
	at com.tutorialspoint.StudentJDBCTemplate.create(StudentJDBCTemplate.java:14)
	at com.tutorialspoint.MainApp.main(MainApp.java:13)
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

好吧,那應該就是系統防火牆沒有開了,我也沒有設定過。檢查防火牆通過規則,果然grep一下沒有見到3306的埠記錄。

[email protected]:~$ sudo iptables -L -n
Chain INPUT (policy DROP)
target     prot opt source               destination
ufw-before-logging-input  all  --  0.0.0.0/0            0.0.0.0/0
ufw-before-input  all  --  0.0.0.0/0            0.0.0.0/0
ufw-after-input  all  --  0.0.0.0/0            0.0.0.0/0
ufw-after-logging-input  all  --  0.0.0.0/0            0.0.0.0/0
......

[email protected]:~$ sudo iptables -L -n | grep 3306
[email protected]:~$ 

那就好辦了,iptables新增一條3306的埠允許通過規則,在重新見檢查一下iptables,這下有了。

[email protected]:~$ sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

[email protected]:~$ sudo iptables -L -n | grep 3306
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:3306
[email protected]:~$ 

重新測試程式,程式訪問成功。果然,開啟mysql的訪問,不僅要設定user表的訪問控制權限,還要設定mysqld.cnf的bind-address,同時系統防火牆規則也要配置好3306的埠通過許可權。這3個地方的控制缺一不可。

//程式日誌
------Records Creation--------
Created Record Name = Zara Age = 11
Created Record Name = Nuha Age = 2
Created Record Name = Ayan Age = 15

mysql> select * from Student ;
+----+------+-----+
| ID | NAME | AGE |
+----+------+-----+
|  1 | Zara |  11 |
|  2 | Nuha |   2 |
|  3 | Ayan |  15 |
+----+------+-----+
3 rows in set (0.00 sec)