系统环境

➜  ~ cat /proc/version 
Linux version 4.18.0-80.el8.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 8.2.1 20180905 (Red Hat 8.2.1-3) (GCC)) #1 SMP Tue Jun 4 09:19:46 UTC 2019
➜  ~ cat /etc/redhat-release
CentOS Linux release 8.0.1905 (Core) 
➜  ~ docker --version
Docker version 19.03.5, build 633a0ea

需求场景

使用docker运行一个可在外网访问的mysql8.0.17数据库

操作小记

# 配置防火墙 开放端口
## 将状态为ESTABLISHED,RELATED的报文放行
➜  ~ iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
## 给发往3307端口的第一个报文放行 
➜  ~ iptables -A INPUT -m state --state NEW -p tcp --dport 3307 -j ACCEPT
## 保存到配置文件iptables中
➜  ~ iptables-save > /etc/sysconfig/iptables
## 显示配置信息
➜  ~ iptables -t filter -nxvL
## 拉去mysql:8.0.17
➜  ~ docker pull mysql:8.0.17
## 显示docker镜像
➜  ~ docker images
## 创建容器
### -d: 在后台运行容器并输出容器id到终端
### --name lgf_mysql: 容器名称为lgf_mysql
### -p 3307:3306: 宿主机3307端口与容器3306端口进行映射
### -e MYSQL_ROOT_PASSWORD=lgf666: mysql用户root的密码为lgf666
### b8fd9553f1f0: 镜像名称
➜  ~ docker run -d --name lgf_mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=lgf666 b8fd9553f1f0
## 显示所有容器
➜  ~ docker ps -a

# 另一个机器终端
ddu-virtual-machine% mysql -h192.168.19.203 -uroot -P3307 -plgf666


# 解决mysql无法外部访问
## 进入lgf_mysql容器
➜  ~ docker exec -it lgf_mysql bin/bash
## 进入mysql服务
root@7d78b79851a0:/# mysql -uroot -plgf666
## 选择mysql数据库
mysql> use mysql
## 查看现有用户
mysql> select host,user,authentication_string from user;
## 进行授权远程连接
mysql> GRANT ALL ON *.* TO 'root'@'%';
## 更改密码规则
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'lgf666';
## 刷新权限
mysql> FLUSH PRIVILEGES;

附录

docker常用命令

  • systemctl start docker: 启动docker
  • systemctl restart docker: 重启docker
  • docker systemctl stop docker: 停止docker
  • docker start [container_name]: 启动某个容器

/etc/sysconfig/iptables

*security
:INPUT ACCEPT [3706:2074972]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [3325:445570]
COMMIT

# 关闭nat表上启用的连接追踪机制
*raw
:PREROUTING ACCEPT [3706:2074972]
:OUTPUT ACCEPT [3325:445570]
COMMIT

# 拆解报文,做出修改,并重新封装的功能
*mangle
:PREROUTING ACCEPT [3706:2074972]
:INPUT ACCEPT [3706:2074972]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [3325:445570]
:POSTROUTING ACCEPT [3325:445570]
COMMIT

# network address translation,网络地址转换功能
*nat
:PREROUTING ACCEPT [1:36]
:INPUT ACCEPT [1:36]
:POSTROUTING ACCEPT [1:260]
:OUTPUT ACCEPT [1:260]
COMMIT

# 负责过滤功能,防火墙
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [3325:445570]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -j DROP
COMMIT

说明

报文流向常见场景

  • 到本机某进程的报文:PREROUTING --> INPUT
  • 由本机转发的报文:PREROUTING --> FORWARD --> POSTROUTING
  • 由本机的某进程发出报文(通常为响应报文):OUTPUT --> POSTROUTING

处理动作

  • ACCEPT:运行数据包通过
  • DROP:直接丢弃数据包,不给任何回应信息
  • REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息
  • SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题
  • MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上
  • DNAT:目标地址转换
  • REDIRECT:在本机做端口映射
  • LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配

规则语句详解

  • :INPUT ACCEPT [0:0]:该规则表示INPUT表默认策略是ACCEPT
  • :INPUT ACCEPT [0:0]:该规则表示INPUT表默认策略是ACCEPT
  • :OUTPUT ACCEPT [0:0]:该规则表示OUTPUT表默认策略是ACCEPT
  • -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT:意思是允许进入的数据包只能是刚刚我发出去的数据包的回应,ESTABLISHED:已建立的链接状态。RELATED:该数据包与本机发出的数据包有关
  • A INPUT -j REJECT --reject-with icmp-host-prohibitedA FORWARD -j REJECT --reject-with icmp-host-prohibited:这两条的意思是在INPUT表和FORWARD表中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机

state模块中的状态

  • NEW:连接中的第一个包
  • ESTABLISHED/RELATED:连接建立
  • INVALID:如果一个包没有办法被识别,或者这个包没有任何状态
  • UNTRACKED:报文未被追踪或无法找到相关的连接

netstat

  • a (all)显示所有选项,默
  • 认不显示LISTEN相关
  • t (tcp)仅显示tcp相关选项
  • u (udp)仅显示udp相关选项
  • n 拒绝显示别名,能显示数字的全部转化成数字。
  • l 仅列出有在 Listen (监听) 的服務状态
  • p 显示建立相关链接的程序名
  • r 显示路由信息,路由表
  • e 显示扩展信息,例如uid等
  • s 按各个协议进行统计
  • c 每隔一个固定时间,执行该netstat命令。

防火墙配置

vim /etc/sysconfig/iptables

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 3306 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -j DROP
iptables-save > /etc/sysconfig/iptables

iptables -t filter -nxvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
      78     4380 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
       0        0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
       0        0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:3306
       0        0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
       1       36 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 61 packets, 5832 bytes)
    pkts      bytes target     prot opt in     out     source               destination

# 开放所有接口
iptables -t filter -A INPUT -j ACCEPT

mysql

新建用户

CREATE USER "username"@"host" IDENTIFIED BY "password"

# Example:
# localhost: 本地登陆
CREATE USER 'test'@'localhost' IDENTIFIED BY '123'
# ip: ip地址登陆
CREATE USER 'test'@'192.168.19.100' IDENTIFIED BY '123'
# %: 外网ip登陆
CREATE USER 'test'@'%' IDENTIFIED BY '123'

删除用户

DROP USER 'username'@'host'

授权

grant privileges on databasename.tablename to 'username'@'host' IDENTIFIED BY 'PASSWORD';

# priveleges(权限列表),可以是all priveleges, 表示所有权限,也可以是select、update等权限,多个权限的名词,相互之间用逗号分开。
# on用来指定权限针对哪些库和表。
# *.* 中前面的*号用来指定数据库名,后面的*号用来指定表名
# to 表示将权限赋予某个用户
# identified by指定用户的登录密码,该项可以省略
# WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人

# Example:
# 授予用户通过外网IP对于该数据库的全部权限
grant all privileges on `test`.* to 'test'@'%' ;

# 授予用户在本地服务器对该数据库的全部权限
grant all privileges on `test`.* to 'test'@'localhost';   
# 给予查询权限
grant select on test.* to 'user1'@'localhost'; 
# 添加插入权限
grant insert on test.* to 'user1'@'localhost'; 
# 添加删除权限
grant delete on test.* to 'user1'@'localhost'; 
# 添加权限
grant update on test.* to 'user1'@'localhost';

查看权限

SHOW GRANTS;
show grants for 'root'@'%';

删除权限

revoke delete on test.* from 'jack'@'localhost';

更改用户名

rename user 'jack'@'%' to 'jim'@'%';

修改密码

# 用set password命令
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');

# 用mysqladmin [root@rhel5 ~]# mysqladmin -uroot -p123456 password 1234abcd
mysqladmin -u用户名 -p旧密码 password 新密码

# 用update直接编辑user表