Nginx配置技巧
- 根据不同的端口或server_name反向映射到不同的服务器
- 单服务的映射:比如有个服务是部署在192.168.0.100这台机器上,访问端口是8080,现在需要在Nginx所在机器的80端口映射到192.168.0.100的8080,在http{}里加配置如下:
server {
#nginx监听端口,即对外访问端口
listen 80;
location / {
#即原服务的地址及端口
proxy_pass http://192.168.0.100:8080;
}
}
- 多服务映射(对外访问端口不一样):比如两个或多个服务,但对外访问端口不一样,则按1的配置方法,加多一个server,有几个服务就加几个这样的配置,以下配置表示
访问80端口跳转到192.168.0.100:8080,
访问8081端口跳转到192.168.0.101:8081
server {
listen 80;
location / {
proxy_pass http://192.168.0.100:8080;
}
}
server {
listen 8081;
location / {
proxy_pass http://192.168.0.101:8081;
}
}
- 多服务映射(对外访问端口一样):比如两个或多个服务,但对外访问端口一样,都是80端口,这时需要指定server_name,以下配置表示所有服务都通过80端口访问,但根据server_name不同映射到不同的服务:
访问test1.xxx.com时跳转到192.168.0.100:8080
访问test2.xxx.com时跳转到192.168.0.100:8081
server {
listen 80;
server_name test1.xxx.com;
location / {
proxy_pass http://192.168.0.100:8080;
}
}
server {
listen 80;
server_name test2.xxx.com;
location / {
proxy_pass http://192.168.0.100:8081;
}
}
注:server_name后面可以有多个域名,
如 server_name test1.xxx.com test2.xxx.com; 表示 test1.xxx.com和test2.xxx.com都走同样的代理
或者使用通配符,如 server_name test1.xxx.*; 表示test1.xxx.com,test1.xxx.com.cn,test1.xxx.net等等都走同样的代理。
- 当需要映射的服务很多,写的server块就很多,则可以拆分nginx.conf配置文件,在conf目录新建一个目录host,在host目录中新建xx.conf文件,有几个服务需要映射,就新建几份,如下是有8个服务,则新建了8个配置文件,
- 编辑xx.conf,将server块拷贝到xx.conf配置文件里,一个文件就配置一个块。
- 编辑nginx.conf文件,将所有server块去掉,在http块加上
include host/*.conf;,表示加载host目录里所有配置文件。
5,根据域名中的上下文不同跳转到不同的服务
比如test.xxx.com/test1跳转到192.168.0.100,test.xxx.com/test2跳转到192.168.0.101,配置如下:
server {
listen 80;
location / test1/ {
proxy_pass http://192.168.0.100/;
}
location / test2/ {
proxy_pass http://192.168.0.1010/;
}
}
- 集群映射配置
即通过nginx负载均衡分发到同几个服务。比如有两台服务192.168.0.100和192.168.0.101是集群服务。需要通过upstream模块指定ip_hash或是用weight权重,但两者不可同时使用。
- 通过ip_hash,则由nginx自由分发,当某个请求上次被分发到第一台服务,则以后此来源请求都被分发到该服务,除非该服务不能访问,配置如下:
访问80端口,由nginx自由分发到192.168.0.100或192.168.0.101。
upstream backend{
#根据客户端IP的hashcode决定访问哪一个后端服务器
hash $remote_addr consistent;
ip_hash;
server 192.168.0.100;
server 192.168.0.101;
}
server {
#nginx监听端口,即对外访问端口(修改此配置)
listen 80;
server_name ~.*;
location / {
proxy_pass http://backend;
}
}
- 通过权重,则由配置人员指定一个weight权重值,以下配置表示,每10个请求,会有9个请求被分发到第一台服务,1个请求被分发到第二台服务:
upstream backend{
server 192.168.0.100 weight=9;
server 192.168.0.101;
}
server {
#nginx监听端口,即对外访问端口(修改此配置)
listen 80;
server_name ~.*;
location / {
proxy_pass http://backend;
}
}
- 自定义错误页面
在html目录中默认有个50x.html文件,当服务出现500时向客户端返回50x.html页面,该页面可以自定义。在server块加上如下配置,表示当服务出现500,502,503,504时向客户端返回50x.html页面:
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
当然也可以再加404等的自定义页面,在html目录中新建40x.html文件,在server块中加如下配置:
error_page 404 /40x.html;
location = /40x.html {
root html;
}
比较粗略的配置,可以在http块加上limit_req_status 503;表示当服务拒绝访问时统一向客户端返回503。
- 配置访问频率和连接数
可以限制客户的请求量和连接数,特别是非法请求,以保证服务的正常运行。
当超过此限制时服务将返回错误代码,比如503。在http块加
#设置限制同一IP对服务器的最大连接数和并发数(速率/限流)
#rate=xr/s表示允许相同标识的客户端的访问频次,这里限制的是每秒10次
limit_req_zone $limit zone=one:10m rate=10r/s;
limit_req zone=one burst=100 nodelay;
#限制同一IP连接数,这里限制同一IP连接数为100
limit_conn_zone $limit zone=perip:10m;
limit_conn perip 100;
- 配置白名单
白名单,即不受访问频率和连接数限制的访问服务。Default 1;中的1表示受限制访问。以下配置表示默认受限访问,但192.168.0.100和192.168.101则不受限访问。在启用白名单,在http块加入配置即可。
#设置白名单,白名单不受访问频率和连接数的限制
geo $whiteiplist {
default 1;
192.168.0.100 0;
192.168.101 0;
}
map $whiteiplist $limit {
1 $binary_remote_addr;
0 "";
}
- 配置黑名单
如需要限制某些IP访问服务,可以在http块,或server块,或 location块(选择其中某一块)加入如下配置,表示192.168.0.103的IP将无法访问服务,返回一个错误代码(如前面介绍的503):
deny 192.168.0.103;
- 通过请求中的关键字跳转
如果需要从客户端发过来的请求中判断是否含有某些关键字,根据关键字再另做处理,则可以在server块中另入这样配置,判断$request_uri:
location / {
proxy_pass http://backend;
#当请求中包含有”123,abc,你好”,关键字时,则跳转到另一个服务http://192.168.0.105
if ($request_uri ~* =(123|abc|你好|)){
proxy_pass http://192.168.0.105;
}
}
或者跳转到指定的本地页面,当请求中是index.php或者是index.jsp时,跳转至html目录:
location /index.php{
root html;
}
location /index.jsp{
root html;
}
当请求中含有 *.php时,跳转至html目录
location ~*.php{
root html;
}
- 配置服务附件上传大小
服务系统存在需要上传附件的功能,如果需要限制附件大小,可以在http块或server块或 location块(选择其中某一块)加入如下配置,表示附件大小设置为500m:
#设置附件上传大小
client_max_body_size 500m;
- 启用压缩
如需要启用静态资源压缩,可在http块中加入如下配置:
#启用压缩:本地静态资源或者代理资源
gzip on;
gzip_proxied any;
#gzip支持的文件内容类型(MIME-TYPE)
gzip_types text/css application/javascript application/x-javascript;
另如果一些静态资源直接由nginx获取,而不再转发到服务器,可加在server块加入如下配置,表示jpg,fig,png,css和js请求将由nginx直接返回给客户端。
location / {
proxy_pass http://backend_E;
#普通资源文件JS,CSS和图片文件,浏览器缓存3d
if ($uri ~* \.(jpg|gif|png|css|js)$){
expires 3d;
}
}
- 将日志文件换成json串格式
#log_format main '$remote_addr - $remote_user [$time_local] "$request"
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#以上是默认的日志格式
#以下是按json串生成日志
log_format main '{"@timestamp":"$time_iso8601",'
'"@version":"1",'
'"server_addr":"$server_addr",'
'"remote_addr":"$remote_addr",'
'"host":"$host",'
'"uri":"$uri",'
'"body_bytes_sent":$body_bytes_sent,'
'"bytes_sent":$body_bytes_sent,'
'"upstream_response_time":$upstream_response_time,'
'"request":"$request",'
'"request_length":$request_length,'
'"request_time":$request_time,'
'"status":"$status",'
'"http_referer":"$http_referer",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"http_user_agent":"$http_user_agent"'
'}';
- 配置https
免费试用的https证书申请网站:https://freessl.cn/
Listen 端口时,注意要加上ssl,证书和key可以放到ssl目录中(在conf目录创建ssl目录)
server {
listen 443 ssl;
ssl_certificate ssl/full_chain.pem;
ssl_certificate_key ssl/private.key;
}
- 请求串超长的问题
当终端发送超长的请求时,可在http块中加入该参数,后面的数字值可自定义:
large_client_header_buffers 8 16k;
- 按不同的server生成日志
默认情况下不管配置有几个代理,Nginx的日志都会记录到access.log文件中,如果想按不同的代理生成不同的文件名,则可以这样配置:
- 本文中的第一点,第4小点提到的按每个server拆分配置文件
- 在server块中加入access_log logs/xxx.log main; (XXX自取名字)
每个server加入不同的日志文件名,即可生成不同的日志文件。当然也可以设置成一样的日志文件名。
- 反爬虫设置
在server块加入如下设置:
#禁止Scrapy等工具的抓取
if ($http_user_agent ~* (Scrapy|python|Curl|java|wget|HttpClient|okhttp)) {
return 404;
}
#禁止指定UA及UA为空的访问
if ($http_user_agent ~ "WinHttp|WebZIP|FetchURL|node-superagent|java/|FeedDemon|Jullo|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|Java|Feedly|Apache-HttpAsyncClient|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|heritrix|EasouSpider|Ezooms|BOT/0.1|YandexBot|FlightDeckReports|Linguee Bot|^$" ) {
return 404;
}
#禁止非GET|HEAD|POST方式的抓取
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 404;
}
- 一些安全及性能方面的设置
在http块中加入如下设置:
# 不要将Nginx版本号在错误页面或服务器头部中显示
server_tokens off;
#设置HSTS,强制需要输入https或http
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
# 这是为了失效某些浏览器的内容类型探嗅
add_header X-Content-Type-Options nosniff;
# 防止跨站脚本 Cross-site scripting (XSS)
add_header X-XSS-Protection "1; mode=block";
#不允许页面从框架frame 或 iframe中显示
add_header X-Frame-Options SAMEORIGIN;
#系统内核空间直接文件复制
sendfile on;
#关闭TCP小包延迟发送特性(Nagle算法)
tcp_nodelay on;
tcp_nopush on;