版本比较
标识
- 该行被添加。
- 该行被删除。
- 格式已经改变。
Host 头匹配流程
draw.io Diagram | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
禁止其它域名访问
nginx安装在192.168.111.124,上面配置2个域名doc.myj.com.cn和zabbix.myj.com.cn。默认情况下输入http://192.168.111.124会打开doc.myj.com.cn页面,要求实现只能通过域名访问,使用IP地址提示403或跳转其它页面。
增加default.conf配置文件
代码块 | ||||
---|---|---|---|---|
| ||||
server { listen 80 default_server; server_name _; return 403; ## index 403.html } |
重启生效
详情可参考:https://nginx.org/en/docs/http/server_names.html
跨域问题处理
假如代理服务器地址是 www.c.com/proxy/html/api/msg?method=1=2; www.c.com是nginx主机地址
远端服务器地址:http://www.b.com/api/msg?method=1=2
在nginx服务器上做如下配置。在location下面再添加一个location。
代码块 | ||
---|---|---|
| ||
location ^~/proxy/html/{ rewrite ^/proxy/html/(.*)$ /$1 break; proxy_pass http://www.b.com/; } |
说明
'^~ /proxy/html/ ‘
就像上面说的一样是一个匹配规则,用于拦截请求,匹配任何以 /proxy/html/开头的地址,匹配符合以后,停止往下搜索正则。
rewrite ^/proxy/html/(.*)$ /$1 break;
代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用,例如www.c.com/proxy/html/api/msg?method=1=2重写。只对/proxy/html/api/msg重写。
rewrite后面的参数是一个简单的正则 ^/proxy/html/(.*)$ ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。
break代表匹配一个之后停止匹配。
Node.js 反向代理
服务端如果使用nodejs运行服务,由于端口不能同时多个服务占用,而服务器中可能又是多个网站,那么可以使用 Nginx 做反向代理,比如有这些网站域名和端口:
域名 | 端口 |
---|---|
www.xxoo.com | 8001 |
www.xo.com | 8002 |
www.xo.cn | 8003 |
配置文件
代码块 | ||
---|---|---|
| ||
server { server_name www.xxoo.com; listen 80; # 设置这个网站的根目录 root /wwwroot/www.xxoo.com/; # 由于下面配置了文件不存在则代码到 Node.js 中,那么直接访问目录(不带默认主页)的话会有问题,这里做下判断 # 如果访问目录下有 index.html 文件,则直接重写到该文件 # break 表示重写且停止,但 url 不变,而 permanent 表示301重定向,url 会更新 if ( -f $request_filename/index.html ){ rewrite (.*) $1/index.html break; } # 如果请求的文件不存在,则代理到 Node.js if ( !-f $request_filename ){ rewrite (.*) /index.js; } # 代理node服务 8001 location = /index.js { # 设置一些代理的header信息,这些信息将被透传到 Node.js 服务的header信息里 proxy_set_header Connection ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; # 代理服务 proxy_pass http://127.0.0.1:8001$request_uri; # 忽略其他重写 proxy_redirect off; } } |
内容说明
访问链接 | 解析过程 | 备注 |
---|---|---|
www.xxoo.com/index.html | Nginx | 由于文件存在,直接使用 Nginx 输出 |
www.xxoo.com | Nginx | 由于判断该目录下有 index.html 文件,则自动重写到该文件,但 url 不变 |
www.xxoo.com/xx.html | Nginx -> Node.js:8001 | 由于文件不存在,使用 Nginx 代理到 Node.js 的 8001 端口 |
www.xxoo.com/xxoo/ | Nginx -> Node.js:8001 | 首先判断该目录是否存在 如果存在再判断是否有 index.html 文件一旦不成立,直接代理到 Node.js |
重写网页图片 CDN
在不调整网页代码的情况下重新调整页面展示图片的后端网络
代码块 | ||
---|---|---|
| ||
location ^~ /test/ { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host "appfleet.com"; proxy_set_header X-Forwarded-Proto https; proxy_pass http://127.0.0.1:2368; proxy_redirect off; #disable compression proxy_set_header Accept-Encoding ""; #rewrite the html sub_filter_once off; sub_filter_types text/html; sub_filter '<img src="https://appfleet.com' '<img loading="lazy" src="https://appfleet-com.cdn.ampproject.org/i/s/appfleet.com'; } |
rewrite 重定向
rewrite 语法格式及参数语法
rewrite是实现URL重写的关键指令,根据regex (正则表达式)部分内容,重定向到replacement,结尾是flag标记。
rewrite <regex> <replacement> [flag];
- 关键字 正则 替代内容 flag标记
- 关键字:其中关键字error_log不能改变
- 正则:perl兼容正则表达式语句进行规则匹配
- 替代内容:将正则匹配的内容替换成replacement
- flag标记:rewrite支持的flag标记
rewrite参数的标签段位置:server,location,if
flag标记说明:
- last #本条规则匹配完成后,继续向下匹配新的location URI规则
- break #本条规则匹配完成即终止,不再匹配后面的任何规则
- redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
- permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
Nginx rewrite变量
常用于匹配HTTP请求头信息、浏览器主机名、URL
HTTP headers:HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE, HTTP_HOST, HTTP_ACCEPT;
connection & request: REMOTE_ADDR, QUERY_STRING;
server internals: DOCUMENT_ROOT, SERVER_PORT, SERVER_PROTOCOL;
system stuff: TIME_YEAR, TIME_MON, TIME_DAY。
详解如下:
- HTTP_USER_AGENT 用户使用的代理,例如浏览器;
- HTTP_REFERER 告知服务器,从哪个页面来访问的;
- HTTP_COOKIE 客户端缓存,主要用于存储用户名和密码等信息;
- HTTP_HOST 匹配服务器ServerName域名;
- HTTP_ACCEPT 客户端的浏览器支持的MIME类型;
- REMOTE_ADDR 客户端的IP地址
- QUERY_STRING URL中访问的字符串;
- DOCUMENT_ROOT 服务器发布目录;
- SERVER_PORT 服务器端口;
- SERVER_PROTOCOL 服务器端协议;
- TIME_YEAR 年;
- TIME_MON 月;
- TIME_DAY 日;
场景举例
1、将uri中的所有空格替换为"_",连续的空格替换为一个"_"放到proxy_pass之前
代码块 |
---|
rewrite '^(\S+) +(\S+)(.*)' $1_$2$3 last; |
2、将zy.com跳转至www.zy.com
代码块 |
---|
if ($host = zy.com' ) { #其中$1是取自regex部分()里的内容,匹配成功后跳转到的URL。 rewrite ^/(.*)$ http://www.zy.com/$1 permanent; } |
3、访问www.zy.com跳转www.test.com/index01.html
代码块 |
---|
rewrite ^/$ http://www.test.com/index01.html permanent; |
4、访问/zy/test01/跳转至/newindex.html,浏览器地址不变
代码块 |
---|
rewrite ^/zy/test01/$ /newindex.html last; |
5、多域名跳转到www.zy.com
代码块 |
---|
if ($host != ‘www.jfedu.net’ ) { rewrite ^/(.*)$ http://www.zy.com/$1 permanent; } |
6、访问文件和目录不存在跳转至index.php
代码块 |
---|
if ( ! -e $request_filename ) { rewrite ^/(.*)$ /index.php last; } |
7、目录对换 /xxxx/123456 ====> /xxxx?id=123456
代码块 |
---|
rewrite ^/(.+)/(\d+) /$1?id=$2 last; |
8、判断浏览器User Agent跳转
代码块 |
---|
if( $http_user_agent ~ MSIE) { rewrite ^(.*)$ /ie/$1 break; } |
9、禁止访问以.sh,.flv,.mp3为文件后缀名的文件
代码块 |
---|
location ~ .*\.(sh|flv|mp3)${ return 403; } |
10、将移动用户访问跳转至移动端
代码块 |
---|
if ( $http_user_agent ~* "(Android)|(iPhone)|(Mobile)|(WAP)|(UCWEB)" ){ rewrite ^/$ http://m.jfedu.net/ permanent; } |
11、访问/10690/zy/123跳转至/index.php?tid/10690/items=123,[0-9]表示任意一个数字,+表示多个,(.+)表示任何多个字符
代码块 |
---|
rewrite ^/([0-9]+)/zy/(.+)$ /index.php?tid/$1/items=$2 last; |
12、匹配URL访问字符串跳转
代码块 |
---|
if ($args ~* tid=13){ return 404; } |
Nginx 取代理后的 IP
1、系统安装:CentOS7/8 系统安装标准
2、Nginx安装:Nginx 编译安装及配置指南
3、Nginx需要包含--with-http_realip_module模块
针对普通的代理方式
在Server段增加
代码块 | ||
---|---|---|
| ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
提示 | ||
---|---|---|
| ||
$proxy_add_x_forwarded_for 这个变量会将所有代理的IP都包含其中,而第一个IP就是用户的真实IP,值的格式如下:TTP_X_FORWARDED_FOR => remote_ip,proxy1_ip, proxy2_ip,... ... |
针对CDN后的反向代理模式
代码块 | ||
---|---|---|
| ||
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; set_real_ip_from 118.89.52.242; real_ip_header X-Forwarded-For; |
上游服务器IP是:118.89.52.242,同时需要从X-Forwarded-For字段中获取访客IP
提示 | ||
---|---|---|
| ||
set_real_ip_from:指定上游服务器 real_ip_header:指定获取访客IP的位置 两个语句可以放置在http、server和location区块中,放置在http区块中将对所有的虚拟空间生效。 |
Conflunece 的 Nginx 配置
代码块 | ||
---|---|---|
| ||
server { client_max_body_size 100m; listen 80; listen 443; ssl on; ssl_certificate /usr/local/etc/ssl/wiki.ourclass.com.pem; ssl_certificate_key /usr/local/etc/ssl/wiki.ourclass.com.key; server_name wiki.ourclass.com; access_log /var/log/nginx/wiki.log main; location / { proxy_pass http://127.0.0.1:8090/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /synchrony { proxy_pass http://127.0.0.1:8091; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location ~ ^/ttyd(.*)$ { proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://127.0.0.1:8094/$1; } # 重定向non-https流量到https if ($scheme != "https") { return 301 https://$host$request_uri; } } |
注意,上面的路径配置有两个,分别是/和/synchrony,前者就是wiki的主体,后者是用来检测wiki的URL地址的一个心跳服务。其中,第二个映射/synchrony中的如下配置必须要有,否则前端多人协作的时候就会有一些问题。
http 1.1 添加的配置是为了保证wiki中的Websocket服务正常运行。
配置Confluence
配置完了上述的系统以后就觉得可以访问了,但是一直会报一个警告就是
注意 |
---|
无法检测Base URL,是不是存在代理的配置问题 |
英文版的是
注意 |
---|
can't check base url warning |
这个问题的解决方案除了上述的/stnchrony配置外,还需要加入一个Tomcat的配置,就是要在<install-directory>/conf/server.xml这个文件里面添加proxyPort和proxyName的配置,如下:
代码块 | ||
---|---|---|
| ||
<Connector port="8090" connectionTimeout="20000" redirectPort="8443" maxThreads="48" minSpareThreads="10" enableLookups="false" acceptCount="10" debug="0" URIEncoding="UTF-8" protocol="org.apache.coyote.http11.Http11NioProtocol" proxyName="ourclass.com" proxyPort="443" scheme="https"/> |
总结
这个问题的解决方案还是需要理解confluence的几个核心的组件,然后在根据这些核心的组件进行相应的配置。尤其是这个/synchrony组件非常关键,如果不加上这个完整的服务根本就起不来。
stream 端口转发配置
安装
./configure --with-stream #添加stream模块
配置
主配置文件nginx.conf增加stream模块配置
之前在http增加的include会提示虚拟目录里的配置项不允许在某个位置
代码块 | ||
---|---|---|
| ||
stream { include rds/*.conf; } |
虚拟目录配置
代码块 | ||
---|---|---|
| ||
#nTMXX-01-ZFPT-订单 upstream nTMXX-01-ZFPT-DD { server rm-wz994z33d9e8i9b38yo.sqlserver.rds.aliyuncs.com:3433 weight=5 max_fails=3 fail_timeout=30s; } server { listen 39600; proxy_connect_timeout 60s; proxy_timeout 4h; proxy_pass nTMXX-01-ZFPT-DD; } |
测试
nginx -t
nginx -s reload 或 systemctl reload nginx
Nginx 邮件代理
代码块 | ||
---|---|---|
| ||
# nginx 分流 993 端口的配置参考如下,465 和 995 照样画葫芦。25 、587 端口用 postfix 或 exim4 ,具体配置可以问 gpt 。
stream {
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
map $ssl_preread_server_name $stream_map993 {
mail.domain1.com upstream_993_svr1;
mail.domain2.com upstream_993_svr2;
mail.domain3.com upstream_993_svr3;
}
upstream upstream_993_svr1 {
server 192.168.1.100:993;
}
upstream upstream_993_svr2 {
server 192.168.1.101:993;
}
upstream upstream_993_svr3 {
server 192.168.1.102:993;
}
# stream 模块监听 993 端口,并进行端口复用
server {
listen 993 reuseport;
listen [::]:993 reuseport ipv6only=on;
proxy_pass $stream_map993;
ssl_preread on;
}
} |
参考
Nginx Config 在线生成配置文件
Nginx Config 是一款可以一键生成 Nginx 配置的神器,相当给力。支持反向代理、HTTPS、HTTP/2、IPv6, 缓存、WordPress、CDN、Node.js 、 Python (Django) 服务器等等。打开网站:https://nginxconfig.io,按照自己的需求进行操作就行了。选择你的场景,填写好参数,系统就会自动生成配置文件。
目录 | ||
---|---|---|
|