Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-12629

Using jenkins-cli connecting to HTTPS port fails due to hostname mismatch in certificate

      We have Jenkins setup to use only HTTPS port with arguments "--httpPort=-1 --httpsPort=8080" that starts server with self signed certificate.

      Using web browser is all ok but when connecting with jenkins-cli.jar it fails due to hostname not being the same as server actual hostname.

      Steps to reproduce (using bash):

      JENKINS_HOST=foo.bar.host
      JENKINS_PORT=8080
      JENKINS_URL=https://${JENKINS_HOST}:${JENKINS_PORT}
      
      # Get HTTPS certificate for java
      openssl s_client -connect ${JENKINS_HOST}:${JENKINS_PORT} </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ${JENKINS_HOST}.cer
      keytool -import -noprompt -trustcacerts -alias ${JENKINS_HOST} -file ${JENKINS_HOST}.cer -keystore myKeystore -storepass 123456
      keytool -list -v -keystore myKeystore -storepass 123456
      
      # Get jenkins-cli
      wget --no-check-certificate ${JENKINS_URL}/jnlpJars/jenkins-cli.jar
      
      # Test access
      alias jcli="java -Djavax.net.ssl.trustStore=myKeystore -Djavax.net.ssl.trustStorePassword=123456 -jar jenkins-cli.jar -s ${JENKINS_URL,,}"
      jcli help
      

      Error displayed:

      Exception in thread "main" java.io.IOException: Failed to connect to https://foo.bar.host:8080/
              at hudson.cli.CLI.getCliTcpPort(CLI.java:211)
              at hudson.cli.CLI.<init>(CLI.java:115)
              at hudson.cli.CLI._main(CLI.java:375)
              at hudson.cli.CLI.main(CLI.java:314)
      Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name mat
      ching localhost found
              at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
              at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
              at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
              at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
              at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
              at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
              at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
              at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
              at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
              at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
              at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
              at hudson.cli.CLI.getCliTcpPort(CLI.java:209)
              ... 3 more
      Caused by: java.security.cert.CertificateException: No name matching localhost found
              at sun.security.util.HostnameChecker.matchDNS(Unknown Source)
              at sun.security.util.HostnameChecker.match(Unknown Source)
              at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(Unknown Source)
              at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
              ... 15 more
      

      I think the root cause is related to how the self-certificate is being generated that should be using the machine actual hostname in the CN part instead of "Test site":

      Owner: CN=Test site, OU=Unknown, O=Unknown, C=Unknown
      Issuer: CN=Test site, OU=Unknown, O=Unknown, C=Unknown
      

          [JENKINS-12629] Using jenkins-cli connecting to HTTPS port fails due to hostname mismatch in certificate

          Jose Sa created issue -

          R. Tyler Croy added a comment -

          This bit me today as well, glad I'm not the only one with these issues. I think the better option would be for jenkins-cli to actually support self-signed certificates, since most installations will have that by default.

          kohsuke is there any way I could beg for that option?

          R. Tyler Croy added a comment - This bit me today as well, glad I'm not the only one with these issues. I think the better option would be for jenkins-cli to actually support self-signed certificates, since most installations will have that by default. kohsuke is there any way I could beg for that option?

          Jose Sa added a comment -

          There is currently a better alternative which is to use SSH directly, if you configure Jenkins to lister on a sshd port on your choosing (example 12345).

          This way you can execute cli commands like this:

          alias jcli='ssh -p 12345 $JENKINS_HOST'
          jcli help
          

          All you need to make sure is to publish your public ssh key in your Jenkins account.

          Jose Sa added a comment - There is currently a better alternative which is to use SSH directly, if you configure Jenkins to lister on a sshd port on your choosing (example 12345). This way you can execute cli commands like this: alias jcli= 'ssh -p 12345 $JENKINS_HOST' jcli help All you need to make sure is to publish your public ssh key in your Jenkins account.
          Jose Sa made changes -
          Priority Original: Critical [ 2 ] New: Major [ 3 ]

          R. Tyler Croy added a comment -

          Well, the SSH API doesn't work for the 'groovy' command, which is the only command that I need to run.

          I'm trapped!

          R. Tyler Croy added a comment - Well, the SSH API doesn't work for the 'groovy' command, which is the only command that I need to run. I'm trapped!

          Jose Sa added a comment - - edited

          I had that problem too, but managed to workaround it with groovysh redirecting from standard input. It must be a bug that "groovy" command doesn't not work with SSH CLI.

          If you don't care about output returned you don't even need to filter it out, but here is an example how to bulk apply some changes to subversion update strategy on all jobs with e certain regular expression pattern:

          ## List jobs
          JOBS_PAT=".*_analysis"
          cat <<_EOF_ >list-jobs.groovy
          for (job in Hudson.instance.items.findAll{ it.name =~ /^${JOBS_PAT}$/ }) println job.name;
          exit
          _EOF_
          jobs=$(jcli groovysh < list-jobs.groovy | tail -n +4 | head -n -2 | sed "s,^[^ ]*groovy[^ ]*,,")
          
          ## get jobs
          mkdir -p old
          for job in $jobs; do
              echo $job
              jcli get-job $job > old/$job.xml
          done
          
          ## change jobs
          mkdir -p new
          for job in $jobs; do
              echo $job
              sed 's/workspaceUpdater class.*/workspaceUpdater class="hudson.scm.subversion.UpdateWithRevertUpdater"\>/' old/$job.xml > new/$job.xml
              diff old/$job.xml new/$job.xml
          done
          
          ## update jobs
          for job in $jobs; do
              echo $job
              jcli update-job $job < new/$job.xml
          done
          

          Jose Sa added a comment - - edited I had that problem too, but managed to workaround it with groovysh redirecting from standard input. It must be a bug that "groovy" command doesn't not work with SSH CLI. If you don't care about output returned you don't even need to filter it out, but here is an example how to bulk apply some changes to subversion update strategy on all jobs with e certain regular expression pattern: ## List jobs JOBS_PAT= ".*_analysis" cat <<_EOF_ >list-jobs.groovy for (job in Hudson.instance.items.findAll{ it.name =~ /^${JOBS_PAT}$/ }) println job.name; exit _EOF_ jobs=$(jcli groovysh < list-jobs.groovy | tail -n +4 | head -n -2 | sed "s,^[^ ]*groovy[^ ]*,," ) ## get jobs mkdir -p old for job in $jobs; do echo $job jcli get-job $job > old/$job.xml done ## change jobs mkdir -p new for job in $jobs; do echo $job sed 's/workspaceUpdater class.*/workspaceUpdater class= "hudson.scm.subversion.UpdateWithRevertUpdater" \>/' old/$job.xml > new /$job.xml diff old/$job.xml new /$job.xml done ## update jobs for job in $jobs; do echo $job jcli update-job $job < new /$job.xml done

          The reason SSH client doesn't work with the groovy command is because ssh(1) lacks the ability to read a script file for the master. You can work around this relatively easily by reading the script from stdin:

          ssh yourjenkins.acme.com groovy = < myscript.groovy
          

          This has obvious downside that you won't be able to access stdin from your groovy script, but it's probably prettier than the work around that involves the groovysh command.

          Kohsuke Kawaguchi added a comment - The reason SSH client doesn't work with the groovy command is because ssh(1) lacks the ability to read a script file for the master. You can work around this relatively easily by reading the script from stdin : ssh yourjenkins.acme.com groovy = < myscript.groovy This has obvious downside that you won't be able to access stdin from your groovy script, but it's probably prettier than the work around that involves the groovysh command.

          Code changed in jenkins
          User: Kohsuke Kawaguchi
          Path:
          cli/src/main/java/hudson/cli/CLI.java
          cli/src/main/java/hudson/cli/NoCheckTrustManager.java
          cli/src/main/resources/hudson/cli/client/Messages.properties
          http://jenkins-ci.org/commit/jenkins/2edf32221f13e36c2c5c44c9f91a068966b59218
          Log:
          [FIXED JENKINS-12629]

          Added the -noCertificateCheck option (the option name is consistent with
          the slave.jar) that lets users bypass the HTTPS certificate check.

          This allows trivial man-in-the-middle attack, so HTTPS will no longer be
          HTTPS.


          You received this message because you are subscribed to the Google Groups "Jenkins Commits" group.
          To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-commits+unsubscribe@googlegroups.com.
          For more options, visit https://groups.google.com/groups/opt_out.

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Kohsuke Kawaguchi Path: cli/src/main/java/hudson/cli/CLI.java cli/src/main/java/hudson/cli/NoCheckTrustManager.java cli/src/main/resources/hudson/cli/client/Messages.properties http://jenkins-ci.org/commit/jenkins/2edf32221f13e36c2c5c44c9f91a068966b59218 Log: [FIXED JENKINS-12629] Added the -noCertificateCheck option (the option name is consistent with the slave.jar) that lets users bypass the HTTPS certificate check. This allows trivial man-in-the-middle attack, so HTTPS will no longer be HTTPS. – You received this message because you are subscribed to the Google Groups "Jenkins Commits" group. To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-commits+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out .
          SCM/JIRA link daemon made changes -
          Resolution New: Fixed [ 1 ]
          Status Original: Open [ 1 ] New: Resolved [ 5 ]

          dogfood added a comment -

          Integrated in jenkins_main_trunk #2293
          [FIXED JENKINS-12629] (Revision 2edf32221f13e36c2c5c44c9f91a068966b59218)

          Result = SUCCESS
          kohsuke : 2edf32221f13e36c2c5c44c9f91a068966b59218
          Files :

          • cli/src/main/java/hudson/cli/CLI.java
          • cli/src/main/resources/hudson/cli/client/Messages.properties
          • cli/src/main/java/hudson/cli/NoCheckTrustManager.java

          dogfood added a comment - Integrated in jenkins_main_trunk #2293 [FIXED JENKINS-12629] (Revision 2edf32221f13e36c2c5c44c9f91a068966b59218) Result = SUCCESS kohsuke : 2edf32221f13e36c2c5c44c9f91a068966b59218 Files : cli/src/main/java/hudson/cli/CLI.java cli/src/main/resources/hudson/cli/client/Messages.properties cli/src/main/java/hudson/cli/NoCheckTrustManager.java

            Unassigned Unassigned
            josesa Jose Sa
            Votes:
            3 Vote for this issue
            Watchers:
            13 Start watching this issue

              Created:
              Updated:
              Resolved: