❶ Nginx的反向代理跨域
什么是跨域?
跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址, b页面为域名地址,所进行的访问行动都是跨域
浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源
同ip(或domain),同端口,同协议视为同一个域,一个域内的脚本仅仅具有本域内的权限,可以理解为本域脚本只能读写 本域内的资源,而无法访问其它域的资源。这种安全限制称为同源策略
现代浏览器在安全性和可用性之间选择了一个平衡点。 在遵循同源策略的基础上,选择性地为同源策略“开放了后门”。例如img script style等标签,都允许垮域引用资源,然而, 你也只能是引用这些资源而已,并不能读取这些资源的内容
同源策略限制以下几种行为:
1.Cookie、LocalStorage 和 IndexDB 无法读取
2.DOM 和 Js对象无法获得
3.AJAX 请求不能发送
http://www.domain.com/a.jshttp://www.domain.com/b.js 同一域名,不同文件或路径 允许http://www.domain.com/lab/c.jshttp://www.domain.com:8000/a.jshttp://www.domain.com/b.js 同一域名,不同端口 不允许http://www.domain.com/a.jshttps://www.domain.com/b.js 同一域名,不同协议 不允许http://www.domain.com/a.jshttp://192.168.4.12/b.js 域名和域名对应相同ip 不允许http://www.domain.com/a.jshttp://x.domain.com/b.js 主域相同,子域不同 不允许http://domain.com/c.jshttp://www.domain1.com/a.jshttp://www.domain2.com/b.js 不同域名 不允许
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
正向代理 :代理位于网站和客户端中间, 客户端无法访问某网站,就将请求发送给代理服务器,代理从网站取回来再发送给客户端,网站并不知道为谁提供服务
反向代理 :客户端访问某网站的一个页面, 但是网站并没有,就偷偷从另外一台服务器上取回来,然后作为自己的内容吐给用户,用户不知道真正提供服务的是谁
对于浏览器来说,访问的就是同源服务器上的一个url。而nginx通过 检测url前缀,把http请求转发到后面真实的物理服务器。并通过rewrite命令把前缀再去掉。这样真实的服务器就可以正确 处理请求,并且并不知道这个请求是来自代理服务器的。
简单说,nginx服务器欺骗了浏览器,让它认为这是同源调用,从而解决了浏览器的跨域问题。又通过重写url,欺骗了真实 的服务器,让它以为这个http请求是直接来自与用户浏览器的。
Location/carrots-admin-ajax/{
proxy_passhttp://dev.admin.carrots.ptteng.com/;
}
proxy_pass 把请求代理到其他主机
两种写法hhttp://dev.admin.carrots.ptteng.com/ 和 http://dev.admin.carrots.ptteng.com
如果访问url = http://server/html/test.jsp ,则被nginx代理后
情况1,将test/作为根路径,请求test/路径下的资源。
情况2,则被nginx代理后,请求路径会变为http://proxy_pass/test.jsp,直接访问server的根资源。
是一个匹配规则,用于拦截请求,匹配任何以/proxy/html/开头的地址,匹配符合以后,停止往下搜索正则。
对于浏览器来说,访问的就是同源服务器上的一个url。而nginx通过检测url前缀,把http请求转发到后面真实的物理服务器。并通过rewrite命令把前缀再去掉。这样真实的服务器就可以正确处理请求,并且并不知道这个请求是来自代理服务器的。
简单说,nginx服务器欺骗了浏览器,让它认为这是同源调用,从而解决了浏览器的跨域问题。又通过重写url,欺骗了真实的服务器,让它以为这个http请求是直接来自与用户浏览器的。
1.执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
2.执行location匹配
3.执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件
如果循环超过10次,则返回500 Internal Server Error错误
7.参考文献
参考一: https://www.cnblogs.com/gabrielchen/p/5066120.html
参考二: http://blog.csdn.net/shendl/article/details/48443299
8.更多讨论
提问:
Q :例如img script style等标签,都允许垮域引用资源?
A :在浏览器中,并且加载的方式其实相当于一次普通的GET请求,唯一不同的是,为了安全起见,浏览器不允许这种方式下对加载到的资源的读写操作,而只能使用标签本身应当具备的能力(比如脚本执行、样式应用等等)。
Q :例如img script style等标签,都允许垮域引用资源?
A :在浏览器中,并且加载的方式其实相当于一次普通的GET请求,唯一不同的是,为了安全起见,浏览器不允许这种方式下对加载到的资源的读写操作,而只能使用标签本身应当具备的能力(比如脚本执行、样式应用等等)。
Q:JSONP和nginx跨域有什么不同
JSONP和nginx是完全不同的 是可以跨域的,而且在跨域脚本中可以直接回调当前脚本的函数
原理:是可以跨域的,而且在跨域脚本中可以直接回调当前脚本的函数
script标签是可以加载异域的JavaScript并执行的,通过预先设定好的callback函数来实现和母页面的交互。它有一个大名,叫做JSONP跨域,JSONP是JSON with Padding的略称。它是一个非官方的协议,明明是加载script,为啥和JSON扯上关系呢?原来就是这个callback函数,对它的使用有一个典型的方式,就是通过JSON来传参,即将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。JSONP只支持GET请求。
❷ 转载:反向代理服务器nginx-proxy-manager
什么是 Nginx Proxy Manager ?
Nginx Proxy Manager 是用于管理 Nginx 代理主机的 Docker 容器,具有简单、强大的界面。它使您可以轻松地转发到您在家里或其他地方运行的网站,包括免费的 SSL,而无需对 Nginx 或 Letsencrypt 了解太多。
通过 phpMyAdmin 在 MariaDB 10 中新建用户 npm ,创建同名的库 npm 并授予所有权限。
在注册表中搜索 nginx-proxy-manager ,选择第一个 jc21/nginx-proxy-manager,版本选择 latest。
在 docker 文件夹中,创建一个新文件夹,并将其命名为 npm,再建 2 个子目录,分别命名为 data 和 letsencrypt
端口
端口不冲突就行,不确定的话可以用命令查一下
在浏览器中输入 http://群晖IP:2081 就能看到主界面
默认的账号: [email protected] ,密码:changeme
登录后可以编辑用户信息
之后是密码
进入主菜单的 SSL Certificates
Add SSL Certificate 有两种方式,一种是在线申请,另一种是添加已有证书
在线申请和我们在‘ 免费的泛域名https证书自动续期 ’一文中介绍的非常类似,需要选择 DNS 解析服务提供商,以及填写 token 等参数
老苏因为已经配置了 Certbot 并实现了自动续期,所以只需要导入现有证书就可以了,Name 老苏用了域名,这样比较容易识别
上传成功后,证书存放在 /data/custom_ssl/ 目录中以 npm-1 、 npm-2 等子目录保存
进入主菜单的 Hosts
以将 http://192.168.0.197:5000 映射到 https://nas.laosu.ml 为例
因为准备用 https 协议访问,所以必须勾选 Force SSL
其他的 HTTP/2 和 HSTS 和群晖内置的是一样的,可根据需要勾选,没啥问题的话老苏建议都勾上
为什么要另外安装 nginx proxy manager 而不是用群晖内置的反向代理的原因,老苏在一开始就讲了,装完之后老苏还发现了几个优点:
❸ Nginx反向代理docker容器进行域名解析绑定的实现方法
可以把多个域名映射到同一个IP地址上
docker 镜像名称由REPOSITORY和TAG组成 [REPOSITORY[:TAG]] ,TAG默认为latest
在宿主机创建持久化 conf--配置目录 html--静态网站目录 logs--日志目录 cert--存放证书目录
将容器内的 nginx.conf 与 default.conf 文件分别拷贝到主机/mnt/nginx与目录/mnt/nginx/conf下,分别执行
conf目录下创建nginx.conf文件
首先要在域名管理中做好域名简析
在conf.d目录下创建 域名为ab..com的配置文件 ab..com.conf 文件 包含ssl证书
在conf.d目录下创建 域名为gh..com的配置文件 gh..com.conf 文件 包含ssl证书
ginx.conf并没有在etc/nginx/conf目录下。
允许https访问 的 default.conf 文件
将服务器的配置文件挂载到容器中,这样我们修改配置文件会方便一些。
退出nginx容器,将容器中的文件nginx.conf先拷贝到宿主机中,conf.d目录下的 default.conf 文件拷贝出来
执行 docker stop ef 命令停止刚刚创建的nginx容器,ef是容器Id,然后执行 docker rm ef 移除容器,
-v /docker-root/nginx/conf/nginx.conf :/etc/nginx/nginx.conf
/docker-root/nginx/conf/nginx.conf 宿主机中的ngix配置文件 挂载 到容器的 /etc/nginx/nginx.conf 配置文件
-v /docker-root/nginx/conf/conf.d:/etc/nginx/conf.d
/docker-root/nginx/conf/conf.d 宿主机中的 配置目录 conf.d 挂载到 容器的 /etc/nginx/conf.d 目录上
-v /docker-root/nginx/cert:/cert/
映射ssl 证书文件
命令,重新创建nginx容器
这样就可以将配置文件、log、静态页面映射到宿主机中。需要修改或者查看直接在宿主机中修改或者查看就可以了。需要注意的是, 配置文件虽然映射到宿主机中,但是如需配置路径,还需配置成容器中的路径 。
注意发布到 云服务器上 服务器安全组是否开放了443端口。
把 vue 生成的 dist目录下的文件 上传到 服务器
/root/docker-root/vue-mcyl-src
文件目录 dist 目录 Dockerfile 文件
转到 此目录下
使用下面的命令 生成镜像
启动容器
docker run -d mcyl-vue:v1.0
conf.d 目录下的配置文件 default.conf
防火墙原因,需要将通信的端口开放
解决办法:
firewall-cmd --zone=public --add-port=9080/tcp --permanent
firewall-cmd --zone=public --add-port=8080-8080/tcp
参考 http://www.ttlsa.com/web/multiple-https-host-nginx-with-a-ip-configuration/
❹ nginx反向代理三种模式
1、基于IP代理
2、基于域名代理
3、基于端口代理
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,其特点是占用内存少,并发能力强,是我们在Web开发中最常用的工具之一。
此外,Nginx能提供性能稳定、并且提供配置灵活的转发功能。它可以根据不同的正则匹配,采取不同的转发策略,并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,它可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。
❺ Nginx反向代理实现负载均衡配置图解
负载均衡配置是超大型机器需要考虑的一些问题 同时也是数据安全的一种做法 下面我来介绍在nginx中反向代理 负载均衡配置图解 大家可参考本文章来操作首先简单的介绍下修改默认的nginx conf 大概在 ~ 行 去掉前面的#号 重启nginx
#location ~ php$ {# proxy_pass ;#}改为 location ~ php$ { proxy_pass // : ;}
分别访问 出现如下图已经能够针对不同请求访问服务器了
这样当我们访问 l的时候 前端的nginx会自动进行响应 当访问 /test php的时候(这个时候nginx目录下根本就没有该文件) 但是通过上面的设置location ~ php$(表示
访问php页面test php : 的Apache进行响应
访问目录phpMyAdmin下的页面的话 : 的Apache进行响应
修改原始默认的nginx conf的server模块部分(大概在 ~ 行)
#location ~ php$ {# proxy_pass ;#}修改为 location ^~ /phpMyAdmin/ { proxy_pass : ;} location ~ php$ { proxy_pass : ;}
上面第一个部分location ^~ /phpMyAdmin/ 表示不使用; index index
2.在配置文件nginx.conf的模块中添加服务器集群server cluster的定义。Tw.WinGWit.
upstream myCluster { server 192.168.2.3:8080 ; server 192.168.2.2:80 ; server 192.168.2.8:80 ;}
表示这个server cluster包含3台服务器
3.然后在server模块中定义负载均衡
location ~ .php$ { proxy_pass //myCluster ; proxy_redirect off; 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_pass //myCluster ; 这里的名字和上面的cluster的名字相同
配置好后,当访问页面,nginx目录下根本没有该文件,但是它会自动将其pass到myCluster定义的服务器群,分别由上述的3台服务器中的一台来做处理。
上面在定义upstream的时候每个server之后没有定义权重,表示两者均衡;如果希望某个更多响应的话,可以加weight
upstream myCluster { server 192.168.2.3:8080 weight=5; server 192.168.2.2:80 ; server 192.168.2.8:80 ;}
这样表示5/7的几率访问第一个server,1/7访问第二个、第三个。另外还可以定义max_fails和fail_timeout等参数。
所以我们使用nginx的反向代理服务器reverse proxy server的功能,将其布置到多台apache server的前端。
nginx仅仅用来处理静态页面响应和动态请求的代理pass,后台的apache服务器来对前台pass过来的动态页面进行处理并返回给nginx。
❻ Nginx 使用反向代理 解决异步api获取问题!
问题解决非常简单,在宝塔服务器站点配置中,对nginx站点配置增加如下配置信息:
1、location 后面的/api是匹配本地url中带有指定目录所用;
2、 rewrite ^/api/(.*)$ /$1 break; 这一段是用来进行匹配修改的,意思是去除掉后面的api
3、 proxy_pass http://localhost:8080; 这一段是用来设置转发地址的,意思就是你要把/api 这个路径指向的地址;
比如说你本地是 123.com 你要把 123.com/api 变成 234.com/api 就在 proxy_pass中输入 http://234.com 即可;
❼ Nginx反向代理的使用及原理
正向代理,用通俗的方式来说,就是代理服务器只起到转发的作用,例如,在顾客进商店购买东西,商店就是一个正向代理,起到的作用就是把商品从厂家代理售卖到顾客手中。
反向代理,就是顾客的请求是确定的,但将商品的需求信息发送给代理商之后,代理商通过各种方式寻找不同的供货商,再把供货商提供的商品转交给顾客。顾客是不知道代理商背后的供货商是谁的。这种方式有点类似于目前的“三只松鼠”等网络直销平台的逻辑,顾客发送芒果干的请求给三只松鼠,三只松鼠从全国进行供货商的选择,拿到货品后再打上三只松鼠的logo转交给顾客,实现反向的代理,代理的是供货商,顾客不知道具体的供应商是谁(所以才会要求包装上需要印上供应商的名称和地址,要不然出问题都不知道找谁。)
Nginx的安装网络有很多资源,包括Linux和Windows的,在此不表。主要关注一下如何进行配置,来看看 nginx.conf.default 中的配置信息:
可以看到,主要的几个配置模块:
下面主要讲讲经常使用的server以及location的配置。
gzip压缩中
对于阿里云上的配置,我们直接使用一级域名 abc.com 解析阿里云服务器的IP地址:
❽ nginx 反向代理和后端服务器获取真实 ip
nginx 反向代理是什么?
为了提高吞吐量,有些服务器是专门跑程序用的,有些服务器是跑静态资源的。
你可能访问一个网页,里面有图片,而这个图片并不是你访问的这个网页的服务器,也叫前端服务器,而是你的图片请求被 Nginx 转发到了一台后端服务器,由后端服务器提供给前端服务器再返回到客户端的。
我这台 nginx 的配置非常细致,有 nginx.conf ,在这个配置中包含了两个文件夹,一个是 sites-available ,一个是 sites-enabled , nginx.cof 一般用来做整个 nginx 的配置。
域名配置段在 sites-avaliable 下,然后建立一个软连接到 sites-enabled 下去。
反向代理就写在域名配置段里,客户端通过访问服务器,服务器将请求分配按照 server 段里的则正匹配,将请求按照 fastcgi 发送到 php-fpm 通过分配再到我们的程序。
反向代理一样,也需要通过正则来捕捉到用户的请求。(2018-12-9,现在流行的做法是将静态资源全部压缩打包,丢到cdn上去,服务器基本只做端口转发,https配置,日志,负载均衡,等很多很多功能)
server 段里多加以上这一条,前端的反向代理的工作就完成了。
(当然要开启反向代理在 nginx.conf 里)以上捕捉到图片格式结尾的就将这种请求转发到服务器地址,后端服务器只要监听这个端口将 root 指向资源目录就行了。
当这一切做完后会发现,后端服务器获取到的并不是用户的 ip 地址而是前端服务器的 ip (通过 nginx 的访问日志),这是正常的。
因为本来就是前段请求的,但是可以通过 proxy_set_header 段将用户的真实ip带到后端服务器去,而后端服务器需要接收传过来的这个参数。
日志的格式默认情况下是不接收这种参数的,日志格式在 nginx.conf 里面定义,默认没有定义,自己加上去就可以了。
这就是日志的格式,可以自己添加和修改,上面主要描述的是定义一个格式这个格式的名字为main。
这个格式里包含了哪些东西顺序是怎样的,定义访问成功的日志的路径,使用main格式来进行写入。
改完后,前端服务器 nginx -s reload ,后端服务器 nginx -s reopen 。
反向代理就是这样。有反向代理,当然也有正向代理了,也很简单。
原文链接: nginx反向代理和后端服务器获取真实ip-服务器
❾ 京东大佬细说:Nginx反向代理时保持长连接,看完直呼"学到了!"
前言:
深入了解nginx,get到nginx的一些性能优化方向。除了了解如何保持长连接,也通过本案例学习到开源中间件的一些常用定位思路和优化方法。
场景描述
HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。如果我们使用了nginx去作为反向代理或者负载均衡,从客户端过来的长连接请求就会被转换成短连接发送给服务器端。为了支持长连接,我们需要在nginx服务器上做一些配置。
要求
到长连接,我们必须做到以下两点:
i.从client到nginx是长连接
ii.从nginx到server是长连接
对于客户端而言,nginx其实扮演着server的角色,反之,之于server,nginx就是一个client。
保持和Client的长连接
我们要想做到Client与Nginx之间保持长连接,需要:
i.Client发送过来的请求携带“keep-alive”header。
ii.Nginx设置支持keep-alive。
HTTP配置
默认情况下,nginx已经开启了对client连接的keepalive 支持。对于特殊场景,可以调整相关参数。
大多数情况下,keepalive_requests = 100也够用,但是对于 QPS 较高的场景,非常有必要加大这个参数,以避免出现大量连接被生成再抛弃的情况,减少TIME_WAIT。QPS=10000 时,客户端每秒发送 10000 个请求 (通常建立有多个长连接),每个连接只能最多跑 100 次请求,意味着平均每秒钟就会有 100 个长连接因此被 nginx 关闭。同样意味着为了保持 QPS,客户端不得不每秒中重新新建 100 个连接。因此,如果用netstat命令看客户端机器,就会发现有大量的TIME_WAIT的socket连接 (即使此时keepalive已经在 Client 和 NGINX 之间生效)。
保持和Server的长连接
想让Nginx和Server之间维持长连接,最朴素的设置如下:
upstream配置
upstream中,有一个参数特别的重要,就是 keepalive 。 这个参数和之前http里面的 keepalive_timeout 不一样。这个参数的含义是,连接池里面最大的空闲连接数量。
不理解?没关系,我们来举个例子:
场景:
有一个HTTP服务,作为upstream服务器接收请求,响应时间为100毫秒。要求性能达到10000 QPS,我们需要在nginx与upstream服务器之间建立大概1000条HTTP请求。(1000/0.1s=10000)
最优情况:
假设请求非常的均匀平稳,每一个请求都是100ms,请求结束会被马上放入连接池并置为idle(空闲)状态。
我们以0.1s为单位:
1. 我们现在keepalive的值设置为10,每0.1s钟有1000个连接。
2. 第0.1s的时候,我们一共有1000个请求收到并释放。
3. 第0.2s的时候,我们又来了1000个请求,在0.2s结束的时候释放。
请求和应答都比较均匀,0.1s释放的连接正好够用,不需要建立新连接,且连接池中没有idle状态的连接。
第一种情况:
应答非常平稳,但是请求不平稳 的时候
1.第0.3s的时候,我们只有500个请求收到,有500个请求因为网络延迟等原因没有进来。这个时候,Nginx检测到连接池中有500个idle状态的连接,就直接关闭了(500-10)个连接。
2.第0.4s的时候,我们收到了1500个请求,但是现在池里面只有(500+10)个连接,所以Nginx不得不重新建立了(1500-510)个连接。如果在第4步的时候,没有关闭那490个连接的话,只需要重新建立500个连接。
第二种情况:
请求非常平稳,但是应答不平稳 的时候
1. 第0.3s的时候,我们一共有1500个请求收到。但是池里面只有1000个连接,这个时候,Nginx又创建了500个连接,一共1500个连接。
2.第0.3s的时候,第0.3s的连接全部被释放,我们收到了500个请求。 Nginx检测到池里面有1000个idle状态的连接,所以不得不释放了(1000-10)个连接。造成连接数量反复震荡的一个推手,就是这个keepalive 这个最大空闲连接数。上面的两种情况说的都是 keepalive设置的不合理导致Nginx有多次释放与创建连接的过程,造成资源浪费。
keepalive 这个参数设置一定要小心,尤其是对于 QPS 要求比较高或者网络环境不稳定的场景,一般根据 QPS 值和 平均响应时间能大致推算出需要的长连接数量。然后将keepalive设置为长连接数量的10%到30%。
location配置
HTTP 协议中对长连接的支持是从 1.1 版本之后才有的,因此最好通过proxy_http_version 指令设置为 1.1。HTTP1.0不支持keepalive特性,当没有使用HTTP1.1的时候,后端服务会返回101错误,然后断开连接。而“Connection” header 可以选择被清理,这样即便是 Client 和 Nginx 之间是短连接,Nginx 和 upstream 之间也是可以开启长连接的。
另外一种高级方式
http里面的map的作用是:让转发到代理服务器的 "Connection" 头字段的值,取决于客户端请求头的"Upgrade" 字段值。
如果$http_upgrade没有匹配,那 "Connection" 头字段的值会是upgrade。
如果$http_upgrade为空字符串的话,那 "Connection" 头字段的值会是 close。
【补充】
NGINX支持WebSocket。对于NGINX将升级请求从客户端发送到后台服务器,必须明确设置Upgrade和Connection标题。这也算是上面情况所非常常用的场景。HTTP的Upgrade协议头机制用于将连接从HTTP连接升级到WebSocket连接,Upgrade机制使用了Upgrade协议头和Connection协议头。为了让Nginx可以将来自客户端的Upgrade请求发送到后端服务器,Upgrade和Connection的头信息必须被显式的设置。
【注意】
在nginx的配置文件中,如果当前模块中没有proxy_set_header的设置,则会从上级别继承配置。继承顺序为:http, server, location。如果在下一层使用proxy_set_header修改了header的值,则所有的header值都可能会发生变化,之前继承的所有配置将会被丢弃。所以,尽量在同一个地方进行proxy_set_header,否则可能会有别的问题。