apache安全配置
apache运行原理
Apache是基于模块化设计的,它的核心代码并不多,大多数的功能都被分散到各个模块中,各个模块在系统启动的时候按需载入。从配置文件中可以看到加载的各个模块。
apache在启动阶段采用root权限来获取更多的资源使用权限,这个时候会加载配置文件,模块,资源文件等,在下一个运行阶段,Apache为了获得系统资源最大的使用权限,将以特权用户root完成启动。分11个阶段处理用户的请求。
apache的两种工作模式
Apache通过MPM(多路处理模块)来使用操作系统的资源,对进程和线程池进行管理。Apache为了能够获得更好的运行性能,针对不同的平台 (Unix/Linux、Window)提供了不同的MPM,用户可以根据实际情况进行选择,其中最常使用的MPM有 prefork和worker两种。
prefork
一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的 (spare)或是空闲的子进程用于迎接即将到来的请求。这样客户端就无需在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身份运行以便邦定80端口,而 Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于配置子进程的低特权用户。
worker
每个进程能够拥有的线程数量是固定的。服务器会根据负载情况增加或减少进程数量。一个单独的控制进程(父进程)负责子进程的建立。每个子进程能够建立 ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。Apache总是试图维持一个备 用(spare)或是空闲的服务线程池。这样,客户端无须等待新线程或新进程的建立即可得到处理。在Unix中,为了能够绑定80端口,父进程一般都是以 root身份启动,随后,Apache以较低权限的用户建立子进程和线程。User和Group指令用于配置Apache子进程的权限。
apache 在centos下配置
apache配置文件,默认文件在/etc/httpd/conf/httpd.conf路径下
那么简单理解一下,配置参数的含义和使用,Allow和Deny可以用于apache的conf文件或者.htaccess文件中(配合Directory, Location, Files等),用来控制目录和文件的访问授权。
所以,最常用的是:
Order Deny,Allow
Allow from All
注意“Deny,Allow”中间只有一个逗号,也只能有一个逗号,有空格都会出错;单词的大小写不限。上面设定的含义是先设定“先检查禁止设定,没有禁止的全部允许”,而第二句没有Deny,也就是没有禁止访问的设定,直接就是允许所有访问了。
但是如果想限制IP访问,如下写
Order Deny,Allow
Deny from 192.168.1.1
Allow from all
这时候限制不起作用,Order取规则为最后一个Allow规则,首先限制IP访问,但是会继续查看Allow规定指定的信息,IP又在all中,所以限制不起作用。所以可以如下写:
Order Deny,Allow
Deny from 192.168.1.1
或者
Order Allow,Deny
Allow from all
Deny from 192.168.1.1
比如:如下的常用配置
1、在配置文件开始部分和下部有两个配置项,用来隐藏banner信息:
ServerTokens OS
修改为:ServerTokens Prod
(在出现错误页的时候不显示服务器操作系统的名称)ServerSignature On
修改为:ServerSignature Off
(不回显apache版本信息)
2、apache在一些系统的默认配置中,开启目录浏览,所以可以使用以下关闭设置。
将Options Indexes FollowSymLinks
改为 Options -Indexes FollowSymLinks
3、取消部分目录的php执行权限
<Directory "/var/www/html/upload">
<FilesMatch "\.(?i:php|php3|php5)$">
Deny from all
</FilesMatch>
</Directory>
//在upload目录下,尽可能多匹配后缀php|php3|php5的文件,不分大小写。
还可以在主机配置文件中增加php_flag engine off指令即可,配置如下:
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
php_flag engine off
5、配置httpd.conf限制一些特殊目录的特定ip访问,如内部接口等。
<Directory "/var/www/html/aaa">
Order Deny,Allow
Deny from all
Allow from 192.168.1.111
</Directory>
6、配置httpd.conf限制一些文件类型的访问,如txt的日志
<Files ~ ".txt$">
Order allow,deny
Deny from all
</Files>
7、针对URL相对路径的禁止访问:
<Location /dir/>
Order allow,deny
Deny from all
</Location>
Nginx 安全配置
nginx 工作原理
Nginx由内核和模块组成,nginx核心模块包括:HTTP模块、EVENT模块和MAIL模块。nginx仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。nginx架构类似于Apache的Worker工作状态,Nginx的每一个Worker进程都管理着大量的线程,真正处理请求的是Worker之下的线程。
nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,fastcgi管理进程选择cgi子进程处理结果并返回被nginx。
nginx涉及到两个账户,一个是nginx的运行账户,一个是php-fpm的运行账户。如果访问的是一个静态文件,则只需要nginx的运行账户对文件具有读取权限;而如果访问的是一个php文件,则首先需要nginx的运行账户对文件有读取权限,读取到文件后发现是一个php文件,则转发给php-fpm,此时则需要php-fpm账户对文件具有读取权限。
nginx 在centos下的安全配置
- nginx设置问题
#隐藏 Nginx 的版本号,提高安全性。
server_tokens off;
#开启高效文件传输模式,sendfile 指令指定 Nginx 是否调用sendfile 函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的负载。
sendfile on;
#是否开启目录列表访问,默认关闭。
autoindex off;
开头的配置
user www-data; //用户和组
worker_processes auto; //进程数
pid /run/nginx.pid; //进程文件
include /etc/nginx/modules-enabled/*.conf; //导入其他配置文件到nginx配置文件
events配置
events {
worker_connections 768; //设置一个worker进程同时打开的最大连接数
# multi_accept on; //告诉nginx收到一个新连接通知后接受尽可能多的连接
}
http配置
http {
##
# Basic Settings
##
sendfile on; //开启高效文件传输模式
tcp_nopush on; //告诉 Nginx 在一个数据包里发送所有头文件
tcp_nodelay on; //告诉 Nginx 不要缓存数据,而是一段一段的发送
keepalive_timeout 65; //连接超时时间,单位是秒
types_hash_max_size 2048; //上传文件大小限制
# server_tokens off; //隐藏 Nginx 的版本号
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types; //包含配置
default_type application/octet-stream; //默认传输类型
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log; //访问日志
error_log /var/log/nginx/error.log; //错误日志
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
server配置
众所周知,Nginx的配置文件分为Server、Location、If等一些配置块,并且存在包含关系,和编程语言比较类似。如果在外层配置的一些选项,是可以被继承到内层的。
但这里的继承也有一些特性,比如add_header,子块中配置后将会覆盖父块中的add_header添加的所有HTTP头,造成一些安全隐患。
server配置在一些系统上不是默认的nginx配置,如果需要修改可以在nginx配置中添加,或者添加include,包含进其他的自定义server。
如下列代码,Server块添加了CSP头:
server {
...
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options DENY;
location = /test {
add_header X-Content-Type-Options nosniff;
rewrite ^(.*)$ /xss.html break;
}
}
但/test的location中又添加了X-Content-Type-Options头,导致父块中的add_header全部失效。
- 禁止一个目录的访问
示例:禁止访问path目录
location ^~ /path {
deny all;
}
可以把path换成实际需要的目录,目录path后是否带有”/“,带“/”会禁止访问该目录和该目录下所有文件。不带”/“的情况就有些复杂了,只要目录开头匹配上那个关键字就会禁止;注意要放在fastcgi配置之前。
这个常见于Nginx做反向代理的情况,动态的部分被proxy_pass传递给后端端口,而静态文件需要Nginx来处理。
假设静态文件存储在/home/目录下,而该目录在url中名字为files,那么就需要用alias设置目录的别名:
location /files {
alias /home/;
}
此时,访问http://example.com/files/readme.txt
,就可以获取/home/readme.txt
文件。
但我们注意到,url上/files
没有加后缀/
,而alias设置的/home/
是有后缀/
的,这个/
就导致我们可以从/home/
目录穿越到他的上层目录。从而导致一个目录穿越问题。
- 禁止php文件的访问及执行
示例:去掉单个目录的PHP执行权限
location ~ /attachments/.*\.(php|php5)?$ {
deny all;
}
示例:去掉多个目录的PHP执行权限
location ~
/(attachments|upload)/.*\.(php|php5)?$ {
deny all;
}
- 禁止IP的访问
示例:禁止IP段的写法:
deny 10.0.0.0/24;
示例:只允许某个IP或某个IP段用户访问,其它的用户全都禁止
allow
x.x.x.x;
allow 10.0.0.0/24;
deny all;
- 禁用非必要的方法
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
- 禁用扩展名
location ~* .(txt|doc|sql|gz|svn|git)$ {
deny all;
}
- 根据用户的真实 IP 做连接限制
## 这里取得原始用户的IP地址
map $http_x_forwarded_for $clientRealIp {
"" $remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr;
}
## 针对原始用户 IP 地址做限制
limit_conn_zone $clientRealIp zone=TotalConnLimitZone:20m ;
limit_conn TotalConnLimitZone 50;
limit_conn_log_level notice;
## 针对原始用户 IP 地址做限制
limit_req_zone $clientRealIp zone=ConnLimitZone:20m rate=10r/s;
#limit_req zone=ConnLimitZone burst=10 nodelay;
limit_req_log_level notice;
参考资料:
https://www.cnblogs.com/chenpingzhao/p/5785416.html
https://wooyun.kieran.top/#!/drops/201.Nginx%E5%AE%89%E5%85%A8%E9%85%8D%E7%BD%AE%E7%A0%94%E7%A9%B6
https://wooyun.kieran.top/#!/drops/315.Apache%E5%AE%89%E5%85%A8%E9%85%8D%E7%BD%AE