【10.21】nginx 反向代理、负载均衡、ssl
4.48/49 nginx 反向代理
-
反向代理:
A(用户)——>B(和C同机房,有公网)——>C(不带公网) -
常用场景:
1)访问不带公网的内网机器
2)解决两台机器之间通信障碍的问题 -
硬件准备:
给 B 机器增加一块网卡,且为仅主机模式,进入 B 机器更改该网卡参数,将其模拟成可以连接公网的网卡
[root@alexis-02 ~]# cd /etc/sysconfig/network-scripts/
[root@alexis-02 network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.194.129 netmask 255.255.255.0 broadcast 192.168.194.255
inet6 fe80::9984:c5c:f045:34ac prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:07:c3:8a txqueuelen 1000 (Ethernet)
RX packets 178 bytes 14992 (14.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 162 bytes 20599 (20.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.13.128 netmask 255.255.255.0 broadcast 192.168.13.255
inet6 fe80::f50a:c70c:20cf:e345 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:07:c3:94 txqueuelen 1000 (Ethernet)
RX packets 5 bytes 866 (866.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 37 bytes 3582 (3.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 4 bytes 352 (352.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4 bytes 352 (352.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@alexis-02 network-scripts]# cp ifcfg-ens33 ifcfg-ens37
[root@alexis-02 network-scripts]# vim ifcfg-ens37
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens37
DEVICE=ens37
ONBOOT=yes
IPADDR=192.168.13.128
NETMASK=255.255.255.0
:wq
[root@alexis-02 network-scripts]# systemctl restart network
-
场景设置:
1)A、B两台机器,其中 A 只有内网,B有内网和外网
2)A 的内网 ip 是 192.168.194.128
3)B 的内网 ip 是 192.168.194.129,B 的外网 ip 是 192.168.13.128
4)C 为客户端,C 只能访问 B 的外网 IP,不能访问 A 或 B 的内网 IP -
实际需求:
C 要访问到 A 的内网上的网站 -
参数配置:
location /
{
proxy_pass http://ip;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
上方的 ip 指的是后端真正 web 服务器的 ip,反向代理的机器上的 nginx 会去访问这个 ip
proxy_set_header 设置代理时的 header 信息;
Host 指域名是什么,$host 也就是 server_name;
X-Real-IP 和 X-Forwarded-For 为了在日志中显示真正客户端的 ip,要把代理服务器和客户端 ip 都要拿到,在日志中体现
访问无公网机器上的 web服务器,用与其同网段有公网机器做反向代理,用户连接该机器就能访问无公网机器上的网站
- 设置:
1、B 机器上 yum 安装 nginx
[root@alexis-02 ~]# vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[root@alexis-02 ~]# yum install -y yum-utils
[root@alexis-02 ~]# yum install -y nginx
[root@alexis-02 ~]# ps aux|grep nginx
root 7517 0.0 0.0 46340 972 ? Ss 04:27 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 7518 0.0 0.1 46748 1932 ? S 04:27 0:00 nginx: worker process
root 7521 0.0 0.0 112724 988 pts/0 R+ 04:28 0:00 grep --color=auto nginx
[root@alexis-02 ~]# netstat -lntp|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7517/nginx: master
2、配置 B 机器上的虚拟主机
[root@alexis-02 ~]# vim /etc/nginx/conf.d/bbs.ars4life.com.conf
server
{
listen 80;
server_name bbs.ars4life.com;
location /
{
proxy_pass http://192.168.194.128;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@alexis-02 ~]# vim /etc/nginx/conf.d/default.conf
deny all;
[root@alexis-02 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@alexis-02 ~]# nginx -s reload
- 以要访问的网站域名为虚拟主机配置文件名
- ip 为网站运行的主机 ip,我们要访问 A 上的网站,只要指向 A 即可,A 的 nginx 已经配置好了
- 无需指定 root,location /php
- 要讲默认虚拟主机配置文件 default.conf 给禁掉,在其配置文件中 server_name 下加上 deny all;
- 改完虚拟主机配置文件之后,检查并重新加载配置
3、将 B 机器公网 ip 加入 windows 的 hosts,让 bbs.ars4life.com 的请求只能访问 192.168.13.128
192.168.13.128 bbs.ars4life.com
4、将 80 端口加入防火墙
[root@alexis-02 ~]# firewall-cmd --add-port=80/tcp --permanent
success
[root@alexis-02 ~]# firewall-cmd --reload
success
[root@alexis-02 ~]# iptables -nvL |grep 80
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 ctstate NEW
5、应该可以正常访问了
总结:
如果不能访问,注意以下几点:
1、权限
2、selinux
3、端口是否开放
4、配置文件内容
5、配置文件名是否以 .conf 结尾
4.50 nginx 负载均衡
负载均衡 就是,把请求均衡地分发到后端的各个机器上面。
比如,A B C D 四台WEB服务器,现在E要访问这4台服务器,F为Nginx反向代理服务器,可以让F把E的请求均衡地发送到
A B C D 4台服务器上。
- 参数配置:
upstream baidu
{
ip_hash;
server 180.101.49.11:80;
server 180.101.49.12:80;
}
server
{
listen 80;
server_name www.baidu.com;
location /
{
proxy_pass http://baidu;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- upstream 后的名称为自定义,不能写 ip,要写字符串,在 proxy_pass 后引用
- upstream 定义一个负载均衡的组
- 同一个服务器里不能出现两个相同的 upstream
- ip hash 是负载均衡的算法,让访问的机器下次访问时再去访问之前访问的服务器
- server 后的 ip 是真正的服务器的 ip 地址,端口
- 后面 server 是虚拟主机配置文件
- proxy_pass 和反向代理不一样的是,http 后面接的是上面定义的 upstream 组
-
windows 的 hosts
192.168.13.128 www.baidu.com -
安装 dig 命令
[root@alexis-02 conf.d]# yum install -y bind-utils
-
ping.chinaz.com 中输入网址,也可以查看网站的 ip,任意一个加入到虚拟主机配置文件中 upstream 中即可
-
访问 www.baidu.com,可以访问,有的浏览器会显示重定向
-
也可以 curl 查看
[root@alexis-02 conf.d]# curl -x180.101.49.11:80 www.baidu.com -I
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: keep-alive
Content-Length: 277
Content-Type: text/html
Date: Mon, 21 Oct 2019 14:51:01 GMT
Etag: "575e1f60-115"
Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
[root@alexis-02 conf.d]# curl -x180.101.49.12:80 www.baidu.com -I
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: keep-alive
Content-Length: 277
Content-Type: text/html
Date: Mon, 21 Oct 2019 14:51:07 GMT
Etag: "575e1f60-115"
Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
- 配置权重
在 server 的 ip 之后加上 weight ,0 -100
upstream baidu
{
ip_hash;
server 180.101.49.11:80 weight=100;
server 180.101.49.12:80 weight=10;
}
4.51 配置 nginx 的ssl
- Nginx的SSL
让 Nginx 实现用 https 来访问网站。http 是 80 端口,https 是 443 端口。
https 其实就是一种加密的 http。
- 为什么要加密?
举例: 咱们要在网上银行汇款,在你汇款过程当中,你会输入银行卡的密码。如果不加密,这些数据在传输过程中就有可能被人截获。
如果使用了 https,那么数据在传输过程中是会加密的。即使抓到了数据包,但是无法破解出来。
-
知识点:
http 1.1 http 2 (https)要想 nginx 支持 ssl,那么编译安装时必须要有 --with-http_ssl_module,如果没有,那么重新编译以下即可
yum 安装直接就支持 ssl
-
申请证书:
网站:www.wosign.com (沃通)
免费的:freessl.org
注册账号,输入域名,开始申请,在这个过程中需要去加一条TXT的记录,在云主机域名解析的位置将生成的ca,.crt,.key 文件保存到 /etc/nginx/ssl/ 下
-
配置:
[root@alexis-01 ~]# vim /etc/nginx/conf.d/bbs.ars4life.com.conf
server {
listen 443 ssl;
server_name bbs.ars4life.com;
ssl on;
ssl_certificate /path/to/xxx.crt;
ssl_certificate_key /path/to/xxx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
xxx.crt 和 xxx.key 就写之前保存在 ssl 下的文件名即可
- 重新加载配置后,需要在防火墙增加 443 端口
[root@alexis-01 ~]# firewall-cmd --add-port=443/tcp --permanent
[root@alexis-01 ~]# firewall-cmd --reload
- 在将 hosts 改为
192.168.194.128 bbs.ars4life.com
访问 bbs.ars4life.com 应该就是 https 开头了
-
也可以通过 curl 测试
curl -k -H “host:bbs.ars4life.com” https://192.168.194.128/index.php -
扩展:
https://github.com/aminglinux/nginx/tree/master/ssl
http://note.youdao.com/noteshare?id=8dcdc978d45b8ce61f2568eadc3a0168&sub=7B5A050672F743ABA69ADDF0E8C758AC