Web架構之Nginx基礎配置
阿新 • • 發佈:2020-03-14
[TOC]
# 1、Nginx 虛擬主機
所謂的虛擬主機,在Web服務裡就是一個獨立的網站站點,這個站點對應獨立的域名(也可能是IP或埠),具有獨立的程式及資源目錄,可以獨立地對外提供服務供使用者訪問。
在Nginx中則使用一個server{} 標籤來標識一個虛擬主機,一個Web服務裡可以有多個虛擬主機標籤對。
虛擬主機型別
```js
1)基於域名的虛擬主機
通過不同的域名區分不同的虛擬主機
應用:外部網站
2)基於埠的虛擬主機
通過不同的埠區分不同的虛擬主機
應用:公司內部網站,網站的後臺
3)基於IP的虛擬主機
通過不同的IP區分不同的虛擬主機
應用:幾乎不用
```
## 1.1、基於域名的虛擬主機
域名1:www.hhjy.com
域名2:bbs.hhjy.org
1.修改nginx配置檔案,建立兩個虛擬主機
```bash
$ cat /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
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 on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
server {
listen 80; # 監聽埠
server_name www.hhjy.com; # 域名:www.hhjy.com
location / { # 匹配url請求為根目錄
root /data/www; # 匹配到url請求後會在該站點目錄下查詢對應的檔案
index index.html index.htm; # 預設主頁檔名
}
}
server {
listen 80;
server_name bbs.hhjy.com; # 域名:bbs.hhjy.com
location / {
root /data/bbs;
index index.html index.htm;
}
}
}
```
2.為各自站點建立目錄,並各自建立index.html
```bash
$ mkdir -p /data/{www,bbs}
$ echo "domain from in www" >/data/www/index.html
$ echo "domain from in bbs" >/data/bbs/index.html
```
3.校驗nginx配置檔案語法並平滑重啟
```bash
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ nginx -s reload
```
4.客戶端新增hosts(因為域名只在測試環境使用,並沒有備案,那就直接修改hosts檔案)
```bash
$ vim /etc/hosts
10.4.7.7 www.hhjy.com bbs.hhjy.com
```
5.訪問兩個虛擬主機/域名
```bash
$ curl www.hhjy.com
domain from in www
$ curl bbs.hhjy.com
domain from in bbs
```
注意事項:
1、當伺服器存在多個虛擬主機,客戶端用IP地址訪問網站的時候,因為HTTP請求頭沒有攜帶host欄位,所以伺服器只會用nginx.conf中的第一個server的location迴應
2、當伺服器存在多個虛擬主機,客戶端用域名訪問網站的時候,因為HTTP請求頭有攜帶host欄位,所以伺服器會根據host裡的域名查詢nginx.conf中對應的location迴應
## 1.2、基於埠的虛擬主機
域名:www.hhjy.com ,埠:81
域名:bbs.hhjy.com ,埠:82
1.修改nginx配置檔案,新增基於埠虛擬主機配置
```bash
$ cat /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
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 on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
server {
listen 81;
server_name www.hhjy.com;
location / {
root /data/www;
index index.html index.htm;
}
}
server {
listen 82;
server_name bbs.hhjy.com;
location / {
root /data/bbs;
index index.html index.htm;
}
}
}
```
2.修改各站點目錄下index.html的內容
```bash
$ echo "port from in www" >/data/www/index.html
$ echo "port from in bbs" >/data/bbs/index.html
```
3.校驗nginx配置檔案語法並平滑重啟
```bash
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ nginx -s reload
```
4.檢查nginx埠發現多了81、82埠
```bash
$ netstat -lntup | grep -E "81|82"
tcp 0 0 0.0.0.0:81 0.0.0.0:* LISTEN 1573/nginx: master
tcp 0 0 0.0.0.0:82 0.0.0.0:* LISTEN 1573/nginx: master
```
5.訪問nginx,以不同埠方式訪問(前面已經做hosts域名繫結IP)
```bash
$ curl www.hhjy.com:81
port from in www
$ curl bbs.hhjy.com:82
port from in bbs
```
## 1.3、基於IP的虛擬主機
我們在上面都是使用域名或者域名+埠方式訪問,但是它們都是指向監聽一個IP地址,下面我們讓nginx監聽多個IP來實現虛擬主機
1.修改nginx配置檔案,新增基於埠虛擬主機配置
```bash
$ cat /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
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 on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
server {
listen 10.4.7.101:80;
server_name www.hhjy.com;
location / {
root /data/www;
index index.html index.htm;
}
}
server {
listen 10.4.7.102:80;
server_name bbs.hhjy.com;
location / {
root /data/bbs;
index index.html index.htm;
}
}
}
```
2.修改各站點目錄下index.html的內容
```bash
$ echo "ip from in www" >/data/www/index.html
$ echo "ip from in bbs" >/data/bbs/index.html
```
3.配置兩個輔助IP 10.4.7.101和10.4.7.102
```bash
$ ip addr add 10.4.7.101/24 dev eth0 label eth0:1
$ ip addr add 10.4.7.102/24 dev eth0 label eth0:2
// 檢查是否配置成功
$ ip add | grep -E "101|102"
inet 10.4.7.101/24 scope global secondary eth0:1
inet 10.4.7.102/24 scope global secondary eth0:2
```
4.先停止nginx(reload可能會不生效),在啟動
```bash
$ nginx -s stop
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ nginx
```
>提示:nginx服務中只要涉及到IP地址的修改,都需要重啟nginx服務,而不能採用平滑重啟
5.訪問nginx,以不同IP方式訪問
```bash
$ curl 10.4.7.101
ip from in www
$ curl 10.4.7.102
ip from in bbs
```
# 2、Nginx include
有時候,虛擬主機配置特別多,總不可能把所有配置都塞到nginx主配置檔案中,而是將每個虛擬主機放到一個nginx配置檔案中,然後統一存放在一個目錄下,但是nginx主程序如何載入這些目錄下的nginx配置檔案,這就要用到`include`引數,只需要指定某個目錄下的*即可,使用方法如下:
直接在nginx主配置檔案下`http區塊`中使用:
```bash
include 檔案目錄/*; # 匹配所有檔案
include 檔案目錄/*.conf; # 匹配以.conf結尾的檔案
include 檔案目錄/*.proxy; # 匹配以.proxy結尾的檔案
```
> 現在版本的nginx的主配置檔案都預設添加了include /etc/nginx/conf.d/*.conf; 引數
# 3、Nginx 日誌配置
## 3.1、訪問日誌
Nginx會把每個訪問到虛擬主機的使用者資訊記錄到指定的日誌檔案中,供運維/開發分析使用者瀏覽行為、流量等
>此功能由ngx_http_log_module模組負責
**訪問日誌引數(http/server區塊):**
```js
log_format # 用來定義記錄日誌的格式(可以定義多種日誌格式,取不同名字即可)
access_log # 用來制定日誌檔案的路徑及使用的何種日誌格式記錄日誌
```
**Nginx訪問日誌預設格式配置如下:**
```js
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
```
其實訪問日誌記錄格式就是從http請求頭部獲取到指定變數名的值而已
**Nginx訪問日誌格式引用配置如下:**
```js
access_log /var/log/nginx/access.log main;
```
**Nginx 日誌變數說明:**
```js
$remote_addr:記錄訪問網站的客戶端源地址資訊
$remote_user:訪問客戶端認證使用者資訊
$time_local:記錄訪問時間與時區
$request:使用者的http請求行資訊
$status:http狀態碼,記錄請求返回的狀態碼,例如:200、301、404等
$http_referer:記錄此次請求是從哪個連線訪問過來的,可以根據該引數進行防盜鏈設定。
$body_bytes_sent:伺服器傳送給客戶端的響應body位元組數
$http_user_agent:記錄客戶端訪問資訊,例如:瀏覽器、手機客戶端等
$http_x_forwarded_for:當前端有代理伺服器時,設定web節點記錄客戶端地址的配置,此引數生效的前提是代理伺服器也要進行相關的x_forwarded_for設定
```
## 3.2、錯誤日誌
Nginx會將自身執行時的故障資訊以及使用者訪問時產生的錯誤資訊都記錄到指定日誌檔案裡,配置記錄nginx錯誤日誌資訊是除錯nginx的重要手段,屬於核心功能模組`http_core_module`的引數,該引數名為`error_log`,可以放在Main區塊中全域性配置,也可以放置在`Server`區塊中單獨記錄虛擬主機的錯誤資訊。
**nginx錯誤日誌記錄級別:**
```js
日誌記錄級別:debug, info, notice, warn, error, crit
```
**Nginx錯誤日誌定義語法:**
``` js
Syntax: error_log file [level];
Default: error_log /var/log/nginx/error.log warn;
Context: main, http, mail, stream, server, location
```
關鍵字不能變,日誌檔案可以指定任意存放日誌的目錄,錯誤日誌級別越高記錄的資訊越少,一般只記錄error,不要配置info等較低的級別,會帶來巨大磁碟I/O消耗。
## 3.3、日誌輪訓切割
如果不對日誌進行切割,那麼當訪問量大和時間久了之後會發現一個日誌檔案會超過100M,那麼大量的日誌資訊儲存在一個日誌檔案裡,也不方便查詢,就需要每天將日誌進行切割,切割的日誌檔案以日期為命名。
1.編寫指令碼檔案,為訪問/錯誤日誌做輪訓切割
```bash
$ cat /server/scripts/cut_nginx_log.sh
#!/bin/bash
LogPath="/var/log"
AccessLogFile="${LogPath}/nginx/access.log"
ErrorLogFile="${LogPath}/nginx/error.log"
NginxCmd=$(which nginx)
if [ ! ${NginxCmd} ];then
echo "nginx 命令不存在,退出日誌切割..."
exit 1
fi
/bin/mv ${AccessLogFile} ${LogPath}/nginx/access_$(date +%F -d '-1day').log
/bin/mv ${ErrorLogFile} ${LogPath}/nginx/error_$(date +%F -d '-1day').log
${NginxCmd} -s reload
```
2.執行指令碼
```bash
$ sh /server/scripts/cut_nginx_log.sh
```
3.檢視日誌切割效果
```bash
$ ls -lh /var/log/nginx/
total 8.0K
-rw-r--r-- 1 root root 0 Mar 13 22:59 access_2020-03-12.log
-rw-r--r-- 1 root root 0 Mar 13 23:00 access.log
-rw-r--r-- 1 root root 63 Mar 13 22:59 error_2020-03-12.log
-rw-r--r-- 1 root root 63 Mar 13 23:00 error.log
```
4.將日誌切割指令碼新增到定時任務,每天凌晨執行
```bash
// 給指令碼賦予可執行許可權
$ chmod +x /server/scripts/cut_nginx_log.sh
// 新增定時任務
$ crontab -e
### Cut Nginx access and error logs at 00:00 each day
00 00 * * * /bin/sh /server/scripts/cut_nginx_log.sh >/dev/null 2>&1
```
# 4、Nginx Location
> Location在前面的文章裡我們已經接觸到了,那麼它到底是幹啥的?
`Location`的作用是可以根據使用者請求的URI來執行不同的應用(URI=URL),location支援很多語法,這些語法可以認為是正則匹配,根據使用者訪問的URI來匹配到對應的location正則
**location語法:**
```js
location[=|~|~*|^~|@]uri {
...
}
// 語法解釋:
location # 關鍵字
[=|~|~*|^~|@] # 正則匹配規則
uri # 匹配的URI路徑
{...} # 匹配URI後要執行的配置段
```
**location正則匹配:**
```js
= # 精確匹配網站url資源資訊
~ # 區分大小寫匹配網站url資源資訊
~* # 不區分大小寫匹配網站url資源資訊
/mp3/ # 指定匹配網站資源目錄資訊
/ # 預設匹配網站資源資訊
! # 對匹配的內容進行取反
^~ # 普通字元匹配,使用字首匹配
// 正則優先順序
優先順序1:=
優先順序2:^~
優先順序3:~
優先順序3:~*
```
官方的location舉例:**
```js
location = / {
[ configuration A ] # 優先順序最高①
}
location / {
[ configuration B ] # 所有匹配都不滿足時候,匹配預設location ④
}
location /documents/ { # 根據資源目錄進行匹配 ③
[ configuration C ]
}
location ^~ /images/ { # 優先匹配②
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ { # 不區分大小寫匹配網站資源 ③
[ configuration E ]
}
```
# 5、Nginx 下載站點
Nginx預設是不允許列出整個目錄瀏覽下載,通過`autoindex`關鍵字可實現目錄瀏覽下載
**autoindex語法:**
```js
Syntax: autoindex on | off; Default:
autoindex off; Context: http, server, location
// autoindex常⽤引數
autoindex_exact_size off;
預設為on, 顯示出⽂件的確切⼤⼩,單位是bytes。
修改為off,顯示出⽂件的⼤概⼤⼩,單位是kB或者MB或者GB。
autoindex_localtime on;
預設為off,顯示的⽂件時間為GMT時間。
修改為on, 顯示的⽂件時間為⽂件的伺服器時間。
charset utf-8,gbk;
預設中⽂⽬錄亂碼,新增上解決亂碼。
```
**配置目錄瀏覽功能**
1.新增nginx配置,開啟目錄瀏覽
```bash
$ vim /etc/nginx/conf.d/web_dir.conf
server {
listen 80;
server_name download.hhjy.org;
location / {
root /data/file;
autoindex on;
autoindex_localtime on;
autoindex_exact_size off;
}
}
```
2.建立站點目錄,並新建幾個測試檔案
```bash
$ mkdir /data/file
$ touch /data/file/t1.txt
$ touch /data/file/t2.txt
```
3.平滑重啟nginx
```bash
$ nginx -s reload
```
4.客戶端修改hosts檔案,繫結域名對應的nginx伺服器ip
```bash
$ vim /etc/hosts
10.4.7.7 download.hhjy.org
```
5.瀏覽器訪問:download.hhjy.org
![](https://img2020.cnblogs.com/blog/1679739/202003/1679739-20200313231844119-1289339447.png)
# 6、Nginx 使用者登入認證
很多時候我們登入內部網站不想做太複雜的使用者登入認證,那麼可以使用Nginx自帶的認證,基於`auth_basic`關鍵字來實現`basic auth`。
**auth_basic語法:**
```js
// 配置語法
Syntax: auth_basic string| off;
Default: auth_basic off;
Context: http, server, location, limit_except
// ⽤戶密碼記錄配置⽂件
Syntax: auth_basic_user_file file;
Default:
Context: http, server, location, limit_except
```
**basic認證實現:**
1.安裝`httpd-tools`工具
```bash
$ yum install httpd-tools
// 使用該工具下的htpasswd命令建立使用者名稱和密碼
$ htpasswd -bc /etc/nginx/conf.d/auth_conf admin 123456
Adding password for user admin
```
2.新增nginx配置,配置auth
```bash
$ vim /etc/nginx/conf.d/basic_auth.conf
server {
listen 80;
server_name auth.hhjy.org;
location / {
auth_basic "Auth access Input your Passwd!";
auth_basic_user_file /etc/nginx/conf.d/auth_conf;
}
}
```
3.平滑重啟nginx
```bash
$ nginx -s reload
```
4.客戶端修改hosts檔案,繫結域名對應的nginx伺服器ip
```bash
$ vim /etc/hosts
10.4.7.7 auth.hhjy.org
```
5.瀏覽器訪問:auth.hhjy.org,輸入設定好的使用者名稱和密碼即可訪問
![](https://img2020.cnblogs.com/blog/1679739/202003/1679739-20200313232750543-18004458