Uploaded image for project: 'Bamboo Data Center'
  1. Bamboo Data Center
  2. BAM-17519

Unable to secure remote agents via automatic keystore management

    XMLWordPrintable

Details

    Description

      Summary

      It is not possible to secure the remote agents to connect to the Bamboo Server (using SSL) through the automatic keystore management feature.

      Steps to Reproduce

      1. Download & Install Bamboo 5.11.x.
      2. Follow the Securing your remote agents documentation to use the automatic keystore management feature.
      3. Install the remote agent.

      Expected Results

      The automatic keystore management feature handles the SSL configuration and creates the following files:

      1. The remote agent keystore at BAMBOO_AGENT_HOME/xml-data/configuration/jmsclient.ks.
      2. The remote agent truststore at BAMBOO_AGENT_HOME/xml-data/configuration/jmsclient.ts.
      3. The Bamboo server keystore at BAMBOO_HOME/xml-data/configuration/broker.ks.

      The remote agent is able to connect to the Bamboo server using SSL.

      Actual Results

      The remote agent truststore at BAMBOO_AGENT_HOME/xml-data/configuration/jmsclient.ts is not created and the installation fails with the following error message:

      INFO   | jvm 2    | 2016/05/04 17:39:47 | 2016-05-04 17:39:47,572 INFO [AgentRunnerThread] [BambooActiveMQConnectionFactory] Setting broker URL to 'failover:(ssl://192.168.10.80:54663?wireFormat.maxInactivityDuration=300000)?initialReconnectDelay=15000&maxReconnectAttempts=10'
      INFO   | jvm 2    | 2016/05/04 17:39:47 | 2016-05-04 17:39:47,574 INFO [AgentRunnerThread] [BambooActiveMQConnectionFactory] Broker URI: ssl://192.168.10.80:54663?wireFormat.maxInactivityDuration=300000 is valid.
      INFO   | jvm 2    | 2016/05/04 17:39:47 | 2016-05-04 17:39:47,670 INFO [AgentRunnerThread] [RemoteAgentHomeLocatorForBootstrap] Using agent home located at [/Users/brosa/Documents/Atlassian/remote-agents/bamboo-5.11.1.1/home]
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 2016-05-04 17:39:48,050 WARN [AgentRunnerThread] [BambooActiveMQConnectionFactory] Unable to automatically manage SSL keys: 
      INFO   | jvm 2    | 2016/05/04 17:39:48 | org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory$ExCertificateException
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.engineGenerateCertificate(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at com.atlassian.bamboo.v2.build.agent.BambooActiveMQConnectionFactory.toJavaCertificate(BambooActiveMQConnectionFactory.java:138)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at com.atlassian.bamboo.v2.build.agent.BambooActiveMQConnectionFactory.getBrokerCertificate(BambooActiveMQConnectionFactory.java:131)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at com.atlassian.bamboo.v2.build.agent.BambooActiveMQConnectionFactory.setupSsl(BambooActiveMQConnectionFactory.java:107)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at java.lang.reflect.Method.invoke(Method.java:497)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:300)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1545)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:276)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:122)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:646)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:646)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:105)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at com.atlassian.bamboo.v2.build.agent.remote.RemoteAgent.initApplicationContext(RemoteAgent.java:253)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at com.atlassian.bamboo.v2.build.agent.remote.RemoteAgent.start(RemoteAgent.java:77)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at java.lang.reflect.Method.invoke(Method.java:497)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at com.atlassian.bamboo.agent.bootstrap.AgentRunner.run(AgentRunner.java:30)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at java.lang.Thread.run(Thread.java:745)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | Caused by: java.io.IOException: DER length more than 4 bytes: 24
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readLength(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readLength(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	at org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.readDERCertificate(Unknown Source)
      INFO   | jvm 2    | 2016/05/04 17:39:48 | 	... 63 more
      
      
      
      

      Workarounds

      Workaround A: Upgrade + remote agents already connected via SSL

      Use this workaround if your goal is to upgrade to an affected version (e.g. 5.10.3 to 5.12.2.1) and you already have a remote agent connected to the Bamboo server using SSL.

      1. Install the remote agent but note that this bug will prevent it from connecting. Refer to the Bamboo remote agent installation guide for details.
      2. Stop the remote agent.
      3. Copy the keys (.ks & .ts) from a working remote agent to the newly installed agent. You'll find the keys here:
        • BAMBOO_AGENT_HOME/xml-data/configuration/jmsclient.ks
        • BAMBOO_AGENT_HOME/xml-data/configuration/jmsclient.ts
      4. Start the remote agent.

      Workaround B: Add secure remote agents for the first time

      Use this workaround if you are already running the affected version and for the first time you need to set up a secure remote agent.

      1. Follow the instructions to create certificates manually. Refer to instructions on How to secure your remote agent (Bamboo Server) for details.
      2. Add the newly created certificates to the Java truststore (cacerts is the default truststore). For example, this is how to import the manually created certificate "bamboo.secure.server.crt" into the Java truststore using Linux:
        sudo keytool -import -trustcacerts -file /opt/atlassian/home/atlassian-bamboo-5.12.2.1/xml-data/configuration/bamboo.secure.server.crt -alias "bamboo.secure.server" -keystore $JAVA_HOME/jre/lib/security/cacerts
        
      1. Configure both the Bamboo server and the agent(s) to not use the automatic certificates but the manually created ones instead by passing in the -Dbamboo.manage.jms.ssl=false JVM parameter on startup:
        • Bamboo server
          <bamboo-install>/bin/setenv.sh
          JVM_SUPPORT_RECOMMENDED_ARGS="-Dbamboo.manage.jms.ssl=false -Djavax.net.ssl.keyStore=/opt/atlassian/home/atlassian-bamboo-5.12.2.1/xml-data/configuration/bamboo.secure.server.ks -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit"
          
        • Bamboo remote agent(s)
          <bamboo-agent-home>/conf/wrapper.conf
          # The Bamboo Agent home configuration file
          wrapper.java.additional.1=-Dbamboo.home=/opt/atlassian/agent/atlassian-bamboo-5.12.2.1
          wrapper.java.additional.2=-Dbamboo.agent.ignoreServerCertName=false
          wrapper.java.additional.3=-Dbamboo.manage.jms.ssl=false
          wrapper.java.additional.4=-Djavax.net.ssl.keyStore=/opt/atlassian/home/atlassian-bamboo-5.12.2.1/xml-data/configuration/bamboo.secure.client.ks
          wrapper.java.additional.5=-Djavax.net.ssl.keyStorePassword=changeit
          wrapper.java.additional.6=-Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre/lib/security/cacerts
          #wrapper.java.additional.3=-Dlog4j.configuration=
          #wrapper.java.additional.3=-agentlib:yjpagent
          
          # Application parameters.  Add parameters as needed starting from 1
          wrapper.app.parameter.1=com.atlassian.bamboo.agent.bootstrap.AgentBootstrap
          wrapper.app.parameter.2=https://BAMBOO_BASE_URL/agentServer
          wrapper.app.parameter.3=
          
          
      1. Start the Bamboo server.
      2. Start the remote agents.

      Scenario C: Revert to use TCP instead of SSL until this issue is fixed.

      Use this workaround if securing your remote agents isn't required at this time.

      1. Shut down the Bamboo server.
      2. Shut down the agent(s).
      3. Change the protocol of your Broker URL and Broker client URL in the bamboo.cfg.xml file to 'TCP'. Do not change the address of this URL. For example, a final solution:
        <property name="bamboo.jms.broker.uri">tcp://0.0.0.0:myport</property>
        <property name="bamboo.jms.broker.client.uri">failover:(tcp://myhost:myport)</property>
        
      1. Start up the Bamboo server.
      2. Start up the Bamboo agent(s).

      Attachments

        Issue Links

          Activity

            People

              pbruski Przemek Bruski
              brosa Bruno Rosa
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: