[root@test ~]# yum -y install gcc make pcre-devel openssl-devel
[root@test ~]# tar xf nginx-1.17.6.tar.gz
[root@test ~]# cd nginx-1.17.6/
[root@test nginx-1.17.6]# ./configure --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
[root@test nginx-1.17.6]# make && make install
[root@test nginx-1.17.6]# useradd nginx -s /sbin/nologin
[root@test nginx-1.17.6]# /usr/local/nginx/sbin/nginx
[root@test nginx-1.17.6]# netstat -ntulp | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6771/nginx: master
[root@test nginx-1.17.6]# /usr/local/nginx/sbin/nginx -V #查询版本与已经安装的模块
nginx version: nginx/1.17.6
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
[root@test nginx-1.17.6]# /usr/local/nginx/sbin/nginx -t #测试配置文件
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@test nginx-1.17.6]# /usr/local/nginx/sbin/nginx -s reload #重新加载
[root@test nginx-1.17.6]# /usr/local/nginx/sbin/nginx -s stop #停止
[root@test nginx-1.17.6]# /usr/local/nginx/sbin/nginx -s quit #优雅停止
[root@test nginx]# vim conf/nginx.conf //操作在/usr/local/nginx目录进行
41 #access_log logs/host.access.log main;
42 auth_basic "password:"; //提示信息,用户登录网站时看到的
43 auth_basic_user_file "/usr/local/nginx/pass"; //用户名密码的文件路径
[root@test nginx]# yum -y install httpd-tools //安装网站工具包,支持htpasswd命令
[root@test nginx]# htpasswd -c /usr/local/nginx/pass abc //创建网站的用户与密码文件
New password:
Re-type new password:
[root@test nginx]# htpasswd /usr/local/nginx/pass xyz //追加新账户,无需c选项
[root@test nginx]# sbin/nginx //如果没开服务则开启服务
[root@test nginx]# sbin/nginx -s reload //如果服务已经开了,则重新加载配置文件最后使用火狐浏览器打开192.168.2.5发现已经需要用户名和密码认证如果要反复测试该功能,需要清空浏览器的历史记录
配置nginx的虚拟主机
http {
server {
listen 80;
server_name www.a.com;
root html;
index index.html index.htm;
}
} //其他配置另加
1.修改主配置文件 去掉注释 :103,120s/#//
server {
listen 443 ssl;
server_name www.c.com; //修改域名
ssl_certificate cert.pem; //证书,包含公钥,/usr/local/nginx/conf下
ssl_certificate_key cert.key; //私钥
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root c; //修改页面存储目录,/usr/local/nginx目录下
index index.html index.htm;
}
}
自建证书与私钥
[root@test nginx]# cd conf/
[root@test conf]# openssl genrsa > cert.key
Generating RSA private key, 2048 bit long modulus
............................................................+++
...................................................................................................+++
e is 65537 (0x10001)
[root@test conf]# openssl req -new -x509 -key cert.key > cert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:xx
State or Province Name (full name) []:xx
Locality Name (eg, city) [Default City]:xx
Organization Name (eg, company) [Default Company Ltd]:xx
Organizational Unit Name (eg, section) []:xx
Common Name (eg, your name or your server's hostname) []:xx
Email Address []:[email protected]
[root@test conf]# cd ..
[root@test nginx]# mkdir c
[root@test nginx]# echo "web-C~~" > c/index.html
[root@test nginx]# sbin/nginx -s reload //重新加载配置
[root@test nginx]# curl -k https://www.c.com //使用命令行测试, k选项是忽略风险
https://www.c.com/ //使用火狐测试,提示,自己随意创建的加密网站,通常浏览器可能会认为不合法有危险或使用火狐浏览器访问https://www.c.com/看到提示---高级---接收风险并继续另外,如果实验还是无法成功,可以先用killall nginx杀掉程序,从新开启再测试
]# yum -y install gcc pcre-devel openssl-devel
]# tar -xf lnmp_soft.tar.gz
]# cd ~/lnmp_soft
]# tar -xf nginx-1.17.6.tar.gz
]# cd ~/lnmp_soft/nginx-1.17.6/
]# ./configure --prefix=/usr/local/nginx --user=nginx --with-http_ssl_module
]# make && make install
]# useradd nginx -s /sbin/nologin
]# systemctl stop firewalld
]# /usr/local/nginx/sbin/nginx
]# netstat -ntulp | grep nginx
打开nginx配置文件,第65到71行
location ~ \.php$ { //~是使用正则表达式,匹配以.php结尾
root html;
fastcgi_pass 127.0.0.1:9000; //一旦用户访问了.php结尾的文件,就让nginx找后台的php-fpm(端口号9000)
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf; //这里需要修改名称
}
]# /usr/local/nginx/sbin/nginx -reload
其他环境
]# yum -y install mariadb mariadb-server mariadb-devel //安装数据库的客户端、服务端、依赖包
]# yum -y install php //安装php程序包
]# yum -y install php-mysql //安装php与数据库关联的软件包
]# yum -y install php-fpm //安装可以让nginx具有动态网站解析能力的软件包
]# systemctl start mariadb //开启数据库
]# systemctl start php-fpm //开启php-fpm
]# netstat -ntulp | grep :3306 //查看数据库端口
]# netstat -ntulp | grep :9000 //查看php-fpm端口
php-fpm的配置文件 /etc/php-fpm.d/www.conf // ;表注释 /;回车
listen = 127.0.0.1:9000 //此处配置决定了php-fpm服务针对什么ip与什么端口
pm.start_servers = 5 //启动开启的进程数量,pstree可以查看php-fpm(fastCGI)的进程数量pm.max_children = 50 //开启的fastCGI子进程最大数量
]# cat test.php
This is HTML message
$d){echo "c is bigger";}
else{ echo "d is bigger";}
?>
]# cp test.php /usr/local/nginx/html/
火狐访问192.168.1.1/test.php ,可以看页面 c is bigger表示设置成功,没配置好会看到文件下载的提示。
rewrite 旧地址 新地址 选项
地址重写的好处:增加服务器的安全性、易于用户记忆键入、易于被搜索引擎收录
]# echo "nginx-A~~" > html/a.html
]# echo "nginx-B~~" > html/b.html
]# cp conf/nginx.conf.default conf/nginx.conf
1.地址重写: 访问http://192.168.1.1/a.html ,看到的是b.html的页面
]# vim conf/nginx.conf
41 #access_log logs/host.access.log main;
42 rewrite /a.html /b.html; // /是网站的根路径,html目录下的否则识别不出文件位置
42 rewrite ^/a.html$ /b.html; // 旧地址的匹配需要用正则表达式,否则跳转不严谨
]# sbin/nginx -s reload
firefox http://192.168.1.1/a.html nginx-----b
2.访问http://192.168.1.1/a.html ,看到的是b.html的页面,网址栏自动变成http://192.168.1.1/b.html
42 rewrite ^/a.html$ /b.html redirect; //添加重定向
]# sbin/nginx -s reload
3.地址重写3:访问老网站,跳转到新的网址
42 rewrite / http://www.baidu.cn;
]# sbin/nginx -s reload 重加载配置文件
firefox http://192.168.1.1 会跳到baidu
4.访问老网站的某个页面时,跳转到新网站对应的相同页面。
42 rewrite ^/(.)$ http://www.tmooc.cn/$1;
//前面使用正则表达式匹配用户输入的任意页面,并保存起来(小括号在正则中的效果是保留,相当于保存复制),后面使用$1将之前保存的页面地址粘贴到新网站
访问192.168.1.1/a.html可以转到www.baidu.com/a.html
5.根据用户浏览器跳转专属网页
]# mkdir html/firefox
]# pwd
/usr/local/nginx
]# echo "nginx-firefox" > html/firefox/index.html
]# echo "nginx-other" > html/index.html
42 if ($http_user_agent ~ firefox) { //如果用户的浏览器使用了火狐,就执行下面的rewrite任务,~ 代表匹配正则,* 是不区分大小写,$http_user_agent是nginx的内置变量,存储了用户的信息,比如用的什么浏览器
rewrite ^/index.html$ /firefox/index.html; //如果用户浏览器是火狐就跳转火狐专用目录的页面
}
sbin/nginx -s reload 重加载配置文件
6.rewrite选项:
last 不再读其他rewrite
break 不再读其他语句
redirect 临时重定向 状态码 302
permanent 永久重定向 状态码 301 爬虫会根据状态码选择是否爬取
1)重定向网页redirect permanent
]# cd /usr/local/nginx
]# echo "nginx A" > html/a.html //准备素材
]# echo "nginx B" > html/b.html
]# echo "nginx C~~" > html/c.html
]# vim conf/nginx.conf //修改配置
42 rewrite /a.html /b.html redirect;
]# curl 192.168.1.1/a.html //此时看到的页面是b,状态码是302
302 Found
]# tail /usr/local/nginx/logs/access.log 也能看到302
192.168.1.1 - - [14/Feb/2022:10:46:14 -0500] "GET /a.html HTTP/1.1" 302 145 "-"
]# vim conf/nginx.conf
42 rewrite /a.html /b.html permanent; //修改redirect,重加载nginx服务
]# curl 192.168.1.1/a.html //此时看到的页面也是b,状态码是301说明redirect与permanent效果在客户机看来是一样的,但是状态码不一样,对于搜索引擎来说更关心301的
2)last 不再读其他或者同一location下的rewrite
42 rewrite /a.html /b.html last; //没有last会再读下面的rewrite,看a页面会得到c页面
rewrite /b.html /c.html;
使用火狐访问192.168.1.1/a.html看到的是b页面
3)break 不再读其他语句的所有rewrite
修改配置文件,将默认的location中加入rewrite语句,然后再创建一个新的location也加入rewrite语句
vim conf/nginx.conf //在默认的location中添加rewrite,再新创建一个location也添加rewrite语句。
41 #access_log logs/host.access.log main;
42 location / {
43 rewrite /a.html /b.html break;
44 root html;
45 rewrite /b.html /c.html;
46 index index.html index.htm;
47 }
48 location /b.html{
49 rewrite /b.html /c.html;
50 }
34 upstream web { //创建nginx集群,名称是web
ip_hash; //同一客户机访问相同服务器时,集群锁定一个后台服务器,避免客户重复登陆的问题
35 server 192.168.1.100:80 max_fails=2 fail_timeout=30;//健康检查
36 server 192.168.1.200:80 weight=2; //权重
server 192.168.1.10:80 down; //加down标记,使集群服务器暂时不参与任务轮询
37 }
48 proxy_pass http://web; //调用web集群
修改配置文件,在 "error_page 404" 那一行的上面添加:
location /status { //当用户输入的地址后面跟了/status之后
stub_status on; //开启网站后台状态信息查看功能
allow 192.168.1.1; //仅仅允许2.5查看
deny all; //拒绝其他所有主机
}
]# sbin/nginx -s reload //重加载配置
http://192.168.1.1/status
47 location ~* \.(jpg|txt|html|png)$ {
48 expires 30d; //都会缓存在客户机上30天
49 }
~*匹配正则忽略大小写 \. 转译成符号点,不代表任意字符 $ 结尾.jpg
然后使用火狐浏览器,先清空历史记录,然后地址栏输入about:cache查看disk文件的列表,
默认情况下nginx无法支持长地址栏,会报414错误
打开配置文件,在默认的虚拟主机上方添加两行
33 #gzip on;
34 client_header_buffer_size 200k; //用户访问网站的头部信息(包含地址栏)长度支持200k大小
35 large_client_header_buffers 4 200k; //第二行表示,如果200k不够,再给4个200k
buffer.sh脚本在执行时会产生超长地址
#!/bin/bash
URL=http://192.168.2.5/index.html?
for i in {1..5000}
do
URL=${URL}v$i=$i
i=1 URL=http://192.168.2.5/index.htmlv1=1 //产生的过程,第1次循环
i=2 URL=http://192.168.2.5/index.htmlv1=1v2=2 //产生的过程,第2次循环
i=3 URL=http://192.168.2.5/index.htmlv1=1v2=2v3=3 //产生的过程,第3次循环….
。。。。。。。
done
curl $URL
Nignx是模块化设计的软件,需要什么功能与模块以及不需要哪些模块,都可以在编译安装软件时自定义,使用–with参数可以开启某些模块,使用–without可以禁用某些模块。最小化安装永远都是对的方案!
./configure --without-http_autoindex_module --without-http_ssi_module
#禁用自动索引文件目录模块
默认Nginx会显示版本信息以及具体的版本号,这些信息给攻击者带来了便利性,便于他们找到具体版本的漏洞。如果需要屏蔽版本号信息,执行如下操作,可以隐藏版本号。
...
http{
server_tokens off; #在http下面手动添加这么一行
...
}
~]# /usr/local/nginx/sbin/nginx -s reload
~]# curl -I http://192.168.1.1 #查看服务器响应的头部信息
DDOS攻击者会发送大量的并发连接,占用服务器资源(包括连接数、带宽等),这样会导致正常用户处于等待或无法访问服务器的状态。
Nginx提供了一个ngx_http_limit_req_module模块默认安装,可以有效降低DDOS攻击的风险,操作方法如下:
~]# yum -y install httpd-tools
~]# ab -c 100 -n 100 http://192.168.1.1
[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
… …
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 nodelay;
limit_req_status 503;
}
}
#备注说明:
#limit_req_zone语法格式如下:
#limit_req_zone key zone=name:size rate=rate;
#limit_req_zone 固定格式
#$binary_remote_addr 调用远程访问IP,存储到one
#zone=one:10m 开启一个10m的内存,名命one
#rate=1r/s; 每个IP处理的请求频率一次每秒
#limit_req zone=one burst=5 nodelay; 缓存5个请求,多出的丢弃 nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,自定义值只能设置 400 到 599 之间。
#上面案例中是将客户端IP信息存储名称为one的共享内存,内存空间为10M
#1M可以存储8千个IP信息,10M可以存储8万个主机连接的状态,容量可以根据需要任意调整
#每秒中仅接受1个请求,多余的放入漏斗
#漏斗超过5个则报错
~]# /usr/local/nginx/sbin/nginx -s reload
客户端使用ab测试软件测试效果:
[root@client ~]# ab -c 100 -n 100 http://192.168.1.1
limit_conn addr 1; 一次只允许每个IP地址一个连接。
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /download/ {
limit_conn addr 1;
}
网站使用的是HTTP协议,该协议中定义了很多方法,可以让用户连接服务器,获得需要的资源。但实际应用中一般仅需要get和post。
未修改服务器配置前,客户端使用不同请求方法测试:
~]# vim /usr/local/nginx/conf/nginx.conf
http{
server {
listen 80;
if ($request_method !~ ^(GET|POST)$ ) {
return 444;
}
#这里,!符号表示对正则取反,~符号是正则匹配符号
#如果用户使用非GET或POST方法访问网站,则retrun返回错误信息
}
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload
修改服务器配置后,客户端使用不同请求方法测试:
[root@client ~]# curl -i -X GET http://192.168.4.5 #正常
[root@client ~]# curl -i -X HEAD http://192.168.4.5 #报错
当客户端连接服务器时,服务器会启用各种缓存,用来存放连接的状态信息。
如果攻击者发送大量的连接请求,而服务器不对缓存做限制的话,内存数据就有可能溢出(空间不足)。
修改Nginx配置文件,调整各种buffer参数,可以有效降低溢出风险。
~]# vim /usr/local/nginx/conf/nginx.conf
http{
client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
… …
}
~]# /usr/local/nginx/sbin/nginx -s reload
http {
.. ..
gzip on; //开启压缩
gzip_min_length 1000; //小文件不压缩
gzip_comp_level 4; //压缩比率
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
//对特定文件压缩,类型参考conf/mime.types
.. ..
}
如果需要处理大量静态文件,可以将文件缓存在内存,下次访问会更快。
http {
open_file_cache max=2000 inactive=20s;
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
#设置服务器最大缓存2000个文件句柄,关闭20秒内无请求的文件句柄
#文件句柄的有效时间是60秒,60秒后过期关闭
#只有访问次数超过5次会被缓存
}
缓存文件放在哪儿? 如何指定哪些请求被缓存?
缓存的有效期是多久? 如何指定哪些请求不被缓存?
proxy_cache_key “ h o s t host hostrequest_uri$cookie_user”;
Nginx默认会缓存所有get和head方法的请求结果,缓存的key默认使用请求字符串,这里是自定义的key
http {
proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=10g;
# 指定缓存位置、缓存名称one、内存中缓存内容大小限制、缓存总大小限制。缓存目录cache 先创建好
upstream www.a.com{
server 127.0.0.1:80 weight=3;
server 127.0.0.1:81 weight=1;
}
server {
listen 80;
proxy_cache one;
server_name www.a.com;
location / {
proxy_pass http://aidan.org;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_key "$host$request_uri$cookie_user";
#自定义的key,缓存的key默认使用请求字符串
proxy_cache_min_uses 5;
#指定请求次数5次以上才缓存
proxy_cache_methods GET HEAD POST;
#默认会缓存所有get和head方法的请求结果,新指定了
proxy_cache_valid 200 302 10m;
#响应状态码为200 302时,10分钟有效缓存
proxy_cache_valid any 5m;
#对应任何状态码,5分钟有效
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
#nginx不会查找缓存,直接进行代理转发。
}
}
}
$ nginx -t
$ nginx -s reload
]# curl I www.a.com
...
X-proxy-Cache: MISS
]# curl I www.a.com
...
X-proxy-Cache: HIT #缓存命中