tomcat白名单(五)其他

0 跟我想法一致

https://www.coder.work/article/2852937

我想从 TLS Client Hello Message 中找到主机名。我想在 java 为透明 ssl 代理完成握手之前找到主机名。 

有没有什么方法可以在不编写整个 ssl 握手 逻辑的情况下找到 SNI 扩展 值?

Java 是否支持带有初始内存缓冲区的ssl 握手? 我的想法是:

  1. 读取 TLS 客户端问候消息,解析并找到 SNI 值
  2. 调用 sslSocket.startHandshake(initialBuffer) 初始缓冲区将包含 TLS 客户端 hello 数据包数据。所以 Java 可以进行握手。

第二个想法是使用SSLEngine 类。但它似乎比要求更多的实现。我假设 SSLEngine在我不需要它的情况下大部分用于异步。

第三个想法是实现完整的TLS协议(protocol)

哪个想法更好?

 

 

1 JSSE

ava安全套接字扩展(Java Secure Socket Extension,JSSE)为基于SSL和TLS协议地Java网络应用程序提供了API及参考实现。使用JSSE,能够保证采用各种应用层协议(比如HTTP、FTP等)地客户程序与服务器程序安全地交换数据。

https://blog.csdn.net/weixin_44641388/article/details/117399609

安全网络通信(SSL&JSSE)

非常全的文章,对JSSE如何实现SSL

 

2 http://www.uml.org.cn/j2ee/201409013.asp

Netty系列之Netty安全性(二)

有些SslHandler源码分析

 

3 SNi

3.1 SNI问题

https://www.jianshu.com/p/78576039b1e2

非常好的文章,对几个客户端支持SNI的情况有详细描述

SNI(Server Name Indication)是 TLS 的扩展,用来解决一个服务器拥有多个域名的情况
有点像7层的nginx根据host头转发,只不过它在4层
在 TLS 握手信息中并没有携带客户端要访问的目标地址。这样会导致一个问题,如果一台服务器有多个虚拟主机,且每个主机的域名不一样,使用了不一样的证书,该和哪台虚拟主机进行通信?这也就解释了为什么SLB需要SNI,我这里可以改为为什么Openshift/HAProxy需要SNI,因为它根据host来决定分发到哪个pod

需要注意:

  1. 有 host 参数的都会在创建 Socket 的时候自动连接 host
  2. 只有直接以 String 传递 host 的方式才会在握手中使用 SNI,以 InetAddress 传递 host 的方式握手时都不会带着 SNI

据说 JDK 不允许传递 InetAddress 的 createSocket 创建出来的 SSLSocket 在 SSL 握手时自动使用 SNI,是因为 InetAddress 构造的时候支持 getByName 函数,该函数可以传个 IP 而不是 Host


3.2
cxf客户端中的java SNI配置(3.1.2)
https://www.cnpython.com/java/876007
SSLConnectionSocketFactory

3.3 https://qa.1r1g.com/sf/ask/2008203851/
如何在JDK 1.7.x中的SSL握手(SNI)中设置主机名

JDK 1.8似乎提供以下选项来显式设置Hostname以连接到启用SNI的站点,

    SNIHostName serverName = new SNIHostName("www.example.com");
    List<SNIServerName> serverNames = new ArrayList<>(1);
    serverNames.add(serverName);
    sslParameters.setServerNames(serverNames);

 

3.4 https://blog.csdn.net/weixin_44388689/article/details/131171346

# determined by the next backend in the chain which may be an app backend (passthrough termination) or a backend
# that terminates encryption in this router (edge)
frontend public_ssl

bind :443
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }

# if the connection is SNI and the route is a passthrough don't use the termination backend, just use the tcp backend
# for the SNI case, we also need to compare it in case-insensitive mode (by converting it to lowercase) as RFC 4343 says
acl sni req.ssl_sni -m found
acl sni_passthrough req.ssl_sni,lower,map_reg(/var/lib/haproxy/conf/os_sni_passthrough.map) -m found
use_backend %[req.ssl_sni,lower,map_reg(/var/lib/haproxy/conf/os_tcp_be.map)] if sni sni_passthrough

# if the route is SNI and NOT passthrough enter the termination flow
use_backend be_sni if sni

# non SNI requests should enter a default termination backend rather than the custom cert SNI backend since it
# will not be able to match a cert to an SNI host
default_backend be_no_sni
————————————————HA如此重视SNI,肯定不让你乱搞,注定了方案二的流产

https://www.haproxy.com/blog/enhanced-ssl-load-balancing-with-server-name-indication-sni-tls-extension

当 haproxy 接收到 HTTPS (443 端口)请求,会检查 HTTPS 请求支持 sni (TLS Server Name Indication)

这边的处理对应了 Router 对 HTTPS 流量的终结方式:

edge HTTPS 流量将在 Router 中解密并以纯 HTTP 转发至后端 Pod
passthrough TLS 加密包直接递交给后端 Pod,Router 不做任何 TLS 终结,不需要 TLS 相关证书
re-encryption 是 edge 的变种,HTTPS 流量将在 Router 中解密后再使用其他证书加密后转发至后端 Pod
也就是 route API 中的 termination 字段。

 

 

3.5

3.5.1 【HAPROXY】四层TCP转发及SNI Proxy简记

https://luotianyi.vc/6818.html

SNI转发是在TCP转发的基础上识别SNI并将流量以四层转发的形式送往源站,好处就是作为中间节点可以直接转发任意站点的流量而不涉及SSL证书的部署简而言之,不用跟客户端握手,直接转发tcp流量,本质就是SLB侵入SSL协议ClientHello,跟我们干的事情差不多

所以SNI在我看来两个作用:

1)一个服务器多个域名多个证书,服务器通过SNI来决定用那个证书

2)正向代理4层转发,用于Openshift/HAProxy

 

3.5.2 haproxy配置sni实现https多域名代理

https://blog.csdn.net/yanggd1987/article/details/80737612

从上面的tcp代理处,我们可以看到通过sni区分不同的域名从而选择后端的服务器。 
另在http代理处,我们可以看到也使用host区分域名实现不同的后端转发

一个4层 1个7层

 

4 总结:

透明 ssl 代理完成握手之前找到主机名

这也就解释了为什么SLB需要SNI,我这里可以改为为什么Openshift/HAProxy需要SNI,因为它根据host来决定分发到哪个pod

有点像7层的nginx根据host头转发,只不过它在4层
在 TLS 握手信息中并没有携带客户端要访问的目标地址

作为中间节点可以直接转发任意站点的流量而不涉及SSL证书的部署。简而言之,不用跟客户端握手,直接转发tcp流量,本质就是SLB侵入SSL协议ClientHello,跟我们干的事情差不多

所以SNI在我看来两个作用:

1)一个服务器多个域名多个证书,服务器通过SNI来决定用那个证书

2)正向代理4层转发,用于Openshift/HAProxy

从上面的tcp代理处,我们可以看到通过sni区分不同的域名从而选择后端的服务器。 
另在http代理处,我们可以看到也使用host区分域名实现不同的后端转发。

posted on 2023-10-18 21:22  silyvin  阅读(44)  评论(0编辑  收藏  举报