Changing the default users password cause rundeck to fail on start

270 views
Skip to first unread message

Erwin

unread,
Feb 11, 2022, 10:41:25 AM2/11/22
to rundeck-discuss
Hello everyone,

Rundeck (version 3.4.10) is running as a container, up until now I've used the default admin creds to play with rundeck.
I wanted to change them, so I followed the documentation and changed the content on realm.properties.

I've deleted the default "admin" and "user" users and added the following line :
admin:mybeautifullpassword,user,admin

But when I deploy again the docker service, Rundeck spits those lines of logs :

[2022-02-11T15:26:18,455] INFO  rundeckapp.Application - The following profiles are active: production
[2022-02-11T15:26:20,079] WARN  util.Environment - Found spring-loaded on classpath but JVM is not 1.8 - skipping

Configuring Spring Security Core ...
... finished configuring Spring Security Core


[2022-02-11T15:26:36,285] ERROR pool.ConnectionPool - Unable to create initial connections of pool.
org.postgresql.util.PSQLException: Something unusual has occurred to cause the driver to fail. Please report this exception.
        at org.postgresql.Driver.connect(Driver.java:281) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:319) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:212) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:744) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:676) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:483) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) ~[tomcat-jdbc-9.0.44.jar!/:?]
       [Cat org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) ~[tomcat-jdbc-9.0.44.jar!/:?]
        at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy.afterPropertiesSet(LazyConnectionDataSourceProxy.java:164) ~[spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy.<init>(LazyConnectionDataSourceProxy.java:108) ~[spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.grails.datastore.gorm.jdbc.connections.DataSourceConnectionSourceFactory.proxy(DataSourceConnectionSourceFactory.java:100) ~[grails-datastore-gorm-7.0.4.RELEASE.jar!/:?]
        at org.grails.datastore.gorm.jdbc.connections.DataSourceConnectionSourceFactory.create(DataSourceConnectionSourceFactory.java:93) ~[grails-datastore-gorm-7.0.4.RELEASE.jar!/:?]
        at org.grails.datastore.gorm.jdbc.connections.CachedDataSourceConnectionSourceFactory.create(CachedDataSourceConnectionSourceFactory.java:37) ~[grails-datastore-gorm-7.0.4.RELEASE.jar!/:?]
        at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:38) ~[grails-datastore-gorm-hibernate5-7.0.3.RELEASE.jar!/:?]
        at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:23) ~[grails-datastore-gorm-hibernate5-7.0.3.RELEASE.jar!/:?]
        at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:64) ~[grails-datastore-core-7.0.4.RELEASE.jar!/:?]
        at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:52) ~[grails-datastore-core-7.0.4.RELEASE.jar!/:?]
        at org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer.create(ConnectionSourcesInitializer.groovy:24) ~[grails-datastore-core-7.0.4.RELEASE.jar!/:?]
        at org.grails.orm.hibernate.HibernateDatastore.<init>(HibernateDatastore.java:212) ~[grails-datastore-gorm-hibernate5-7.0.3.RELEASE.jar!/:?]
        at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:490) ~[?:?]
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:200) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:308) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:293) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1358) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:694) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1358) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck(AbstractAutowireCapableBeanFactory.java:1008) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:885) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:613) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:533) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:491) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:265) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1451) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1250) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:874) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:778) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:528) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) [spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) [spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) [spring-beans-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:228) [spring-context-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:722) [spring-context-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:535) [spring-context-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) [spring-boot-2.1.13.RELEASE.jar!/:2.1.13.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) [spring-boot-2.1.13.RELEASE.jar!/:2.1.13.RELEASE]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) [spring-boot-2.1.13.RELEASE.jar!/:2.1.13.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.1.13.RELEASE.jar!/:2.1.13.RELEASE]
        at grails.boot.GrailsApp.run(GrailsApp.groovy:96) [grails-core-4.0.3.jar!/:4.0.3]
        at grails.boot.GrailsApp.run(GrailsApp.groovy:456) [grails-core-4.0.3.jar!/:4.0.3]
        at grails.boot.GrailsApp.run(GrailsApp.groovy:443) [grails-core-4.0.3.jar!/:4.0.3]
        at grails.boot.GrailsApp$run.call(Unknown Source) [grails-core-4.0.3.jar!/:?]
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) [groovy-2.5.6.jar!/:2.5.6]
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115) [groovy-2.5.6.jar!/:2.5.6]
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:135) [groovy-2.5.6.jar!/:2.5.6]
        at rundeckapp.Application.main(Application.groovy:32) [classes!/:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [rundeck.war:?]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [rundeck.war:?]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51) [rundeck.war:?]
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:58) [rundeck.war:?]
Caused by: java.lang.IllegalArgumentException: Empty string 'password'
        at org.postgresql.shaded.com.ongres.scram.common.util.Preconditions.checkNotEmpty(Preconditions.java:56) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.shaded.com.ongres.scram.client.ScramSession$ServerFirstProcessor.clientFinalProcessor(ScramSession.java:128) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.jre7.sasl.ScramAuthenticator.processServerFirstMessage(ScramAuthenticator.java:132) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:690) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:146) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:197) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:217) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.Driver.makeConnection(Driver.java:458) ~[postgresql-42.2.13.jar!/:42.2.13]
        at org.postgresql.Driver.connect(Driver.java:260) ~[postgresql-42.2.13.jar!/:42.2.13]
        ... 85 more


I'm using postgresql indeed, the connexion to the database is configured with environment variables in the docker-compose file :

    environment:
      RUNDECK_DATABASE_DRIVER: org.postgresql.Driver
      RUNDECK_DATABASE_USERNAME: rundeck
      RUNDECK_DATABASE_URL: jdbc:postgresql://postgresql/rundeck
    secrets:
      - RUNDECK_ADMIN_PASSWORD
    entrypoint: >-
      sh -c '
        RUNDECK_DATABASE_PASSWORD=$$(cat /run/secrets/RUNDECK_POSTGRES_PASSWORD) \
        sed -i "/admin:admin/d" ~/server/config/realm.properties && \
        sed -i "/user:user/d" ~/server/config/realm.properties && \
        echo "admin:$$(cat /run/secrets/RUNDECK_ADMIN_PASSWORD),user,admin" >> ~/server/config/realm.properties && \
        exec /tini /home/rundeck/docker-lib/entry.sh
      '

It seems that IF I touch the realm.properties file, Rundeck freaks out, even if I don't delete the "admin" and "user" users. I don't understand what is has to do wit postgresql however, can someone help me with this?

Regards,

--
Erwin

Erwin

unread,
Feb 11, 2022, 10:43:15 AM2/11/22
to rundeck-discuss
Note : I've tried to use BCRYPT password like the documentation suggests, but the result is the same :(

rac...@rundeck.com

unread,
Feb 11, 2022, 2:33:25 PM2/11/22
to rundeck-discuss

Hi Erwin,

Try to use the RUNDECK_DATABASE_PASSWORD env var in the environment section, here you can see a full functional example.

In addition, a good approach is to use the realm.properties mounted as a volume, take a look at this example.

Regards.

Andrew Kunz

unread,
Feb 14, 2022, 6:06:26 AM2/14/22
to rundeck-discuss

Database password -e works fine what about the rundeck admin?

Andrew

Erwin

unread,
Feb 14, 2022, 6:13:36 AM2/14/22
to rundeck-discuss
Hello,

I prefer to avoid putting passwords directly in my compose file, for two reasons :
- Better security, anyone viewing the file will only see the secrets name (you could argue that you just need to exec into rundeck's container to see the passwords, but for that you need to be in the docker group on the server)
- The docker-compose (and other associated files for the rundeck project) can be put in a git repository without any modification, without the risk of the repo containing passwords. to launch the stack on a new server, I just need to configure the secrets.
=> This also facilitate our continuity plan if a disaster struck our datacenter.

Right now, I'm using the file realm.properties as a config file, as you suggested. It works as intended (Although I really don't like this... Since now, the password to access the service are more easily accessed).
It's really weird that if I modify the file with the entrypoint before launching rundeck, it throws my a postgres error.

If rundeck could handle environment variables loaded for secrets (like the mysql/mariadb image) I would be even better (I swear I saw a Github issue about that, but I can't find it now).


Regards,
--
Erwin
Reply all
Reply to author
Forward
0 new messages