52:nginx負載均衡|ssl原理|生成ssl祕鑰對|nginx配置ssl

一、nginx負載均衡;(使用upstream來指定多個web  server)php

註釋:代理一臺機器是代理,代理兩臺機器就是負載均衡了;html

代理服務器後面能夠有多個web服務器,多個web服務器去提供服務,能夠實現一個負載均衡的功能,mysql

而正常的訪問,用戶訪問web服務器,是一臺一臺的去請求,要麼就指定一個IP,而後把域名解析到這臺IP上了;nginx

而若是配置負載均衡的話,當用戶每次訪問的是負載均衡地址,再由負載均衡去向後端的web1服務器去請求,而在web1服務器宕機後,則負載均衡會把用戶的請求轉發到web2服務器上;web

配置負載均衡,須要使用upstream模塊算法

這裏將qq做爲演示對象;sql

dig命令查看解析到的IP地址;  yum    install   -y     bind-utilsvim

[root@localhost_001 vhost]# yum install -y bind-utils^C
[root@localhost_001 vhost]# dig qq.com

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> qq.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25501
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;qq.com.				IN	A

;; ANSWER SECTION:
qq.com.			120	IN	A	111.161.64.48
qq.com.			120	IN	A	111.161.64.40

;; Query time: 22 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: 三 10月 31 11:04:30 CST 2018
;; MSG SIZE  rcvd: 67

註釋:會看到返回兩個IP,這兩個IP就是域名解析到的IP地址;windows

1:添加一個配置文件;‘   /usr/local/nginx/conf/vhost/load.conf後端

[root@localhost_001 vhost]# cat /usr/local/nginx/conf/vhost/load.conf 
upstream qq_com                     #upstream後的名稱自定義
{
    ip_hash;                        #目的是爲了讓同一個用戶始終保持在同一個機器上
    server 111.161.64.40:80;        #若是域名解析端口是80,這段配置上的指定端口80是能夠省略的
    server 111.161.64.48:80;
}
server
{
    listen 80;                      #定義監聽端口
    server_name www.qq.com;         #域名

    location /
    {
        proxy_pass      http://qq_com;         #這裏填寫的是upstream 的名字
                                               #即「http://upstream」,由於做爲一個模塊,代理訪問的是經過解析後的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;
    }
}

註釋:須要用upstream來指定多個後端的web  server;

註釋:當後端有多個web  server提供服務時,當咱們長時間訪問一個域名時,在必定的時效內,會出現須要從新登陸或者跳轉到了另外一臺服務器的地址上,而圖例中的ip_hash,就是保證同一個IP訪問域名時,始終經過這臺web服務的地址訪問;

2:在未加載配置時,本機去訪問時,默認是訪問的默認主機;

[root@localhost_001 vhost]# curl -x127.0.0.1:80 www.qq.com
This is a default site.

3:檢測nginx是否有錯誤,並從新加載配置文件;

[root@localhost_001 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@localhost_001 vhost]# /usr/local/nginx/sbin/nginx -s reload

4:再次訪問時,則顯示QQ源碼;說明能夠正常代理;

[root@localhost_001 vhost]# curl -x127.0.0.1:80 www.qq.com -I

註釋:知識點:nginx不支持https的代理,也就是針對端口443的,只能代理http,tcp等;

若想要實現代理https,nginx監聽443端口,但web必須是80端口;

ssl原理:好比咱們訪問一些網站時,會自動加上了https;

http和https的區別:https的通訊是加密的,若是不加密,中間的數據會被截取,會被旁聽,致使信息泄露,https就是對這個數據的通訊進行加密;

SSL的工做原理;

1:瀏覽器發送一個https的請求給服務器;

2:服務器有一套本身數字證書,能夠本身製做,也能夠向組織申請(每一年多少錢),而區別在於本身製做的證書要客戶經過驗證才能繼續訪問,而使用受信任的的公司申請的證書則不會彈出,提示頁面,這套證書其實就是一對公鑰(加密)加一對私鑰(解密);

3:首先服務會把公鑰發送給客戶端(也就是瀏覽器);

4:客戶端(瀏覽器)收到公鑰後,會驗證其是否合法有效(這個過程是瀏覽器來判斷),無效則會警告提醒,有效則會生成一端隨機字符串,並用收到的公鑰加密;

5:客戶端(瀏覽器)把加密後的隨機字符串傳送給服務器;

6:服務器收到加密字符串後,先用私鑰解密(以前用公鑰加密),獲取這一串隨機字符串,在用這段隨機字符串加密要傳輸的數據,(該加密爲對稱加密,所謂對稱加密,就是將數據和私鑰也就是這個隨機字符串>經過某種算法混合在一塊兒,這樣除非知道私鑰,不然沒法獲取數據內容);

7:服務器端把加密後的數據傳輸給客戶端;

8:客戶端收到數據後,再用本身的私鑰也就是那個隨機字符串解密;

一、生成ssl祕鑰對;

註釋:頒發一套證書,須要用到openssl工具,  給nginx裏;

切換到/usr/local/nginx/conf目錄下;

[root@localhost_001 ~]# cd /usr/local/nginx/conf/

若沒有openssl這個工具,能夠手動安裝一下;   yum    install   -y    openssl

如何查看這個包是否已經安裝;

[root@localhost_001 conf]# rpm -qf `which openssl`
openssl-1.0.2k-12.el7.x86_64

2:生成一個祕鑰;     openssl      genrsa    -des3   -out    tmp.key  2048

genrsa     表示生成rsa的祕鑰

2048       表示長度爲2048

tmp.key      表示名稱爲tmp.key

生成這個祕鑰必需要有密碼才能夠;

[root@localhost_001 conf]# rpm -qf `which openssl`
openssl-1.0.2k-12.el7.x86_64
[root@localhost_001 conf]# openssl genrsa  -des3 -out tmp.key 2048
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:

註釋:(可是在生成祕鑰後比較麻煩,在nginx的配置文件裏指定密碼,每次訪問瀏覽器都須要輸入密碼,在https輸入密碼很不方便,因此須要去掉這個密碼;)以下;   

轉換key,取消密碼;  轉換後兩個私鑰是相同的,一個有密碼,一個沒有密碼;openssl   rsa   -in tmp.key  -out fenye.key

[root@localhost_001 conf]# openssl rsa -in tmp.key -out fenye.key 
Enter pass phrase for tmp.key:
writing RSA key
[root@localhost_001 conf]# rm -fr tmp.key

-in    表示指定那一個祕鑰要被轉換;         -out   表示轉換後的祕鑰輸出是什麼;

註釋:而這個時候tmp.key和fenye.key實際上是同一個,前者有密碼,後這沒有密碼;

二、生成證書請求文件;還須要拿這個請求和私鑰一塊兒生成公鑰文件;

[root@localhost_001 conf]# openssl req -new -key  fenye.key -out fenye.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]:china           ## //國家,2個字母
State or Province Name (full name) []:beijing      ##省或者州       
Locality Name (eg, city) [Default City]:beijing    ##城市
Organization Name (eg, company) [Default Company Ltd]:fenye      ##公司
Organizational Unit Name (eg, section) []:fenye                  ##組織 
Common Name (eg, your name or your server's hostname) []:fenye   ##主機名
Email Address []:beijing                                         ##郵箱
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:12345                                    #密碼
An optional company name []:fenye                                一個可選的公司名稱

註釋:正式頒發的證書,須要填寫其對應的信息;

2:使用請求文件和私鑰生成公鑰文件;     -day  表示365天;  

[root@localhost_001 conf]# openssl x509 -req -days 365 -in fenye.csr -signkey fenye.key -out fenye.crt
Signature ok
subject=/C=11/ST=beijing/L=beijing/O=fenye/OU=fenye/CN=fenye/emailAddress=beijing
Getting Private key
[root@localhost_001 conf]# ls fenye.*
fenye.crt  fenye.csr  fenye.key

註釋:   fenye.crt    是公鑰          fenye.key    是公鑰;

3:將openssl證書和nginx相結合;

編輯新建文件  /usr/local/nginx/conf/vhost/ssl.conf

[root@localhost_001 vhost]# cat ssl.conf 
server
{
    listen 443;                                             #監聽端口;
    server_name www.test.com  bbs.test.com  www.test1.com;  #域名及別名;
    index index.html index.php;
    root /data/wwwroot/test.com;                            #根目錄;
    ssl on;                                            #打開ssl開關;
    ssl_certificate fenye.crt;                         #指定公鑰;
    ssl_certificate_key fenye.key;                     #指定私鑰;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;               #支持協議;
}


server
{
    listen 443;
    server_name www.aaa.com;
    index index.html index.php;
    root /data/wwwroot/default;
    ssl on;
    ssl_certificate fenye.crt;
    ssl_certificate_key fenye.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}

而後重啓nginx;  -s  reload   會報錯以下

[root@localhost_001 vhost]# /usr/local/nginx/sbin/nginx -s reload
nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/vhost/ssl.conf:7

註釋:這是由於咱們在編譯是nginx,沒有加入ssl模塊,會顯示識別不到的;因此須要從新編譯nginx並加上 --with-https_ssl_module

查看相關ssl的參數;

[root@localhost_001 nginx-1.4.7]# ./configure --help |grep -i ssl
  --with-http_ssl_module             enable ngx_http_ssl_module
  --with-mail_ssl_module             enable ngx_mail_ssl_module
  --with-openssl=DIR                 set path to OpenSSL library sources
  --with-openssl-opt=OPTIONS         set additional build options for OpenSSL

開始從新編譯nginx,並加上  --with-https_ssl_module

[root@localhost_001 nginx-1.4.7]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module
[root@localhost_001 nginx-1.4.7]# make
[root@localhost_001 nginx-1.4.7]# make install
[root@localhost_001 nginx-1.4.7]# echo $?
0

而後查看是否已經加載 http_ssl_module

[root@localhost_001 nginx-1.4.7]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.4.7
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module

而後檢測並重啓nginx服務;   -t    -s   reload

[root@localhost_001 nginx-1.4.7]# /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@localhost_001 nginx-1.4.7]# /usr/local/nginx/sbin/nginx -s reload

三、查看監聽端口,發現多出來的443端口;

[root@localhost_001 vhost]# netstat -lnpt
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      3663/nginx: master  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      808/sshd            
tcp        0      0 0.0.0.0:56888           0.0.0.0:*               LISTEN      808/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      962/master          
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      3663/nginx: master  
tcp6       0      0 :::22                   :::*                    LISTEN      808/sshd            
tcp6       0      0 :::56888                :::*                    LISTEN      808/sshd            
tcp6       0      0 ::1:25                  :::*                    LISTEN      962/master          
tcp6       0      0 :::3306                 :::*                    LISTEN      1071/mysqld

四、切換路徑,並新建一個測試文件;   /data/wwwroot/test.com

[root@localhost_001 vhost]# cd /data/wwwroot/test.com/
[root@localhost_001 test.com]# vim index.html 
The is ssl;

五、測試,若直接用curl命令訪問,須要添加/etc/hosts;

[root@localhost_001 vhost]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 www.test.com
[root@localhost_001 vhost]# curl https://www.test.com/
curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
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.

註釋:意思說這個證書被標記爲不能夠信任,由於使咱們本身頒發的,實際上已經配置成功了的;

而後咱們在windows的C:/windows/system32/drivers/etc/hosts下添加hosts;

192.168.149.129  www.test.com

四、而後在瀏覽器裏來訪問;   https://www.test.com

註釋:由於是咱們本身頒發的證書,會顯示不受瀏覽器信任,點擊繼續前往www.test.com

顯示不安全的鏈接;這個是本身頒發的證書,瀏覽器不被信任,會顯示紅色,不安全,正常的樣子應該是綠色的;

註釋:之後若想訪問https的網站,能夠去沃通買證書;

註釋:訪問是要看下防火牆是否開啓,若是開啓,能夠臨時使用iptables  -F來清空規則,或者能夠添加一條容許443端口通的規則,以下;

iptables   -I    INPUT    -p    tcp   --dport   443   -j    ACCEPT

相關文章
相關標籤/搜索