當前位置: 妍妍網 > 碼農

Nginx同一個IP上多個網域名稱配置安裝SSL證書

2024-03-20碼農

0x01 前言

在同一台伺服器上配置多個帶有SSL證書的HTTPS網站時,每個網站確實需要使用不同的埠號,以避免沖突。這是因為SSL/TLS協定通常是在特定的埠上執行的,預設情況下是443埠。

當您嘗試在相同的埠上配置多個HTTPS網站時,伺服器將不知道如何區分傳入的請求應該路由到哪個網站。每個HTTPS請求都包含主機名資訊(即網站網域名稱),但這部份資訊是在SSL/TLS握手之後才被解析的。在握手過程中,伺服器需要根據客戶端提供的證書資訊來確定使用哪個SSL證書進行加密通訊。如果多個網站使用相同的埠,伺服器將無法確定在握手過程中應該使用哪個證書。

因此,為了在同一台伺服器上執行多個HTTPS網站,您需要為每個網站分配不同的埠號。這樣,當客戶端嘗試連線到伺服器時,它們可以透過指定不同的埠號來存取不同的網站。當然,使用非預設埠號可能會增加一些配置和管理的復雜性,但這是實作多個HTTPS網站在同一台伺服器上執行的必要步驟。

0x02 解決方案

Nginx支持TLS協定的SNI擴充套件,這使得它可以在同一個IP地址和埠上,使用不同的SSL證書為不同的網域名稱提供服務。SNI擴充套件在客戶端的TLS握手過程中發送,允許伺服器知道客戶端正在嘗試連線的網域名稱,從而能夠選擇正確的SSL證書。

關於SNI的支持,它確實需要客戶端和伺服器端的支持。客戶端(例如瀏覽器或其他TLS客戶端)必須在TLS握手過程中發送SNI資訊。在伺服器端,Nginx依賴於OpenSSL庫來提供SNI的支持。因此,如果Nginx在編譯時連結的OpenSSL庫支持SNI,那麽Nginx就能夠使用SNI。

編譯Nginx時,SNI的支持是由OpenSSL庫決定的。具體來說,Nginx會檢查OpenSSL的 ssl.h 表頭檔中的宏定義和函式原型,來確定是否支持SNI。如果編譯時使用的OpenSSL庫支持SNI(即SSL_CTRL_SET_TLSEXT_HOSTNAME可用),那麽Nginx在執行時就會啟用SNI功能。

在實際部署中,只要確保伺服器上的OpenSSL庫支持SNI,並且Nginx是在連結了支持SNI的OpenSSL庫的情況下編譯的,那麽SNI就可以正常工作。這通常意味著在大多數現代系統上,只要安裝了最新版本的OpenSSL,並且Nginx是用這個版本的OpenSSL編譯的,SNI就應該能夠正常工作。

編譯

註意:Nginx在預設情況下是 TLS SNI support disabled 。重新編輯,添加配置: --with-openssl-opt="enable-tlsext"

./configure --prefix=/usr/local/openresty --with-luajit \
--with-http_ssl_module --with-openssl=/usr/local/openssl \
--with-openssl-opt="enable-tlsext" --without-http_redis2_module \
--with-http_iconv_module --with-http_stub_status_module \
--with-http_xslt_module --add-dynamic-module=/home/www/DEMO/nginx-ts-module \
--add-dynamic-module=/home/www/DEMO/nginx-rtmp-module
...
make
sudo make install

配置

網域名稱列表

序號 名稱 網域名稱 HTTPS 主機
1 官方網域名稱 www.tinywan.com https://www.tinywan.com
2 直播網域名稱 live.tinywan.com https://live.tinywan.com
3 點播網域名稱 vod.tinywan.com https://vod.tinywan.com

main.conf

# 配置HTTP請求重新導向
server {
listen 80;
server_name www.tinywan.com; 
rewrite ^ https://$http_host$request_uri? permanent;
}

www.conf

server {
listen 443 ssl;
server_name www.tinywan.com;
root /home/www/web/www.tinywan.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/www.tinywan.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.tinywan.com//privkey.pem;
server_tokens off;
}

live.conf

# live.tinywan.com
server{
listen 443 ssl;
server_name live.tinywan.com;
root /home/www/web/live.tinywan.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/www.tinywan.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.tinywan.com//privkey.pem;
server_tokens off;
}

vod.conf

# vod.tinywan.com
server{
listen 443 ssl;
server_name vod.tinywan.com;
root /home/www/web/vod.tinywan.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/www.tinywan.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.tinywan.com//privkey.pem;
server_tokens off;
}