1. 程式人生 > >Nginx 配置 HTTP 和 HTTPS

Nginx 配置 HTTP 和 HTTPS

AI one 當前 som include 控制 AC remote 新的

Nginx 的配置文件 nginx.conf 中有一些頂級指令(即上下文)用來分組適用於不同流量類型的指令:

  • events,通用的連接處理。
  • http,HTTP 流量。
  • mail,Mail 流量。
  • stream,TCP 流量。

放置在這些上下文之外的指令(directives)被認為是放置在主上下文(main context)中。在每個流量處理上下文中,可以放置一個或多個 server 上下文來定義用於控制請求處理的虛擬服務器(virtual servers)。

在 http 上下文中,每個 server 上下文負責對一個特定域名或 IP 地址的資源的請求進行處理,server 上下中的一個或多個 location 上下文用來定義如何處理特定的 URI 集合。

對於 mail 和 stream 上下文,每個 server 上下文負責對特定 TCP 端口或 UNIX 套接字上的流量進行處理。

nginx.conf 配置文件的一個大致框架如下所示:

user nobody; # 位於主上下文的指令

events {
    # 連接處理的配置
}

http {
    # 對 HTTP 請求的配置,會影響所有的虛擬服務器

    server {
        # 對第一臺 HTTP 虛擬服務器的配置

        location /one {
            # 配置該如何處理以 /one 開始的 URI
        }
    }
}

stream {
    # 對 TCP 請求的配置,會影響所有的虛擬服務器

    server {
        # 對第一臺 TCP 虛擬服務器的配置
    }
}

基本配置

在 nginx.conf 文件中的配置可分為三個部分:配置主上下文、配置 events 上下文和配置 http 上下文。

主上下文的配置是全局設置,具體配置如下:

user nginx nginx;
worker_processes 2;
error_log /var/log/nginx/error.log  notice;
worker_rlimit_nofile 1024;
  • user,指定運行 worker process 的用戶和用戶組,默認由 nginx 用戶運行。
  • worker_processes,指定 Nginx 開啟的子進程(worker process)數量。
  • error_log,指定全局錯誤日誌文件。

    根據包含的日誌信息詳細度遞減,分別 debug、info、notice、warn、error 和 crit 級別可供選擇。

  • worker_rlimit_nofile,指定一個 Nginx 進程最多可打開的文件描述符數量。

    Linux 中可打開的文件描述符數量通過 ulimit -n 1024 命令來設置。

events 上下文用來指定 Nginx 的工作模式以及連接上限,具體配置如下:

events {
    use epoll;
    worker_connections 1024;
}
  • use,指定 Nginx 的工作模式。

    Nginx 支持的工作模式有 select、poll、kqueue、epoll、rtsig 和 /dev/poll。

    其中 select 和 poll 是標準工作模式,kqueue 和 epoll 是高效工作模式。

    epoll 用於 Linux 平臺上,而 kqueue 則用於 BSD 系統。

  • worker_connections,指定 Nginx 中每個進程的最大連接數(即接收客戶端的最大請求數)。

    最大客戶端連接數由 worker_processes 和 worker_connections 共同決定,即 Max_clients = worker_processes*worker_connections。

    進程接受的最大連接數受 Linux 系統進程的最大可打開文件描述符限制,可通過 ulimit 命令來修改。

http 上下文是 Nginx 中最核心的模塊,它負責 HTTP 服務器相關的屬性配置。具體配置如下:

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"‘;
    access_log /var/log/nginx/access.log main;
    
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    keepalive_timeout 10;
    
    server {
        # 配置 HTTP 虛擬服務器
    }
}
  • include,包含 /etc/nginx/mime.type 文件,此文件用於設定文件的 mime 類型以便於 Nginx 識別。
  • default_type,設置默認文件類型為二進制流。

    當文件類型在 mime.type 文件中未指定時默認為二進制流,此時訪問該文件,Nginx 不會解析,而是直接下載。

  • log_format,設置日誌格式以及記錄哪些信息。
  • access_log,此 http 上下文中的全局訪問日誌。

    後面的 main 指定日誌格式,即使用 log_format 中定義的格式。

  • sendfile,開啟高效的文件傳輸模式。

    設置 tcp_nopush 和 tcp_nodelay 為 on 是為防止網絡阻塞。

  • keepalive_timeout,設置客戶端連接保持活動的超時時間。

http 中的 server 上下文用於配置 HTTP 虛擬服務器,具體配置如下:

server {
    listen 80;
    server_name localhost 192.168.0.99 www.hao.com;

    root /www/nginx;
    index index.html index.jsp;
        
    charset utf-8;
    access_log /var/log/nginx/host.access.log  main;
    error_log /var/log/nginx/host.error.log  error;
        
    location / {
        # 配置如何處理特定的 URI 集合
    }
}
  • listen,此虛擬服務器監聽的端口。不同的虛擬服務器可監聽不同的端口。
  • server_name,指定 IP 地址或域名。
  • root,定義此虛擬服務器的根目錄。
  • index,定義此虛擬服務器的默認首頁地址。按序依次訪問定義的文件。
  • charset,設置網頁的默認編碼格式。
  • access_log,此虛擬服務器的訪問日誌。
  • error_log,此虛擬服務器的錯誤日誌。

server 中的 location 上下文用於配置處理特定的 URI 集合,具體配置如下:

location / {
    root /home/nginx;
    index index.html index.jsp;
}
  • location /,匹配訪問路徑為以 / 開始的 URI。
  • root,以 / 開始的 URI 在當前 location 上下文中的根目錄。

    可與 server 上下文中的根目錄相同,也可自定義一個新的根目錄。

  • index,當前 location 上下文中默認的首頁地址。

HTTPS 配置

客戶端通過 HTTPS 可與服務器進行安全的交互,不用擔心消息會被攔截和讀取。HTTPS 證書用來幫助客戶端核實它們連接的服務器的身份。

服務器證書是一個公共實體,它被發送到連接到服務器的每個客戶端。私鑰則是一個安全實體,應該被存儲到一個受訪問限制的文件中,但是它必須對 Nginx 的主進程可讀。

要使 Nginx 提供 HTTPS 功能,第一步是要創建 SSL 證書。首先在 nginx 的安裝目錄下創建一個 ssl 目錄。

mkdir /etc/nginx/ssl

然後在 ssl 目錄中創建 SSL 證書,如下是創建一個有效期 10 年,加密強度為 RSA2048 SSL 密鑰 nginx.key 和 X509 證書文件 nginx.crt。

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout nginx.key -out nginx.crt
  • -x509 指定使用 X.509 證書簽名請求(Certificate Signing Request,CSR)管理。
  • -node 告訴 openssl 在生成證書時忽略密碼環節(此處需要 Nginx 自動讀取此文件,而非是以用戶交互的形式)。
  • -day 指定證書的有效期。
  • -newkey rsa:2048 表示生成一個新證書和一個新的 SSL key(加密強度為 RSA 2048)。
  • -keyout 指定 SSL 輸出文件名。
  • -out 指定生成的證書文件名。

執行上述命令後,會要求填入下述信息。

Generating a 2048 bit RSA private key
.....................................+++
...........+++
writing new private key to ‘/etc/nginx/ssl/nginx.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) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:hao
Organizational Unit Name (eg, section) []:hao
Common Name (eg, your name or your server‘s hostname) []:www.hao.com
Email Address []:[email protected]

SSL 創建完成後,第二部就是配置 Nginx 使用 SSL。首先是配置將 HTTP 請求的重定向到 HTTPS。

server {
    listen 80;
    server_name localhost 192.168.0.99 www.hao.com;

    # HTTPS 配置
    rewrite ^ https://$http_host$request_uri? permanent;
}
  • rewrite,對 URL 進行重寫。

    語法:rewrite 規則 定向路徑 重寫類型;

    規則,匹配目標 URL 的字符串或正則表達式。

    定向路徑,匹配到規則後要定向的路徑。

    $http_host 表示主機地址。

    $request_uri 表示 URI。

    重寫類型,

    last,完成 rewrite 後,瀏覽器地址欄的 URL 不變。

    break,本條規則匹配完成後,終止匹配,不再匹配後面的規則,瀏覽器地址欄的 URL 不變。

    redirect,返回 302 臨時重定向,瀏覽器地址會顯示跳轉後的 URL。

    permanent,返回 301 永久重定向,瀏覽器地址欄會顯示跳轉後的 URL。

然後配置對 HTTPS 請求的處理。

server {
    listen 443 ssl;
    server_name www.hao.com;

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    root /www/nginx/https;
    index index.html index.jsp;
        
    keepalive_timeout 70;
        
    server_tokens off;

    access_log /var/log/nginx/www.hao.com.access.log;
    error_log /var/log/nginx/www.hao.com.error.log;
}
  • listen,監聽 443 端口並使用 ssl 參數。
  • ssl_certificate,指定服務器證書的路徑。
  • ssl_certificate_key,指定私鑰的路徑。
  • ssl_protocols,指定 SSL 協議(Nginx 默認使用)。
  • ssl_ciphers,以 OpenSSL 庫理解的格式指定密碼(Nginx 默認使用)。
  • server_tokens,關閉(顯示)Nginx 版本號。

最後重啟 Nginx 以使用新的配置文件。

service nginx restart

也可配置一個同時處理 HTTP/HTTPS 的服務器,server 上下文中的配置如下:

server {
    listen 80;
    listen 443 ssl;
    server_name 192.168.0.99;

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;

    root /www/nginx;
    index index.html index.jsp;
        
    keepalive_timeout 70;
        
    server_tokens off;

    access_log /var/log/nginx/www.hao.com.access.log;
    error_log /var/log/nginx/www.hao.com.error.log;   
}

HTTPS 服務器優化

SSL 連接會占用更多的更多的 CPU 資源(例如 SSL 握手),因此在多處理器系統上,應多運行幾個工作進程(worker process)。有兩種方法可以減少每個客戶端執行 SSL 握手的操作:

  • 首先使連接 keep-alive,然後通過一個連接發送多個請求。
  • 然後是重用 SSL session 參數,以避免並行和後續連接的 SSL 握手。

Session 存儲在 worker 共享的 SSL session 高速緩存中,並可通過 ssl_session_cache 指令配置。在 http 上下文中對 session 的配置如下所示。

http {
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
}
  • ssl_session_cache,指定 SSL 共享緩存的大小為 10M。
  • ssl_session_timeout,指定 SSL 共享緩存的超時為 10 mins。

Nginx 配置 HTTP 和 HTTPS