Nginx高级设置

文章目录

  • 一、Nginx高级设置
    • Nginx状态页
    • Nginx第三方模块
    • Nginx变量使用
      • 内置变量
      • 自定义变量
    • Nginx自定义访问日志
      • 自定义默认格式日志
      • 自定义json格式日志
    • Nginx压缩功能
    • https功能
      • https配置参数
      • 自签名证书
    • 虚拟主机
  • 二、Nginx代理服务
  • 三、代理服务常见模式
  • 四、Nginx代理服务支持协议
  • 五、Nginx反向代理配置语法
  • 六、Nginx反向代理场景实践

一、Nginx高级设置

Nginx状态页

基于nginx模块ngx_http_stub_status_module实现,在编译安装nginx的时候需要添加编译参数–with-http_stub_status_module,否则配置完成之后监测会是提示语法错误

注意:状态页显示的是整个服务器的状态,而非虚拟主机的状态

[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
location /nginx_status {
	stub_status on;
	auth_basic "auth login";
	auth_basic_user_file /apps/nginx/conf/.htpasswd;
	allow 192.168.0.0/16;
	allow 127.0.0.1;
	deny all;
}
http://file.test.com/nginx_status
  • Active connections:2表示Nginx正在处理的活动连接数2个。
  • server 2 表示Nginx启动到现在共处理了2个连接
  • accepts 2 表示Nginx启动到现在共成功创建2次握手
  • handled requests 1 表示总共处理了1次请求
  • Reading:Nginx读取到客户端的Header信息数,数值越大,说明排队越长,性能不足
  • Writing:Nginx返回给客户端Header信息数,数值越大,说明访问量越大
  • Waiting:Nginx已经处理完正在等候下一次请求指令的驻留链接(开启keep-alive的情况下,这个值等于Active-(Reading+Writing))

Nginx第三方模块

第三模块是对nginx的功能扩展,第三方模块需要在编译安装Nginx的时候使用参数–add-module=PATH指定路径添加,有的模块是由公司的开发人员针对业务需求定制开发的,有的模块是开源爱好者开发好之后上传到github进行开源的模块,nginx支持第三方模块需要从源码重新编译支持,比如:开源的echo模块https://github.com/openresty/echo-nginx-module

[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
location /main {
	index index.html;
	default_type text/html;
	echo "hello world,main-->";
	echo $remote_addr;
	echo_reset_timer;	# 将计时器开始时间重置为当前时间
	echo_location /sub1;
	echo_location /sub2;
	echo "took $echo_timer_elapsed sec for total.";
}
location /sub1 {
	echo_sleep 2;
	echo hello;
}
location /sub2 {
	echo_sleep 1;
	echo world;
}
[root@localhost src]# wget https://github.com/openresty/echo-nginx-module/archive/refs/heads/master.zip
[root@localhost src]# unzip master.zip
[root@localhost src]# mv echo-nginx-module-master echo-nginx-module
[root@localhost src]# cd nginx-1.18.0
[root@localhost nginx-1.18.0]# ./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-prce \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-file-aio \
--add-module=/usr/local/src/echo-nginx-module
[root@localhost nginx-1.18.0]# make -j 2 && make install
http://file.test.com/main

Nginx变量使用

nginx的变量可以在配置文件中应用,作为功能判断或者日志等场景使用

变量可以分为内置变量和自定义变量

内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问的相关的值

内置变量

官方文档:https://nginx.org/en/docs/varindex.html

常用内置变量

$remote_addr;
# 存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for;
# 此变量表示将客户端IP追加请求报文中X-Forwarded-For首字母段,多个IP之间用逗号分割,如果请求中没有X-Forwarded-For,就使用$remote_addr
$args;
# 变量中存放了URL中的参数
$document_root;
# 保存了正对当前资源的系统根目录
$document_uri;
# 保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比如/img/logo.png
$host;
# 存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
# 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果媒体设置,则显示0
$remote_port;
# 客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_body_file;
# 做反向代理时发给后端服务器的本地资源的名称
$request_method
# 请求资源的方式,GET/PUT等等
$request_filename
# 当前请求的资源文件的磁盘路径,由root或alias指令与URL请求生成的文件绝对路径
# /apps/nginx/html/www/index.html
$request_uri;
# 包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args
$scheme;
# 请求的协议,例如:http,https,ftp等等
$server_protocol;
# 保存了客户端请求资源的使用的协议版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等等
$server_addr;
# 保存了服务器的IP地址
$server_name;
# 请求的服务器的主机名
$server_port;
# 请求的服务器的端口号
$http_<name>
# name为任意请求报文首部字段,表示记录请求报文的首部字段
$http_user_agent;
# 客户端浏览器的详细信息
$http_cookie;
# 客户端的cookie信息
$cookie_<name>;
# name为任意请求报文首部字段cookie的key名

自定义变量

假如需要自定义变量名和值,使用指令set $variable value;

语法格式:

Syntax:Set $variable value;
Default: -
Context: server, location, if

范例:

[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
location {
set $name zs;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";
}

Nginx自定义访问日志

访问日志是记录客户端即用户的具体请求内容信息,全局配置模块中的error_log是记录nginx服务器允许时的日志保存路径和记录日志的level,因此有着本质的区别,而且Nginx的错误日志一般只有一个,但是访问日志可以在不同server中定义多个,定义一个日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容。

访问日志由ngx_http_log_module模块实现

语法格式:

Syntax: access_log path [format [buffer=size] [gzip [=level]] [flush=time] [if=condition]];
access_log off;
Default:
access_log logs/access.log combined;
Context:	http, server, location, if in location, limit_excepts

自定义默认格式日志

如果虚脱保留日志的源格式,至少添加相应的日志内容,则配置如下:

[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
log_fomat nginx_format1  '$remote_addr - $remote_user [$time_local] "$request" ' '$status  $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"' 
'$server_name:$server_port';
access_log  logs/access.log  nginx_format1;
# 重启nginx并访问测试日志格式
# /apps/nginx/logs/access.log

自定义json格式日志

Nginx的默认访问日志记录内容相对比较单一,默认的格式也不方便后期做日志统计分析,生产环境中通常将nginx日志转换为json日志,然后配合使用ELK做日志收集-统计-分析。

log_format access_json '{"@timestamp":"$time_iso8601",'
	'"host":"$server_addr",'
	'"Clientip":"$remote_addr",'
	'"size":$body_bytes_sent,'
	'"responsetime":$request_time,'
	'"upstreamhost":"$upstream_response_time",'
	'"upstreamhost":"$upstream_addr",'
	'"http_host":"$host",'
	'"uri":"$uri",'
	'"xff":"$http_x_forwarded_for",'
	'"tcp_xff":"$proxy_protocol_addr",'
	'"status":"$status"}';
access_log logs/access.log access_json

Nginx压缩功能

Nginx支持对指定类型的文件进行压缩,然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,不过会占用相应的CPU资源。

Nginx对文件的压缩功能是依赖于模块ngx_http_gzip_module

官方文档:https://nginx.org/en/docs/http/ngx_http_gzip_module.html

# 启用或禁用gzip压缩,默认关闭
gzip on | off;
# 压缩比由低到高1到9,默认为1
gzip_comp_level level;
# 禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
# gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# 启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
# 指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
# 指明进队哪些类型的资源指向压缩操作,默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
# 如果启用压缩,是否再相应报文首部插入"vary: Accept-Encoding",一般建议打开
gzip_vary on | off
# 重启nginx并进行访问测试压缩功能
[root@localhost ~]# curl -I --compressed servername

https功能

https配置参数

nginx的https功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数–with-http_ssl_module开启

官方文档:https://nginx.org/en/docs/http/ngx_http_ssl_module.html

配置参数如下:

ssl on | off;
listen 443 ssl;
# 为指定的虚拟主机配置是否启用ssl功能,此功能再1.15.0废弃,使用listen [ssl]替代。
ssl_certificate_key /path/to/file;
# 当前虚拟主机使用的公钥文件,一般是crt文件
ssl_cerificate_key /path/to/file;
# 当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
# 支持ssl协议版本,早期为ssl现在是TSL,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
	# 配置ssl缓存
	off
	# 关闭缓存
	none:
	# 通知客户端支持ssl session cache,但实际不支持
	builtin[:size]:
	# 使用OpenSSL内建缓存,为每worker进程私有
	[shared:name:size]
	# 在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000多个会话信息,多个虚拟主机可以使用相同的缓存名称
	ssl_session_timeout time;
	# 客户端连接可以复用ssl session cache中缓存的有效时长,默认5m

自签名证书

  • 生成ca证书
cd /apps/nginx 
mkdir certs && cd certs 
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 - out ca.crt
  • 生成证书请求文件
openssl req -newkey rsa:4096 -nodes -sha256 -keyout iproute.cn.key -out iproute.cn.csr
  • 签发证书
openssl x509 -req -days 36500 -in iproute.cn.csr -CA ca.crt -CAkey ca.key - CAcreateserial -out iproute.cn.crt 
cat iproute.cn.crt ca.crt > iproute.crt
  • 验证证书内容
openssl x509 -in iproute.cn.crt -noout -text
  • 证书配置,在nginx的主配置文件中写
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
server { 
	listen 80; 
	listen 443 ssl; 
	ssl_certificate /apps/nginx/certs/iproute.crt; 			
	ssl_certificate_key /apps/nginx/certs/iproute.cn.key; 
	ssl_session_cache shared:sslcache:20m; 
	ssl_session_timeout 10m; 
	root /apps/nginx/html; 
}

虚拟主机

[root@localhost ~]# ll /apps/nginx/conf.d
总用量 12
-rw-r--r--. 1 root root 107 925 16:45 bbs.conf
-rw-r--r--. 1 root root 109 925 16:45 blog.conf
-rw-r--r--. 1 root root 107 925 16:44 www.conf

[root@localhost conf.d]# cat *.conf
server {
	listen *:8080;
	server_name bbs.eagle.com;
	location / {
	root /apps/nginx/html/bbs;
	index index.html;
	}
}
server {
	listen *:8080;
	server_name blog.eagle.com;
	location / {
	root /apps/nginx/html/blog;
	index index.html;
	}
}
server {
	listen *:8080;
	server_name www.eagle.com;
	location / {
	root /apps/nginx/html/www;
	index index.html;
	}
}

二、Nginx代理服务

  • 代理一次往往并不模式,该服务我们常常用到如(代理理财,代理租房,代理收货等等)

租房—>中介—>房源

  • 在没有代理模式的情况下,客户端和Nginx服务端,都是客户端直接请求服务端,服务端直接响应客户端
  • 那么在互联网请求里,客户端往往无法直接向服务端发起请求,那么就需要用到代理服务,来实现客户端和服务通信

三、代理服务常见模式

  • Nginx作为代理服务,按照应用场景模式进行总结,代理分为正向代理、反向代理
    Nginx高级设置_第1张图片
  • 正向代理与反向代理的区别
    • 区别在于形式上服务的”对象“不一样
    • 正向代理代理的对象是客户端,为客户端服务
    • 反向代理代理的对象是服务端,为服务端服务

四、Nginx代理服务支持协议

  • Nginx作为代理服务,可支持的代理协议非常的多
    Nginx高级设置_第2张图片

  • 如果将Nginx作为反向代理服务,常常会用到如下几种代理协议
    Nginx高级设置_第3张图片

五、Nginx反向代理配置语法

  • 代理配置语法
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except

http://localhost:8000/uri/
http://192.168.56.11:8000/uri/
http://unix:/tmp/backend.socket:/uri/
  • 添加发往后端服务端请求头信息
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
		proxy_set_header Connection close;
Context: http, server, location

# 用户请求的时候HOST的值是www.eagleslab.com, 那么代理服务会像后端传递请求的还是eagleslab
proxy_set_header Host $http_host;
# 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
proxy_set_header X-Real-IP $remote_addr;
# 客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  • 代理到后端的TCP连接、响应、返回等超时时间
//nginx代理与后端服务器连接超时时间(代理连接超时) # 去饭店
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location

//nginx代理等待后端服务器的响应时间	# 点菜
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location

//后端服务器数据回传给nginx代理超时时间	# 等上菜菜
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
  • proxy_buffer代理缓冲区
# nginx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传,不是全部接受完再传给客户端
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location

# 设置nginx代理保存用户头信息的缓冲区大小
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location

# proxy_buffers 缓冲区
# 为每个连接设置缓冲区数量为number,每块缓冲区的大小为size,这些缓冲区用于保存从代理的服务器读取的响应。
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
  • 常用优化配置
    • Proxy代理网站常用优化配置如下,将配置写入新文件,调用时使用include即可
[root@localhost ~]# vim /etc/nginx/proxy_params
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
  • 重复使用配置
    • 代理配置location时调用方便后续多个Location重复使用
location / {
	proxy_pass http://127.0.0.1;
	include proxy_params;
}

六、Nginx反向代理场景实践

  • Nginx反向代理配置实例

在这里插入图片描述

  • 客户端请求反向代理80端口,反向代理web02代理后向后端转发请求,转发至后端的8080端口,服务端web01处理之后向代理服务器返回结果
  • web01服务器配置一个网站,监听在8080端口
[root@web01 ~]# vim /etc/nginx/conf.d/web.conf
server{
	listen 8080;
	server_name localhost;
	
	location / {
		root /code/8080
		index index.html;
		allow all;
	}
}

[root@web01 ~]# nginx -t
[root@web01 ~]# systemctl restart nginx
[root@web01 ~]# mkdir -p /code/8080
[root@web01 ~]# echo "listening 8080..." > /code/8080/index.html
  • proxy代理服务,配置监听80端口,使能够通过代理服务器访问到后端的8080端口内容
[root@web02 ~]# vim /etc/nginx/conf.d/proxy_web_node1.conf
server{
	listen 80;
	server_name proxy.test.com;
	
	location / {
	proxy_pass http://192.168.64.129:8080;
	}
}

[root@web02 ~]# nginx -t
[root@web02 ~]# systemctl restart nginx
  • 存在的问题,通过抓包可以看到客户端是使用域名对网站进行访问的,但是代理却是使用的IP地址加端口号
  • 当访问80端口的时候,没有域名的情况下,默认会去找排在最上面的那个配置文件。
  • 所以我们需要解决这个问题,保留住最开始的请求头部信息。
  • 并且发现我们向代理服务器发起的http是1.1但是代理向web服务器发起的是1.0,1.0不支持长链接,解决这个问题就指定协议版本
    Nginx高级设置_第4张图片
    Nginx高级设置_第5张图片
  • 修改配置文件,使用proxy_set_header模块
[root@web02 ~]# vim /etc/nginx/conf.d/proxy_web_node1.conf
server{
	listen 80;
	server_name proxy.test.com;
	
	location / {
		proxy_pass http://192.168.64.129:8080;
		proxy_set_header Host $proxy_host;
	}
}

  • 使用http1.1协议
[root@web02 ~]# vim /etc/nginx/conf.d/proxy_web_node1.conf
server{
	listen 80;
	server_name proxy.test.com;
	
	location / {
		proxy_pass http://192.168.64.129:8080;
		proxy_set_header Host $proxy_host;
		proxy_http_version 1.1;
	}
}
  • 在生产环境中,我们必须要记录客户端的来源IP,如果所有的访问日志,全部都来源于代理,那么我们根本不知道有哪些地区的用户访问了我们什么页面。
    • 还需要使用proxy_set_header
server{
	listen 80;
	server_name proxy.test.com;
	
	location / {
		proxy_pass http://192.168.64.129:8080;
		proxy_set_header Host $proxy_host;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

你可能感兴趣的:(企业服务,nginx,运维,服务器,linux)