Как я могу использовать подстановочный сертификат ssl для взаимной аутентификации нескольких серверов WCF через X509?

StackOverflow https://stackoverflow.com/questions/1630968

  •  06-07-2019
  •  | 
  •  

Вопрос

У меня есть два сервера WCF, оба в домене mydomain.com (вымышленный пример, как и IP ниже!), соответственно с именами server1 и server2.

Они оба доступны через их общедоступные IP-адреса (foo.1 и 2), но также и из частной локальной сети, в которой они находятся (т.е. 192.168.0.1 и 192.168.0.2)

У меня есть подстановочный сертификат ssl для * .mydomain.com. Он правильно установлен в соответствующих хранилищах (например, Personal для шифрования и Trusted Clients для аутентификации)

Я бы хотел, чтобы оба моих сервера соединялись друг с другом по их локальным сетевым адресам, используя мой групповой сертификат для проверки подлинности.

Я обновил файл C: \ Windows \ System32 \ drivers \ etc \ hosts, чтобы он выглядел следующим образом:

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

Это не те IP-адреса, которые я получу, если разрешу Server1.mydomain.com (я бы предпочел получить foo.1 - 2)

Я также отредактировал DNS-суффикс конкретного соединения для своих локальных интерфейсов IPV4 на «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: не удалось подключиться к   сервер Server2:   System.ServiceModel.Security.MessageSecurityException:   Проверка подлинности не удалась для исходящих   сообщение. Ожидаемая идентичность DNS   удаленная конечная точка была   'server2.mydomain.com', но удаленный   конечная точка предоставила претензию DNS   'Mydomain.com. Если это   законная удаленная конечная точка, вы можете   исправить проблему явно   указание DNS-идентификатора «mydomain.com»   как свойство идентичности   EndpointAddress при создании канала   прокси.

Я пытался заставить сервер отвечать на Server2.mydomain.com вместо просто mydomain.com, но безуспешно. Любой намек на то, как это сделать?

Я также попробовал решение, предложенное в сообщении об ошибке, но это, похоже, не имеет никакого эффекта (другие пользователи, похоже, имеют та же проблема , и я пока не нашел решения). Есть идеи, как это исправить?

Изменить: Я уточнил у своего поставщика сертификатов, действительно ли я могу использовать его для аутентификации X509.

Это было полезно?

Решение

В конце концов я понял, почему мое поле идентичности игнорировалось.

Моя конечная точка была построена так:

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 );

Другие советы

Я думаю, что утверждение DNS о переопределении ошибки, о котором идет речь, будет указано на стороне клиента, а не на сервере, поэтому вы ничего не открываете, внеся это изменение, за исключением того, что ваш клиент может успешно подключиться к любому серверу в вашем домен (если бы это было прослушивание). Ошибка, которую вы видите, похожа на эквивалент безопасности сообщения о несоответствии имени хоста в сертификате. Я получил защиту сообщений для работы с сертификатами подстановочных знаков после многих извращений, но вам, возможно, придется выполнить некоторую пользовательскую проверку, так как в вашем сертификате, вероятно, не указано использование проверки подлинности клиента.

По какой причине вы не используете безопасность на транспорте? Гораздо проще начать работать, если у вас нет промежуточной маршрутизации уровня 7 ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top