文章目錄
3.1 nginx基礎
Nginx是由伊戈爾·賽索耶夫爲俄羅斯訪問量第二的Rambler.ru站點(俄文:Рамблер)開發的,第一個公開版本0.1.0發佈於2004年10月4日。
3.1.1 nginx優點
Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,在BSD-like 協議下發行。其特點是佔有內存少,併發能力強,事實上nginx的併發能力在同類型的網頁服務器中表現較好.
Nginx和Apache的區別
- apache 相對於nginx 的優點:
rewrite ,比nginx 的rewrite 強大
動態頁面,nginx處理動態請求是雞肋,一般動態請求要apache去做,nginx只適合靜態和反向。
模塊超多,基本想到的都可以找到
少bug ,nginx 的bug 相對較多超穩定- nginx相對於apache的優點:
輕量級,同樣起web 服務,比apache佔用更少的內存及資源 ,支持更多的併發連接,體現更高的效率,這點使 Nginx 尤其受到虛擬主機提供商的歡迎。在高連接併發的情況下,Nginx是Apache服務器不錯的替代品: Nginx在美國是做虛擬主機生意的老闆們經常選擇的軟件平臺之一. 能夠支持高達 50,000 個併發連接數的響應, 這歸功於Nginx爲我們選擇了 epoll and kqueue 作爲開發模型.
抗併發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高性能
高度模塊化的設計,編寫模塊相對簡單
社區活躍,各種高性能模塊出品迅速
Nginx本身就是一個反向代理服務器
負載均衡能力突出,Nginx 既可以在內部直接支持 Rails 和 PHP 程序對外進行服務, 也可以支持作爲 HTTP代理 服務器對外進行服務. Nginx採用C進行編寫, 不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多.- 核心區別:apache是同步多進程模型,一個連接對應一個進程;nginx是異步的,多個連接(萬級別)可以對應一個進程
Nginx和Apache的區別:https://blog.51cto.com/wnqcmq/1184888
3.1.2 nginx應用場景
-
靜態資源服務
通過本地文件系統提供服務
-
反向代理服務
nginx的強大性能
緩存
負載均衡
-
API服務
3.1.3 nginx歷史背景
互聯網的數據量爆炸式增長
摩爾定律
低效的Apache性能
C10K問題:https://www.jianshu.com/p/ba7fa25d3590
3.1.4 nginx版本發佈歷史
nginx版本介紹
1.開源
nginx.org
阿里巴巴的tengine 針對大訪問量網站的nginx版本
tengine:http://tengine.taobao.org/
OpenResty.org(由創始人章亦春維護)
OpenResty 是一個基於 Nginx 與 Lua 的高性能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。用於方便地搭建能夠處理超高併發、擴展性極高的動態 Web 應用、Web 服務和動態網關。
OpenResty 通過匯聚各種設計精良的 Nginx 模塊(主要由 OpenResty 團隊自主開發),從而將 Nginx 有效地變成一個強大的通用 Web 應用平臺。這樣,Web 開發人員和系統工程師可以使用 Lua 腳本語言調動 Nginx 支持的各種 C 以及 Lua 模塊,快速構造出足以勝任 c10K 乃至 1000K 以上單機併發連接的高性能 Web 應用系統。
OpenResty 的目標是讓你的Web服務直接跑在 Nginx 服務內部,充分利用 Nginx 的非阻塞 I/O 模型,不僅僅對 HTTP 客戶端請求,甚至於對遠程後端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進行一致的高性能響應。
OpenResty.:http://openresty.org/cn/
2.商業
nginx.com
OpenResty.com
3.1.5 nginx安裝
1.nginx下載&解壓
[root@localhost ~]# wget http://nginx.org/download/nginx-1.14.0.tar.gz
[root@localhost ~]# tar xf nginx-1.14.0.tar.gz
2.編譯安裝
安裝依賴工具
[root@localhost ~]# yum install -y gcc automake pcre-devel openssl-devel zlib-devel
編譯並安裝
[root@localhost nginx-1.14.0]# ./configure
[root@localhost nginx-1.14.0]# make
[root@localhost nginx-1.14.0]# make install
- ./configure
生成一個make編譯時需要用到Makefile
通用選項
--prefix=PATH # 定義安裝目錄(默認/usr/local)
--withXXXmoduleXXX # 啓用XXX模塊(需提前安裝模塊相對應的軟件包)
--withoutXXX # 禁用模塊
- make
安裝Makefile編譯軟件,生成相關可執行文件
- make install
將編譯好的相關文件拷貝到系統目錄中
將可執行文件路徑加到PATH
[root@localhost nginx-1.14.0]# export PATH=$PATH:/usr/local/nginx/sbin
管理nginx
啓動 執行nginx啓動
關閉 nginx -s stop
重啓 nginx -s reload
開機自動
寫入rc.local
3.nginx配置文件通用語法
添加vim的nginx語法解析
在~/.vim
源碼目錄contrib/vim/*拷貝到~/.vim
[root@localhost ~]# mkdir ~/.vim
[root@localhost ~]# cp -a nginx-1.14.0/contrib/vim/* ~/.vim
nginx配置語法
- 1.配置文件由指令(directive)與指令塊(directive block)構成
DIRECTIVE ARGS;
NAME {
DIRECTIVE;
NAME2 {
}
};
-
2.每條指令以;分號結尾,指令與參數間以空格符號分格
-
3.指令塊以{}大括號將多條指令組織在一起
-
4.include語句包含多個配置文件提升可維護性
-
5.使用#註釋,提高可讀性
-
6.使用$符號調用變量
-
7.部分指令的參數支持正則表達式(rewrite/location)
nginx配置文件中時間單位
expire 3m; #3分鐘後刷新cachnginx配置文件中時間單位
ms
s
m
h
d
w
M
y
nginx配置文件中的空間單位
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s #10m共享內存提供給worker進程使用
空
bytes
k/K
m/M
g/G
nginx常見指令快
- http http核心參數
- server 虛擬主機參數
- location url定義
- upstream 上游負載均衡
主配置文件內容結構
#user nobody; worker進程執行者
worker_processes 1; worker進程數量
#error_log logs/error.log; 錯誤日誌
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid; pid文件路徑
events {
worker_connections 1024;
每個worker進程支持最大連接數
}
http {
include mime.types;
nginx支持的媒體類型
default_type application/octet-stream;
默認的媒體類型
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
訪問日誌及格式
sendfile on;
開啓高效傳輸模式
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
連接超時時間
#gzip on;
開啓壓縮
server {
server區塊開始,裏面定義一個獨立的虛擬主機
listen 80;
監聽端口
server_name localhost;
提供服務的域名或主機名
#charset koi8-r;
#access_log logs/host.access.log main;
此虛擬主機訪問日誌及格式
location / {
第一個location區塊開始
root html;
站點的根目錄
index index.html index.htm;
站點的默認首頁
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
錯誤狀態碼爲50x時返回/50x.html
#www.pl1.com/50x.html
location = /50x.html {
當訪問/50x.html時
root html;
指定去哪個根目錄查找50x.html
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
代理服務器配置
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
結合fastcgi實現php動態程序
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
https功能定義
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
4.nginx目錄結構
[root@localhost ~]# tree /usr/local/nginx/
/usr/local/nginx/
├── client_body_temp
├── conf
│ ├── fastcgi.conf
│ ├── fastcgi.conf.default
│ ├── fastcgi_params
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types
│ ├── mime.types.default
│ ├── nginx.conf
│ ├── nginx.conf.default
│ ├── scgi_params
│ ├── scgi_params.default
│ ├── uwsgi_params
│ ├── uwsgi_params.default
│ └── win-utf
├── fastcgi_temp
├── html
│ ├── 50x.html
│ └── index.html
├── logs
│ ├── access.log
│ ├── error.log
│ └── nginx.pid
├── proxy_temp
├── sbin
│ └── nginx
├── scgi_temp
└── uwsgi_temp
9 directories, 21 files
3.1.6 nginx命令行
1.nginx命令行
-
nginx -h 獲取幫助
-
nginx -c FILE 指定配置文件
-
nginx -p FILE 指定運行目錄
-
nginx -s SIGNAL 發送信號
stop 立即停止服務
quit 優雅停止服務
reload 重載配置文件
reopen 刷新日誌文件
-
nginx -t 測試配置文件語法
-
nginx -v 打印nginx版本
-
nginx -V 查看nginx編譯選項
2.nginx熱部署
將舊nginx備份,將新nginx覆蓋,平滑啓動
kill -USR2 PID
3.nginx優雅關閉
nginx -s quit
kill -WINCH PID
4.nginx優雅重啓
nginx -s reload
kill -HUP PID
5.nginx日誌切割
將源日誌備份
nginx -s reopen
kill -USR1 PID
信號 | 作用 |
---|---|
TERM或INT | 快速停止Nginx服務 |
QUIT | 平緩停止Nginx服務 |
HUP | 使用新的配置文件啓動進程,之後平緩停止原有進程,也就是所謂的“平滑重啓” |
USR1 | 重新打開日誌文件,常用於日誌切割 |
USR2 | 使用新版本的Nginx文件啓動服務,之後平緩停止原有Nginx進程,也就是所謂的“平滑升級” |
WINCH | 平滑停止worker process,用於Nginx服務器平滑升級 |
3.1.7 搭建靜態資源web服務器
1.準備好服務器server,並安裝nginx
2.準備好靜態網頁文件,並放到安裝目錄下的html中
3.啓動服務 /usr/local/nginx/sbin/nginx
4.基本配置 配置文件nginx.conf
server {
listen 80; #監聽端口
location / {
alias html/blog_test/; #指定訪問URL路徑指向(root html/blog_test/;)
}
...
注:alias後面是目錄的的話後面要加/
添加index.html
[root@localhost ~]# vim /usr/local/nginx/html/blog_test/index.html
<!DOCTYPE html>
<html>
<head>
<title>This is a test!!!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<p>this is a test</p>
<p>
<img src="1.jpg">
</p>
</body>
</html>
測試
5.壓縮功能
未使用壓縮
gzip on;
gzip_min_length 1; 小於1字節不壓縮
gzip_comp_level 2; 壓縮級別2
gzip_types text/plain; 壓縮類型
Nginx的Gzip壓縮功能雖然好用,但是下面兩類文件資源不太建議啓用此壓縮功能。
1) 圖片類型資源 (還有視頻文件)
原因:圖片如jpg、png文件本身就會有壓縮,所以就算開啓gzip後,壓縮前和壓縮後大小沒有多大區別,所以開啓了反而會白白的浪費資源。(可以試試將一張jpg圖片壓縮爲zip,觀察大小並沒有多大的變化。雖然zip和gzip算法不一樣,但是可以看出壓縮圖片的價值並不大)
2) 大文件資源
原因:會消耗大量的cpu資源,且不一定有明顯的效果。
gzip:https://www.cnblogs.com/kevingrace/p/10018914.html
6.文件共享
location / {
alias html/blog_test/; #指定訪問URL路徑指向
autoindex on;
}
7.對傳輸速率限制
location / {
root html/blog_test/;
#index index.html index.htm;
autoindex on;
set $limit_rate 1k;
}
8.access日誌
日誌中可以調用所有模塊的內置變量
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/haha.com.log main;
查看
[root@localhost ~]# cat /usr/local/nginx/logs/haha.com.log
192.168.217.1 - - [29/May/2020:22:46:49 -0400] "GET / HTTP/1.1" 200 224 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36" "-"
9.虛擬主機
-
簡介
虛擬主機在web服務中相當於一個獨立的網站站點,這個站點一般使用獨立的域名或IP或端口,可以獨立的向外提供web服務
-
虛擬主機類型
基於IP的虛擬主機
基於端口的虛擬主機
基於域名的虛擬主機(常用)
nginx.conf
server {
listen 8080;
server_name www.haha1.com;
error_log logs/error_haha1.log;
access_log logs/access_haha1.log ;
location / {
root /data/haha1/;
index index.html;
}
}
server {
listen 8080;
server_name www.haha2.com;
error_log logs/error_haha2.log;
access_log logs/access_haha2.log ;
location / {
root /data/haha2/;
index index.html;
}
}
測試配置文件 nginx -t
重啓nginx服務 nginx -s reload
創建文件
[root@localhost ~]# mkdir -p /data/{haha1,haha2}
[root@localhost ~]# echo "<h>haha1</h>" > /data/haha1/index.html
[root@localhost ~]# echo "<h>haha2</h>" > /data/haha2/index.html
優化虛擬主機配置
include FILE
include vhost/hehe1.conf;
include vhost/hehe2.conf;
創建目錄與配置文件
[root@localhost ~]# mkdir /data/{hehe1,hehe2}
[root@localhost ~]# echo "<h>hehe1</h>" > /data/hehe1/index.html
[root@localhost ~]# echo "<h>hehe2</h>" > /data/hehe2/index.html
[root@localhost ~]# mkdir /usr/local/nginx/conf/vhost
[root@localhost ~]# vim /usr/local/nginx/conf/vhost/hehe1.conf
server {
listen 80;
server_name www.hehe1.com;
location / {
root /data/hehe1;
index index.html index.htm;
}
}
[root@localhost ~]# vim /usr/local/nginx/conf/vhost/hehe2.conf
server {
listen 80;
server_name www.hehe2.com;
location / {
root /data/hehe2;
index index.html index.htm;
}
}
訪問
nginx狀態檢測模塊(http_stub_status_module)
回到編譯目錄下重新編譯
[root@localhost ~]# cd nginx-1.14.0
[root@localhost nginx-1.14.0]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module
[root@localhost nginx-1.14.0]# make
[root@localhost nginx-1.14.0]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
[root@localhost nginx-1.14.0]# cd objs/
[root@localhost objs]# cp ./nginx /usr/local/nginx/sbin/nginx
[root@www objs]# nginx -s stop
[root@www objs]# cp ./nginx /usr/local/sbin/nginx
[root@www objs]# nginx
[root@localhost ~]# nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module
建議使用熱部署
kill -USR2 PID
kill -WINCH PID
修改
server {
listen 80;
server_name www.hehe1.com;
location / {
root /data/hehe1;
index index.html index.htm;
}
location /status {
stub_status on; #<==打開狀態信息開關
access_log off;
allow 192.168.217.0/24;
deny all;
}
}
重啓
[root@www ~]# nginx -s stop
[root@www ~]# nginx
[root@www ~]# curl www.hehe1.com/status
Active connections: 2
server accepts handled requests
2 2 2
Reading: 0 Writing: 1 Waiting: 1
3.1.8 搭建具備緩存功能的反向代理服務器
set_real_ip_from:真實服務器上一級代理的 IP 地址或者 IP 段,可以寫多行
real_ip_header:從哪個 header 頭檢索出要的 IP 地址
real_ip_recursive:遞歸排除 IP 地址,ip 串從右到左開始排除 set_real_ip_from 裏面出現的 IP,如果出現了未出現這些 ip 段的 IP,那麼這個 IP 將被認爲是用戶的 IP。
在server端配置upstream
[root@server ~]# vim /usr/local/nginx/conf/nginx.conf
upstream haha {
server 192.168.217.155;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
access_log logs/host.access.log main;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://haha;
}
測試
抓包
[root@localhost ~]# tcpdump -i ens33 tcp port 80 and host 192.168.217.154 -c 100 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
08:04:24.356274 IP 192.168.217.155.46256 > 192.168.217.154.http: Flags [S], seq 3157995737, win 29200, options [mss 1460,sackOK,TS val 162211595 ecr 0,nop,wscale 7], length 0
08:04:24.356314 IP 192.168.217.154.http > 192.168.217.155.46256: Flags [S.], seq 149939911, ack 3157995738, win 28960, options [mss 1460,sackOK,TS val 16793423 ecr 162211595,nop,wscale 7], length 0
這裏有了真實地址
上游服務器server1
可以看到真實ip
靜態內容可以緩存下來
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
location / {
add_header Nginx-Cache "$upstream_status";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://haha;
proxy_cache my_cache;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 304 302 1d;
}
關掉nginx嘗試
測試
可以關掉nginx,server上已有緩存的情況下,還是可以打開源資源
有緩存的
[root@www ~]# siege -c200 -t5 proxy.haha.com
{ "transactions": 371926,
"availability": 100.00,
"elapsed_time": 300.01,
"data_transferred": 16116.00,
"response_time": 0.16,
"transaction_rate": 1239.71,
"throughput": 53.72,
"concurrency": 199.65,
"successful_transactions": 371926,
"failed_transactions": 0,
"longest_transaction": 28.81,
"shortest_transaction": 0.00
}
沒緩存的
[root@www ~]# siege -c200 -t5 proxy.haha.com
{ "transactions": 271674,
"availability": 100.00,
"elapsed_time": 299.38,
"data_transferred": 11774.29,
"response_time": 0.22,
"transaction_rate": 907.46,
"throughput": 39.33,
"concurrency": 199.70,
"successful_transactions": 271674,
"failed_transactions": 0,
"longest_transaction": 7.28,
"shortest_transaction": 0.02
}
1.X-Real-IP與X-Forwarded-For區別
一般來說,X-Forwarded-For
是用於記錄代理信息的,每經過一級代理(匿名代理除外),代理服務器都會把這次請求的來源IP
追加在X-Forwarded-For
中
來自4.4.4.4
的一個請求,header包含這樣一行
X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3
而X-Real-IP
,沒有相關標準,上面的例子,如果配置了X-Read-IP
,可能會有兩種情況
// 最後一跳是正向代理,可能會保留真實客戶端IP
X-Real-IP: 1.1.1.1
// 最後一跳是反向代理,比如Nginx,一般會是與之直接連接的客戶端IP
X-Real-IP: 3.3.3.3
X-Forwarded-For確實是一般的做法
1.他在正向(如squid)反向(如nginx)代理中都是標準用法,而正向代理中是沒有x-real-ip相關的標準的,也就是說,如果用戶訪問你的 nginx反向代理之前,還經過了一層正向代理,你即使在nginx中配置了x-real-ip,取到的也只是正向代理的IP而不是客戶端真實IP
2.多級代理很少見,只有一級代理的情況下二者是等效的
3.如果有多級代理,x-forwarded-for效果是大於x-real-ip的,可以記錄完整的代理鏈路
HTTP 請求頭中的 X-Forwarded-For:https://imququ.com/post/x-forwarded-for-header-in-http.html
2.proxy_set_header與add_header區別 查看緩存命中情況
proxy_set_header
是Nginx
設置請求頭信息給上游服務器,add_header
是Nginx
設置響應頭信息給瀏覽器。
proxy_set_header:https://blog.csdn.net/felix_yujing/article/details/51682655
proxy_set_header設置:https://blog.csdn.net/a19860903/article/details/49914131
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
但是,如果客戶端請求頭中沒有攜帶這個頭部,那麼傳遞到後端服務器的請求也不含這個頭部。 這種情況下,更好的方式是使用$host
變量——它的值在請求包含“Host”請求頭時爲“Host”字段的值,在請求未攜帶“Host”請求頭時爲虛擬主機的主域名:
句法: | proxy_set_header field value; |
---|---|
默認: | proxy_set_header主機$ proxy_host; proxy_set_header連接關閉; |
內容: | http ,server ,location |
proxy_set_header:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
句法: | add_header name value [always]; |
---|---|
默認: | - |
內容: | http ,server ,location ,if in location |
add_header:http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
3.1.9 使用goaccess分析access日誌
1.安裝goaccess
[root@www ~]# yum -y install goaccess
2.生成分析報告
[root@www ~]# goaccess /usr/local/nginx/logs/access.log -o /usr/local/nginx/html/report.html --real-time-html --time-format='%H:%M:%S' --date-format='%d/%b/%Y' --log-format=COMBINED
WebSocket server ready to accept new client connections
Accepted: 13 192.168.217.1
Active: 1
3.編輯nginx.conf
location /report.html {
alias /usr/local/nginx/html/report.html;
}
4.在瀏覽器訪問server1的report.html測試
IP/report.html
3.1.10 HTTP/HTTPS
1.HTTP通信安全問題
在http協議中,所有報文的發送接收都是以明文的形式進行的,即在tcp/ip五層網絡模型中,數據直接以明文的形式從應用層HTTP發送給傳輸層TCP,之間沒有任何加密過程
三大風險及解決方案
竊聽/嗅探風險
- 針對竊聽/嗅探風險,我們可以對數據使用密碼加密算法進行加密,即使中間人截獲了我們的數據,由於沒有相應的解密密鑰,拿到了數據也沒法破解。
數據篡改風險
- 針對篡改風險,我們可以使用相關的數字簽名算法,保障數據的完整性。
身份僞造風險
- 針對身份僞造風險,我們可以通過頒發數字證書來證明對方的身份。
2.SSL/TLS協議
SSL/TLS 和 HTTPS 協議聯繫非常緊密,HTTPS 是在 SSL/TLS 協議基礎之上建立起來的。
- 發展歷史
-
網絡層次
用戶在沒有感知的情況下實現了對應用層的數據加密
-
基本原理
簡單地講,SSL/TLS就是同時結合各種密碼算法、數字簽名算法及數字證書等技術的一套協議,目的就是爲了保證通信的安全性。
採用SSL/TLS協議,通信雙方建立連接之前需要進行握手,目的是協商出會話密鑰,用於後續對通信數據的加解密操作。
-
依賴三類算法
對稱加密算法
- 數據加解密使用同一份密鑰,加解密速度快,效率高,缺點是密鑰的管理難度大,一旦密鑰傳輸泄露,那就沒啥用處了。
- 常用的對稱加密算法有:DES、3DES、Blowfish、IDEA、RC4、RC5、RC6和AES
非對稱加密算法
- 數據加解密使用公鑰和私鑰,公鑰用於傳輸,私鑰自己保存,安全性較高,但加解密速度偏慢。
- 常用的非對稱加密算法有:RSA、ECC(移動設備用)、Diffie-Hellman、El Gamal、DSA
散列算法
- 該類函數特點是函數單向不可逆、對輸入非常敏感、輸出長度固定,針對數據的任何修改都會改變散列函數的結果,用於防止信息篡改並驗證數據的完整性。
- MAC、MD5、SHA1
TLS/SSL
- SSL/TLS則結合兩者的優缺點,數據包的加密使用對稱加密算法,而對稱加密算法的密鑰採用非對稱加密手段協商獲取。
-
PKI公鑰基礎設施
RSA身份驗證的隱患
-
RSA算法無法確保服務器身份的合法性,因爲公鑰並不包含服務器的信息,存在安全隱患
-
中間人攻擊
-
信息抵賴
-
PKI架構
CA 負責頒發證書
RA 證書登記機構(負責登記訂閱人的信息)
CSR 證書籤名申請,訂閱人向RA填寫申請信息
1 瀏覽器訪問https站點會向web服務器請求證書,web服務器將公鑰證書發給瀏覽器
2 瀏覽器根據本地的記錄才驗證證書的合法性有效性
3 所有過期證書會存放CRL Server中,性能非常差
OCSP 瀏覽器通過OCSP查詢證書是否有效
證書分類
DV Domain validated,域名驗證證書
OV Organization Validation,組織驗證證書
EV Extended Validation,擴展驗證證書
證書鏈
根證書 一般在操作系統或瀏覽器中內置
二級證書 根CA認可的二級證書CA機構頒發
主證書 站點申請
- 抓包分析TLS通訊過程
工作流程圖
1、客戶端向服務器端發送一個Client Hello
Client Hello中攜帶了當前客戶端支持的TLS協議的版本號(Version)、客戶端支持的加密套件(Cipher Suites)、一個隨機數(Random1)、客戶端支持的壓縮算法(Compression Method)
2、服務器端想客戶端返回一個Server Hello
第一步客戶端告訴服務端我所支持的相關信息,第二步服務端協商返回確定的信息,如確定使用哪種加密套件(Cipher Suites)或壓縮方法等。以及另一個隨機數(Random2),至此客戶端和服務端都有兩個隨機數(Random1+Random2),這兩個隨機數會在後續生產對稱密鑰時用到.
加密套件詳解
3、服務器端向客戶端返回一個Certificate
服務器給客戶端下發一份證書,讓客戶端驗證自己的身份,客戶端驗證通過後取出證書中的公鑰。
4、服務器端向客戶端返回Server key change,Server Hello Done
客戶端後續可以對這些參數算出會話密鑰,傳遞完參數之後,告訴客戶端服務器端的握手結束(Done)了。
5、客戶端向服務器端發送Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
這一步,客戶端根據第四步傳過來的公鑰,生成一個叫預備-主密鑰的pre-master key,然後Client Key Exchange將這個預備-主密鑰傳給服務器端。服務器端結合自己的私鑰解出這個預備-主密鑰的信息,得到第三個隨機數,所以,到目前爲止,客戶端和服務器都擁有 Random1 + Random2 + Random3。
緊接着兩邊根據D-H算法及第四步傳遞的相關參數生成一個會話密鑰,後續就使用這個密鑰進行通信了。可以看出,會話密鑰能不能被破解,關鍵看第三個隨機數能不能被破解,而且第三個隨機數用wireShark是抓取不到的。
-
Change Cipher Spec
這一步是告訴服務器端後期的通信都會使用我們協商出來的密鑰進行通信。
-
Encrypted Handshake Message
客戶端將前面的握手消息生成摘要再用協商好的祕鑰加密(對稱加密),這是客戶端發出的第一條加密消息。服務端接收後會用祕鑰解密,能解出來說明前面協商出來的祕鑰是一致的。
6、服務器端向客戶端返回Change Cipher Spec, Encrypted Handshake Message
同第5步,如果服務器端通過D-H算法能夠解密摘要,那麼服務器端應該告訴客戶端說我們之間協商的會話密鑰是一致的
3.1.11 用免費證書實現https站點
使用本地證書
[root@www ~]# yum install -y openssl
1.創建rsa私鑰
[root@www ~]# openssl genrsa -des3 -out ssl.key 1024 # 密碼必須填寫
Generating RSA private key, 1024 bit long modulus
..............................................................++++++
.............++++++
e is 65537 (0x10001)
Enter pass phrase for ssl.key:
Verifying - Enter pass phrase for ssl.key:
[root@www ~]# openssl rsa -in ssl.key -out ssl.key
Enter pass phrase for ssl.key:
writing RSA key
2.生成證書請求文件
[root@www ~]# openssl req -new -key ssl.key -out ssl.csr
Enter pass phrase for ssl.key:
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]:CN
State or Province Name (full name) []:GD
Locality Name (eg, city) [Default City]:GZ
Organization Name (eg, company) [Default Company Ltd]:haha
Organizational Unit Name (eg, section) []:CN
Common Name (eg, your name or your server's hostname) []:www.haha.com
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
3.最後根據這2個文件(ssl.key ssl.csr)生成crt證書文件
[root@www ~]# openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
Signature ok
subject=/C=CN/ST=GD/L=GZ/O=haha/OU=CN/CN=www.haha.com/[email protected]
Getting Private key
加入ssl模塊
[root@www ~]# nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --with-http_stub_status_module --with-http_ssl_module
4.配置nginx ssl
server {
listen 443 ssl;
server_name www.haha.com;
ssl_certificate /usr/local/nginx/key/ssl.crt;
ssl_certificate_key /usr/local/nginx/key/ssl.key;
ssl_session_timeout 5m;
location / {
alias /data/private/;
index index.html;
}
}
server {
listen 80;
server_name www.haha.com;
location / {
rewrite ^/(.*)$ https://www.haha.com:443/$1 permanent;
}
}
創建key目錄
[root@www ~]# mkdir /usr/local/nginx/key
[root@www ~]# mv ssl.* /usr/local/nginx/key/
創建index
[root@www ~]# mkdir /data/private
[root@www ~]# echo "<h1>hello ssl</h1>" > /data/private/index.html
測試
使用外部證書
通過證書運營商申請證書
https://buy.cloud.tencent.com/ssl?fromSource=ssl
將獲取到的證書配置在nginx中(配置同上)
3.1.12 nginx解析php應用
在lnmp架構中部署discuz
php-fpm
yum install php-fpm php-mysql -y
systemctl restart php-fpm
數據庫設置
yum install -y mariadb-server mariadb
mysql_secure_installation
初始化
建庫
create database discuzdb;
授權
grant all on discuzdb.* to ‘disuser’@‘localhost’ identified by ‘dispass’;
systemctl restart mariadb
nginx配置
vim nginx.conf
http{
include conf.d/*.conf;
}
mkdir conf/conf.d
vi conf/conf.d/discuz.conf
server {
listen 80;
server_name discuz.pl.com;
root /data/www/discuz;
location / {
index index.php;
}
#discuz.pl.com/index.php
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
index.php
mkdir /data/www
vi /data/www/index.php
<?php
$con = mysql_connect("localhost","disuser","dispass");
if (!$con)
{
echo "faild,check username and password!!";
}
else {
echo "successful!!!";
}
// 一些代碼...
mysql_close($con);
?>