Eu gostaria de usar o JNLP para conectar os escravos Jenkins ao mestre Jenkins. O mestre está executando um proxy SSL nginx configurado de acordo com a documentação oficial . Além desta documentação, encontro problemas relacionados a certificados.
Atualmente, posso fazer com que o escravo sem cabeça JNLP domine a conexão para funcionar apenas com conexão HTTP não segura, mas não com HTTPS (embora meu painel de controle jenkins funcione em geral). Uso um certificado autoassinado assinado por meu próprio certificado CA personalizado (x509 com base em openssl).
Então, como digo ao binário java do meu escravo que confie no meu certificado CA SSL? Eu tentei isso.
# 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
Na verdade, o JAVA parece não procurar o certificado no keystore fornecido. Qual é o meu erro aqui?
EDITAR
Problema semelhante / mesmo ocorre ao usar o jenkins cli. De acordo com isso , agora suponho que não tenha nada a ver com a confiança no meu certificado, pois não consigo ver umjavax.net.ssl.SSLHandshakeException
Acabei de receber uma redefinição de conexão
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)
.. então eu assumo um problema de configuração com o meu proxy. Peguei a configuração da configuração do proxy reverso e adicionei a seguinte configuração para forçar o 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
[....]
}
[....]
}
Novamente, ao mudar para HTTP não seguro, o JNLP e o jenkins-cli funcionam conforme o esperado. Então qual é o erro?
Talvez eu precise passar informações adicionais do cabeçalho? Talvez eu precise de uma configuração SSL adicional nas minhas configurações de proxy?
javax.net.debug=ssl
, capture a saída (grande!) e adicione isso?javax.net.debug=ssl
fez o truque. Eu pude descobrir que o binário java (oracle jdk 7) tentou fazer o handshake TLSv1 com cifras 'fracas' ... Depois de instalar o Java Cryptography Extension (JCE), tive um suporte cifrado mais forte e consegui dizer ao java binário para fazer TLSv1.2. usando-Dhttps.protocols=TLSv1.2
. No entanto, após a atualização para o Oracle JDK 8, ele funciona imediatamente. Então, obrigado pelo seu apoio e me direcionando para a direção certa ... Talvez você formule isso como resposta e eu vou excluí-lo e votá-lo.Respostas:
(Expandido com base no feedback dos comentários)
Esse servidor está configurado para exigir a versão do protocolo TLSv1.2 (somente) e ciphersuites usando pelo menos um AES-GCM ou AES de 256 bits, com troca de chave DHE ou ECDHE (para a qual o OpenSSL e o nginx usam grafias variantes EDH e EECDH em alguns casos, incluindo este).
O cliente JSSE no Oracle ou OpenJDK JDK7 não oferece TLSv1.2 ou 1.1 por padrão (não conhecido pela IBM, que possui seus próprios provedores de criptografia), mas eles são implementados e podem ser ativados ; para
(Https)URLConnection
isso pode ser feito com a propriedade do sistemahttps.protocols
. (Ou sobrepondo sua fábrica de soquetes, mas a propriedade do sistema geralmente é mais fácil.) Mas o JDK7 não implementa o GCM, e as versões do Oracle (mas NÃO as do OpenJDK) proíbem a criptografia simétrica de 256 bits, a menos que você instale os " Arquivos de política de jurisdição JCE Unlimited Strength Jurisdiction "do site da Oracle; consulte https://stackoverflow.com/a/33712287/2868801 e possivelmentehttps://stackoverflow.com/questions/30350120/sslhandshakeexception- while-connecting-to-a-https-sitePor outro lado, o JDK8 (Oracle e OpenJDK) oferece TLSv1.2 e 1.1 por padrão e implementa o GCM, para que ele possa se conectar sem a política Força Ilimitada.
Tanto o 7 quanto o 8 oferecem suporte à troca de chaves DHE e ECDHE. Mas para qualquer outra pessoa em uma situação semelhante ao JDK6: ECDHE não funciona, a menos que você adicione um provedor de terceiros para primitivas de ECC, como
bcprov
em http://www.BouncyCastle.orgfonte
Para os googlers que acessam esta página com base no título, e não no conteúdo desta pergunta, e desejam que os escravos JNLP se conectem a um Jenkins com proxy reverso que está sendo executado em um servidor separado e não no servidor de proxy reverso, consulte minha resposta para Jenkins: como configurar o Jenkins atrás do proxy reverso do Nginx para que os escravos JNLP se conectem .
fonte