none
Service WCF / TLS : SecurityNegotiationException uniquement sur réseau à forte latence RRS feed

  • Question

  • Bonjour à tous,

    Je cherche à faire fonctionner un service WCF auto hébergé sur un réseau à forte latence / faible débit, et je me frotte à des problèmes qui dépassent mes compétences...
    Le client est en W8.1, et le serveur en 2008 R2.

    Le service implémente cette interface :

    [OperationContract(Name = "send-file")]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    void SendFile(MyFileInfo myFile);

    MyFileInfo contient un tableau d'octets (autour de 45ko).
    TLS est configuré pour une double authentification client/serveur par certificat (les certificats proviennent de la même CA).

    J'ai mis en place la conf suivante :
    - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
    - Expect100Continue = true
    - KeepAlive  = false


    Mon App.config est le suivant (identique sur client et serveur) :

    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="MyHttpsBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
                sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" messageEncoding="Text"
                hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="104857600" maxReceivedMessageSize="104857600"
                textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="104857600" maxArrayLength="104857600" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
                    <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
                    <security mode="Transport">
                        <transport clientCredentialType="Certificate" proxyCredentialType="None" />
                        <message clientCredentialType="None" ></message>
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>

        <services>
            <service
            name="MyService"
            behaviorConfiguration="MyHttpsBehavior">
                <endpoint binding="wsHttpBinding"
                bindingConfiguration="MyHttpsBinding" name="MyEndpoint"
                contract="IMyInterface">
                </endpoint>
            </service>
        </services>

        <behaviors>
            <serviceBehaviors>
                <behavior name="MyHttpsBehavior">
                    <serviceMetadata httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                    <serviceCredentials>
                        <clientCertificate>
                            <authentication certificateValidationMode="ChainTrust"/>
                        </clientCertificate>
                    </serviceCredentials>
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>


    Le MTU est fixé sur les machines à 1248.
    Tout fonctionne bien sur un réseau normal (ethernet, wifi...) mais ça se corse quand je simule un réseau plus contraint (latence à 800ms et débit à 492 Kbps (kbits, pas koctets)) : je reçoit sur mon client l'exception suivante : "System.ServiceModel.Security.SecurityNegotiationException: Could not establish trust relationship for the SSL/TLS secure channel with authority 'myserver:4444'".

    Si je coupe le simulateur de latence, l'exception disparait et les échanges passent à nouveau.
    Tous mes timeouts WCF sont à 5 minutes, je ne vois absolument rien dans les journaux d'évènement serveur ni client, et aucune trace applicative sur mon service qui ne semble même pas recevoir la requête.

    J'ai sniffé le flux avec wireshark, et du point de vue du client, voici ce que j'obtiens :

     2  26.958440 client -> server  TCP 66 64972 → 4444 [SYN] Seq=0 Win=8192 Len=0 MSS=1208 WS=256 SACK_PERM=1
     3  26.958603  server -> client TCP 66 4444 → 64972 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
     4  28.606141 client -> server  TCP 54 64972 → 4444 [ACK] Seq=1 Ack=1 Win=66304 Len=0
     5  28.606359 client -> server  TCP 276 64972 → 4444 [PSH, ACK] Seq=1 Ack=1 Win=66304 Len=222
     6  28.610326  server -> client TCP 1262 4444 → 64972 [ACK] Seq=1 Ack=223 Win=66304 Len=1208
     7  28.610328  server -> client TCP 711 4444 → 64972 [PSH, ACK] Seq=1209 Ack=223 Win=66304 Len=657
     8  30.277053 client -> server  TCP 54 64972 → 4444 [ACK] Seq=223 Ack=1866 Win=61440 Len=0
     9  30.277177 client -> server  TCP 236 64972 → 4444 [PSH, ACK] Seq=223 Ack=1866 Win=61440 Len=182
     10  30.279375  server -> client TCP 161 4444 → 64972 [PSH, ACK] Seq=1866 Ack=405 Win=66048 Len=107
     11  31.920922 client -> server  TCP 331 64972 → 4444 [PSH, ACK] Seq=405 Ack=1973 Win=61440 Len=277
     12  31.921599  server -> client TCP 139 4444 → 64972 [PSH, ACK] Seq=1973 Ack=682 Win=65792 Len=85
     13  32.249867 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=682 Ack=1973 Win=61440 Len=1208
     14  32.250099 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=1890 Ack=1973 Win=61440 Len=1208
     15  32.250226  server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=3098 Win=66304 Len=0
     16  32.250437 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=3098 Ack=1973 Win=61440 Len=1208
     17  32.250699 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=4306 Ack=1973 Win=61440 Len=1208
     18  32.250816  server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=5514 Win=66304 Len=0
     19  33.623716 client -> server  TCP 54 64972 → 4444 [ACK] Seq=5514 Ack=2058 Win=61440 Len=0
     ... paquets similaires...
     89  37.189910 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=61082 Ack=2058 Win=61440 Len=1208
     90  37.190103 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=62290 Ack=2058 Win=61440 Len=1208
     91  37.190260  server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=63498 Win=53760 Len=0
     92  37.190303 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=63498 Ack=2058 Win=61440 Len=1208
     93  37.190499 client -> server  TCP 1262 64972 → 4444 [ACK] Seq=64706 Ack=2058 Win=61440 Len=1208
     94  37.190654  server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=65914 Win=51200 Len=0
     95  37.190699 client -> server  TCP 1262 64972 → 4444 [PSH, ACK] Seq=65914 Ack=2058 Win=61440 Len=1208
     96  37.190890 client -> server  TCP 865 64972 → 4444 [PSH, ACK] Seq=67122 Ack=2058 Win=61440 Len=811
     97  37.191046  server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=67933 Win=49152 Len=0
     98 160.241458  server -> client TCP 60 4444 → 64972 [RST, ACK] Seq=2058 Ack=67933 Win=0 Len=0

    Le paquet 98 (RST ACK) semble déclencher la fermeture de la connexion ainsi que la levée de mon exception, et il arrive systématiquement 2 minutes après le paquet précédent.

    Si je désactive TLS, tout se passe bien...

     
    L'un d'entre vous aurait-il une idée sur la question ?
    Merci d'avance

    lundi 20 février 2017 08:38

Réponses

  • Sans aucune idée sur la cause du problème (et sans temps alloué pour creuser plus en détail), l'erreur a été contournée en désactivant l'envoi du certificat client.
    • Marqué comme réponse djezzz vendredi 24 février 2017 08:27
    vendredi 24 février 2017 08:27