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