MySQL数据库安全加固(环境还是用之前装的ubuntu进行测试,详见文章39http://t.csdnimg.cn/7tuY2)
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 |
+-----------+------------------+
记录的是客户端的IP地址
默认是本地连接
练习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(练习2的目的就是为了防爆破,不改用户名默认的就是在黑客的爆破字典中)
练习3:mysql用户及用户权限综合练习
可以切换到刚装好dvwa时的镜像,或者自己改登录信息
#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 |
+-----------+------------------+
掌握的知识:对用户进行增删改查;对用户授权、撤销权限。 grant /revoke/show grants
练习4: mysql口令策略(口令复杂度)练习
mysql口令策略需要相关插件,在我们使用的mysql 5.7中插件已经存在,只是默认情况下没有启用。
0.查看插件
SHOW VARIABLES LIKE 'plugin_dir';
用于显示服务器变量 plugin_dir
的值。这个特定的变量表示MySQL插件目录的路径。
#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> create user testuser2 identified by 'User_1234';
//创建新用户时密码得高强度
Query OK, 0 rows affected (0.00 sec)
mysql> exit;
# 重新登录
tedu@ubuntu:~$ mysql -utestuser2 -pUser_1234
mysql>
练习4比较重要的,我一般我们都会用到
练习5:登录失败处理练习
0.查看插件 connection_control.so是失败处理
#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查看策略变量配置(之后登录失败去验证一下,会看到失败三次后延时10秒)以上都是为了防止黑客爆破
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.查看进程(mysqld d表示守护进程)(我们这个虚拟机默认是mysql了,其它的可以先看进程)
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数据目录所属的账户(可以看到是root,所以不够安全)
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连接。(我这个环境是10网段)(执行这个后就只能在物理机上去连接过去了,本地就不让了)
mysql> update mysql.user set host='192.168.10.1' where user='root';
3.重启mysql
service mysql restart
4.尝试远程连接,连接成功(在物理机上执行)
mysql -uroot -proot -h192.168.10.137(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.131
注意: 即使远程客户端已连接,再执行操作时,也会提示连接失败。
练习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 'd:\\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,执行加载又成功了!
安全审计
总结:
1.检查并删除可疑账户,修改默认账户,例如root的账号名
2.设置mysql账户的密码复杂度,登录失败处理(防爆破)
3.最小权限原则
4.尽量不要使用root远程登录,或不需要时,禁止远程登录(如果网站站库分离,则创建与当前网站相关的用户而不是直接使用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
Group apache
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安全审计
acc是访问日志,error是错误日志,audit是审计日志,
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
增加如下图所示的信息设置。第一个就是对于/var/www/html下的目录不允许访问的,第2个允许访问/var/www/html/DVWA下边所有的
<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服务。
- 再次访问网站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所示
其实这个是可定制的,可以通过web容器定制也可以通过web应用定制,避免敏感信息的泄露
练习4:将Apache的默认端口80修改为端口81
1.通过浏览器访问登录页面,默认端口80,显示结果如图所示
2.使用sudo vi /etc/apache2/ports.conf命令打开配置文件,增加如图所示的信息设置。
注意:修改的是端口文件ports.conf,不是配置文件。![](https://i-blog.csdnimg.cn/direct/8b0b28cb80c04d13b750250ba03dbd39.png)
3.通过 sudo systemctl restart apache2命令重启apache服务。
4.再次通过浏览器访问登录页面,增加端口81,显示结果如图所示
练习5:隐藏Apache版本,防止信息泄露
和我们的那个404那个有区别
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访问,发现没有服务器信息了,。如图-17所示