jjethwa / rundeck

GNU General Public License v3.0
123 stars 137 forks source link

Configs/ Secrets can not be used from inside /etc/rundeck #145

Closed danielpalstra closed 6 years ago

danielpalstra commented 6 years ago

Hi,

Docker services will fail to start when mounting docker configs/ secrets inside the /etc/rundeck directory. The container fails to start because of the chown commands used in https://github.com/jjethwa/rundeck/blob/master/content/opt/run#L17. When configs/ secrets are added the file permissions are managed by docker so they should be allright. I am opening this issue to discuss the solution so I can open a PR.

I suggest to replace the chown commands by the following command so that files which are read only are skipped and the startup proces can continue. find /etc/rundeck -t f -exec chown {} || true \;

What do you think?

jjethwa commented 6 years ago

Hi @danielpalstra

Thanks for reporting the issue. The chown commands were added a long time ago to alleviate the ownership issues when using volumes. Can you provide an example of how you are mounting secrets inside the /etc/rundeck volume?

I think we could probably limit the chown to the specific subset of rundeck configs needed as the startup process runs as root, so that find might always return the full set.

danielpalstra commented 6 years ago

I am using the following compose file to deploy a docker stack on a swarm. (I've removed some environment specific bits). I am adding 2 acl's in the etc dir, but I am also adding other files to /etc/rundeck which are referenced from projects. The same applies to /var/rundeck.

version: '3.3'
services:
  rundeck:
    image: /operations/rundeck:custom
    environment:
      EXTERNAL_SERVER_URL: ""
      RUNDECK_ADMIN_PASSWORD: 
      JAAS_CONF_FILE: jaas-activedirectory.conf
      LOGIN_MODULE: activedirectory
      # use external database
      NO_LOCAL_MYSQL: true
      RUNDECK_STORAGE_PROVIDER: db
      RUNDECK_PROJECT_STORAGE_TYPE: file
      DATABASE_URL: jdbc:mysql://db/rundeck?autoReconnect=true
      DATABASE_ADMIN_USER: root
      # TODO: take from mysql-root secret
      DATABASE_ADMIN_PASSWORD: root 
      # TODO: take from mysql-password secret
      RUNDECK_PASSWORD: rundeck
    ports:
      - "44400:4440"
    volumes:
      - rundeck_mysql:/var/lib/mysql
      - rundeck_log:/var/log/rundeck
    configs:
      - source: adminacl
        target: /admin.acpolicy
      - source: adminacl
        target: apitoken.aclpolicy
    secrets:
      - source: keytab
        target: /etc/automation.keytab
      - source: jaas_config
        target: jaas-activedirectory.conf
      - source: clusters
        target: clusters.yaml
  db:
    image: mariadb:latest
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root
#      - MYSQL_ROOT_PASSWORD=root'
      - MYSQL_DATABASE=rundeck
      - MYSQL_USER=rundeck
      - MYSQL_PASSWORD_FILE=/run/secrets/mysql-password
#      - MYSQL_PASSWORD='rundeck'
    secrets:
      - mysql-root
      - mysql-password
    volumes:
      - db:/var/lib/mysql

volumes:
  rundeck_mysql:
  rundeck_log:
  db:
configs:
  adminacl:
    file: ./config/admin.acpolicy
  apitokenacl: 
    file: ./config/apitoken.aclpolicy

secrets:
  keytab:
    file: ./secrets/automation.keytab
  jaas_config:
    file: ./secrets/jaas-activedirectory.conf
  clusters:
    file: ./secrets/clusters.yaml
  mysql-root:
    external: true
  mysql-password:
    external: true

Just my 2 cents on the volumes. Imo the /etc/rundeck, /var/lib/rundeck/ and some others shouldn't be volumes by default by referencing them in the Dockerfile. The data in the volumes should be static once in production. A user can always mount the specified directory as volume when needed anyway.

jjethwa commented 6 years ago

Thanks, @danielpalstra

So the quick solution would be to set the uid, gid, and mode in the secret definition. For example:

secrets:
  - source: keytab
    target: /etc/automation.keytab
    uid: '101'
    gid: '101'
    mode: 0440

The best way for the container to handle it would be just chown'ing the subset of directories and files it will need to touch. That will be the safest way, what do you think?

The volumes are there for compatibility with the older versions of the container and docker, but it might be time to deprecate them. I'll see if I can find some recommendations from the docker folks or community if it's time to do that. Most likely, it's way past :stuck_out_tongue:

danielpalstra commented 6 years ago

The best way for the container to handle it would be just chown'ing the subset of directories and files it will need to touch. That will be the safest way, what do you think?

I agree. Since docker sets the uid and gid for the mounted secres and configs the script should only touch files that are not already owned by the rundeck user. By following that approach read only files because of mounting secrets will be skipped.

Do you want me to add a PR?

jjethwa commented 6 years ago

That would be great! Thanks so much, @danielpalstra