26

我知道它很少使用,但是可以在 Snap 中访问客户端证书吗?

如果没有,是否可以使用不同的网络堆栈?

4

1 回答 1

2

这在 Snap 的软件包中对您不可用snap-server,我假设这是您运行服务器的方式。

Buuuuut 构建起来并不难,无论是通过分叉还是作为一个单独的模块(不过,您必须复制一些代码,因为您需要的一些内部值不会被导出)。bindHttps位于 Snap.Internal.Http.Server.TLS 中,是您要定位的目标。此函数主要是对从库中调用OpenSSL.SessionHsOpenSSL的包装器,它本身是对 OpenSSL 库的松散包装器。

幸运的是,OpenSSL 完全支持客户端证书。您只需将验证模式设置为SSL_VERIFY_PEER. 还有其他旋钮你也可以摆弄。您还必须确保安装证书链以实际验证客户端证书。信任链和所有爵士乐。作为参考,请参阅nginx 是如何做到的。

更好的是,这个函数被暴露HsOpenSSLfunction contextSetVerificationMode :: SSLContext -> VerificationMode -> IO ()。您会注意到ctx :: SSLContextSnap 的定义中存在bindHttps. 您所要做的就是复制或分叉该模块并介绍您的调用。

它看起来像这样(未经验证的代码警报):

± % diff -u /tmp/{old,new}
--- /tmp/old    2016-04-11 11:02:42.000000000 -0400
+++ /tmp/new    2016-04-11 11:02:56.000000000 -0400
@@ -19,6 +19,7 @@

      ctx <- SSL.context
      SSL.contextSetPrivateKeyFile ctx key
+     SSL.contextSetVerificationMode ctx (SSL.VerifyPeer True True (Just (\_ _ -> return True)))
      if chainCert
        then SSL.contextSetCertificateChainFile ctx cert
        else SSL.contextSetCertificateFile ctx cert

如果没有客户端证书,第一个布尔值告诉 OpenSSL 失败。第二个布尔值告诉 OpenSSL 客户端证书仅在第一次请求时需要,在重新协商时不再需要。第三个值是回调。我认为正确的做法是在回调中返回 True 。无论如何,这就是nginx 所做的。

于 2016-04-11T15:04:30.703 回答