当前位置: 欣欣网 > 码农

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;
}