官方文档
https://nginx.org/en/docs/
systemd.service
- https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
// 创建nginx.service
[root@nginx ~]# cat /usr/lib/systemd/system/nginx.service
#/usr/lib/systemd/system/nginx.service
[Unit]
Description=Nginx Service
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
[Install]
WantedBy=multi-user.target
[root@nginx ~]# systemctl daemon-reload
// 验证
[root@nginx ~]# systemctl enable nginx.service --now
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@nginx ~]# ss -ntulp | grep 80
tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5605,fd=6),("nginx",pid=5604,fd=6))
虚拟主机的类型
测试准备
// 虚拟Web主机类型的测试准备
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# echo 'Nginx~~' > html/index.html
nginx]# mkdir html_test
nginx]# echo "www.a.com~~" > html_test/a.html
nginx]# echo "www.b.com~~" > html_test/b.html
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
include conf.d/*.conf /* 在http{}中增加一行*/
nginx]# mkdir conf/conf.d
基于域名
// 基于域名的虚拟Web主机
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/servername.conf
server{
listen 80; # listen IP地址:端口; 省略IP地址默认本地所有地址
server_name www.a.com;
root html_test;
index a.html;
}
server{
listen 80;
server_name www.b.com;
root html_test;
index b.html;
}
nginx]# sbin/nginx -s reload
客户端:
]# echo "192.168.88.80 www.a.com www.b.com" >> /etc/hosts
[root@client ~]# curl 192.168.88.80
Nginx~~
[root@client ~]# curl www.a.com
www.a.com~~
[root@client ~]# curl www.b.com
www.b.com~~
基于端口
// 基于端口的虚拟Web主机
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/port.conf
server{
listen 8001;
root html_test;
index a.html;
}
server{
listen 8002;
root html_test;
index b.html;
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80
Nginx~~
[root@client ~]# curl 192.168.88.80:8001
www.a.com~~
[root@client ~]# curl 192.168.88.80:8002
www.b.com~~
基于IP地址
// 基于IP的虚拟Web主机
Nginx服务器(192.168.88.80,192.168.99.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/ip.conf
server{
listen 192.168.88.80; # listen IP地址:端口; 省略端口默认80
root html_test;
index a.html;
}
server{
listen 192.168.99.80;
root html_test;
index b.html;
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80
www.a.com~~
[root@client ~]# curl 192.168.99.80
www.b.com~~
SSL
- SSL需要模块http_ssl_module,软件openssl-devel
// SSL虚拟Web主机(https)
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx-1.22.1]# yum install -y gcc make pcre-devel openssl-devel
nginx-1.22.1]# ./configure --with-http_ssl_module // 模块http_ssl_module
nginx-1.22.1]# make // 注意不要安装make install
nginx-1.22.1]# killall nginx // 杀死使用中的nginx进程
nginx-1.22.1]# \cp objs/nginx /usr/local/nginx/sbin/nginx
nginx-1.22.1]# cd /usr/local/nginx
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
98 server { # 解除server{}注释
99 listen 443 ssl; # ssl启用SSL协议
100 server_name localhost;
101
102 ssl_certificate cert.pem; # 指定证书(公钥+企业信息)
103 ssl_certificate_key cert.key; # 指定私钥
104
105 ssl_session_cache shared:SSL:1m;
106 ssl_session_timeout 5m;
107
108 ssl_ciphers HIGH:!aNULL:!MD5; # 加密算法套件配置优先选择强加密,禁止使用匿名加密,禁止使用MD5
109 ssl_prefer_server_ciphers on; # 优先选择服务器的推荐加密算法而不是客户端的偏好
110
111 location / {
112 root html;
113 index index.html index.htm;
114 }
115 }
nginx]# openssl genrsa > conf/cert.key
nginx]# openssl req -x509 -key conf/cert.key > conf/cert.pem
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:guangdong
Locality Name (eg, city) [Default City]:shenzhen
Organization Name (eg, company) [Default Company Ltd]:gongsi
Organizational Unit Name (eg, section) []:bumen
Common Name (eg, your name or your server's hostname) []:nginx
Email Address []:test@100.com
nginx]# sbin/nginx
nginx]# echo 'Nginx~~' > html/index.html
客户端:
[root@client ~]# curl 192.168.88.80
Nginx~~
[root@client ~]# curl https://192.168.88.80
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
[root@client ~]# curl -k https://192.168.88.80
Nginx~~
Nginx+PHP
// Nginx+PHP
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# cat html/test.php
<?php
echo "test.php~~\n"
?>
// 方式一:网络方式
// 部署nginx
nginx]# vim conf/nginx.conf
65 location ~ \.php$ {
66 root html;
67 fastcgi_pass 127.0.0.1:9000; # 指定php-fpm服务的IP地址和端口
68 fastcgi_index index.php;
70 include fastcgi.conf;
71 }
nginx]# sbin/nginx -s reload
nginx]# yum install -y php php-fpm php-mysqlnd // php-fpm是php的依赖
nginx]# vim /etc/php-fpm.d/www.conf
38 ;listen = /run/php-fpm/www.sock
39 listen = 127.0.0.1:9000 # php-fpm服务监听端口
nginx]# systemctl enable php-fpm.service --now
// 方式二:socket文件(两个服务同处一台设备)
nginx]# vim conf/nginx.conf
65 location ~ \.php$ {
66 root html;
67 # fastcgi_pass 127.0.0.1:9000;
68 fastcgi_pass unix:/run/php-fpm/www.sock; # 指定本机php-fpm服务的socket文件路径
69 fastcgi_index index.php;
71 include fastcgi.conf;
72 }
nginx]# sbin/nginx -s reload
nginx]# yum install -y php php-fpm php-mysqlnd
nginx]# vim /etc/php-fpm.d/www.conf
38 listen = /run/php-fpm/www.sock
55 listen.acl_users = apache,nginx,nobody # nginx进程通过用户nobody运行
nginx]# systemctl enable php-fpm.service --now
客户端:
[root@client ~]# curl 192.168.88.80/test.php
test.php~~
地址重写 rewrite
rewrite 旧地址 新地址 [选项];
:旧地址是客户端访问的地址,新地址是服务端实际的网页地址。- 注意:rewrite语句的旧地址是包含匹配,且支持正则表达式。
启用rewirte_log
// 虚拟Web主机类型的测试准备
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# echo 'Nginx~~' > html/index.html
nginx]# mkdir html_test
nginx]# echo 'Nginx_test~~' > html_test/index.html
nginx]# echo "A~~" > html_test/a.html
nginx]# echo "B~~" > html_test/b.html
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
6 error_log logs/error.log notice; // error_log日志启用notice级别,查看记录的地址重写信息
http {}
20 rewrite_log on; // 开启记录地址重写的inti
21 include conf.d/*.conf; /* 在http{}中增加一行*/
}
nginx]# mkdir conf/conf.d
nginx]# tail -8 logs/error.log // 查看地址重写信息
重写路径
// 地址重写类型一:客户端访问网页A实际访问网页B
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/reindex.conf
server{
listen 8003;
root html_test;
rewrite /a.html /b.html;
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80:8003
Nginx_test~~
[root@client ~]# curl 192.168.88.80:8003/b.html
B~~
[root@client ~]# curl 192.168.88.80:8003/a.html
B~~
重写域名
// 地址重写类型二:客户端访问域名A实际访问域名B
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/reserver.conf
server{
listen 8004;
root html_test;
rewrite /(.*) https://fanyi.baidu.com/#en/zh/$1; # `$数字`代表前者第数字个`()`的保留内容
}
nginx]# sbin/nginx -s reload
客户端:
浏览器访问 http://192.168.88.80:8004,跳转 https://fanyi.baidu.com/#en/zh/
浏览器访问 http://192.168.88.80:8004/test,跳转 https://fanyi.baidu.com/#en/zh/test
[root@client ~]# curl 192.168.88.80:8004
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.22.1</center>
</body>
</html>
[root@client ~]# curl 192.168.88.80:8004/test
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.22.1</center>
</body>
</html>
识别浏览器
// 地址重写类型一:客户端使用不同浏览器访问同一域名返回不同内容
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/rebrowser.conf
server{
listen 8005;
root html_test;
if ( $http_user_agent ~* firefox ){
# $http_user_agent是nginx的内置变量,存储用户浏览器信息。选项~匹配正则表达式,选项*不区分大小写
rewrite /(.*) /firefox/$1; # 捕获任意内容,跳转html_test/firefox/相同内容
}
}
nginx]# sbin/nginx -s reload
nginx]# mkdir html_test/firefox
nginx]# echo 'Nginx_firefox~~' > html_test/firefox/index.html
nginx]# echo "firefox_A~~" > html_test/firefox/a.html
nginx]# echo "firefox_B~~" > html_test/firefox/b.html
客户端:
其它浏览器访问
http://192.168.88.80:8005,返回 Nginx_test~~
http://192.168.88.80:8005/a.html,返回 A~~
http://192.168.88.80:8005/b.html,返回 B~~
火狐浏览器访问
http://192.168.88.80:8005,404
http://192.168.88.80:8005/index.html,返回 Nginx_firefox~~
http://192.168.88.80:8005/a.html,返回 firefox_A~~
http://192.168.88.80:8005/b.html,返回 firefox_B~~
选项
-
rewrite 旧地址 新地址 [选项];
:旧地址是客户端访问的地址,新地址是服务端实际的网页地址。 -
注意:rewrite语句的旧地址是包含匹配,且支持正则表达式。默认不会更新URL。
-
rewrite语句可以写在server{}中,也可以写在location{}中(location{}中可以嵌套location{})。
就rewrite语句而言,会逐级读取rewrite语句(server{}是比location{}高一级的):按顺序读取server{}中的rewrite语句,再匹配location{}中的rewrite语句。
-
选项:
- 选项
permanent
是永久重定向。地址栏更新URL。状态码301。爬虫只收集永久重定向的地址。 - 选项
redirect
是临时重定向。地址栏更新URL。状态码302。 - 选项
last
:不再读取同级别的rewrite语句,但可以匹配同级别其他location{}和下一级的location{},读取其中的rewrite语句。 - 选项
break
:不再读取同级别的rewrite语句和同级别其他locaton{}中的rewrite语句,但可以匹配下一级的location{},读取其中的rewrite语句。
- 选项
redirect、permanent
- 选项
permanent
是永久重定向。地址栏更新URL。状态码301。爬虫只收集永久重定向的地址。 - 选项
redirect
是临时重定向。地址栏更新URL。状态码302。- 选项
redirect
和permanent
,对客户端访问来说无区别,对服务端运维工程师来说查看状态码有区别,对爬虫来说只收集永久重定向的地址。
- 选项
// 地址重写选项redirect、permanent
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# for i in {a,b,c,d,e,j,k,m,n};do echo "${i}~~" > html_test/${i}.html;done
// rewrite 旧地址 新地址 [选项]; 旧地址匹配正则表达式
nginx]# cat conf/conf.d/8006.conf
server {
listen 8006;
root html_test;
rewrite /a.html /b.html; # 旧地址匹配正则表达式
rewrite ^/j\.html$ /k.html; # 旧地址匹配正则表达式
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80:8006/a.html
b~~
[root@client ~]# curl 192.168.88.80:8006/1/a.html
b~~
[root@client ~]# curl 192.168.88.80:8006/a1html
b~~
[root@client ~]# curl 192.168.88.80:8006/j.html
k~~
[root@client ~]# curl 192.168.88.80:8006/1/j.html // 404
[root@client ~]# curl 192.168.88.80:8006/j1html // 404
浏览器访问 http://192.168.88.80:8006/a.html,返回b~~,地址栏不会更新URL
浏览器访问 http://192.168.88.80:8006/j.html,返回k~~,地址栏不会更新URL
// 选项permanent:地址栏更新URL,永久重定向301。爬虫只收集永久重定向的地址。
nginx]# cat conf/conf.d/301.conf
server {
listen 8007;
root html_test;
rewrite /a.html /b.html permanent; # 选项permanent会显示跳转后的新地址
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80:8007/a.html // 301
浏览器访问 http://192.168.88.80:8007/a.html,返回b~~,地址栏更新为 http://192.168.88.80:8007/b.html
// 选项redirect:地址栏更新URL,临时重定向302
nginx]# cat conf/conf.d/302.conf
server {
listen 8008;
root html_test;
rewrite /a.html /b.html redirect; # 选项redirect会显示跳转后的新地址
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80:8008/a.html // 302
浏览器访问 http://192.168.88.80:8008/a.html,返回b~~,地址栏更新为 http://192.168.88.80:8008/b.html
last、break
- 选项
last
:不再读取同级别的rewrite语句,但可以匹配同级别其他location{}和下一级的location{},读取其中的rewrite语句。 - 选项
break
:不再读取同级别的rewrite语句和同级别其他locaton{}中的rewrite语句,但可以匹配下一级的location{},读取其中的rewrite语句。 - 不同情形:
- 如果last在server{}中,则按顺序读取server{}中的rewrite语句,直到last直接匹配下一级location{},按顺序读取该location{}中的rewrite语句。
- 如果last在location{}中,则按顺序读取本location{}中的rewrite语句,直到last直接匹配本级其他location{},按顺序读取该location{}中的rewrite语句。
- 如果break在server{}中,则按顺序读取server{}中的rewrite语句,直到break直接匹配下一级location{},按顺序读取该location{}中的rewrite语句。
- 如果break在location{}中,则按顺序读取本location{}中的rewrite语句,直到break,结束匹配本级别的location{}。
// 地址重写选项last、break
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# for i in {a,b,c,d,e,j,k,m,n};do echo "${i}~~" > html_test/${i}.html;done
// 就rewrite语句而言,会逐级读取rewrite语句(server{}是比location{}高一级的):按顺序读取server{}中的rewrite语句,再匹配location{}中的rewrite语句
nginx]# cat conf/conf.d/8011.conf
server {
listen 8011;
root html_test;
rewrite /a.html /b.html; # 1
location /d.html { # ld
rewrite /d.html /e.html; # d1
}
location /b.html { # lb
rewrite /b.html /m.html; # b1
}
location /c.html { # lc
rewrite /c.html /d.html; # c1
}
rewrite /b.html /c.html; # 2
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80:8011
Nginx_test~~
[root@client ~]# curl 192.168.88.80:8011/a.html
e~~ // 匹配过程:1符合——》2符合——》匹配lc(c1符合)——》匹配ld(d1符合)
// 选项last:不再读取同级别的rewrite语句,但可以匹配同级别其他location{}和下一级的location{},读取其中的rewrite语句。
nginx]# cat conf/conf.d/last.conf
server {
listen 8012;
root html_test;
rewrite /a.html /b.html last; # 1
rewrite /b.html /c.html; # 2
location /b.html { # lb
rewrite /b.html /d.html; # b1
rewrite /d.html /e.html; # b2
}
location /k.html { # lk
rewrite /k.html /n.html; # k1
}
location /j.html { # lj
rewrite /j.html /k.html last; # j1
rewrite /k.html /c.html; # j2
}
rewrite /k.html /m.html; # 3
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80:8012/a.html
e~~ // 匹配过程:1符合,last跳过2和3——》匹配lb(b1符合——》b2符合)
[root@client ~]# curl 192.168.88.80:8012/j.html
n~~ // 匹配过程:1不符——》2不符——》3不符——》匹配lj(j1符合,last跳过j2)——》匹配lk(k1符合)
// 选项break:不再读取同级别的rewrite语句和同级别其他locaton{}中的rewrite语句,但可以匹配下一级的location{},读取其中的rewrite语句。
nginx]# cat conf/conf.d/break.conf
server {
listen 8013;
root html_test;
rewrite /a.html /b.html break; # 1
rewrite /b.html /c.html; # 2
location /b.html { # lb
rewrite /b.html /d.html; # b1
rewrite /d.html /e.html; # b2
}
location /k.html { # lk
rewrite /k.html /n.html; # k1
}
location /j.html { # lj
rewrite /j.html /k.html break; # j1
rewrite /k.html /c.html; # j2
}
rewrite /k.html /m.html; # 3
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80:8013/a.html
e~~ // 匹配过程:1符合,break跳过2和3——》匹配lb(b1符合——》b2符合)
[root@client ~]# curl 192.168.88.80:8013/j.html
k~~ // 匹配过程:1不符——》2不符——》3不符——》匹配lj(j1符合,break跳过j2和同级别lk)
反向代理
准备集群
// 准备集群
Web集群(192.168.101-103):
]# yum install -y httpd
]# systemctl enable httpd.service --now
[root@web1 ~]# echo 'Welcome to web1 on 192.168.88.101.' > /var/www/html/index.html
[root@web2 ~]# echo 'Welcome to web2 on 192.168.88.102.' > /var/www/html/index.html
[root@web3 ~]# echo 'Welcome to web3 on 192.168.88.103.' > /var/www/html/index.html
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
include conf.d/*.conf; /* 在http{}中增加一行*/
nginx]# mkdir conf/conf.d
七层代理
// 七层代理,可以代理http、https,写在配置文件的http{}中
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/webs.conf
upstream webs {
server 192.168.88.101 weight=1 max_fails=3 fail_timeout=5; # ip地址:端口,省略端口默认80
server 192.168.88.102 weight=2 max_fails=3 fail_timeout=5;
server 192.168.88.103 weight=1 max_fails=3 fail_timeout=5;
}
server {
listen 100;
location / {
proxy_pass http://webs;
root html;
index index.html;
}
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# for i in {1..8};do curl 192.168.88.80:100;done
Welcome to web2 on 192.168.88.102.
Welcome to web2 on 192.168.88.102.
Welcome to web1 on 192.168.88.101.
Welcome to web3 on 192.168.88.103.
Welcome to web2 on 192.168.88.102.
Welcome to web2 on 192.168.88.102.
Welcome to web1 on 192.168.88.101.
Welcome to web3 on 192.168.88.103.
四层代理 stream
- 四层代理需要模块stream
// 四层代理,可以代理TCP、UDP,写在http{}外,stream{}中
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx-1.22.1]# ./configure --with-stream
nginx-1.22.1]# make // 注意不要安装make install
nginx-1.22.1]# killall nginx // 杀死使用中的nginx进程
nginx-1.22.1]# \cp objs/nginx /usr/local/nginx/sbin/nginx
nginx-1.22.1]# cd /usr/local/nginx
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf // 在http{}之外增加stream{}
stream { # 四层代理写在stream{}中,七层代理写在http{}中
upstream webs {
server 192.168.88.101:80 weight=1 max_fails=3 fail_timeout=5; # 四层代理不能省略端口
server 192.168.88.102:80 weight=2 max_fails=3 fail_timeout=5;
server 192.168.88.103:80 weight=1 max_fails=3 fail_timeout=5;
}
server {
listen 100; # `listen 100;`为TCP协议,`listen 100 udp;`为UDP协议
proxy_pass webs;
}
upstream ssh {
server 192.168.88.101:22 weight=1 max_fails=3 fail_timeout=5;
server 192.168.88.102:22 weight=2 max_fails=3 fail_timeout=5;
server 192.168.88.103:22 weight=1 max_fails=3 fail_timeout=5;
}
server {
listen 123;
proxy_pass ssh;
}
}
nginx]# sbin/nginx
客户端:
[root@client ~]# for i in {1..8};do curl 192.168.88.80:100;done
Welcome to web1 on 192.168.88.101.
Welcome to web3 on 192.168.88.103.
Welcome to web2 on 192.168.88.102.
Welcome to web2 on 192.168.88.102.
Welcome to web1 on 192.168.88.101.
Welcome to web3 on 192.168.88.103.
Welcome to web2 on 192.168.88.102.
Welcome to web2 on 192.168.88.102.
[root@client ~]# ssh 192.168.88.80 -p 123
[root@web1 ~]# logout
[root@client ~]# ssh 192.168.88.80 -p123
[root@web2 ~]# logout
[root@client ~]# ssh 192.168.88.80 -p123
[root@web2 ~]# logout
[root@client ~]# ssh 192.168.88.80 -p123
[root@web3 ~]# logout
会话保持 ip_hash
// 会话保持 ip_hash
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# cat conf/conf.d/webs.conf
upstream webs {
ip_hash; # 会话保持
server 192.168.88.101 weight=1 max_fails=3 fail_timeout=5;
server 192.168.88.102 weight=2 max_fails=3 fail_timeout=5;
server 192.168.88.103 weight=1 max_fails=3 fail_timeout=5;
}
server {
listen 100;
location / {
proxy_pass http://webs;
root html;
index index.html;
}
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# for i in {1..4};do curl 192.168.88.80:100;done
Welcome to web2 on 192.168.88.102.
Welcome to web2 on 192.168.88.102.
Welcome to web2 on 192.168.88.102.
Welcome to web2 on 192.168.88.102.
监控状态 stub_status
- 监控服务器状态模块http_stub_status_module
// 监控服务器状态
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx-1.22.1]# ./configure --with-http_stub_status_module // 模块http_stub_status_module
nginx-1.22.1]# make // 注意不要安装make install
nginx-1.22.1]# killall nginx // 杀死使用中的nginx进程
nginx-1.22.1]# \cp objs/nginx /usr/local/nginx/sbin/nginx
nginx-1.22.1]# cd /usr/local/nginx
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
include conf.d/*.conf /* 在http{}中增加一行*/
nginx]# mkdir conf/conf.d
nginx]# cat conf/conf.d/status.conf
server{
location /status {
stub_status on; # 启用服务器状态监控模块
allow 127.0.0.1; # 或者Nginx服务器IP地址。使用监控服务器功能。或者127.0.0.1(只能访问127.0.0.1)
deny all; # 拒绝所有人使用监控服务器功能
}
}
nginx]# sbin/nginx
nginx]# curl 192.168.88.80/status
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.22.1</center>
</body>
</html>
nginx]# curl 127.0.0.1/status
Active connections: 1
server accepts handled requests
11 11 34
Reading: 0 Writing: 1 Waiting: 0
网页用户认证 auth_basic_user_file
auth_basic "任意字符串"或on或off;
:"任意字符串"或on是开启网页用户密码认证,off是关闭。auth_basic_user_file 用户密码文件路径;
:用户密码文件路径
的相对路径是从本配置文件路径
开始,建议写绝对路径。
// 网页用户认证
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# echo 'Nginx~~' > html/index.html
nginx]# vim conf/nginx.conf // 在server{}中增加以下两行
auth_basic "password"; # auth_basic用户认证,"任意字符串"或on表示开启
auth_basic_user_file "/usr/local/nginx/pass"; # auth_basic_user_file指定用户密码文件的路径
nginx]# sbin/nginx -s reload
// 使用htpasswd命令创建用户密码文件/usr/local/nginx/pass
]# yum -y install httpd-tools // htpasswd命令由httpd-tools提供
]# htpasswd -c /usr/local/nginx/pass tom // 选项-c创建文件,将用户tom输入的密码加密后存储在该文件
New password:
Re-type new password:
Adding password for user tom
]# cat /usr/local/nginx/pass
tom:$apr1$pNHO9ZzZ$NV6AOIhfJA0F4hw8XVuJK/
]# htpasswd /usr/local/nginx/pass jerry // 选项-c会覆盖已有文件
New password:
Re-type new password:
Adding password for user jerry
客户端:
[root@client ~]# curl 192.168.88.80
返回401
[root@client ~]# curl 用户名:密码@192.168.88.80
Nginx~~
Nginx优化
隐藏版本 server_tokens
// 隐藏版本
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# vim conf/nginx.conf // 在http{}中增加一行
http {
……省略一万字
server_tokens off;
……省略一万字
}
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# curl 192.168.88.80/sadfafdg
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center> // 隐藏版本
</body>
</html>
修改报错页 error_page
// 修改报错页
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
http {
……省略一万字
root 全局网页文件根目录路径; # 省略默认为html/
error_page 404 /te404.html; # 全局网页文件根目录/te404.html
server {
root server网页文件根目录路径; # 省略默认全局网页文件根目录
error_page 404 /st404.html; # server网页文件根目录/st404.html
}
server
……省略一万字
}
nginx]# sbin/nginx -s reload
nginx]# echo 'te404~~' > 全局网页文件根目录/te404.html
nginx]# echo 'st404~~' > server网页文件根目录/st404.html
客户端:
[root@client ~]# curl 192.168.88.80/sadfafdg // 返回对应的404页面
高并发访问
// 提高并发访问的处理能力
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
3 worker_processes auto; # 自动根据服务器CPU进程数(逻辑处理器)调整工作进程数
12 events {
13 worker_connections 50000;
14 }
nginx]# sbin/nginx -s reload
nginx]# vim /etc/security/limits.conf // 结尾新增两行,新终端生效
* soft nofile 100000 # soft警戒值,nofile 最大打开文件数,nproc 最大进程数
* hard nofile 100000 # hard极限值
nginx]# ulimit -n
100000
防止缓冲区溢出
-
缓冲区溢出(Buffer Overflow)是指在程序中,当向一个固定长度的缓冲区写入数据时,如果写入的数据超过了缓冲区的容量,超出部分会溢出到相邻的内存区域中,从而可能导致程序的崩溃或安全漏洞。攻击者可以通过输入过长的数据,使得超出缓冲区的数据覆盖相邻的内存区域,改变程序的控制流,执行恶意代码或者破坏程序的正常运行。这可能会导致系统崩溃、任意代码执行、拒绝服务攻击等安全问题。
-
缓冲区的大小:如果较小,可能会导致Nginx在处理大型请求头部或请求体时报错414、400、413,并且如果攻击者在请求头部中加入恶意代码,过小的缓冲区会可能导致恶意代码溢出到其他内存区域造成安全漏洞。如果较大,多并发访问时会占用服务器内存资源。
// 修改请求头部缓冲区大小
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf // http{}中增加四行
http {
client_header_buffer_size 100k; # 每个客户端请求头的缓冲区大小,默认为1k或4k,请求头部超过大小返回414
large_client_header_buffers 4 100k; # 客户端请求头的缓冲区数量和每个缓冲区的大小,请求头部超过总大小返回400
client_body_buffer_size 200k; # 每个客户端请求体的缓存区大小
client_max_body_size 400k; # 允许的请求体最大大小,请求体超过大小返回413
}
nginx]# sbin/nginx -s reload
说明:
当单个客户端请求头部过大,超过了client_header_buffer_size默认的缓冲区大小100k,如果没有配置large_client_header_buffers会返回414,如果配置了large_client_header_buffers,nginx会根据large_client_header_buffers的参数,创建4个100k的缓冲区来存储大型请求头部的数据,如果请求头部超过总大小400k则返回400。
当单个客户端请求体过大,超过了client_body_buffer_size默认的缓冲区大小200k,nginx会尝试动态地扩展缓冲区大小,直到达到client_max_body_size指令配置的限制400k,请求体超过最大大小400k则返回413。
本地缓存时间
// 修改浏览器本地缓存数据的时间
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf // http{}中增加三行
http {
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
expires 10d; # expires设置数据过期时间,被访问后会在客户端时间保留缓存的时间
}
}
nginx]# sbin/nginx -s reload
请求缓冲区限速防DOS攻击
// 请求缓冲区限速,防DOS攻击
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf
17 http {
# 新增一行,创建请求缓冲区,名test,大小10m,接收请求速度每秒1个请求
18 limit_req_zone $binary_remote_addr zone=test:10m rate=1r/s;
36 server {
37 listen 80;
38 server_name localhost;
# 新增一行,使用缓冲区test(每秒1个请求),最多排队5个请求排队。即每秒最多6个请求
39 limit_req zone=test burst=5;
nginx]# sbin/nginx -s reload
客户端:
[root@client ~]# yum install -y httpd-tools
[root@client ~]# ab -n100 -c100 192.168.88.80/
……省略一万字
Complete requests: 100
Failed requests: 94
(Connect: 0, Receive: 0, Length: 94, Exceptions: 0)
Non-2xx responses: 94
……省略一万字
session共享
// session共享:将session存储在公共的Redis服务器
当用户访问服务器时,服务器会为该用户生成一个唯一的session ID,存储在session和cookie中,并将cookie发送给客户端。
当用户再次访问服务器时,客户端将cookie中的session ID发送给服务器,服务器可以通过session ID找到对应的session数据。
]# less /etc/php-fpm.d/www.conf
431 php_value[session.save_handler] = files # session信息以文件形式存储在本地
432 php_value[session.save_path] = /var/lib/php/session # 存储session信息的目录
// Nginx调度器反向代理Web集群,并充当Redis服务器
Nginx服务器(192.168.88.80,Nginx目录为/usr/local/nginx):
nginx-1.22.1]# ./configure --with-stream // 四层代理模块stream
nginx-1.22.1]# make
nginx-1.22.1]# killall nginx
nginx-1.22.1]# \cp objs/nginx /usr/local/nginx/sbin/nginx
nginx-1.22.1]# cd /usr/local/nginx
nginx]# \cp conf/nginx.conf.default conf/nginx.conf
nginx]# vim conf/nginx.conf // 在http{}之外增加stream{}
stream { # 四层代理写在stream{}中,七层代理写在http{}中
upstream webs {
server 192.168.88.101:80 weight=1 max_fails=3 fail_timeout=5; # 四层代理不能省略端口
server 192.168.88.102:80 weight=2 max_fails=3 fail_timeout=5;
server 192.168.88.103:80 weight=1 max_fails=3 fail_timeout=5;
}
server {
listen 100; # `listen 100;`为TCP协议,`listen 100 udp;`为UDP协议
proxy_pass webs;
}
nginx]# sbin/nginx
nginx]# yum install -y redis
nginx]# vim /etc/redis.conf
69 #bind 127.0.0.1 # bind表示服务器监听的客户端IP地址。127.0.0.1只允许本地连接本redis服务。
88 protected-mode no # 关闭保护模式,服务可被其他设备使用
nginx]# systemctl enable redis --now
// Web集群部署LNMP,并指定session使用Redis服务存储
Web集群(192.168.101-103):
部署lnmp:安装nginx、php、php-fpm、php-mysqlnd、mysql-server——》配置nginx、php-fpm——》启服务nginx、php-fpm、mysqld
]# ls phpredis-5.1.0-1.x86_64.rpm
phpredis-5.1.0-1.x86_64.rpm // 支持php与redis的交互的插件phpredis
]# yum -y install phpredis-5.1.0-1.x86_64.rpm
]# vim /etc/php-fpm.d/www.conf
431 php_value[session.save_handler] = redis # session数据的保存方式,使用Redis数据库
432 php_value[session.save_path] = "tcp://192.168.88.80:6379" # session数据保存的路径
]# systemctl restart php-fpm.service