Nginx代理一个服务器就叫代理服务,若是一个Nginx代理多个服务器就叫作负载均衡。php
例如:用户 经过 代理服务器A,可以访问后端的Web服务器X、Web服务器Y和Web服务器Z。html
由于Nginx的代理proxy_pass只能指定一个ip,因此要使用upstream模块实现负载均衡。前端
在vhost下建立一个load.conf配置文件:mysql
[root@nginx vhost]# vim load.conf upstream 163.com { ip_hash; //让用户保持在一台后端服务器上链接 server 183.237.146.122; // 用dig工具查到163网站有两台服务器 server 120.241.97.238; // 用dig工具查到163网站有两台服务器 } server { listen 80; //监听端口 server_name www.163.com; // 域名 location / { proxy_pass http://163.com; //这里指定upstream的名字 proxy_set_header Host $Host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
验证测试:linux
[root@nginx ~]# curl -x127.0.0.1:80 www.163.com -I HTTP/1.1 200 OK Server: nginx/1.14.0 Date: Mon, 11 Jun 2018 15:26:23 GMT Content-Type: text/html; charset=GBK Connection: keep-alive Expires: Mon, 11 Jun 2018 15:27:43 GMT Vary: Accept-Encoding,User-Agent,Accept Cache-Control: max-age=80 X-Via: 1.1 PSzjhzyhsxnx203:4 (Cdn Cache Server V2.0), 1.1 PSgdzsydtf37:9 (Cdn Cache Server V2.0) X-Dscp-Value: 0 [root@nginx ~]# curl -x127.0.0.1:80 www.163.com <div class="cm_mod_title"> <h2> <span class="title icon_pleft icon_ntes_stock"> </span> </h2> <div class="ntes_stock_right"> <a href="http://quotes.money.163.com/usstock/NTES.html"> <em> </em><span _ntesquote_="code:US_NTES;attr:price;fixed:2;color:updown"></span> <span _ntesquote_="code:US_NTES;attr:percent;percent:2;color:updown"></span> </a> </div> </div> <ul class="clearfix cm_ul_round"> <li><a href="http://corp.163.com/18/0208/15/DA4OBLMF00832V3T.html"> </a></li> <li><a href="http://corp.163.com/17/1116/10/D3BU8G9J00832V3T.html"> ¨</a></li> <li><a href="http://corp.163.com/17/0810/10/CRFKSQHL00832V3T.html"> ¨</a></li> <li><a href="http://corp.163.com/17/0511/12/CK5I4TTU00832V3T.html"> ¨</a></li> </ul> </div> <!-- µײ¿Ђ --> <div ne-module="modules/synthesis/download/download.js"><div class="mod_news_download"> <a href="http://www.163.com/newsapp" class="down_news_link"> </a> <a href="https://itunes.apple.com/cn/app/id425349261" class="down_ios_link">iosЂ</a> <a href="https://download.ws.126.net/3g/client/netease_newsreader_android.apk" class="down_android_link">AndroidЂ</a>
Nginx不支持后端是https的Web服务器的代理,能够这样部署:用户能够访问前端的代理服务器是443端口的https的服务器,后端被代理的Web-Server依旧是80端口的http服务器。android
https访问连接是一种加密的网络传输协议,http没有通过加密,数据在传输过程当中可能会被拦截、旁听侦听等,这样数据就有可能被泄漏。ios
使用https的传输协议,即便数据被拦截被抓包,也须要进行解密才可以读取到数据的内容。nginx
https的大概原理和过程:sql
一、用户客户端发出访问请求(h t t p s:// w w w.domain.com )vim
二、服务端会根据数字证书生成一对私钥、公钥crt
三、服务端把公钥crt发回给客户端
四、客户端判断数字证书是否合法:不合法就提示用户,证书合法就生成随机字符串Ckey
五、客户端用公钥crt加密Ckey,并把加密后的字符串发给服务器
六、服务器用私钥解密得到随机字符串Ckey
七、服务器用Ckey把客户想要访问的数据内容进行加密,返回给客户端
八、客户端用Ckey解密得到想要访问的数据。整个https协议传输的过程就结束了。
服务器的数字证书,能够向证书机构申请,也能够本身给本身颁发,本身颁发可能浏览器会认为不可信任。
咱们使用openssl工具来颁发数字证书生成私钥和公钥:须要安装openssl包
咱们把密钥对放在conf目录下:到conf目录下去使用openssl工具
[root@nginx ~]# cd /usr/local/nginx/conf/ [root@nginx conf]# openssl genrsa -des3 -out tmp.key 2048 //生成私钥tmp.key Generating RSA private key, 2048 bit long modulus .........................+++ ...................................................+++ e is 65537 (0x10001) Enter pass phrase for tmp.key: //设置私钥的密码 Verifying - Enter pass phrase for tmp.key: [root@nginx conf]# ls -l tmp.key -rw-r--r-- 1 root root 1751 6月 12 22:15 tmp.key
私钥使用密码不是很方便,咱们转换key,取消掉密码:
[root@nginx conf]# openssl rsa -in tmp.key -out lgs.key Enter pass phrase for tmp.key: writing RSA key [root@nginx conf]# ls -l lgs.key //转换成lgs.key,与tmp.key同样,只是不含密码 -rw-r--r-- 1 root root 1679 6月 12 22:17 lgs.key [root@nginx conf]# rm -f tmp.key //把含密码的私钥删掉
生成证书的请求文件:输入一些国家、组织等信息
[root@nginx conf]# openssl req -new -key lgs.key -out lgs.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:lgs string is too long, it needs to be less than 2 bytes long Country Name (2 letter code) [XX]:china string is too long, it needs to be less than 2 bytes long Country Name (2 letter code) [XX]:lgsxp86 string is too long, it needs to be less than 2 bytes long Country Name (2 letter code) [XX]:86 State or Province Name (full name) []:gd Locality Name (eg, city) [Default City]:huizhou Organization Name (eg, company) [Default Company Ltd]:lgs Organizational Unit Name (eg, section) []:lgs Common Name (eg, your name or your server's hostname) []:lgs Email Address []:scause@163.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:961303 An optional company name []:lgs [root@nginx conf]# ls -l lgs.csr -rw-r--r-- 1 root root 1082 6月 12 22:22 lgs.csr
用私钥和请求证书生成公钥:
[root@nginx conf]# openssl x509 -req -days 365 -in lgs.csr -signkey lgs.key -out lgs.crt Signature ok subject=/C=86/ST=gd/L=huizhou/O=lgs/OU=lgs/CN=lgs/emailAddress=scause@163.com Getting Private key [root@nginx conf]# ls -l lgs.crt -rw-r--r-- 1 root root 1241 6月 12 22:23 lgs.crt
在vhost目录下,建立一个ssl.conf配置文件:加入https的配置段
[root@nginx conf]# cd vhost/ [root@nginx vhost]# ls aaa.com.conf load.conf nginx_log_rotate.sh proxy.conf test.com.conf [root@nginx vhost]# vim ssl.conf server { listen 443; //监听443端口 server_name test.com; //域名 index index.html; root /data/wwwroot/test.com; ssl on; //打开ssl ssl_certificate lgs.crt; //指定公钥 ssl_certificate_key lgs.key; //指定私钥 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; //指定协议 } [root@nginx vhost]# /usr/local/nginx/sbin/nginx -t nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/vhost/ssl.conf:7 nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
从新加载配置报错,提示没有没法识别ssl:是由于当时编译的时候没有指定ssl:
[root@nginx vhost]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.14.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) configure arguments: --prefix=/usr/local/nginx
须要从新编译nginx,加上ssl配置参数:
[root@nginx vhost]# cd /usr/local/src/ [root@nginx src]# ls mysql-5.6.36-linux-glibc2.5-x86_64.tar.gz mysql-test-5.7.18-linux-glibc2.5-x86_64.tar.gz nginx-1.14.0 nginx-1.14.0.tar.gz php-5.6.32 php-5.6.32.tar.bz2 [root@nginx src]# cd nginx-1.14.0 [root@nginx nginx-1.14.0]# ls auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src [root@nginx nginx-1.14.0]# ./configure --help|grep -i ssl --with-http_ssl_module enable ngx_http_ssl_module --with-mail_ssl_module enable ngx_mail_ssl_module --with-stream_ssl_module enable ngx_stream_ssl_module --with-stream_ssl_preread_module enable ngx_stream_ssl_preread_module --with-openssl=DIR set path to OpenSSL library sources --with-openssl-opt=OPTIONS set additional build options for OpenSSL [root@nginx nginx-1.14.0]# ./configure --prefix=/usr/local/nginx/ --with-http_ssl_module Configuration summary + using system PCRE library + using system OpenSSL library + using system zlib library nginx path prefix: "/usr/local/nginx/" nginx binary file: "/usr/local/nginx//sbin/nginx" nginx modules path: "/usr/local/nginx//modules" nginx configuration prefix: "/usr/local/nginx//conf" nginx configuration file: "/usr/local/nginx//conf/nginx.conf" nginx pid file: "/usr/local/nginx//logs/nginx.pid" nginx error log file: "/usr/local/nginx//logs/error.log" nginx http access log file: "/usr/local/nginx//logs/access.log" nginx http client request body temporary files: "client_body_temp" nginx http proxy temporary files: "proxy_temp" nginx http fastcgi temporary files: "fastcgi_temp" nginx http uwsgi temporary files: "uwsgi_temp" nginx http scgi temporary files: "scgi_temp" [root@nginx nginx-1.14.0]# make objs/src/http/modules/ngx_http_upstream_least_conn_module.o \ objs/src/http/modules/ngx_http_upstream_keepalive_module.o \ objs/src/http/modules/ngx_http_upstream_zone_module.o \ objs/ngx_modules.o \ -ldl -lpthread -lcrypt -lpcre -lssl -lcrypto -ldl -lpthread -lz \ -Wl,-E sed -e "s|%%PREFIX%%|/usr/local/nginx/|" \ -e "s|%%PID_PATH%%|/usr/local/nginx//logs/nginx.pid|" \ -e "s|%%CONF_PATH%%|/usr/local/nginx//conf/nginx.conf|" \ -e "s|%%ERROR_LOG_PATH%%|/usr/local/nginx//logs/error.log|" \ < man/nginx.8 > objs/nginx.8 make[1]: 离开目录“/usr/local/src/nginx-1.14.0” [root@nginx nginx-1.14.0]# make install test -f '/usr/local/nginx//conf/nginx.conf' \ || cp conf/nginx.conf '/usr/local/nginx//conf/nginx.conf' cp conf/nginx.conf '/usr/local/nginx//conf/nginx.conf.default' test -d '/usr/local/nginx//logs' \ || mkdir -p '/usr/local/nginx//logs' test -d '/usr/local/nginx//logs' \ || mkdir -p '/usr/local/nginx//logs' test -d '/usr/local/nginx//html' \ || cp -R html '/usr/local/nginx/' test -d '/usr/local/nginx//logs' \ || mkdir -p '/usr/local/nginx//logs' make[1]: 离开目录“/usr/local/src/nginx-1.14.0” [root@nginx nginx-1.14.0]# echo $? 0
把ssl模块编译进Nginx后,再从新检测配置,而后重启nginx服务:再检查是否有监听443端口
[root@nginx nginx-1.14.0]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.14.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx/ --with-http_ssl_module [root@nginx vhost]# /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx//conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx//conf/nginx.conf test is successful [root@nginx vhost]# /etc/init.d/nginx restart Restarting nginx (via systemctl): [ 肯定 ] [root@nginx vhost]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4086/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 892/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1254/master tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 4086/nginx: master tcp6 0 0 :::22 :::* LISTEN 892/sshd tcp6 0 0 ::1:25 :::* LISTEN 1254/master tcp6 0 0 :::3306 :::* LISTEN 1202/mysqld
验证测试访问https:
[root@nginx test.com]# vim /etc/hosts //加入test.com 到hosts文件中 [root@nginx test.com]# curl https://test.com curl: (60) Peer's certificate issuer has been marked as not trusted by the user. //识别到ssl了,可是提示不可信任 More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.
用浏览器来访问:
[root@nginx test.com]# iptables -I INPUT -p tcp --dport 443 -j ACCEPT //开放443端口 [root@nginx test.com]# iptables -nvL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 14 1776 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 2901 225K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 1 60 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 961 94062 INPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0 961 94062 INPUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0 961 94062 INPUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID 960 94010 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited