9 Replies Latest reply on Jul 25, 2019 6:10 AM by amadets

    Wildfly and SNI

    amadets Newbie

      Hi,

      I was looking for solution on #wildfly-user chat but nothing. I will try here. I read that Wildfly 15 and above support SSL SNI certificate. I read documentation (chapters how to configure elytron and SNI) and forum but I don't find solution.
      I am trying to configure my 2 application to use the same https port and 2 virtual host but different SSL certificate.
      Step 1:
      Localy, I register in my hosts file:
      127.0.0.1 app1.com
      127.0.0.1 app2.com
      Step 2:
      1st has a jboss-web.xml:

      <jboss-web> 
           <context-root>/app1</context-root>
           <virtual-host>app1</virtual-host>
      </jboss-web>

      and 2nd:

      <jboss-web> 
           <context-root>/app2</context-root>
           <virtual-host>app2</virtual-host>
      </jboss-web>

      Step3:
      In default-server standalone.xml defined:

      <host name="app1" alias="app1.com" default-web-module="app1.war"/> 
      <host name="app2" alias="app2.com" default-web-module="app2.war"/>

      Step4:
      Open a web browser and type:
      app1.com -> return data from app1
      app2.com -> return data from app2
      and all is correctly. With SSL self-signed certificate also all is ok. And certificate is the same for both.
      Step5:
      Enable elytron:

      <https-listener name="https" socket-binding="https" ssl-context="httpsSSC1" enable-http2="true"/> 

      Step6:
      Generate two keystore with self-signed certificates and aliases: app1.com and app2.com
      Step7:
      Configure elytron:

      <subsystem xmlns="urn:wildfly:elytron:5.0" ... ... 
           <tls>
                <key-stores>
                     <key-store name="httpsKS1">
                          <credential-reference clear-text="password"/>
                          <implementation type="JKS"/>
                          <file path="application1.keystore" relative-to="jboss.server.config.dir"/>
                     </key-store>
                     <key-store name="httpsKS2">
                          <credential-reference clear-text="password"/>
                          <implementation type="JKS"/>
                          <file path="application2.keystore" relative-to="jboss.server.config.dir"/>
                     </key-store>
                </key-stores>
                <key-managers>
                     <key-manager name="httpsKM1" key-store="httpsKS1">
                          <credential-reference clear-text="password"/>
                     </key-manager>
                     <key-manager name="httpsKM2" key-store="httpsKS2">
                          <credential-reference clear-text="password"/>
                     </key-manager>
                </key-managers>
                <server-ssl-contexts>
                     <server-ssl-context name="httpsSSC1" protocols="TLSv1.2" key-manager="httpsKM1"/>
                     <server-ssl-context name="httpsSSC2" protocols="TLSv1.2" key-manager="httpsKM2"/>
                </server-ssl-contexts>
                <server-ssl-sni-contexts>
                     <server-ssl-sni-context name="symbolicName" default-ssl-context="httpsSSC1">
                          <sni-mapping host="app1.com" ssl-context="httpsSSC1"/>
                          <sni-mapping host="app2.com" ssl-context="httpsSSC2"/>
                     </server-ssl-sni-context>
                </server-ssl-sni-contexts>
           </tls>
      </subsystem>

      Step8:
      start server, everything is ok and open a web browser and type:
      app1.com -> return data from app1
      app2.com -> return data from app2
      but certificate is always from 1st keyStore (exactly from keystore  marked as default-ssl-context).

      I test solution on wildfly 15.0.0 and 17.0.1
      Why? What's wrong? Could you help me?

        • 1. Re: Wildfly and SNI
          Tomaž Cerar Master

          try changing

           

          <sni-mapping host="app1.com" ssl-context="httpsSSC1"/>

          <sni-mapping host="app2.com" ssl-context="httpsSSC2"/>

          to:

           

          <sni-mapping host="app1" ssl-context="httpsSSC1"/>

          <sni-mapping host="app2" ssl-context="httpsSSC2"/>

          • 2. Re: Wildfly and SNI
            amadets Newbie

            Thanks Tomaz for your replay. But when I changed host attribute, is the same problem.

            I tried more variants with this but nothing.

             

            I downloaded source code of wildfly-elytron-ssl (1.9.1.Final) and debugged it.

            When wildfly starting it correctly parse configuration and call org.wildfly.security.ssl.SNIContextMatcher to build wildcards or exacts.

            It use a javax.net.ssl.SNIHostName to createSNIMatcher with name as parameter. Documentation for this metod say that name is "regex the regular expression patternrepresenting the hostname(s) to match (for example www\\.example\\.com)".

            Ok, so I tried with this:

                 host="app1\\.com",

            but org.wildfly.extension.elytron.HostContextMapValidator throw exception.

            Ok, so i debugged it and found a comment for this method:

            ---

            // Hostnames can contain ASCII letters a-z (case-insensitive), digits 0-9, hyphens and dots.

            // This pattern allows also [,],*,? characters to make regular expressions possible. Non-escaped dot represents any character, escaped dot is delimeter.

            static Pattern hostnameRegexPattern = Pattern.compile("[0-9a-zA-Z\\[.*]" + // first character can be digit, letter, left square bracket, non-escaped dot or asterisk

                            "([0-9a-zA-Z*.\\[\\]?-]" + // any combination of digits, letters, asterisks, non-escaped dots, square brackets, question marks and hyphens

                            "|" +                       // OR

                            "(?<!\\\\\\.)\\\\\\.)*" +   // if there is an escaped dot, there cannot be another escaped dot right behind it

                            // backslash must be escaped, so '\\\\' translates to literally slash, and '\\.' translates to literally dot

                            "[0-9a-zA-Z*.\\[\\]?]");   // escaped dot or hyphen cannot be at the end

            --

             

            and with this information again tried more variants but nothing new.

            What can i do with this?

            • 3. Re: Wildfly and SNI
              Diana Vilkolakova Newbie

              HostContextMapValidator was added in the latest WildFly (we'll have to investigate this change more). What you are trying to do should work on WildFly 15 and WildFly 16.

              • 4. Re: Wildfly and SNI
                amadets Newbie

                Ok, i tried configuration on wildfly 15.0.0.Final, wildfly 16.0.0.Final and 17.0.1.Final and on these configuration it doesn't work correctly (debugged only on 17.0.1).

                I think a problem is not in validator or configuration.

                org.wildfly.security.ssl.SNIContextMatcher has a public SSLContext getContext method which I think is for resolve context based wildcars or exacts server names, but this method is never call when are the requests from browser.

                What else can I check?

                • 5. Re: Wildfly and SNI
                  Diana Vilkolakova Newbie

                  On the WildFly 17 validation, it seems to be acting correctly. When using configuration file, you should not escape backslash. The additional escaping is necessary in the documentation for the createSNIMatcher method because of JAVA Strings.

                  So your configuration should look like this:

                   

                  <sni-mapping host="app1\.com" ssl-context="httpsSSC1"/>
                  <sni-mapping host="app2\.com" ssl-context="httpsSSC2"/>
                  

                   

                  amadets  wrote:

                   

                  but this method is never call when are the requests from browser.

                  Just to be sure - did you use https in your browser ? How did you check the certificate that was used?

                   

                  Could you share the output from the following commands?

                   

                  openssl s_client -servername app1.com  -connect app1.com:443  -debug

                  openssl s_client -servername app2.com  -connect app2.com:443  -debug

                  • 6. Re: Wildfly and SNI
                    Diana Vilkolakova Newbie

                    Can you try to substitute this line:

                     

                    <https-listener name="https" socket-binding="https" ssl-context="httpsSSC1" enable-http2="true"/>

                     

                    with

                     

                    <https-listener name="https" socket-binding="https" ssl-context="symbolicName" enable-http2="true"/>

                    • 7. Re: Wildfly and SNI
                      amadets Newbie

                      How can i check certificate? Open chrome or firefox, write app1.com and app2.com in new tab, server send certificate for tab1 and tab2, open chrome/firefox certificate view dialog. In this scenario certificate is the same.

                      • 8. Re: Wildfly and SNI
                        amadets Newbie

                        It's solution!. When ssl-context changed to ssl-context="symbolicName" all is ok. The certificates are differents and org.wildfly.security.ssl.SNIContextMatcher -> getContext was call correctly. I tried with 17.0.1.Final.

                        Next few days i will check with more complicated environments and I think all will be ok. I'll let you know.

                        thx

                        • 9. Re: Wildfly and SNI
                          amadets Newbie

                          I have tested sni last few days and all is correctly on wildfly 17.0.1. thx.