0

我正在使用Netty 4.1.14.Final我的应用程序的框架。我想实现服务器可以在客户端请求使用时检查 SNI 信息netty-tcnative-boringssl-static

但是当我指定-servernameassvc.v1时,我的应用程序崩溃了一次,我收到了这条消息:

java: ../ssl/handshake_server.c:541: negotiate_version: Assertion `!ssl->s3->have_version' failed.

使用 OpenSSL 命令:

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但是,如果我指定assvc.v1而不带下划线,它会很好地工作_

这是我的 Netty 服务器实现:
// 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.Final netty-tcnative-boringssl-static -> 2.0.5.Final

4

1 回答 1

1

根据原始 RFC 952 并由 RFC 1123 修改,主机名不允许包含下划线字符。以下内容来自Hostname的维基百科页面。

协议的 Internet 标准(征求意见)要求组件主机名标签只能包含 ASCII 字母“a”到“z”(以不区分大小写的方式)、数字“0”到“9”和减号符号 ('-')。RFC 952中主机名的原始规范要求标签不能以数字或减号开头,也不能以减号结尾。但是,后续规范 ( RFC 1123 ) 允许主机名标签以数字开头。不允许使用其他符号、标点符号或空格。

于 2018-07-24T04:59:10.280 回答