MySQL数据库安全加固 web容器Apache安全加固 一、mysql安全加固 1.mysql身份鉴别 默认账号:数据库系统默认普通账号或测试账号需要关闭或者删除 默认管理员账号:默认的管理员账号或管理测试账号需要关闭或删除,高权限账号需要控制 口令策略:口令的长度、复杂度、账号权限等严格按照等保或公司要求来设置 登录失败处理:设置登录失败的次数、等待时间等提升口令的安全,防止爆破等攻击 练习1:添加/删除/查看用户练习 #1.登录 tedu@ubuntu:~$ mysql -uroot -proot #2.查看所有数据库 mysql> show databases; #3.设置当前数据库 mysql> use mysql; #4.查看当前数据库所有表 mysql> show tables; #5.查看表中有哪些列 mysql> desc user; #6.获取用户信息 mysql> select host,user from mysql.user; #7.创建用户 mysql> create user testuser identified by '123456'; #8.创建用户 mysql> create user 'testuser2'@'localhost' identified by '123456'; #9.查看 +-----------+------------------+ | host | user | +-----------+------------------+ | % | testuser | | localhost | debian-sys-maint | | localhost | dvwa | | localhost | mysql.session | | localhost | mysql.sys | | localhost | root | | localhost | testuser2 | +-----------+------------------+ #10.删除账号 mysql> drop user testuser; mysql> drop user 'testuser2'@'localhost'; #11.重新查看 mysql> select host,user from mysql.user; +-----------+------------------+ | host | user | +-----------+------------------+ | localhost | debian-sys-maint | | localhost | dvwa | | localhost | mysql.session | | localhost | mysql.sys | | localhost | root | +-----------+------------------+ 练习2:mysql修改MySQL的root用户的密码,修改MySQL的root用户名 #1.通过alter user命令修改用户 密码 tedu@ubuntu:~$ mysql -uroot -proot mysql> alter user root@localhost identified by '123456'; mysql> exit; #2.通过基本的数据操作update修改表中的数据方式修改 用户名 tedu@ubuntu:~$ mysql -uroot -p123456 mysql> select host,user from mysql.user; mysql> update mysql.user set user='myroot' where user='root'; mysql> select host,user from mysql.user; mysql> exit; tedu@ubuntu:~$ service mysql restart tedu@ubuntu:~$ mysql -umyroot -p123456 一定要注意:修改了用户名后,需要重启mysql 练习3:mysql用户及用户权限综合练习 #1.root用户登录mysql tedu@ubuntu:~$ mysql -uroot -proot #2.查看所有用户 mysql> select host,user from mysql.user; #3.查看dvwa用户权限 mysql> show grants for 'dvwa'@'localhost'; # USAGE 权限表示可以连接到数据库服务器 # 第二行表示对dvwa数据库有所有权限 +--------------------------------------------------------+ | Grants for dvwa@localhost | +--------------------------------------------------------+ | GRANT USAGE ON *.* TO 'dvwa'@'localhost' | | GRANT ALL PRIVILEGES ON `dvwa`.* TO 'dvwa'@'localhost' | +--------------------------------------------------------+ #4.查看root用户权限 mysql> show grants for 'root'@'localhost'; # 第一行表示root拥有对所有数据库的所有权限 # 第二行是代理权限,可以不用关注 +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | | GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+ #5.创建用户 mysql> create user testuser identified by '123456'; #6.查看所有用户 mysql> select host,user from mysql.user; # % 表示通过该用户可以任意远程连接但是需要配置文件的配合,默认配置不支持远程。 # localhost表示通过该用户只能本地连接 +-----------+------------------+ | host | user | +-----------+------------------+ | % | testuser | | localhost | debian-sys-maint | | localhost | dvwa | | localhost | mysql.session | | localhost | mysql.sys | | localhost | root | +-----------+------------------+ #7.查看testuser用户的权限,注意与其他用户的区别 mysql> show grants for testuser; # 只有连接权限 +--------------------------------------+ | Grants for testuser@% | +--------------------------------------+ | GRANT USAGE ON *.* TO 'testuser'@'%' | +--------------------------------------+ #8.退出,尝试使用testuser用户连接 mysql> exit; tedu@ubuntu:~$ mysql -utestuser -p123456 mysql> show databases; # 只能查看 information_schema +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ # 以下两个操作都会失败,因为没有权限 mysql> select host,user from mysql.user; ERROR 1142 (42000): SELECT command denied to user 'testuser'@'localhost' for table 'user' mysql> create database testDB; ERROR 1044 (42000): Access denied for user 'testuser'@'%' to database 'testDB' # 9.重新以root登录 mysql> exit; mysql> mysql -uroot -proot; # 10.为testuser授于所有数据库的所有操作权限 mysql> grant all privileges on *.* to testuser identified by '123456' WITH GRANT OPTION; # 11.查看testuser权限 mysql> show grants for testuser; +-----------------------------------------------------------------+ | Grants for testuser@% | +-----------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'testuser'@'%' WITH GRANT OPTION | +-----------------------------------------------------------------+ # 12.使用testuser重新登录,查看所有数据库,与以前是有区别的 mysql> exit; tedu@ubuntu:~$ mysql -utestuser -p123456 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | dvwa | | mysql | | performance_schema | | sys | +--------------------+ # 12.撤销testuser用户所有权限 mysql> exit; # mysql -uroot -proot mysql> revoke insert,delete on *.* from testuser; mysql> show grants for testuser; mysql> revoke all privileges on *.* from testuser; mysql> show grants for testuser; # 13.修改密码,并使用新密码登录 mysql> alter user testuser identified by '123.com'; mysql> exit; tedu@ubuntu:~$ mysql -utestuser -p123.com mysql> # 14.退出使用root用户登录删除testuser用户 mysql> exit; tedu@ubuntu:~$ mysql -uroot -proot mysql> drop user testuser; Query OK, 0 rows affected (0.00 sec) mysql> select host,user from mysql.user; +-----------+------------------+ | host | user | +-----------+------------------+ | localhost | debian-sys-maint | | localhost | dvwa | | localhost | mysql.session | | localhost | mysql.sys | | localhost | root | +-----------+------------------+ 掌握的知识:对用户进行增删改查;对用户授权、撤销权限。 create user/drop user/alter user/select host,user from mysql.user grant /revoke/show grants 练习4: mysql口令策略(口令复杂度)练习 mysql口令策略需要相关插件,在我们使用的mysql 5.7中插件已经存在,只是默认情况下没有启用。 0.查看插件 #1.进入mysql查看插件位置 mysql> show variables like 'plugin_dir'; +---------------+------------------------+ | Variable_name | Value | +---------------+------------------------+ | plugin_dir | /usr/lib/mysql/plugin/ | +---------------+------------------------+ #2.重新打开一个终端 tedu@ubuntu:~$ ls /usr/lib/mysql/plugin/ adt_null.so libmemcached.so semisync_master.so auth_socket.so locking_service.so semisync_slave.so connection_control.so mypluglib.so validate_password.so innodb_engine.so mysql_no_login.so version_token.so keyring_file.so rewriter.so 1.修改配置文件 tedu@ubuntu:~$ sudo vi /etc/mysql/my.cnf 增加如下内容 [mysqld] plugin-load-add=validate_password.so #服务器在启动时加载插件,并防止在服务器运行时删除插件。 validate-password=FORCE_PLUS_PERMANENT 2.重启mysql tedu@ubuntu:~$ sudo service mysql restart 3.进入mysql查看策略变量配置 mysql>SHOW VARIABLES LIKE 'validate_password%'; +--------------------------------------+--------+ | Variable_name | Value | +--------------------------------------+--------+ | validate_password_check_user_name | OFF | | validate_password_dictionary_file | | | validate_password_length | 8 | | validate_password_mixed_case_count | 1 | | validate_password_number_count | 1 | | validate_password_policy | MEDIUM | | validate_password_special_char_count | 1 | +--------------------------------------+--------+ # 验证 mysql>set global validate_password_check_user_name=ON; mysql>alter user 'root'@'localhost' identified by 'Root.1234'; mysql>exit; tedu@ubuntu:~$ mysql -uroot -pRoot.1234 mysql> create user testuser identified by '123456'; ERROR 1819 (HY000): Your password does not satisfy the current policy requirements # 如果用户存在,可以先删除 mysql> drop user testuser; mysql> create user testuser identified by 'User_1234'; Query OK, 0 rows affected (0.00 sec) mysql> exit; # 重新登录 tedu@ubuntu:~$ mysql -utestuser -pUser_1234 mysql> 练习5:登录失败处理练习 0.查看插件 #1.进入mysql查看插件位置 mysql> show variables like 'plugin_dir'; +---------------+------------------------+ | Variable_name | Value | +---------------+------------------------+ | plugin_dir | /usr/lib/mysql/plugin/ | +---------------+------------------------+ #2.重新打开一个终端 tedu@ubuntu:~$ ls /usr/lib/mysql/plugin/ adt_null.so libmemcached.so semisync_master.so auth_socket.so locking_service.so semisync_slave.so connection_control.so mypluglib.so validate_password.so innodb_engine.so mysql_no_login.so version_token.so keyring_file.so rewriter.so 1.修改配置文件 tedu@ubuntu:~$ sudo vi /etc/mysql/my.cnf 增加如下内容 [mysqld] plugin-load-add=connection_control.so #服务器在启动时加载插件,并防止在服务器运行时删除插件。 connection_control=FORCE_PLUS_PERMANENT 2.重启mysql tedu@ubuntu:~$ sudo service mysql restart 3.进入mysql查看策略变量配置 mysql> SHOW VARIABLES LIKE 'connection%'; +-------------------------------------------------+------------+ | Variable_name | Value | +-------------------------------------------------+------------+ | connection_control_failed_connections_threshold | 3 | | connection_control_max_connection_delay | 2147483647 | | connection_control_min_connection_delay | 1000(毫秒) | +-------------------------------------------------+------------+ mysql> SET GLOBAL connection_control_min_connection_delay = 10000; mysql>exit; tedu@ubuntu:~$mysql -uroot -proot1 #error tedu@ubuntu:~$mysql -uroot -proot2 #error tedu@ubuntu:~$mysql -uroot -proot3 #error tedu@ubuntu:~$mysql -uroot -proot # 10秒后进入 2.MySQL访问控制 文件权限控制:以普通权限运行数据库服务,设置属主和运行参数等; 命令历史记录保护:必要情况需要清空日志文件内容; 用户最小权限:在数据库权限配置能力内,根据用户的业务需要,配置其所需的最小权限; 超时锁定:设置超时时间,在时间内没有操作,再次操作是,就会提示超时 监听本机:数据库不需要远程访问时,可禁止远程连接 练习1:设置mysql进程的属主 避免进程属主是root。 1.修改mysql配置文件 sudo vi /etc/mysql/my.cnf 增加如下配置 [mysql.server] user=mysql 2.重启mysql服务 tedu@ubuntu:~$ sudo service mysql restart 3.查看进程 tedu@ubuntu:~$ ps -ef | grep mysqld mysql 3612 1 0 21:44 ? 00:00:00 /usr/sbin/mysqld tedu 3650 3340 0 21:45 pts/2 00:00:00 grep --color=auto mysqld 练习2:查看MySQL数据目录所属的账户是否属于mysql账户 1.查看是否存在mysql用户和mysql组 tedu@ubuntu:~$ cat /etc/passwd|grep mysql mysql:x:121:129:MySQL Server,,,:/nonexistent:/bin/false tedu@ubuntu:~$ cat /etc/group|grep mysql mysql:x:129: 结果是存在mysql用户和mysql组 2.查看mysql数据目录所属的账户 tedu@ubuntu:~$ ls -l /usr/share/mysql 总用量 2204 drwxr-xr-x 2 root root 4096 1月 6 2022 bulgarian drwxr-xr-x 2 root root 4096 1月 6 2022 charsets drwxr-xr-x 2 root root 4096 1月 6 2022 czech drwxr-xr-x 2 root root 4096 1月 6 2022 danish 3.修改后重新查看 tedu@ubuntu:~$ sudo chown -R mysql:mysql /usr/share/mysql [sudo] tedu 的密码: tedu@ubuntu:~$ ls -l /usr/share/mysql 总用量 2204 drwxr-xr-x 2 mysql mysql 4096 1月 6 2022 bulgarian drwxr-xr-x 2 mysql mysql 4096 1月 6 2022 charsets drwxr-xr-x 2 mysql mysql 4096 1月 6 2022 czech drwxr-xr-x 2 mysql mysql 4096 1月 6 2022 danish -rw-r--r-- 1 mysql mysql 1833 1月 29 2021 debian_create_root_user.sql 练习3:超时锁定 mysql> show global variables like '%timeout%'; mysql> set global interactive_timeout=300; 练习4:禁止远程连接 默认就是禁止远程连接的,如何让其支持远程连接呢? 1.打开mysql的配置文件 sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf 找到bind-address,将其注释 # bind-address = 127.0.0.1 2.查看目前有哪些用户是支持远程连接的,如果不支持可以修改。将root用户设置为支持从192.168.10.1连接。 mysql> update mysql.user set host='192.168.10.1' where user='root'; 3.重启mysql service mysql restart 4.尝试远程连接,连接成功(在物理机上执行) mysql -uroot -pRoot.1234 -h192.168.1.132(ubuntu1604的地址) 5.禁止远程连接,打开mysql的配置文件 sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf 找到bind-address这一行,将注释去掉 bind-address = 127.0.0.1 6.重启mysql service mysql restart 7.尝试连接,失败 mysql -uroot -proot -h192.168.10.132 注意: 即使远程客户端已连接,再执行操作时,也会提示连接失败。 练习5:禁止从客户端加载文件到数据库表中(在物理机上做的实验) 类似于文件上传漏洞 1.创建testdb库以及user表,user表中有id、name字段。表中没有数据 2.hello.txt文件内容 1,tedu 2,tarena 3,ntd2305 4,<script>alert(1)</script> 5,<?php eval($_POST[8])?> 3.执行以下命令,将文件中的内容加载到数据表中 use testdb; select * from user; load data local infile 'f:\\myfile\\hello.txt' into table user fields terminated by ',' lines terminated by '\n' (id,name); select * from user; 执行结果,user表中有文件的数据了,表示加载成功 4.防止加载 在mysql配置文件mysql-ini的[mysqld]部分增加下面的参数 local-infile=0 5.重启mysql,执行加载失败(sql报错)! 6.删除local-infile=0,重启mysql,执行加载又成功了! 完成练习5,15:31回来 总结: 1.检查并删除可疑账户,修改默认账户,例如root的账号名 2.设置mysql账户的密码复杂度,登录失败处理(防爆破) 3.最小权限原则 4.尽量不要使用root远程登录,或不需要时,禁止远程登录 5.不需要时,禁止通过mysql读写文件 6.不需要时,禁止客户端加载文件到数据库 二、apache安全加固 1.Apache身份识别 练习1:以专门的用户账号apache和apache组运行Apache服务 1.查看Apache服务的用户信息 ps -ef|grep apache root 2613 1 0 09:02 ? 00:00:00 /usr/sbin/apache2 -k start www-data 2616 2613 0 09:02 ? 00:00:00 /usr/sbin/apache2 -k start www-data 2617 2613 0 09:02 ? 00:00:00 /usr/sbin/apache2 -k start www-data 2618 2613 0 09:02 ? 00:00:00 /usr/sbin/apache2 -k start www-data 2619 2613 0 09:02 ? 00:00:00 /usr/sbin/apache2 -k start www-data 2620 2613 0 09:02 ? 00:00:00 /usr/sbin/apache2 -k start 不合规。 2.创建apache组,创建apache用户,并添加到apache组 sudo groupadd apache sudo useradd -g apache apache cat /etc/passwd|grep apache apache:x:1001:1001::/home/apache: cat /etc/group|grep apache apache:x:1001: 3.打开apache的配置文件apache2.conf,添加以下内容 sudo vi /etc/apache2/apache2.conf User apache #109 Group apache #110 4.重启Apache服务,并查看用户信息 service apache2 restart ps -ef|grep apache root 6716 1 0 14:37 ? 00:00:00 /usr/sbin/apache2 -k start apache 6719 6716 0 14:37 ? 00:00:00 /usr/sbin/apache2 -k start apache 6720 6716 0 14:37 ? 00:00:00 /usr/sbin/apache2 -k start apache 6721 6716 0 14:37 ? 00:00:00 /usr/sbin/apache2 -k start apache 6722 6716 0 14:37 ? 00:00:00 /usr/sbin/apache2 -k start apache 6723 6716 0 14:37 ? 00:00:00 /usr/sbin/apache2 -k start 2.Apache访问控制 练习1:配置文件和日志文件的访问权限 1.配置文件属主可读写,其他用户无权限 tedu@ubuntu:~$ sudo chmod 600 /etc/apache2/apache2.conf 2.日志文件属主可读写,其他用户只读权限 tedu@ubuntu:~$ sudo chmod 644 /var/log/apache2/*.log 3.Apache安全审计 tedu@ubuntu:~$ ls /var/log/apache2/*.log /var/log/apache2/access.log /var/log/apache2/error.log /var/log/apache2/modsec_audit.log /var/log/apache2/other_vhosts_access.log 4.Apache入侵防范 练习1:设置Apache,禁止访问除了 /var/www/html/DVWA之外的任何目录 1.使用sudo vi /etc/apache2/apache2.conf命令打开配置文件 tedu@ubuntu:~$ sudo vi /etc/apache2/apache2.conf 增加如下图所示的信息设置。 <Directory /var/www/html> Order Deny,Allow Deny from all </Directory> <Directory /var/www/html/DVWA> Order Allow,Deny Allow from all </Directory> 2.重启apache服务 tedu@ubuntu:~$ sudo systemctl restart apache2 3.查看结果,首先访问网站根目录,页面如图所示,很明显是禁止访问的 注意:受缓存影响,有可能也可以看到apache默认页面,可以清除浏览器缓存,重新访问。 然后访问网站根目录下的DVWA目录,很明显是可以访问的。 练习2:设置Apache,禁止用户查看/var/www/html/DVWA/config目录列表 1.首先访问网站url: http://192.168.10.138/DVWA/config,可以看到目录列表的 2.使用sudo vi /etc/apache2/apache2.conf命令打开配置文件,增加如图所示的信息设置。 3.通过 sudo systemctl restart apache2或service apache2 restart命令重启apache服务。 4. 再次访问网站url: http://192.168.10.138/DVWA/config,页面如下图所示 练习3:将404错误页面重定向,防止Apache信息泄露 实现此案例需要按照如下步骤进行。 1.通过浏览器访问一个不存在的url,显示结果如图-9所示 2.使用sudo vi /etc/apache2/apache2.conf命令打开配置文件,增加如图所示的信息设置。 ErrorDocument 404 "<h1>Custom 404 Page</h1>" 3.通过 sudo systemctl restart apache2命令重启apache服务。 4.再次通过浏览器访问一个不存在的url,显示结果如图-11所示 练习4:将Apache的默认端口80修改为端口81 1.通过浏览器访问登录页面,默认端口80,显示结果如图所示 2.使用sudo vi /etc/apache2/ports.conf命令打开配置文件,增加如图所示的信息设置。 注意:修改的是端口文件ports.conf,不是配置文件。 3.通过 sudo systemctl restart apache2命令重启apache服务。 4.再次通过浏览器访问登录页面,增加端口81,显示结果如图所示 练习5:隐藏Apache版本,防止信息泄露 1.使用sudo apt install curl命令安装curl工具,使用curl访问,发现返回了服务器信息。 2.使用sudo vi /etc/apache2/apache2.conf命令打开配置文件,增加如图-16所示的信息设置 注意:写到配置文件的最后面 ServerTokens Prod ServerSignature off 3.通过 sudo systemctl restart apache2命令重启apache服务 4.再次使用curl访问,发现没有服务器信息了,。