Jenkins在nginx SSL反向代理后面使用JNLP


0

我想用JNLP将jenkins奴隶连接到jenkins master。主服务器在SSL nginx代理后面运行 根据官方文件设置 。除了这个文档,我遇到了与证书相关的问题。

目前,我可以让JNLP无头奴隶主连接只能使用不安全的HTTP连接,但不能使用HTTPS(尽管我的jenkins仪表板一般都可以)。 我使用由我自己的自定义CA证书(基于openssl的x509)签名的自签名证书。

那么如何告诉我的slave的java二进制文件信任我的SSL CA证书?我试过这个。

# add CA certificate to key store
$ keytool -import -file /usr/local/share/ca-certificates/my_ca.crt -alias my_ca -storepass mypassword

# try to reference keystore to JNLP headless call
$ java -Djavax.net.ssl.keyStorePassword=mypassword -Djavax.net.ssl.keyStore=/home/myuser/.keystore -jar slave.jar -jnlpUrl https://proxied-jenkins.example.com/computer/testslave/slave-agent.jnlp

实际上JAVA似乎没有在提供的密钥库中查找证书。这里我的错误是什么?

编辑

使用jenkins cli时会出现类似/相同的问题。根据 这个 ,现在 我认为,它与我的证书的信任无关 因为我看不到 javax.net.ssl.SSLHandshakeException

我只是收到连接重置

Failing to obtain https://proxied-jenkins.example.com/computer/testslave/slave-agent.jnlp
java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at hudson.remoting.Launcher.parseJnlpArguments(Launcher.java:269)
    at hudson.remoting.Launcher.run(Launcher.java:219)
    at hudson.remoting.Launcher.main(Launcher.java:192)

..所以我假设我的代理配置问题。我接受了配置 反向代理配置 并添加以下配置以强制SSL:

upstream jenkins-upstream {
  server unproxied-jenkins.example.com:8080 fail_timeout=0;
}

server {
  listen 80;
  server_name proxied-jenkins.example.com;
  return 301 https://$host$request_uri;
}
server {
  listen 443;
  server_name proxied-jenkins.example.com;

  #this is the jenkins web root directory (mentioned in the /etc/default/jenkins file)
  root            /var/run/jenkins/war/;

  ssl on;
  ssl_certificate /etc/nginx/conf.d/proxied-jenkins.example.com.crt;
  ssl_certificate_key /etc/nginx/conf.d/proxied-jenkins.example.com.key;
  ssl_protocols TLSv1.2;
  ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;

  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  [...] # continuing according to jenkins documentation
  location @jenkins {
      proxy_pass                  http://jenkins-upstream
      [....]
  }
  [....]
}

再次更改为不安全的HTTP时,JNLP和jenkins-cli按预期工作。那是什么错误?
也许我需要传递额外的标题信息?也许我的代理设置需要额外的SSL配置?


您需要SSL中的CAcert 信任 客户端进程,而不是SSL密钥库。并非所有SSLHandshakeException都是由于证书问题造成的,但是你没有得到那个,因此你可能会失败 之前 验证证书的重点。 (1)您使用的是什么版本的Java(6/7/8,Oracle / OpenJDK / IBM /?)? (2)你能否(2A)使用Wireshark tcpdump或类似网络进行网络捕获,尽可能过滤并显示或链接到该网络;或(2B)使用sysprop运行 javax.net.debug=ssl,捕获(大!)输出,并添加?
dave_thompson_085

@ dave_thompson_085 javax.net.debug=ssl 做了伎俩。我能够发现,java二进制文件(oracle jdk 7)试图用'弱'密码进行TLSv1握手...安装Java Cryptography Extension(JCE)后我得到了更强的密码支持,我能够告诉java二进制做TLSv1.2。通过使用 -Dhttps.protocols=TLSv1.2。但是在升级到Oracle JDK 8之后,它可以开箱即用。所以,感谢你们的支持,并指出我正确的方向......也许你把它作为答案来表达,我将除外并投赞成票。
ITL

Answers:


2

(根据评论反馈扩大)

该服务器配置为要求协议版本TLSv1.2(仅限),以及使用至少一种AES-GCM或256位AES的密码套件,使用DHE或ECDHE密钥交换(OpenSSL和因此nginx使用变体拼写EDH和EECDH在某些情况下包括这一个)。

Oracle或OpenJDK中的JSSE客户端 JDK7默认不提供TLSv1.2或1.1 (不知道IBM,它有自己的加密提供程序)但是它们已经实现了 可以启用 ;对于 (Https)URLConnection 这可以通过系统属性完成 https.protocols。 (或者通过覆盖其套接字工厂,但系统属性通常更容易。)但是JDK7 没有实现GCM和Oracle 版本(但不是OpenJDK) 禁止256位对称加密,除非 你安装“JCE 无限的力量 管辖权政策文件“来自Oracle网站;请参阅 https://stackoverflow.com/a/33712287/2868801 可能 https://stackoverflow.com/questions/30350120/sslhandshakeexception-while-connecting-to-a-https-site

相比之下,JDK8(Oracle和OpenJDK)默认提供TLSv1.2和1.1,并实现GCM,因此它可以在没有Unlimited Strength策略的情况下连接。

7和8都支持DHE和ECDHE密钥交换。但对于处于类似情况的其他人来说 JDK6:ECDHE不起作用,除非 您为ECC基元添加第三方提供程序,如 bcprov http://www.BouncyCastle.org


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.