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