JVM 使用下划线“_"作为 SNI 服务器名称的一部分崩溃 [英] JVM crashes using underline '_' as part of SNI server name
问题描述
我将 Netty 4.1.14.Final
用于我的应用程序框架.我想实现服务器可以在客户端使用 netty-tcnative-boringssl-static
请求时检查 SNI 信息.
I'm using Netty 4.1.14.Final
for my application's framework. I want to implement that the server can check the SNI information when the clients request using netty-tcnative-boringssl-static
.
但是当我将 -servername
指定为 svc.v1
时,我的应用程序崩溃了一次,我收到了这条消息:
But my application crashes once as I specify the -servername
as svc.v1
, and I got this message:
java: ../ssl/handshake_server.c:541: negotiate_version: Assertion `!ssl->s3->have_version' failed.
使用 OpenSSL 命令:
with the OpenSSL command:
openssl s_client -cert service.crt -key service.key -CAfile root_ca.pem -connect 127.0.0.1:8080 -servername svc.v1_1
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 210 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1532336403
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
---
但是,如果我将 -servername
指定为 svc.v1
,而没有下划线 _
,则效果很好.
However, it works well if I specify the -servername
as svc.v1
, without the underline _
.
// define ssl provider
private static final SslProvider SSL_PROVIDER = SslProvider.OPENSSL;
// factory method for creating ssl context
public SslContext serverCtx(InputStream certificate, InputStream privateKey) {
try {
return SslContextBuilder.forServer(certificate, privateKey)
.sslProvider(SSL_PROVIDER)
.clientAuth(ClientAuth.REQUIRE)
.trustManager(TwoWayTrustManagerFactory.INSTANCE)
.build();
} catch (Exception e) {
throw new RuntimeException("failed to create ssl context", e);
}
}
// SNI Matcher implementation
@Slf4j
public class MySNIMatcher extends SNIMatcher {
private final byte[] hostIdentifier;
public MySNIMatcher(Identifier hostIdentifier) {
super(0);
this.hostIdentifier = hostIdentifier.idDistKey().getBytes(StandardCharsets.US_ASCII);
}
@Override
public boolean matches(SNIServerName sniServerName) {
return Arrays.equals(sniServerName.getEncoded(), hostIdentifier);
}
}
// Netty bootstrap
bootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
if (conf.logEnable())
pipeline.addLast("logging", new LoggingHandler());
if (conf.sslEnable()) {
// conf.sslCtx() will actually use serverCtx() to create context
SSLEngine engine = conf.sslCtx().newEngine(ch.alloc());
SSLParameters s = engine.getSSLParameters();
s.setSNIMatchers(new MySNIMatcher(...));
s.setEndpointIdentificationAlgorithm("HTTPS");
engine.setSSLParameters(s);
pipeline.addLast("ssl", new SslHandler(engine, true));
}
codec(pipeline);
int idleTimeout = (int) TimeUnit.MILLISECONDS.toSeconds(conf.idleTimeout());
if (0 < idleTimeout)
pipeline.addLast("idle", new IdleStateHandler(0, 0, idleTimeout));
pipeline.addLast("handler", handler);
}
})
版本:netty -> 4.1.14.Finalnetty-tcnative-boringssl-static -> 2.0.5.Final
Version: netty -> 4.1.14.Final netty-tcnative-boringssl-static -> 2.0.5.Final
推荐答案
主机名不允许包含下划线字符,根据原始 RFC 952,并由 RFC 1123 修改.以下来自 Wikipedia page for 主机名.
Hostnames are not allowed to contain an underscore character, per the original RFC 952, and modified by RFC 1123. The following is from the Wikipedia page for Hostname.
协议的 Internet 标准(征求意见)要求组件主机名标签只能包含 ASCII 字母a"到z"(不区分大小写)、数字0"到9",和减号 ('-').RFC 952 中主机名的原始规范,要求标签不能以数字开头或以减号,并且不得以减号结尾.但是,随后的规范(RFC 1123)允许主机名标签以数字开头.不允许使用其他符号、标点符号或空格.
The Internet standards (Requests for Comments) for protocols mandate that component hostname labels may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), the digits '0' through '9', and the minus sign ('-'). The original specification of hostnames in RFC 952, mandated that labels could not start with a digit or with a minus sign, and must not end with a minus sign. However, a subsequent specification (RFC 1123) permitted hostname labels to start with digits. No other symbols, punctuation characters, or white space are permitted.
这篇关于JVM 使用下划线“_"作为 SNI 服务器名称的一部分崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!