Nginx (engine x) 是一個高性能的HTTP和反向代理服務,也是一個IMAP/POP3/SMTP服務。php
Nginx是由伊戈爾·賽索耶夫爲俄羅斯訪問量第二的Rambler.ru站點(俄文:Рамблер)開發的,第一個公開版本0.1.0發佈於2004年10月4日。
其將源代碼以類BSD許可證的形式發佈,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。2011年6月1日,nginx 1.0.4發佈。
Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。其特色是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁服務器中表現較好。
延伸版本:tengine(淘寶)、openresrt(章亦春)。html
代碼或軟件包必須從官網下載,第三方的軟件包可能會有後門、安全漏洞等風險。nginx
$ wget http://nginx.org/download/nginx-1.15.5.tar.gz -P /usr/src # 下載nginx $ cd /usr/src $ tar xvf nginx-1.15.5.tar.gz $ cd nginx-1.15.5 $ yum -y install gcc # nginx是c寫的 $ yum -y install pcre-devel # url重寫用到的包 $ yum -y install zlib zlib-devel # 解壓縮用到的包
configure經常使用參數有兩個:--prefix=path;--help 配置參數web
$ ./configure --prefix=/usr/local/nginx .... Configuration summary + using system PCRE library + OpenSSL library is not used + using system zlib library nginx path prefix: "/usr/local/nginx" # nginx安裝路徑 nginx binary file: "/usr/local/nginx/sbin/nginx" # nginx啓動文件 nginx modules path: "/usr/local/nginx/modules" # nginx所使用的模塊 nginx configuration prefix: "/usr/local/nginx/conf" # nginx配置文件目錄 nginx configuration file: "/usr/local/nginx/conf/nginx.conf" # nginx配置文件 nginx pid file: "/usr/local/nginx/logs/nginx.pid" # pid文件,進程號 nginx error log file: "/usr/local/nginx/logs/error.log" # nginx錯誤日誌 nginx http access log file: "/usr/local/nginx/logs/access.log" # nginx訪問日誌(誰訪問了網站) 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"
# 編譯源碼生成可執行程序 依賴gcc $ make -j4 # 安裝程序 $ make install
一個服務有三要素:端口、監聽地址、協議。nginx使用的是七層協議(http),使用端口:80,監聽地址默認是0.0.0.0(全部機器)。
在nginx啓動前,須要先檢查端口是否被佔用:chrome
$ lsof -i:80 # 第一種方法 # contos7須要安裝netstat工具 $ yum install net-tools $ netstat -ntpl # 第二種方法 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1317/master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1095/sshd tcp6 0 0 ::1:25 :::* LISTEN 1317/master tcp6 0 0 :::22 :::* LISTEN 1095/sshd
查看發現沒有人使用80端口,啓動nginx程序:apache
$ /usr/local/nginx/sbin/nginx $ lsof -i :80 # 查看服務是否啓動 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 11524 root 6u IPv4 29204 0t0 TCP *:http (LISTEN) nginx 11525 nobody 6u IPv4 29204 0t0 TCP *:http (LISTEN)
$ yum install elinks # 除了elinks還有curl、lynx等文本瀏覽器 $ elinks http://192.168.10.42 -dump
查看文件:/usr/local/nginx/conf/nginx.confjson
#啓動子進程程序默認用戶 #user nobody; #一個主進程和多個工做進程。工做進程是單進程的,且不須要特殊受權便可運行;這裏定義的是工做進程數量 worker_processes 1; #全局錯誤日誌的位置及日誌格式 #error_log是指令定義的是錯誤日誌 後面是路徑及日誌級別 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #定義pid文件在哪,文件中的是主進程號,/usr/local/nginx/logs/nginx.pid #pid logs/nginx.pid; events { #每一個工做進程最大的併發數(一個工做進程能夠有多少個線程) worker_connections 1024; } #http服務器設置 http { #設定mime類型,類型由mime.type文件定義 include 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"'; #$remote_addr與$http_x_forwarded_for用以記錄客戶端的ip地址; #$remote_user:用來記錄客戶端用戶名稱; #$time_local: 用來記錄訪問時間與時區; #$request: 用來記錄請求的url與http協議; #$status: 用來記錄請求狀態;成功是200, #$body_bytes_sent :記錄發送給客戶端文件主體內容大小; #$http_referer:用來記錄從那個頁面連接訪問過來的; #$http_user_agent:記錄客戶瀏覽器的相關信息; #全局訪問日誌路徑 #access_log logs/access.log main; # 日誌放置的位置 #sendfile指令指定 nginx 是否調用sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,必須設爲on。若是用來進行下載等應用磁盤IO重負載應用,可設置爲off,以平衡磁盤與網絡IO處理速度,下降系統uptime。 sendfile on; #此選項容許或禁止使用socke的TCP_CORK的選項,此選項僅在使用sendfile的時候使用 #tcp_nopush on; #長鏈接超時時間 #keepalive_timeout 0; keepalive_timeout 65; #開啓壓縮 #gzip on; #配置虛擬主機 server { #虛擬主機使用的端口 listen 80; #虛擬主機域名 server_name localhost; #虛擬主機支持的字符集 #charset koi8-r; #虛擬主機的訪問日誌路徑 #access_log logs/host.access.log main; #定義web根路徑 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; #定義頁面路徑 location = /50x.html { root html; } #定義反向代理服務器 數據服務器是lamp模型(apache發佈) # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} #定義PHP爲本機服務的模型(經過nginx發佈) # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #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 # #拒絕apache DR目錄及子目錄下的.htaccess文件訪問 #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的配置方案 # HTTPS server # #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; # } #} }
這一行指定了啓動子進程程序的默認用戶。centos
$ lsof -i :80 # 查看服務是否啓動 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 11524 root 6u IPv4 29204 0t0 TCP *:http (LISTEN) nginx 11525 nobody 6u IPv4 29204 0t0 TCP *:http (LISTEN)
父進程是由root啓動的,子進程則是用nobody啓動的。瀏覽器
一個主進程和多個工程進程(子進程)。工做進程是單進程的,且不須要特殊受權便可運行。
這裏定義的是工做進程數量。通常狀況建議有幾個核就寫幾個。
# 安裝kellall命令 $ yum search killall $ yum -y install psmisc # 殺死nginx $ killall nginx $ lsof -i :80 # 查看是否殺死程序 # 添加新用戶 $ useradd -s /sbin/nologin -r www # 修改nginx.conf的進程 user www; worker_processes 4; # 再次啓動nginx $ /usr/local/nginx/sbin/nginx $ lsof -i :80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 11661 root 6u IPv4 30504 0t0 TCP *:http (LISTEN) nginx 11662 www 6u IPv4 30504 0t0 TCP *:http (LISTEN) nginx 11663 www 6u IPv4 30504 0t0 TCP *:http (LISTEN) nginx 11664 www 6u IPv4 30504 0t0 TCP *:http (LISTEN) nginx 11665 www 6u IPv4 30504 0t0 TCP *:http (LISTEN)
這個指定的是每一個工做進程(子進程)最大的併發數,也就是一個工做進程能夠有多少個線程。
工做進程 * 線程 就能夠獲得併發的數量。
一個server叫作一個虛擬主機,server的主要配置。
默認網站概念:當Nginx配置文件中有且只有一個Server的時候,該Server就被Nginx認爲是默認網站,全部發給Nginx服務器80端口的數據都會默認給該Server。
所以只有一個server的時候叫作默認網站,有多個server的時候則叫作虛擬主機。
http { # 默認網站 server { listen 80; server_name localhost; charset utf-8; # 修改字符集utf-8 #access_log logs/host.access.log main; # 使用默認日誌路徑 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; location = /50x.html { # 錯誤代碼頁的位置 root html; } } }
訪問控制配置規則是容許個別,拒絕全部。
location /a { allow 192.168.1.0/24; # 容許訪問的網段 deny all; #return 404; return http://www.jd.com; }
對nginx.conf文件作以下配置:
# 網站根目錄的相對路徑,定位的路徑在:/usr/local/nginx/html/a location /a { # 只容許本機訪問拒絕全部 allow 127.0.0.1; deny all; }
重啓nginx服務測試驗證:
$ /usr/local/nginx/sbin/nginx -g ../conf/nginx.conf # 啓動前校驗配置文件是否有問題 $ /usr/local/nginx/sbin/nginx $ lsof -i :80 # 檢驗服務是否啓動 $ elinks http://192.168.31.42/a --dump # 訪問被拒絕 403 Forbidden $ elinks http://127.0.0.1/a --dump aaaa
注意這裏返回的是403,告訴了訪問者,說明這裏有目錄,只是不容許訪問。爲了迷惑訪問者再也不嘗試訪問可作以下配置:
# 網站根目錄的相對路徑,定位的路徑在:/usr/local/nginx/html/a location /a { # 只容許本機訪問拒絕全部 allow 127.0.0.1; deny all; return 404; # 還能夠返回5xx系列,或者直接返回url:return www.jd.com }
配置修改後,不想從新啓動服務,能夠給服務發送信號告訴它配置文件重讀:
$ killall -s HUP nginx $ lsof -i :80 $ elinks http://192.168.31.42/a --dump 404 Not Found
登陸驗證的規則是:任何人均可以訪問,可是須要憑用戶密碼才能訪問。常見格式以下所示:
location /b { auth_basic "登錄驗證"; auth_basic_user_file /etc/nginx/htpasswd; }
語法:auth_basic string | off;
默認值是:auth_basic off;
語法:auth_basic_user_file file;
$ mkdir /etc/nginx/ $ touch /etc/nginx/htpasswd $ echo 'sko:123456' > /etc/nginx/htpasswd $ killall -s HUP nginx ####打開瀏覽器訪問192.168.31.42#####
此時打開瀏覽器訪問192.168.31.42/b/能夠發現彈出了登陸框,輸入用戶名和密碼後並不能登陸成功,由於密碼並無加密。
使用htpasswd實現密碼加密:-c是指定文件路徑沒有文件會自動建立;-m是生成加密。文件後的sky是指定的用戶名。
# 安裝htpasswd $ yum -y install httpd-tools # 查看包來源 $ rpm -qf `which htpasswd` httpd-tools-2.4.6-88.el7.centos.x86_64 # 建立加密密碼的用戶 $ htpasswd -m /etc/nginx/htpasswd sky New password: # 輸入密碼 Re-type new password: # 重複密碼 Adding password for user sky $ cat /etc/nginx/htpasswd sky:$apr1$kRE.rFXV$lbR2/Ga09e/i91qGrg/931
此時打開瀏覽器訪問192.168.31.42/b/,輸入sky/123後,登陸成功,看到頁面信息bbbb。
Nginx訪問日誌主要有兩個參數控制:
$remote_addr #記錄訪問網站的客戶端地址 $remote_user #遠程客戶端用戶名 $time_local #記錄訪問時間與時區 $request #用戶的http請求起始行信息 $status #http狀態碼,記錄請求返回的狀態碼,例如:200、30一、404等 $body_bytes_sent #服務器發送給客戶端的響應body字節數 $http_referer #記錄這次請求是從哪一個鏈接訪問過來的,能夠根據該參數進 行防盜鏈設置。 $http_user_agent #記錄客戶端訪問信息,例如:瀏覽器、手機客戶端等 $http_x_forwarded_for #當前端有代理服務器時,設置web節點記錄客戶端 地址的配置,此參數生效的前提是代理服務器也要進行相關的x_forwarded_for設 置
http { include 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"'; # 第一步:自定義日誌格式 log_format hqs_01 '[$time_local] $remote_addr "$request" $status' #access_log logs/access.log main; #####其餘代碼省略#### server { listen 80; server_name localhost; #charset koi8-r; charset utf-8; #access_log logs/host.access.log main; # 第二步:自定義日誌 access_log logs/host.access.log hqs_01; } }
重啓服務後,從瀏覽器上訪問服務,查看日誌信息:
$ tailf logs/host.access.log [11/Dec/2018:15:51:49 +0800] 192.168.31.28 "GET /b/ HTTP/1.1" 304sendfileon [11/Dec/2018:15:52:28 +0800] 192.168.31.28 "GET / HTTP/1.1" 200sendfileon
http { include 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"'; # 自定義日誌格式 log_format hqs_01 '[$time_local] $remote_addr "$request" $status'; # 自定義json日誌格式 log_format main_json '{"@timestamp":"$time_local",' '"client_ip": "$remote_addr",' '"request": "$request",' '"status": "$status",' '"bytes": "$body_bytes_sent",' '"x_forwarded": "$http_x_forwarded_for",' '"referer": "$http_referer"' '}'; server { listen 80; server_name localhost; #charset koi8-r; charset utf-8; #access_log logs/host.access.log main; # 自定義日誌 access_log logs/host.access.log main_json; location / { root html; index index.html index.htm; }
從新啓動nginx後,查看日誌,能夠看到新的日誌格式:
$ killall nginx $ sbin/nginx $ tailf logs/host.access.log {"@timestamp":"11/Dec/2018:16:25:30 +0800","client_ip": "192.168.31.28","request": "GET / HTTP/1.1","status": "304","bytes": "0","x_forwarded": "-","referer": "-"} {"@timestamp":"11/Dec/2018:16:25:34 +0800","client_ip": "192.168.31.28","request": "GET /a HTTP/1.1","status": "404","bytes": "555","x_forwarded": "-","referer": "-"}
盜鏈是指服務提供商本身不提供服務的內容,經過技術手段繞過其它有利益的最終用戶界面(如廣告),直接在本身的網站上向最終用戶提供其它服務提供商的服務內容,騙取最終用戶的瀏覽和點擊率。受益者不提供資源或提供不多的資源,而真正的服務提供商卻得不到任何的收益。
百度就是最大的盜鏈公司,不少圖片和數據在百度就看到了。服務提供商須要支付帶寬,但訪問和用戶並無增長,反而會愈來愈少。
防盜鏈:在HTTP協議中,有一個表頭字段叫referer,採用URL的格式來表示從哪兒連接到當前的網頁或文件。經過referer,網站能夠檢測目標網頁訪問的來源網頁,若是是資源文件,則能夠跟蹤到顯示它的網頁地址。有了referer跟蹤來源,就能夠經過技術手段來進行處理,一旦檢測到來源不是本站即進行阻止或者返回指定的頁面。
location /c { valid_referers none blocked *.ayitula.com; if ($invalid_referer) { return 403 } }
valid_referers定義的是有效的referer:
valid_referers none blocked *.ayitula.com; - none:沒有referer字段的(用戶直接過來訪問的) - blocked:硬件防火牆標識的 - *.ayitula.com:本身的內網服務器
if ($invalid_referer){return 403}說明全部不知足valid_referer的referer都是無效的referer,直接返回403頁面。
若是要實現寬廣匹配:~是匹配,*是不區分大小寫 .(png|gif|bmp)$:域名內任意以png/gif/bmp結尾的。
location ~* \.(png|gif|bmp)$ { valid_referers none blocked *.ayitula.com; if ($invalid_referer) { return 403 } }
發佈一個內部HTML網站,要求對圖片目錄作防盜鏈設置,用戶只能來自192.168.31.0網段,訪問網站須要使用帳號密碼。