NGINX进阶
文章目录
nginx访问控制
用于location段
allow:设定允许哪台或哪些主机访问,多个参数用换行及分号隔开
deny:设定禁止哪台或哪些主机访问,多个参数用换行及分号隔开
示例:
allow 192.168.1.1/32;
allow 172.16.0.0/16;
deny all;
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
location / {
root html;
index index.html index.htm;
allow 192.168.159.1;
deny all;
}
[root@nginx ~]# systemctl restart nginx.service
[root@nginx ~]# curl 192.168.159.167
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.20.2</center>
</body>
</html>
192.168.159.1可以访问
Nginx用户认证
应用于http, server, location, limit_except段
配置如下
auth_basic "欢迎信息";
auth_basic_user_file "/path/to/user_auth_file"
//首先要下载httpd-tools软件包
[root@nginx ~]# dnf -y install httpd-tools
//生成密码隐藏文件.usr_auth_file,用zwl用户登录
[root@nginx ~]# htpasswd -c -m /usr/local/nginx/conf/.usr_auth_file zwl
New password:
Re-type new password:
Adding password for user zwl
[root@nginx ~]#
//修改配置文件,开启用户认证
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
location / {
root html;
index index.html index.htm;
allow 192.168.159.1;
deny all;
auth_basic "hello";
auth_basic_user_file /usr/local/nginx/conf/.usr_auth_file;
}
[root@nginx ~]# systemctl restart nginx.service
https配置
生成私钥,生成证书签署请求并获得证书,然后在nginx.conf中配置如下内容:
server {
listen 443 ssl;
server_name www.idfsoft.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
自签证书及部署
//自签证书
[root@nginx ~]# mkdir /usr/local/nginx/conf/ssl
[root@nginx ~]# cd /usr/local/nginx/conf/ssl/
[root@nginx ssl]# openssl genrsa -out nginx.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.........+++++
................................................+++++
e is 65537 (0x010001)
[root@nginx ssl]#
[root@nginx ssl]# openssl req -new -key nginx.key -out nginx.csr
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]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:RT
Organization Name (eg, company) [Default Company Ltd]:www.zwl.com
Organizational Unit Name (eg, section) []:www.zwl.com
Common Name (eg, your name or your server's hostname) []:www.zwl.com
Email Address []:123@456.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@nginx ssl]#
[root@nginx ssl]# openssl x509 -req -days 365 -in nginx.csr -signkey nginx.key -out nginx.crt
Signature ok
subject=C = CN, ST = HB, L = RT, O = www.zwl.com, OU = www.zwl.com, CN = www.zwl.com, emailAddress = 123@456.com
Getting Private key
[root@nginx ssl]# ls
nginx.crt nginx.csr nginx.key
[root@nginx ssl]#
//修改nginx配置文件
[root@nginx ssl]# !vim
vim /usr/local/nginx/conf/nginx.conf
server {
listen 443 ssl;
server_name www.zwl.com;
ssl_certificate ssl/nginx.crt;
ssl_certificate_key ssl/nginx.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
allow 192.168.159.1;
deny all;
auth_basic "hello";
auth_basic_user_file /usr/local/nginx/conf/.usr_auth_file;
}
Nginx启用状态页面
开启status:stub_status [on | off]; (不添加参数默认on)
应用于server,location段
配置开启
//首先得有--with-http_stub_status_module模块
[root@nginx ~]# nginx -V
nginx version: nginx/1.20.2
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module
//编辑配置文件,开启状态页面
[root@nginx ~]# !vim
vim /usr/local/nginx/conf/nginx.conf
location = /status {
stub_status;
[root@nginx ~]# systemctl reload nginx.service
[root@nginx ~]# curl 192.168.159.167/status
Active connections: 1
server accepts handled requests
2 2 2
状态页面信息详解:
状态码 | 表示的意义 |
---|---|
Active connections | 当前所有处于打开状态的连接数 |
accepts | 总共处理了多少个连接 |
handled | 成功创建多少握手 |
requests | 总共处理了多少个请求 |
Reading | nginx读取到客户端的Header信息数,表示正处于接收请求状态的连接数 |
Writing | nginx返回给客户端的Header信息数,表示请求已经接收完成,且正处于处理请求或发送响应的过程中的连接数 |
Waiting | 开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx已处理完正在等候下一次请求指令的驻留连接 |
zabbix监控Nginx状态
环境说明
主机名 | ip | 服务 | 系统 |
---|---|---|---|
zabbix | 192.168.159.167 | zabbix | centos8 |
nginx | 192.168.159.168 | nginx zabbix_agentd | centos8 |
zabbix安装详情看我前面做的文档
nginx端,安装zabbix_agentd
[root@nginx ~]# useradd -rMs /sbin/nologin zabbix
[root@nginx ~]# dnf -y install make gcc gcc-c++ pcre-devel openssl openssl-devel wget
[root@nginx ~]# wget https://cdn.zabbix.com/zabbix/sources/stable/6.2/zabbix-6.2.2.tar.gz
[root@nginx ~]# tar -xf zabbix-6.2.2.tar.gz
[root@nginx ~]# cd zabbix-6.2.2/
[root@nginx zabbix-6.2.2]# ./configure --enable-agent
[root@nginx zabbix-6.2.2]# make install
[root@nginx zabbix-6.2.2]# vim /usr/local/etc/zabbix_agentd.conf
......
Server=192.168.159.167
......
ServerActive=192.168.159.167
......
Hostname=nginx
[root@nginx zabbix-6.2.2]# zabbix_agentd
[root@nginx zabbix-6.2.2]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:10050 0.0.0.0:*
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@nginx zabbix-6.2.2]#
在zabbix服务端这边,添加监控项,和报警
开启状态页面,并在nginx端写监控脚本
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
location = /status {
stub_status on;
allow 192.168.159.168;
deny all;
}
[root@nginx ~]# mkdir /scripts
[root@nginx ~]# cd /scripts/
[root@nginx scripts]# vim nginx_status.sh
#!/bin/bash
case $1 in
Reading)
curl -s 192.168.159.168/status |awk "NR==4{print\$2}"
;;
Writing)
curl -s 192.168.159.168/status |awk "NR==4{print\$4}"
;;
Waiting)
curl -s 192.168.159.168/status |awk "NR==4{print\$6}"
;;
*)
exit
;;
esac
[root@nginx scripts]# chmod +x nginx_status.sh
[root@nginx scripts]# vim /usr/local/etc/zabbix_agentd.conf
UnsafeUserParameters=1
UserParameter=nginx_status[*],/bin/bash /scripts/nginx_status.sh $1
[root@nginx scripts]# pkill zabbix_agentd
[root@nginx scripts]# zabbix_agentd
//zabbix端
[root@zabbix ~]# zabbix_get -s 192.168.159.168 -k nginx_status[Writing]
1
Reading监控
Writing
Waiting
反向代理与负载均衡
nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力。
nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从nginx发布的路径去读取,而不需要从后台服务器获取了。
但是要注意,这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync做服务端自动同步或者使用NFS、MFS分布式共享存储。
Http Proxy模块,功能很多,最常用的是
proxy_pass和
proxy_cache
如果要使用proxy_cache,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,如:
./configure --add-module=../ngx_cache_purge-1.0 ......
nginx通过upstream模块来实现简单的负载均衡,upstream需要定义在http段内
在upstream段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,如:
upstream idfsoft.com {
ip_hash;
server 127.0.0.1:9080 weight=5;
server 127.0.0.1:8080 weight=5;
server 127.0.0.1:1111;
}
注意:这个方法本质还是轮询,而且由于客户端的ip可能是不断变化的,比如动态ip,代理,翻墙等,因此ip_hash并不能完全保证同一个客户端总是由同一个服务器来处理。
定义好upstream后,需要在server段内添加如下内容:
server {
location / {
proxy_pass http://idfsoft.com;
}
}
nginx负载均衡配置、nginx负载均衡调度器高可用配置
环境说明
主机名 | ip | 服务 | 系统 |
---|---|---|---|
129 | 192.168.159.129 | nginx keepalived | centos8 |
134 | 192.168.159.134 | nginx keepalived | centos8 |
167 | 192.168.159.167 | httpd | centos8 |
168 | 192.168.159.168 | nginx | centos8 |
//在167上源码安装httpd
[root@167 ~]# groupadd -r apache
[root@167 ~]# useradd -r -M -s /sbin/nologin -g apache apache
[root@167 ~]# dnf -y install openssl-devel pcre-devel expat-devel libtool gcc gcc-c++
[root@167 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/apr/apr-1.7.0.tar.gz
[root@167 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/apr/apr-util-1.6.1.tar.gz
[root@167 ~]# tar -xf apr-1.7.0.tar.gz -C /usr/local/src/
[root@167 ~]# tar -xf apr-util-1.6.1.tar.gz -C /usr/local/src/
[root@167 apr-1.7.0]# vim configure
# $RM "$cfgfile"
[root@167 apr-1.7.0]# ./configure --prefix=/usr/local/apr
[root@167 apr-1.7.0]# make && make install
[root@167 apr-util-1.6.1]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
[root@167 apr-util-1.6.1]# make && make install
[root@167 src]# wget https://downloads.apache.org/httpd/httpd-2.4.54.tar.gz
[root@167 src]# tar -xf httpd-2.4.54.tar.gz
[root@167 src]# ls
apr-1.7.0 apr-util-1.6.1 httpd-2.4.54 httpd-2.4.54.tar.gz
[root@167 httpd-2.4.54]# ./configure --prefix=/usr/local/apache \
> --sysconfdir=/etc/apache \
> --enable-so \
> --enable-ssl \
> --enable-cgi \
> --enable-rewrite \
> --with-zlib \
> --with-pcre \
> --with-apr=/usr/local/apr \
> --with-apr-util=/usr/local/apr-util/ \
> --enable-modules=most \
> --enable-mpms-shared=all \
> --with-mpm=prefork
[root@167 httpd-2.4.54]# make && make install
//安装后配置
[root@167 ~]# echo 'export PATH=/usr/local/apache/bin:$PATH' > /etc/profile.d/httpd.sh
[root@167 ~]# source /etc/profile.d/httpd.sh
[root@167 ~]# ln -s /usr/local/apache/include/ /usr/include/httpd
[root@167 ~]# echo 'MANDATORY_MANPATH /usr/local/apache/man' >> /etc/man_db.conf
[root@167 ~]# sed -i '/#ServerName/s/#//g' /etc/apache/httpd.conf
//设置源码安装apache能使用systemctl 开启、关闭、重启、开机自启
[root@167 ~]# cd /usr/lib/systemd/system
[root@167 system]# cp sshd.service apache.service
[root@167 system]# vim apache.service
[Unit]
Description=httpd server daemon
After=network.target sshd-keygen.target
[Service]
Type=forking
ExecStart=/usr/local/apache/bin/apachectl
ExecStop=/usr/local/apache/bin/apachectl stop
ExecReload=/bin/kill -HUP $MAINPID
[root@167 ~]# systemctl restart httpd.service
[root@167 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
[root@167 ~]#
在168上源码部署nginx
//关闭防火墙和selinux
[root@168 ~]# setenforce 0
[root@168 ~]# sed -ri 's/^(SELINUX=).*/\1disabled/g' /etc/selinux/config
[root@168 ~]# systemctl disable --now firewalld.service
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
//创建用户
[root@168 ~]# useradd -rMs /sbin/nologin nginx
//安装所需要的依赖包
[root@168 ~]# dnf -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make wget vim
//下载nginx源码包,并解压
[root@168 ~]# wget http://nginx.org/download/nginx-1.20.2.tar.gz
[root@168 ~]# tar -xf nginx-1.20.2.tar.gz
//开始配置
[root@168 nginx-1.20.2]# ./configure \
> --prefix=/usr/local/nginx \
> --user=nginx \
> --group=nginx \
> --with-debug \
> --with-http_ssl_module \
> --with-http_realip_module \
> --with-http_image_filter_module \
> --with-http_gunzip_module \
> --with-http_gzip_static_module \
> --with-http_stub_status_module
//开启编译
[root@168 nginx-1.20.2]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install
[root@168 nginx-1.20.2]# cd /usr/local/nginx/
[root@168 nginx]# ls
conf html logs sbin
安装完成后配置以内容
[root@168 ~]# echo "export PATH=$PATH:/usr/local/nginx/sbin" > /etc/profile.d/nginx.sh
[root@168 ~]# source /etc/profile.d/nginx.sh
[root@168 ~]# nginx
[root@168 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@168 ~]# nginx -s stop
[root@168 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@168 ~]# cat > /usr/lib/systemd/system/nginx.service << EOF
> [Unit]
> Description=nginx server daemon
> After=network.target
>
> [Service]
> Type=forking
> ExecStart=/usr/local/nginx/sbin/nginx
> ExecStop=/usr/local/nginx/sbin/nginx -s stop
> ExecReload=/bin/kill -HUP \$MAINPID
>
> [Install]
> WantedBy=multi-user.target
> EOF
[root@168 ~]# systemctl daemon-reload
[root@168 ~]# systemctl enable --now nginx.service
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@168 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@168 ~]#
在129上安装nginx
//源码安装nginx就行,这台只是做一个代理转发
[root@129 ~]# dnf -y install nginx
[root@129 ~]# vim /etc/nginx/nginx.conf
upstream zwl.com {
server 192.168.159.167 weight=5;
server 192.168.159.168 weight=5;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://zwl.com;
}
[root@129 ~]# systemctl enable --now nginx.service
在134上也安装nginx
//源码安装nginx就行,这台只是做一个代理转发
[root@134 ~]# dnf -y install nginx
//因为129和134上的nginx配置是一样的都是做转发,直接把129上的nginx.conf复制去替换
[root@129 ~]# scp -r /etc/nginx/nginx.conf root@192.168.159.134:/etc/nginx/
The authenticity of host '192.168.159.134 (192.168.159.134)' can't be established.
ECDSA key fingerprint is SHA256:w1jC4OTx6KkZbLbuZccFQUen4XI6ScQ+JLHjUalJHgk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.159.134' (ECDSA) to the list of known hosts.
root@192.168.159.134's password:
nginx.conf 100% 2597 2.1MB/s 00:00
[root@134 ~]# systemctl enable --now nginx.service
在129和134上分别安装keepalived做高可用
//在129和134上分别安装keepalived做高可用
//在129上安装keepalived,把129作为主
[root@129 ~]# dnf -y install keepalived
//配置主keepalived
[root@129 ~]# cd /etc/keepalived/
[root@129 keepalived]# mv keepalived.conf keepalived.conf.bak
[root@129 keepalived]# vi keepalived.conf
[root@129 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.159.212
}
}
virtual_server 192.168.159.212 80 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP
real_server 192.168.159.129 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.159.134 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
[root@129 ~]# systemctl enable --now keepalived.service
// 配置备keepalived
[root@134 ~]# dnf -y install keepalived
[root@129 keepalived]# scp keepalived.conf root@192.168.159.134:/etc/keepalived/
[root@129 keepalived]# scp keepalived.conf root@192.168.159.134:/etc/keepalived/
root@192.168.159.134's password:
keepalived.conf 100% 796 1.1MB/s 00:00
[root@129 keepalived]#
[root@134 ~]# vim /etc/keepalived/keepalived.conf
[root@134 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.159.212
}
}
virtual_server 192.168.159.212 80 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP
real_server 192.168.159.129 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.159.134 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
[root@134 ~]# systemctl enable --now keepalived.service
//查看VIP在哪里
[root@129 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:62:95:21 brd ff:ff:ff:ff:ff:ff
inet 192.168.159.129/24 brd 192.168.159.255 scope global dynamic noprefixroute ens160
valid_lft 1641sec preferred_lft 1641sec
inet 192.168.159.212/32 scope global ens160
valid_lft forever preferred_lft forever
inet6 fd15:4ba5:5a2b:1008:20c:29ff:fe62:9521/64 scope global dynamic noprefixroute
valid_lft 86394sec preferred_lft 14394sec
inet6 fe80::20c:29ff:fe62:9521/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@134 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:70:77:e7 brd ff:ff:ff:ff:ff:ff
inet 192.168.159.134/24 brd 192.168.159.255 scope global dynamic noprefixroute ens160
valid_lft 961sec preferred_lft 961sec
inet6 fd15:4ba5:5a2b:1008:20c:29ff:fe70:77e7/64 scope global dynamic noprefixroute
valid_lft 86389sec preferred_lft 14389sec
inet6 fe80::20c:29ff:fe70:77e7/64 scope link noprefixroute
valid_lft forever preferred_lft forever
//129是主,就把134的nginx服务关闭
[root@134 ~]# systemctl stop nginx.service
测试