nginx正向代理与反向代理详解⽬录
正向代理
nginx反向代理
nginx反向代理02
反向代理03
反向代理04
反向代理05
反向代理06
正向代理
就是假设有⼀个内⽹
内⽹有两台机器,这两台机器只有 a 可以上⽹
b 不能上⽹,但是 a 和 b 通过⽹络相连接
这时如果 b 想访问外⽹,就可以通过 a 来正向代理访问外⽹
正向代理就是在内⽹中模拟⽬标服务器,把内⽹中其它机器的请求
转发给外⽹中的真正的⽬标服务器
所以正向代理是接受内⽹其它机器的请求的
反向代理则是反过来
也是⼀个内⽹,有⼏台机器,只有其中⼀台与外⽹连接
但是反向代理接受的不是内⽹机器的访问请求
反向代理接受的是外⽹过来的访问请求
然后把请求转发到内⽹中的其它机器上去
外⽹发出请求的⽤户并不知道反向代理的服务器把请求转发给了谁
要在⼀台机器上设置正向代理的功能
如图,编辑⼀个nginx配置⽂件
上图就是配置⽂件内容
如果配置⼀台服务器作为正向代理服务器
那么这个虚拟主机配置⽂件就必须是默认虚拟主机
因为所有访问这台机器的⽹络请求应该先访问这个虚拟主机才对
所以这⾥要设置 default_server
然后还要把原来的默认虚拟主机配置⽂件名称修改掉
如图,把 f 配置⽂件的名称修改⼀下
这样就取消了原来的默认虚拟主机配置⽂件了
因为默认的默认虚拟主机配置⽂件就是 f
配置⽂件⾥⾯的 resolver 119.29.29.29
意思是配置⼀个 dns 地址
因为是做正向代理,接受了内⽹请求的域名后
要把请求发送给真正要访问的服务器
但是内⽹发送的域名是没有包含 ip 地址的
所以还要把域名发送给 dns 服务器解析 ip 地址
拿到 ip地址后才能转发到要访问的服务器上去
所以这⾥需要配置⼀个 dns 地址
resolver什么意思中文接受了内⽹域名后,就会把域名发送到这个 dns 上去解析
下⾯的 location 按照图中设置就可以了
这样正向代理服务器接受内⽹机器请求后
就会把域名发到配置的dns上解析,然后访问真正的服务器
再把真正服务器返回的内容发送给发出请求的内⽹机器
nginx反向代理
做⼀个反向代理的例⼦
如图建⽴⼀个测试的虚拟主机配置⽂件
监听 8080 端⼝,域名为 st
根⽬录是 /data/wwwroot/test
访问虚拟主机显⽰的⾸页⽂件是 index.html
如图,创建虚拟主机的根⽬录 /data/wwwroot/test
然后使⽤ echo "test_8080" > !$/index.html
创建⼀个内容为 test_8080 的⾸页⽂件
这个⽂件在 /data/wwwroot/test ⽬录⾥⾯
如图,新建⼀个反向代理的虚拟主机配置⽂件
监听 80 端⼝,域名为 st
下⾯的 location / ⾥⾯就是反向代理的配置
当访问这个虚拟主机的时候,就会把访问请求发送给 127.0.0.1:8080
如图,使⽤ curl 访问 127.0.0.1:8080 虚拟主机
成功返回了 test_8080 这说明这个虚拟主机能够被访问
如图,再创建⼀个虚拟主机配置⽂件
跟之前的 test 虚拟主机差不多
但是这个虚拟主机并没有设置域名
location 设置返回的内容是 8080 default 字符串
保存退出,重载 nginx
还要把 test虚拟主机的 default server 设置取消掉
那么现在 127.0.0.1:8080 对应两个虚拟主机
⼀个是 test 虚拟主机,另外⼀个是 8080 default 虚拟主机
这两个虚拟主机的 ip 端⼝都是⼀模⼀样的
它们的区别是 test 虚拟主机是有域名的
⽽ 8080 default 虚拟主机是没有域名的
现在已经设置了 8080 default 为默认虚拟主机
所以如果只访问 127.0.0.1:8080 的话
访问的⼀定是 8080 default 虚拟主机
如果想访问 test 虚拟主机,就需要加上 test 虚拟主机的域名
才能成功访问 test 虚拟主机
如图,可以看到访问 curl 127.0.0.1:8080/ 返回的结果是 8080 default
使⽤ curl -x127.0.0.1:st
这⾥带上了域名,返回的就是 test_8080
说明想访问 test 虚拟主机,ip端⼝还需要绑定域名才⾏
如图,curl 访问 127.0.0.1:80 域名 st
返回的是 test_8080 说明这个反向代理成功了
我们访问的是 80 端⼝,实际却返回了 8080 端⼝的虚拟主机的内容
如图,这⾥把反向代理虚拟主机⾥⾯的 proxy_pass ⾏下⾯的都注释掉
保存退出,重载 nginx
如图,再使⽤ curl 访问 127.0.0.1:80 域名 st
实际返回的却是 8080 default
⽽我们想访问的却是 test 虚拟主机
如图,proxy_set_header Host $host;
这⼀⾏代码就是指定访问的域名
上⾯设置了 127.0.0.1:8080
反向代理的时候就会指向这个 ip端⼝
如果不设置 host 那就只会访问 127.0.0.1:8080 的虚拟主机
如果设置了 host ,那么就会指向跟指定的 host 绑定的 127.0.0.1:8080
这⾥的 $host 是系统变量,实际的值就是当前的虚拟主机的 server_name 也就是 st ,server_name 是什么,host的值就是什么
这⾥设置了 host 就相当于 curl -x127.0.0.1:st
如果这⾥不设置 host 那么就只会访问 127.0.0.1:8080
这样就可以把域名跟 ip端⼝进⾏绑定
如图,除了写 ip端⼝之外,proxy_pass 也可以直接写域名
这⾥写的是 www.123:8080/
但是这样写的话, nginx 并不知道这个域名指向哪⾥
所以还需要在系统⾥⾯绑定对应的 ip
例如在 /etc/hosts ⽂件⾥⾯,写⼊对应的域名和 ip 进⾏绑定
这样nginx ⾥⾯的 proxy_pass 的域名系统就会解析出⼀个 Ip 地址
然后再访问这个 ip端⼝
下⾯的 proxy_header Host 作⽤就是设置⼀个域名
这个域名会与上⾯的 ip端⼝绑定访问
如果上⾯的 ip端⼝写的不是 ip ⽽是域名
跟下⾯指定的域名是不冲突的,因为上⾯写的域名的作⽤是⽤来解析ip的下⾯指定的域名才会跟上⾯解析出来的 ip端⼝进⾏绑定访问
这个例⼦使⽤的是 $host 这是 nginx全局变量
这个变量实际是对应了⼀个值的,就是当前虚拟主机 server_name 的值但是⼀般来说,还是直接写 ip 端⼝⽅便⼀些
上⾯就是指定 ip端⼝
下⾯指定跟 ip端⼝绑定的 host 域名
nginx反向代理02
如图,proxy_pass 指令后⾯可以跟 url
有三种格式,传输协议+域名+uri (访问路径)
传输协议+ip端⼝+uri
传输协议+socket
这⾥ unix ,http ,https 都是传输协议的种类
域名+uri 和 ip端⼝+uri 还有 socket 都是访问的路径
socket ⼀般是某个程序专⽤的访问端⼝
访问某个socket就是访问某个特定的程序,所以不需要使⽤路径
如图,写 proxy_pass 的时候,不同的写法有不同的结果
⽐如 location /aming/
如果访问的路径包含 /aming/ 就会触发
这⾥的proxy_pass 就会执⾏
但是location ⾥⾯的 proxy_pass 不同的写法会导致实际访问的路径有差别
虽然因为访问的路径包含 /aming/ ⽬录才执⾏ proxy_pass
但是实际访问的路径不⼀定包含 /aming/
这个例⼦是访问虚拟主机内的 /aming/a.html ⽂件
根据 proxy_pass 的不同写法实际上会访问到不同的路径去
如果 ip端⼝后⾯没有接任何⽬录符号
就会访问 /aming/a.html,这是我们想要的
如果 ip端⼝后⾯接了根⽬录符号 /
那么就会直接访问根⽬录⾥⾯的 a.html⽂件,这显然不对
ip端⼝后⾯接 /linux/ 那么就会访问 /linux/ ⾥⾯的 a.html⽂件
如果 ip端⼝后⾯是 /linux 最后没有跟⽬录符号 /
就会访问 /linuxa.html
所以如果想正确访问 /aming/a.html
有两种写法,⼀种是 ip端⼝后⾯不要加任何⽬录符号 /
第⼆种是完整的写成 ip端⼝/aming/ 这样写
根据上⾯⽰例可以发现,ip端⼝后⾯不管是什么⽬录
实际访问路径就会变成直接把最终要访问的⽂件名称 a.html
直接添加到 ip端⼝后⾯的⽬录上去
所以 ip端⼝后⾯不写任何⽬录符号的话,系统才会⾃⼰添加 /aming/a.html 这个⽬录路径⼀旦有任何⽬录符号存在,就会直接把 a.html 放在这个⽬录符号后⾯
第⼆种情况是,ip端⼝+ /linux
实际结果是访问 /linuxa.html
这可能是因为 linux 后⾯没有跟上任何⽬录符号 /
所以系统把 linux 认为是⼀个没有写完的⽂件名称
然后就直接把 a.html 这个⽂件名称跟 linux 粘贴在⼀起
这样就变成了要访问的⽂件是 /linuxa.html 的形式