文章目录
本文牵扯到名为
mysql
的用户和组,以及mysql程序,为明确辨析,mysql
用户和组用markdown的反引号
标识,效果:
关于创建mysql
用户和组的原因
一般我们会需要创建一个普通用户来管理数据库,而不是使用
root
用户。
实测mysql8安装完会自动创建 名为mysql
的用户和组,
原因:资料1、资料2、资料3
- SELECT … INTO OUTFILE … 是可以写文件的。
- MySQL 开在
root
上意味着它可以在系统的任何位置写任何文件。 - MySQL 攻击可以利用 sql injection 跟上面写文件的语句,在系统特定位置写特定的文件,可以在系统上执行任何命令,包括拿到一个 shell 。(细节就不说了,我也没搞过,想知道自己搜吧 …)
- MySQL 开在
mysql
用户上,保证它对系统大部分位置不可写,从而 MySQL 即使被攻击,也可以限制它对整个系统的影响。 - 在MySQL启动的时候,单进程mysqld,该进程的属主就是
mysql
。这样就保证了mysql服务的独立性,即使mysql服务被黑掉,得到了mysql
用户权限,也不会影响整个系统的安全
准备工作:删除残留文件 & 卸载多余程序!!!
- rpm查看是否有mysql和mariadb,如果有则需要卸载。
- centos7 内部集成了mariadb,而安装mysql的话会和mariadb的文件冲突,所以需要先卸载掉mariadb。会提示有依赖关系,强制卸载即可
rpm -qa | grep mariadb rpm -e mariadb-libs --nodeps
- centos7 内部集成了mariadb,而安装mysql的话会和mariadb的文件冲突,所以需要先卸载掉mariadb。会提示有依赖关系,强制卸载即可
- 删除残留文件(mariadb 和 如果安装过的mysql 的残留)。(也不一定都有残余,mysqld.log文件和var/lib/mysql文件夹会残留)
rm -f /var/log/mysqld.log # 删除mysql的log文件。 rm -rf /var/lib/mysql # 删除data目录(这是mysql的数据目录) rm /etc/my.cnf rm -rf /usr/share/mysql-8.0
userdel -r mysql 、groupdel mysql
删除mysql
用户和组(如果残留文件删除干净了,这一步也可以不执行,因为文件删除干净了,就不会有文件属于这个mysql
用户和组)。- 注意:mysql会自动创建普通用户,就叫
mysql
,来管理自身。但是自动创建的和手动创建的不大一样,自动创建的在登录系统时并不会显示在用户项中(不过可以用来登录,passwd mysql
指令修改密码后登录系统)。 - 分析:如果之前安装过mysql,卸载时之前的
mysql
用户并不会被删除,再次安装如果有属于之前这个mysql
用户的文件没有删除干净,那么很可能会启动失败(新安装的mysql文件覆盖不了旧文件,应该是因为新mysql
用户和旧mysql
用户不是一个id,虽然用户会被覆盖,但是旧文件绑定的是旧mysql
用户的id,新mysql
用户没有权限覆盖和使用旧文件),等会会写
- 注意:mysql会自动创建普通用户,就叫
安装步骤
- <一>:mysql官网下载rpm包,复制链接用迅雷下载比较快,迅雷可能会多给加一个tar的后缀,直接去掉即可
centos7是el7的包
- <二>:Xftp传输到Linux,一般放在/opt/下。可以再新建个mysql文件夹,将tar包解包到mysql/,得到几个rpm包。
mkdir mysql # CentOS6 tar -xvf mysql-8.0.19-1.el6.x86_64.rpm-bundle.tar -C /opt/mysql # CentOS7 tar -xvf mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar -C /opt/mysql
- <三>:rpm安装
执行以下安装命令时会有cd mysql # rpm命令支持通配符,rpm -ivh mysql-*直接全部安装即可。 # 但是最好还是一个一个安装,我用通配符安装后执行mysqld --initialize时出错了,又重新安装的 cd /opt/mysql/
warning ... Header V3 DSA/SHA1 Signature ... NOKEY
的错误,不用管。原因可参考链接# CentOS6下安装 mysql el6版本 命令 rpm -ivh mysql-community-common-8.0.19-1.el6.x86_64.rpm rpm -ivh mysql-community-libs-8.0.19-1.el6.x86_64.rpm rpm -ivh mysql-community-client-8.0.19-1.el6.x86_64.rpm rpm -ivh mysql-community-server-8.0.19-1.el6.x86_64.rpm # CentOS7下安装 mysql el7版本 命令 rpm -ivh mysql-community-common-8.0.19-1.el7.x86_64.rpm rpm -ivh mysql-community-libs-8.0.19-1.el7.x86_64.rpm rpm -ivh mysql-community-client-8.0.19-1.el7.x86_64.rpm # 如果下一步提示缺少libaio.so,需执行`yum install libaio`再次执行下面命令 rpm -ivh mysql-community-server-8.0.19-1.el7.x86_64.rpm
- [四](此步不需要):安装完成后,执行
mysqld --initialize
初始化命令 (生成log文件,给root分配随机密码,创建基础数据库(在data目录内,初始化之前无文件)等。- 实测mysql8即使不执行这条命令,启动时也会自动初始化,效果如下:
- 实测mysql8即使不执行这条命令,启动时也会自动初始化,效果如下:
- [五](此步不需要):实测mysql8安装完成后(安装完mysql-community-server),会自动创建
mysql
用户和组,如果没有则先创建。# 查看是否有mysql用户和组: # 方法一: id mysql # 方法二: cat /etc/passwd 查看用户列表 cat /etc/group 查看用户组列表
- [六](此步不需要):修改 数据目录(data目录) 权限给
mysql
用户和组 。实测mysql8安装完后,文件权限默认分配给了mysql
用户和组,如图(如果没有则执行chown -R mysql:mysql /var/lib/mysql
)
- 【附1】:查看mysql配置文件位置:
mysqld --verbose --help |grep -A 1 'Default options'
- 【附2】:查看data目录位置:进入mysql配置文件
vim /etc/my.cnf
查看可知datadir=/var/lib/mysql/
- 【附1】:查看mysql配置文件位置:
- <七>:启动
# CentOS6 service mysqld start # CentOS7 systemctl start mysqld
- 若启动失败:先看log文件报什么错,上图有log文件位置(/var/log/mysqld.log)。对应错误自行解决。(有一个问题不好排查:因为之前安装过mysql,残留的log文件或data目录等没有删除,新安装时默认用自动生成的新
mysql
用户创建文件,但是没有这两个的权限无法覆盖和使用,那么初始化时会失败。可以尝试现在用root
用户删除,然后初始化生成密码,再启动) - 设置开机自启(实测mysql8默认开机自启)
# CentOS6 chkconfig mysqld on # CentOS7 systemctl enable mysql
- 若启动失败:先看log文件报什么错,上图有log文件位置(/var/log/mysqld.log)。对应错误自行解决。(有一个问题不好排查:因为之前安装过mysql,残留的log文件或data目录等没有删除,新安装时默认用自动生成的新
- <八>:
mysql -u root -p
登录数据库 (此处root用户是mysql的root用户,而不是系统的root
用户。开始时创建的mysql
用户和组也是系统的,并不是mysql的)- 密码在log文件中,可执行
grep "password" /var/log/mysqld.log
查看
- 密码在log文件中,可执行
- <九>:要求必须修改root密码,否则不能进行操作。执行:
ALTER USER 'root'@'localhost' IDENTIFIED BY '密码';
- 注意:mysql5.7起,默认安装了密码安全检查插件(validate_password),默认密码检查策略要求密码必须包含:大小写字母、数字和特殊符号,并且长度不能少于8位。否则会提示ERROR 1819 (HY000): Your password does not satisfy the current policy requirements错误。
- [十]:完成,
show databases
可看到有初始数据库。
添加远程登录用户
此处root用户是mysql的root用户,而不是系统的
root
用户。开始时创建的mysql
用户和组也是系统的,并不是mysql的
默认只允许root用户在本地登录,如果要在其它机器上连接mysql,必须修改root用户允许远程连接,或者添加一个允许远程连接的帐户。
修改root远程访问权限:use mysql;
> select host, user from user;
查看表格中 root 用户的 host,默认应该显示的 localhost,只支持本地访问,不允许远程访问。
授权 root 用户的所有权限并设置远程访问:update user set host='%' where user ='root';
> flush privileges;
要刷新权限才生效
防火墙放行3306端口
- CentOS6:
vim /etc/sysconfig/iptables
,新增如下红框内容,然后重启防火墙service iptables restart
- CentOS7:默认没有开启防火墙firewalld,开启命令
systemctl start firewalld
。放行mysql命令firewall-cmd --permanent --add-service=mysql
,重启防火墙firewall-cmd --reload
修改默认编码格式
mysql8.0默认编码方式为utf8mb4,因此使用时不需要修改。可用SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
查看。
个人记录
文件权限问题
- 把data目录所有者和组修改为
root
用户,会启动失败。
- log文件中有失败原因
Permission denied
应该是权限出了问题
mysqld: File './binlog.index' not found (OS errno 13 - Permission denied) 2020-02-25T11:59:42.879908Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19) starting as process 9241 2020-02-25T11:59:42.882557Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-02-25T11:59:42.882687Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.
- log文件中有失败原因
- 将data目录权限改回
mysql
,启动成功。发现mysql进程的UID是mysql
用户,而不是root
用户,所以启动不起来的原因难道是没有data目录的读取权限?查看文件权限发现果真如此,其他组用户只有执行权限,刚才data目录所有者和所有组是root
,用mysql
用户启动,必然读取不了root
用户的文件,如图:
- 其实这里也体现出了用一个普通用户管理数据库的必要性,文章开头已经讲到了:
指定用户启动服务
也可以在/etc/rc.d/init.d/mysqld 修改启动脚本,把user=mysql改为user=root。但是最后还是不能stop,只能kill,不知道为啥
- 但是查看进程信息时可以看到,进程启动时所执行的命令,其中有 --user=mysql
- 那么我们把data目录权限再改成
root
,然后执行service mysqld start --user=root
,这下可以看到,成功以root
用户启动了mysql
- 再试一下关掉服务,但是会发现关不了。其实细心一点会发现,加了
--user=root
选项后,另一个mysql进程的启动指令在--user=mysql
基础之上也加了个--user=root
,那么直接kill掉就可以了。如图:
mysql运行在root上的风险试验
那么为什么不以
root
用户启动mysql呢,这里我试验一下,这才是我一开始就想实验的
试验的过程中,可能会出现启动失败的情况,执行chown -R mysql:mysql /var/lib/mysql
基本就能解决
- 实验猜想:用root用户启动mysql,在/etc/my.cnf添加
secure_file_priv=/root/
执行SELECT "hello" INTO OUTFILE "/root/hello.txt"
,看能否在/root/目录写入文件。- 如果能在/root/下写入文件,则对应文章开头,应该能说明有风险。其实更准确的试验应该是黑到mysql数据库启动的用户,然后进行系统文件的修改,但是我没这本事。。。
- 第一步:在/etc/rc.d/init.d/mysqld 修改启动脚本,把user=mysql改为user=root
- 第二步:在/etc/my.cnf添加
secure_file_priv=/root/
- 第三步:启动—失败,原因是没有/root目录的权限。。???我都用
root
启动了,还没有这个目录的权限。
- 已经花费很长时间了,试验先暂停吧,以后可能就知道怎么回事了,毕竟还不精通linux。
- 如果不写secure_file_priv=/root/是可以启动成功的,启动用户也会是
root
。失败原因可能是启动脚本没有修改全面,毕竟只改了user=root,或许没有完全把mysql的启动者改成root
,可能还有其他需要改的
- 如果不写secure_file_priv=/root/是可以启动成功的,启动用户也会是
- 至此,瞎捣鼓了半天,可能会启动失败,执行
chown -R mysql:mysql /var/lib/mysql
基本就能解决
😁欢迎加入QQ群交流: [游戏-Web-开发技术栈 ☄️] ‘300567032’
点击下方图标一键加入!