Nginx安全优化包括:删除不要的模块、修改版本信息、限制并发、拒绝非法请求、防止buffer溢出。
MySQL安全优化包括:初始化安全脚本、密码安全、备份与还原、数据安全。
Tomcat安全优化包括:隐藏版本信息、降权启动、删除默认测试页面.
优化Nginx服务的安全配置
1) 删除不需要的模块
[root@proxy ~]# tar -xf nginx-1.12.tar.gz
[root@proxy ~]# cd nginx-1.12
./configure --without-http_autoindex_module --without-http_ssi_module //--without禁用自动索引文件目录模块和ssi指令模块
[root@proxy nginx-1.12]# make
[root@proxy nginx-1.12]# make install
2) 修改版本信息,并隐藏具体的版本号
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf //隐藏版本号
… …
http{
server_tokens off; //手动添加该行,隐藏版本信息,显示软件为nginx
… …
}
[root@proxy ~]# nginx -s reload
[root@proxy ~]# curl -I http://192.168.4.5 //I大写的i,查看服务器响应的头部信息,版本信息隐藏,但还显示软件为nginx
[root@proxy nginx-1.12]# vim +48 src/http/ngx_http_header_filter_module.c //源码包目录下执行
static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
//下面是我们修改后的效果:
static u_char ngx_http_server_string[] = "Server: Jacob" CRLF;
static u_char ngx_http_server_full_string[] = "Server: Jacob" CRLF;
static u_char ngx_http_server_build_string[] = "Server: Jacob" CRLF;
[root@proxy nginx-1.12]# ./configure //重新编译安装Nignx,版本信息将不再显示为Nginx,而是Jacob
[root@proxy nginx-1.12]# make && make install
[root@proxy nginx-1.12]# killall nginx
[root@proxy nginx-1.12]# /usr/local/nginx/sbin/nginx //启动服务
[root@proxy nginx-1.12]# curl -I http://192.168.4.5 //查看版本信息验证
3) 限制并发量(防止DDOS攻击)
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf //使用ngx_http_limit_req_module模块限制并发,模块默认安装
… …
http{
… …
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
listen 80;
server_name localhost;
limit_req zone=one burst=5; //每秒中仅接受1个请求,多余的放入漏斗,漏斗超过5个则报错
}
}
limit_req_zone语法格式如下:
limit_req_zone key zone=name:size rate=rate;
上面案例中是将客户端IP信息存储名称为one的共享内存,内存空间为10M(1M可以存储8千个IP信息,10M可以存储8万个主机连\状态,容量可以根据需要任意调整)
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
客户端使用ab测试软件测试效果:
[root@client ~]# ab -c 100 -n 100 http://192.168.4.5/
4) 拒绝非法的请求
网站使用的是HTTP协议,该协议中定义了很多方法,可以让用户连接服务器,获得需要的资源。但实际应用中一般仅需要get和post。
具体HTTP请求方法的含义如表-1所示。
未修改服务器配置前,客户端使用不同请求方法测试:
[root@client ~]# curl -i -X GET http://192.168.4.5 //正常
[root@client ~]# curl -i -X HEAD http://192.168.4.5 //正常
//curl命令选项说明:
-i选项:既显示HTTP的头部信息,也显示页面信息 -I 只显示头部信息 -X选项:指定请求服务器的方法
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf //修改配置,拒绝非法的请求
http{
server {
listen 80;
if ($request_method !~ ^(GET|POST)$ ) { //!符号表示对正则取反,~符号是正则匹配符号
return 444; //如果用户使用非GET或POST方法访问网站,则retrun返回444的错误信息
}
}
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
[root@client ~]# curl -i -X GET http://192.168.4.5 //测试GET正常
[root@client ~]# curl -i -X HEAD http://192.168.4.5 //测试HEAD报错
4) 防止buffer溢出
当客户端连接服务器时,服务器会启用各种缓存,用来存放连接的状态信息。如果攻击者发送大量的连接请求,而服务器不对缓存做限制的话,内存数据就有可能溢出(空间不足)。
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf //修改Nginx配置文件,调整各种buffer参数,可以有效降低溢出风险
http{
client_body_buffer_size 1K; //数据大小
client_header_buffer_size 1k; //头部信息大小
client_max_body_size 1k;
large_client_header_buffers 2 1k;
… …
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
数据库安全
1) 初始化安全脚本
安装完MariaDB或MySQL后,默认root没有密码,并且提供了一个任何人都可以操作的test测试数据库。有一个名称为mysql_secure_installation的脚本,该脚本可以帮助我们为root设置密码,并禁止root从远程其他主机登陆数据库,并删除测试性数据库test。
[root@proxy ~]# systemctl status mariadb //确保服务已启动
[root@proxy ~]# mysql_secure_installation //执行初始化安全脚本
2)密码安全
[root@proxy ~]# mysqladmin -uroot -predhat password 'mysql' //修改密码,旧密码为redhat,新密码为mysql
[root@proxy ~]# mysql -uroot -pmysql
MariaDB [(none)]>set password for root@'localhost'=password('redhat'); //使用账户登录数据库,修改密码
MariaDB [(none)]> select user,host,password from mysql.user;
+--------+---------+---------------------------------------------+
| user | host | password |
+--------+---------+---------------------------------------------+
| root | localhost | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
| root | 127.0.0.1 | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
| root | ::1 | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
+--------+-----------+--------------------------------------------+
[root@proxy ~]# cat .bash_history //通过命令行修改的密码,.bash_history会自动记录历史,历史记录中记录了明文密码
mysqladmin -uroot -pxxx password 'redhat'
[root@proxy ~]# cat .mysql_history //通过mysql命令修改的密码,.mysql_history会自动记录所有操作指令,记录了明文密码
set password for root@'localhost'=password('redhat');
select user,host,password from mysql.user;
flush privileges;
另外数据库还有一个binlog日志里也有明文密码(5.6版本后修复了)。
管理好自己的历史,不使用明文登录,选择合适的版本5.6以后的版本,
日志,行为审计(找到行为人),使用防火墙从TCP层设置ACL(禁止外网接触数据库)。
3)数据备份与还原
[root@proxy ~]# mysqldump -uroot -predhat mydb table > table.sql //备份数据库中的某个数据表,用户名为root,密码为redhat
[root@proxy ~]# mysqldump -uroot -predhat mydb > mydb.sql //备份某个数据库
[root@proxy ~]# mysqldump -uroot -predhat --all-databases > all.sql //备份所有数据库
[root@proxy ~]# mysql -uroot -predhat mydb < table.sql //还原数据表
[root@proxy ~]# mysql -uroot -predhat mydb < mydb.sql //还原数据库
[root@proxy ~]# mysql -uroot -predhat < all.sql //还原所有数据库
4)数据安全
A:
[root@proxy ~]# mysql -uroot -predhat //使用管理员,登陆数据库
MariaDB [(none)]> grant all on *.* to tom@'%' identified by '123'; //创建一个数据库账户tom, %表示可以在任何地方登陆
tcpdump -w log -i any src or dst port 3306 //使用tcpdump抓取源或目标端口是3306的数据包,保存到log文件中
B:
[root@client ~]# mysql -utom -p123 -h 192.168.4.5 //在B主机使用mysql命令登陆远程数据库服务器A;用户名tom,密码123
MariaDB [(none)]> select * from mysql.user; //登陆数据库后,任意执行一条查询语句,回到服务器查看抓取的数据包
[root@proxy ~]# tcpdump -A -r log //使用tcpdump查看之前抓取的数据包,很多数据库的数据都明文显示出来
可以使用SSH远程连接服务器后,再从本地登陆数据库(避免在网络中传输数据,因为网络环境中不知道有没有抓包者)。
或者也可以使用SSL对MySQL服务器进行加密,类似与HTTP+SSL一样,MySQL也支持SSL加密(确保网络中传输的数据是被加密的)。
Tomcat安全性
1) 隐藏版本信息、修改tomcat主配置文件(隐藏版本信息)
[root@proxy ~]# curl -I http://192.168.2.100:8080/xx //-I访问不存在的页面文件,查看头部信息(版本信息)
[root@proxy ~]# curl -I http://192.168.2.100:8080 //-I访问存在的页面文件,查看头部信息(版本信息)
[root@proxy ~]# curl http://192.168.2.100:8080/xx //正常访问不存在的页面文件,查看错误信息(版本信息)
[root@web1 tomcat]# yum -y install java-1.8.0-openjdk-devel
[root@web1 tomcat]# cd /usr/local/tomcat/lib/
[root@web1 lib]# jar -xf catalina.jar //解压jar包
[root@web1 lib]# vim org/apache/catalina/util/ServerInfo.properties //根据自己的需要,修改版本信息的内容(错误页面中版本信息)
[root@web1 lib]# vim /usr/local/tomcat/conf/server.xml //修改版本信息,手动添加server参数(头部信息中的版本信息)
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" redirectPort="8443" server="jacob" />
[root@web1 lib]# /usr/local/tomcat/bin/shutdown.sh //关闭服务
[root@web1 lib]# /usr/local/tomcat/bin/startup.sh //启动服务
[root@proxy ~]# curl -I http://192.168.2.100:8080/xx //访问不存在的页面文件,查看头部信息
[root@proxy ~]# curl -I http://192.168.2.100:8080 //访问存在的页面文件,查看头部信息
[root@proxy ~]# curl http://192.168.2.100:8080/xx //访问不存在的页面文件,查看错误信息
2)降级启动(普通用户启动)
[root@web1 ~]# useradd tomcat
[root@web1 ~]# chown -R tomcat:tomcat /usr/local/tomcat/ //修改tomcat目录的权限,让tomcat账户对该目录有操作权限
[root@web1 ~]# su -c /usr/local/tomcat/bin/startup.sh tomcat //使用su命令切换为tomcat账户启动tomcat服务
[root@web1 ~]# chmod +x /etc/rc.local //该文件为开机启动文件
[root@web1 ~]# vim /etc/rc.local //修改文件,添加如下内容
su -c /usr/local/tomcat/bin/startup.sh tomcat
3)删除默认的测试页面
[root@web1 ~]# rm -rf /usr/local/tomcat/webapps/*