【2018.06.12學習筆記】【linux高級知識 12.17-12.20】

12.17 Nginx負載均衡

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

12.18 ssl原理

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協議傳輸的過程就結束了。

服務器的數字證書,能夠向證書機構申請,也能夠本身給本身頒發,本身頒發可能瀏覽器會認爲不可信任。

12.19 生成ssl密鑰對

咱們使用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

12.20 Nginx配置ssl

在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

相關文章
相關標籤/搜索