背景

原来申请的正式域名备案通过,TLS证书也申请了。之前使用的临时域名和证书作为测试环境使用。于是要在单个ECS主机上配置nginx多个证书和多个域名。

实践

nginx部署多个TLS证书很简单,在不同的virtual host分别配置证书就搞定了。比如我有a.comb.com两个域名,在nginx.conf分别配置2个server就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 443 ssl http2;
server_tokens off;
server_name a.com; ssl_certificate cert/a.com.pem; #将domain name.pem替换成您证书的文件名。
ssl_certificate_key cert/a.com.key; #将domain name.key替换成您证书的密钥文件名。 # more config
} server {
listen 443 ssl http2;
server_tokens off;
server_name b.com; ssl_certificate cert/b.com.pem; #将domain name.pem替换成您证书的文件名。
ssl_certificate_key cert/b.com.key; #将domain name.key替换成您证书的密钥文件名。 # more config
}

ps. 推荐一个nginx conf配置在线美化工具:Nginx Beautifier

问题再深入

在一个主机(IP)上配置多个域名,使用虚拟主机(virtual host)就可以解决了。但是申请TLS证书的时候,是绑定了具体的域名和IP地址。建立TLS连接的时候,服务器要下发哪个证书呢?
等等,证书明明和域名绑定,都知道了域名,为什么会有选择选择证书的问题?
那是因为,域名是http的概念。client和server先建立了tcp连接,再经过TLS握手,才能实现https通信。在最初,这个过程,是没有域名的概念的!
为了解决当个主机部署多个TLS证书的问题,带来了TLS的SNI扩展。

(图片来源:https://blogs.akamai.com/2017/03/reaching-toward-universal-tls-sni.html

SNI介绍

摘自wiki,”服务器名称指示”

服务器名称指示(英语:Server Name Indication,缩写:SNI)是TLS的一个扩展协议,在该协议下,在握手过程开始时客户端告诉它正在连接的服务器要连接的主机名称。这允许服务器在相同的IP地址和TCP端口号上呈现多个证书,并且因此允许在相同的IP地址上提供多个安全(HTTPS)网站(或其他任何基于TLS的服务),而不需要所有这些站点使用相同的证书。

TLS SNI在client hello握手阶段,增加了一个扩展字段,表明想要和哪个域名建立TLS连接(注意是明文)。服务器根据SNI,选择证书并且下发。以下是TLS v1.2握手抓包

这个扩展字段,OpenSSL 0.9.8 版本开始支持。现代的浏览器和服务器都支持了。

TLS v1.2的SNI是明文传输,这就可以被第三方直接截获,暴露了域名,甚至阻止建立https连接(等等,有人在敲门,我先收个快递)。。。这就是censorship问题了。

TLS ESNI扩展

TLS v1.2的SNI是明文传输引发安全隐患,那么加密不就可以了吗?不行,因为TLS连接还没有建立。这就是先有鸡还是先有蛋的问题。
google、amazon、microsoft等大厂想出一个办法,既然SNI是明文,我就传输无公害的host,比如他们自家的域名,等tls连接建立之后,再把真实域名传输过去。
这就是TLS ESNI扩展,使用的技术叫域前置(英语:Domain fronting)。

如果要censorship,那么就要一刀切都关闭!
怎么样,是不是很狂拽酷炫吊炸天!不过,理想很丰满,现实很骨感。截至目前,Google、Amazon都由于不可描述的原因,关闭了此项服务。

在此只聊聊技术上的问题。
即使有了TLS v1.3 ESNI,在建立连接后返回真实域名,但是传统的DNS查询是明文的!解决方式就是加密DNS,DNS over TLS (DoT) and DNS over HTTPS (DoH)。具体以后再研究。

小结

  • 单个主机上nginx多个证书的配置,在不同的server上配置ssl_certificatessl_certificate_key即可。
  • 背后的原理涉及到TLS的SNI扩展。
  • TLS v1.2的SNI扩展字段是明文的,并且由于在client hello阶段传输,会被第三方直接获取,带来安全隐患。
  • TLS v1.3引入ESNI扩展,技术上叫domian fronting,使用安全的host建立TLS连接,之后再传输目标域名。结合加密DNS,实现安全通信。

参考资料

### 本文作者ycwu314,转载请注明出处 https://ycwu314.github.io/p/https-sni-nginx-config/ ###

nginx配置多个TLS证书,以及TLS SNI简介的更多相关文章

  1. Linux下Nginx配置阿里云 SSL证书实现HTTPS访问

    这篇文章主要介绍了nginx配置ssl证书实现https访问的示例 1.服务器系统:Centos 2. 阿里云申请SSL证书 选择“免费版DV SSL”,点击立即购买: 下载证书 列表中找到已签发的证 ...

  2. Nginx 配置 HTTPS自签名证书

    工具: OpenSSL ssl的开源实现,几乎实现了市面上所有的加密 libcrypto: 通用加密库, 任何软件要实现加密功能 链接调用这个库 libssl: TLS/SSL 加密库 openssl ...

  3. nginx 配置本地https(免费证书)

    Linux系统下生成证书 生成秘钥key,运行: $ openssl genrsa -des3 -out server.key 20481会有两次要求输入密码,输入同一个即可 输入密码 然后你就获得了 ...

  4. Nginx配置SSL自签名证书

    生成自签名SSL证书 生成RSA密钥(过程需要设置一个密码,记住这个密码) $ openssl genrsa -des3 -out domain.key 1024 拷贝一个不需要输入密码的密钥文件 $ ...

  5. apache、nginx配置openssl自签名证书

    1.生成私钥 生成rsa私钥,des3算法,2048位强度.server.key是秘钥文件名,需要提供一个至少4位的密码. [root@localhost ~]# openssl genrsa -de ...

  6. Linux中Nginx中添加自签证书TLS

    创建自签证书TLS openssl req \ -newkey rsa: \ -x509 \ -nodes \ -keyout test.com.key \ -new \ -out test.com. ...

  7. 使用vault pki 为nginx 生成tls 证书文件

    关于vault pki 管理的使用的可以参考官方文档或者docker-vault 以下演示一个简单的基于vault pki 为nginx 提供tls 证书 项目环境配置 nginx 配置文件   wo ...

  8. [Apple开发者帐户帮助]六、配置应用服务(5.2)推送通知(APN):使用TLS证书与APN通信

    您的通知服务器可以使用TLS证书与Apple推送通知服务(APN)通信. 首先在开发者帐户中启用推送通知.接下来生成适用于开发和生产环境的APNs客户端TLS证书.然后从Mac导出客户端TLS标识并将 ...

  9. [nginx][tls] nginx配置https与ssl/tls的sni的方法

    一 https的sni配置方法 http {       }       server {               listen 443 ssl;               server_nam ...

随机推荐

  1. (day44)css样式、css布局

    目录 一.css样式 (一)文字样式 (1)文字字体font-family (2)字体大小font-size (3)字体粗细font-weight (4)字体颜色color (二)文本样式 (1)文字 ...

  2. js常用方法总结(以后遇到再进一步总结)

    1.index()    返回指定元素相对于其他指定元素的 index 位置. <h1>店铺评价</h1> <div class="star starcd&qu ...

  3. openlayers绘制点,线,圆等

    由于我的业务需求是可以在底图上进行一些操作,比如绘制电子围栏等功能,于是需要使用openlayers中的画笔功能,接下来开始一波操作 还是上一篇的html页面, 直接上代码 <!doctype ...

  4. Apex 小知识:SOQL 在循环中的应用

    两种在循环中引用 SOQL 的方法 第一种方法: List<Account> accounts = [SELECT Id FROM Account WHERE NumberOfEmploy ...

  5. 调试经验分享-让自己的电脑充当WI-Fi模块,用来抓取连接Wi-Fi模块APP上的通信数据

    需求 手头有了厂家的APP和Wi-Fi模块 在已经知道APP是通过TCP连接Wi-Fi模块(8266), 同时也知道了连接的端口号的 情况下如何知道厂家的APP发送给Wi-Fi模块的数据 打开自己的笔 ...

  6. 【转】web.xml详解

    转载:https://www.cnblogs.com/vanl/p/5737656.html. 一:web.xml加载过程 简单说一下,web.xml的加载过程.当我们启动一个WEB项目容器时,容器包 ...

  7. [LeetCode] 29. Divide Two Integers 两数相除

    Given two integers dividend and divisor, divide two integers without using multiplication, division ...

  8. .Net Core 基于CAP框架的事件总线

    .Net Core 基于CAP框架的事件总线 CAP 是一个在分布式系统中(SOA,MicroService)实现事件总线及最终一致性(分布式事务)的一个开源的 C# 库,她具有轻量级,高性能,易使用 ...

  9. JAVA基础系列:Arrays.binarySearch二分查找

    首先,binarySearch方法为二分法查找,所以数组必须是有序的或者是用sort()方法排序之后的 1)  binarySearch(Object[] a, Object key) a: 要搜索的 ...

  10. springcloud(七,多个服务消费者配置,以及zuul网关案例)

    spring cloud (一.服务注册demo_eureka) spring cloud (二.服务注册安全demo_eureka) spring cloud (三.服务提供者demo_provid ...