如何使用 ssl 通配符证书通过 X509 相互验证多个 WCF 服务器?

发布于 2024-08-08 15:00:24 字数 2458 浏览 2 评论 0原文

我有两个 WCF 服务器,都位于 mydomain.com 域(虚构的示例,如下面的 IP!),分别命名为 server1 和 server2。

它们都可以通过其公共 IP 地址(foo.1 和 2)进行访问,也可以从它们所在的私有 LAN(即 192.168.0.1 和 192.168.0.2)进行访问。

我拥有 *.mydomain.com 的通配符 ssl 证书。它已正确安装在相关商店中(即用于加密的个人和用于身份验证的受信任客户端)

我希望我的两台服务器使用我的通配符证书在其本地网络地址上相互连接以进行身份​​验证。

我已经更新了 C:\Windows\System32\drivers\etc\hosts 文件,使其看起来像这样:

192.168.0.1     Server1.mydomain.com
192.186.0.2     Server2.mydomain.com

如果我解析 Server1.mydomain.com,这些不是我得到的 IP 地址(我宁愿得到 foo.1 - 2)

我还编辑了我的 IPV4 本地接口的连接特定 DNS 后缀到“mydomain.com”

我的证书在我的 Server.config 文件中是这样引用的(我已经删除了与身份验证无关的所有部分)

        <behavior name="ServerToServerBehavior" >
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="Online"/>
            </clientCertificate>
            <serviceCertificate x509FindType="FindByThumbprint" findValue="13a41b3456e431131cd461de"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="myServerAsClientBehaviorConfiguration">
          <clientCredentials>
            <clientCertificate x509FindType="FindByThumbprint" findValue="13a41b3456e431131cd461de" storeLocation="LocalMachine"/>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="Online" trustedStoreLocation="LocalMachine"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>

这在我自己的具有本地生成的 X509 证书的开发计算机上运行得很好,但在我的生产环境中,这是我得到的:

Server.Connect:无法连接到 服务器服务器2: System.ServiceModel.Security.MessageSecurityException: 传出身份验证失败 信息。预期的 DNS 身份 远程端点是 'server2.mydomain.com' 但远程 端点提供的 DNS 声明 'mydomain.com'。如果这是一个 合法的远程端点,您可以 通过明确地解决问题 指定 DNS 身份“mydomain.com” 作为身份属性 创建通道时的端点地址 代理。

我试图让服务器回答 Server2.mydomain.com 而不仅仅是 mydomain.com,但没有成功。关于如何执行此操作有任何提示吗?

我也尝试了错误消息中建议的解决方案,但这似乎根本没有效果(其他用户似乎有 同样的问题,我还没有找到解决方案)。关于如何解决这个问题有什么想法吗?

编辑 : 我已向我的证书提供商核实我确实可以使用它进行 X509 身份验证。

I've got two WCF servers, both on the domain mydomain.com (fictional example, as are IP below !), respectively named server1 and server2.

They are both accessible through their public IP addresses (foo.1 and 2), but also from the private LAN they are on (ie 192.168.0.1 and 192.168.0.2)

I own a wildcard ssl certificate for *.mydomain.com. It's installed correctly in the relevant stores (ie Personal for encryption and Trusted Clients for Authentication)

I'd like both my servers to connect with one another on their local network addresses using my wildcard certificate for authentication purposes.

I've updated the C:\Windows\System32\drivers\etc\hosts file to make it look like this :

192.168.0.1     Server1.mydomain.com
192.186.0.2     Server2.mydomain.com

Those are not the IP addresses I get if I resolve Server1.mydomain.com (I would rather get foo.1 - 2)

I've also edited the Connection-specific DNS suffix for my IPV4 local interfaces to "mydomain.com"

My certificate is referred to like this in my Server.config files (I've stripped all the parts not related to authentication)

        <behavior name="ServerToServerBehavior" >
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="Online"/>
            </clientCertificate>
            <serviceCertificate x509FindType="FindByThumbprint" findValue="13a41b3456e431131cd461de"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="myServerAsClientBehaviorConfiguration">
          <clientCredentials>
            <clientCertificate x509FindType="FindByThumbprint" findValue="13a41b3456e431131cd461de" storeLocation="LocalMachine"/>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="Online" trustedStoreLocation="LocalMachine"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>

This works perfectly fine on my own dev computer with locally generated X509 certificates, but in my production environment, here's what I get :

Server.Connect : Failed to connect to
server Server2 :
System.ServiceModel.Security.MessageSecurityException:
Identity check failed for outgoing
message. The expected DNS identity of
the remote endpoint was
'server2.mydomain.com' but the remote
endpoint provided DNS claim
'mydomain.com'. If this is a
legitimate remote endpoint, you can
fix the problem by explicitly
specifying DNS identity 'mydomain.com'
as the Identity property of
EndpointAddress when creating channel
proxy.

I've tried to get the server to answer Server2.mydomain.com instead of just mydomain.com, without success. Any hint on how to do this?

I've also tried the solution suggested in the error message, but this seems to have no effect at all (other users seem to have the same problem and I've yet to find a solution). Any idea on how to fix this ?

Edit :
I've check with my certificate provider that I can indeed use it for X509 authentication.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

满意归宿 2024-08-15 15:00:24

我最终明白了为什么我的身份字段被忽略了。

我的端点是这样构造的:

DistantServer = new ServiceReferenceServerToServer.ServerToServerClient("myServerBinding", "net.tcp://server.mydomain.com/Server");

当提供 uri 参数时,DNS 身份字段(在 app.config 中定义)也会被覆盖(即使它是空的,当我们使用字符串而不是真实的字符串时就是这种情况) URI 对象)。

解决方案是使用以下代码以编程方式设置它:

        System.ServiceModel.EndpointAddress uri = new System.ServiceModel.EndpointAddress(new Uri("net.tcp://server.mydomain.com/Server"),new System.ServiceModel.DnsEndpointIdentity("mydomain.com"),new System.ServiceModel.Channels.AddressHeader[0]);

        DistantServer = new ServiceReferenceServerToServer.ServerToServerClient("myServerBinding", uri );

I eventually understood why my Identity field was being ignored.

My endpoint was constructed like this :

DistantServer = new ServiceReferenceServerToServer.ServerToServerClient("myServerBinding", "net.tcp://server.mydomain.com/Server");

when the uri parameter is provided, the DNS identity field (defined in the app.config), is overridden as well (even if it's empty, which is the case when we use a string instead of a real URI object).

the solution is to set it programatically using the following code :

        System.ServiceModel.EndpointAddress uri = new System.ServiceModel.EndpointAddress(new Uri("net.tcp://server.mydomain.com/Server"),new System.ServiceModel.DnsEndpointIdentity("mydomain.com"),new System.ServiceModel.Channels.AddressHeader[0]);

        DistantServer = new ServiceReferenceServerToServer.ServerToServerClient("myServerBinding", uri );
爱已欠费 2024-08-15 15:00:24

我认为错误所讨论的 DNS 声明覆盖将在客户端而不是服务器上指定,因此您不会通过进行该更改来打开任何内容,除非您的客户端可以成功连接到域中的任何服务器(如果它在听)。您看到的错误有点像消息安全性,相当于证书上的主机名不匹配。经过大量的努力后,我已经获得了与通配符证书一起使用的消息安全性,但是您可能需要执行一些自定义验证工作,因为您的证书可能没有指定客户端身份验证用法。

您不使用传输安全的原因是什么?除非你有中间第 7 层路由,否则工作起来要简单得多......

I think the DNS claim override the error is talking about would be specified on the client side, not the server, so you're not opening anything up by making that change except that your client could successfully connect to any server in your domain (if it were listening). The error you're seeing is kinda like the message security equivalent of a hostname mismatch on the cert. I've gotten message security to work with wildcard certs after a lot of screwing around, but you might have to do some custom validation work since your cert probably doesn't have the Client Authentication usage specified.

Any reason you're not using Transport security? MUCH simpler to get working unless you've got intermediate Layer7 routing...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文