Nginx安裝及配置
Nginx (engine x) 是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務
安裝
我是用的環境是centos 7,系統默認的yum源沒有nginx,找到一個使用nginx官方源地址
首先建立nginx的yum倉庫,執行下面的命令
sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
可以看到已經添加上了nginx的源,下面就是下載安裝了
下載安裝命令也很簡單
sudo yum install -y nginx
安裝成功^_^
查看官方安裝文檔(https://www.nginx.com/resources/wiki/start/topics/tutorials/install/)上的源不一樣,不過都是一樣的建立本地yum倉庫
啓動nginx服務
service nginx start
默認是80端口,但測試訪問發現並不能進入歡迎頁面,查了一下,centos默認是關閉80端口的,我們設置一下防火牆
開啓80端口
sudo firewall-cmd --zone=public --permanent --add-service=http
開啓443端口
sudo firewall-cmd --zone=public --permanent --add-service=https
必須要重新加載一下防火牆配置才行哦,下面我們再來訪問一下
完美。
配置
默認的網站目錄爲: /usr/share/nginx/html
全局的配置文件爲:/etc/nginx/nginx.conf
默認的配置文件爲: /etc/nginx/conf.d/default.conf
日誌文件目錄爲:/var/log/nginx/
我們查看具體的配置文件內容,發現其實nginx.conf是主要的配置文件,新增的都在/etc/nginx/conf.d/,nginx.conf將整個目錄的配置文件都include了
配置結構
Nginx配置文件常見結構的從外到內依次是「http」「server」「location」等等,缺省的繼承關係是從外到內,也就是說內層塊會自動獲取外層塊的值作爲缺省值。
Http
設定http服務器,利用它的反向代理功能提供負載均衡支持
http {
#文件擴展名與文件類型映射表
include /etc/nginx/mime.types;
#默認文件類型
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 /var/log/nginx/access.log main;
#sendfile指令指定 nginx 是否調用sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,必須設爲on。如果用來進行下載等應用磁盤IO重負載應用,可設置爲off,以平衡磁盤與網絡IO處理速度,降低系統uptime。
sendfile on;
#此選項允許或禁止使用socket的TCP_CORK的選項,此選項僅在使用sendfile的時候使用
#tcp_nopush on;
#長連接超時時間,單位是秒
keepalive_timeout 65;
#開啓gzip壓縮輸出
#gzip on;
#導入其他配置
include /etc/nginx/conf.d/*.conf;
}
整個配置文件結構其實大概是這樣的
http {
#全局的配置
…………
server{
#虛擬主機的配置
…………
location {
#每個請求的處理,如請求轉發、靜態文件映射、負載均衡等
…………
}
}
}
下面再具體瞭解一下每一層的配置
Server
接收請求的服務器需要將不同的請求按規則轉發到不同的後端服務器上,在 nginx 中我們可以通過構建虛擬主機(server)的概念來將這些不同的服務配置隔離。不同的url會對應不同的server配置,而轉發到相應的後端服務器上做處理。
server {
listen 80; #服務監聽端口
server_name localhost; #服務的域名或IP
root html; #指定服務的頁面根目錄
index index.html index.htm; #指定訪問的默認首頁地址
}
通常我們可以配置多個server,像這樣
server {
listen 80;
server_name host1;
root html;
index index.html index.htm;
}
server {
listen 80;
server_name host2;
root /data/www/html;
index index.html index.htm;
}
我們可以將不同的服務在/etc/nginx/conf.d/目錄下創建相應的conf以區分,方便管理,而nginx.conf會將這個目錄下的conf全部引入的。
Location
每個 url 請求都會對應的一個服務,nginx 進行處理轉發或者是本地的一個文件路徑,或者是其他服務器的一個服務路徑。而這個路徑的匹配是通過 location 來進行的。我們可以將 server 當做對應一個域名進行的配置,而 location 是在一個域名下對更精細的路徑進行配置。
location [匹配規則] {
#具體處理配置,如轉發、反向代理、負載均衡等
}
location 匹配規則:
~ 波浪線表示執行一個正則匹配,區分大小寫
~* 表示執行一個正則匹配,不區分大小寫
^~ ^~表示普通字符匹配,如果該選項匹配,只匹配該選項,不匹配別的選項,一般用來匹配目錄
= 進行普通字符精確匹配
匹配例子:
location = / {
# 只匹配"/".
[ configuration A ]
}
location / {
# 匹配任何請求,因爲所有請求都是以"/"開始
# 但是更長字符匹配或者正則表達式匹配會優先匹配
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 開始的請求,並停止匹配 其它location
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg結尾的請求.
# 但是所有 /images/ 目錄的請求將由 [Configuration C]處理.
[ configuration D ]
}
請求:
/ -> 符合configuration A
/documents/document.html -> 符合configuration B
/images/1.gif -> 符合configuration C
/documents/1.jpg ->符合 configuration D
功能配置
主要的功能配置都是在location裏面的,下面我們來學習不同功能的配置方法
靜態文件映射
訪問文件的配置主要有 root 和 alias
alias後跟的指定目錄是準確的,並且末尾必須加 /。
location /c/ {
alias /a/;
}
如果訪問站點http://location/c訪問的就是/a/目錄下的站點信息。
root後跟的指定目錄是上級目錄,並且該上級目錄下要含有和location後指定名稱的同名目錄才行。
location /c/ {
root /a/;
}
這時訪問站點http://location/c訪問的就是/a/c目錄下的站點信息。
轉發
配置起來很簡單比如我要將所有的請求到轉移到真正提供服務的一臺機器的 8001 端口,只要這樣:
location / { proxy_pass 172.16.1.1:8001; }
這樣訪問host時,就都被轉發到 172.16.1.1的8001端口去了。
負載均衡
#負載均衡服務器列表配置在http下面
upstream myserver {
ip_hash;
server 172.16.1.1:8001;
server 172.16.1.2:8002;
server 172.16.1.3;
server 172.16.1.4;
}
location / {
proxy_pass http://myserver;
}
我們在 upstream 中指定了一組機器,並將這個組命名爲 myserver,這樣在 proxypass 中只要將請求轉移到 myserver 這個 upstream 中我們就實現了在四臺機器的反向代理加負載均衡。
負載均衡的模式
輪詢:默認模式,每個請求按時間順序逐一分配到不同的後端服務器,如果後端服務器down掉,能自動剔除。
weight:指定輪詢機率,weight和訪問比率成正比,用於後端服務器性能不均的情況。
upstream bakend {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}
ip_hash:每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端服務器,可以解決session的問題。
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
fair:按後端服務器的響應時間來分配請求,響應時間短的優先分配。
upstream backend {
server server1;
server server2;
fair;
}
url_hash:按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。
#例:在upstream中加入hash語句,server語句中不能寫入weight等其他的參數,hash_method是使用的hash算法
upstream backend {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
負載均衡設備的IP及設備狀態
每個設備的狀態設置爲: 1.down表示單前的server暫時不參與負載 2.weight爲weight越大,負載的權重就越大。 3.max_fails:允許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream模塊定義的錯誤 4.fail_timeout:max_fails次失敗後,暫停的時間。 5.backup: 其它所有的非back
up機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。
upstream bakend{#定義負載均衡設備的Ip及設備狀態}{
ip_hash;
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
加固
隱藏服務器版本號
默認我們訪問不存在的頁面時,報錯頁面上會有nginx的版本信息,這會向黑客提供信息,以方便查找當前版本的漏洞,加以利用
修改ngixn.conf,http層裏面添加server_tokens off;
我們訪問不存在的頁面試一下
這樣沒有版本信息了
禁止目錄瀏覽
默認是不允許列出整個目錄的,如果不是做下載服務器的,就不要打開這個,避免敏感信息暴露給黑客並下載
如果開啓了就會是下面這樣的效果
配置關閉即可
autoindex off
限制訪問敏感資源
有些資源我們可能不想對外開放,比如一些版本控制的備份文件,如.git/.svn等,這些暴露了可能會將整個項目的結構或是源代碼都泄露了,
location /my/ { deny all; }
上面我設置了my這個目錄下的所有資源都拒絕,效果如下
所以要識別好公開的資源,限制敏感資源的訪問
限制HTTP請求方法
關閉沒必要的請求方法,一般都是get|post了
下面配置在server裏面,預期之外的會返回500狀態
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 500; }
這個要放到最前面
限制IP/域名訪問
ngx_http_access_module 模塊使有可能對特定IP客戶端進行控制. 規則檢查按照第一次匹配的順序
location ~ .*my.html$ {
root /usr/share/nginx/html;
deny 192.168.0.105; #禁止ip
allow 192.168.189.134; #允許ip
deny all; #拒絕其他所有
}
限制訪問的ip,即限制了服務的客戶,防止不允許的人訪問,減少風險
控制超時時間
可以緩解dos攻擊,避免黑客僞造用戶訪問服務,造成服務器壓力過大,帶寬佔滿,
備份nginx.conf配置文件。
編輯配置文件,具體設置如下:
client_body_timeout 10; #設置客戶端請求主體讀取超時時間 client_header_timeout 10; #設置客戶端請求頭讀取超時時間 keepalive_timeout 5 5; #第一個參數指定客戶端連接保持活動的超時時間,第二個參數是可選的,它指定了消息頭保持活動的有效時間 send_timeout10; #指定響應客戶端的超時時間
驗證一下設置
錯誤頁面重定向
避免錯誤頁面提供敏感信息,一般我們會定製一些通用的錯誤頁面返回給客戶端
我們在http段配置
error_page 500 502 503 504 /50x.html;
類似上面這種配置,將狀態碼500、502、503、504全部重定向到50x.html
nginx降權
如果發生入侵,獲取了當前運行nginx的用戶,則擁有該用戶的全新了,我們應當使用最下權限運行ngixn,絕對禁止root用戶運行!!!
備份nginx.conf配置文件。
編輯配置文件,添加如下一行內容:
user nobody;
保存,然後後重啓nginx服務。
說明:nobody在linux中是一個不能登陸的帳號,一些服務進程如apache,aquid等都採用一些特殊的帳號來運行,比如nobody,news,games等等,這是就可以防止程序本身有安全問題的時候,不會被黑客獲得root權限