containers / podman-compose

a script to run docker-compose.yml using podman
GNU General Public License v2.0
5.12k stars 486 forks source link

Secrets aren't getting created properly when specified in the compose file #655

Open dgiridharan opened 1 year ago

dgiridharan commented 1 year ago

Summary podman-compose fails to create secrets defined in the compose file, resulting in permission errors.

Describe the bug When defining secrets in a compose file for podman-compose for public/private ssh keys, the secrets are not created, and permission errors occur for the ssh keys in the container.

Expected Behavior The secrets should be created and ssh keys should be present in the container with proper permissions.

Actual Behavior The secrets are not created, and permission errors occur for the ssh keys in the container. Contents of the .ssh folder in the container:

[root@f89333bda8fa .ssh]# ls -l
ls: cannot access 'id_ed25519': Permission denied
ls: cannot access 'id_ed25519.pub': Permission denied
total 0
-????????? ? ? ? ?            ? id_ed25519
-????????? ? ? ? ?            ? id_ed25519.pub

Using podman secret ls confirms that no secrets are created.

To Reproduce Run podman-compose up using the following compose.yaml file:

services:
  secrets-test:
    image: registry.fedoraproject.org/fedora:latest
    secrets:
      - source: ssh-key
        target: /root/.ssh/id_ed25519
        mode: 0600
      - source: ssh-key-pub
        target: /root/.ssh/id_ed25519.pub
        mode: 0644
    tty: true
    stdin_open: true
secrets:
  ssh-key:
    file: $HOME/.ssh/id_ed25519
  ssh-key-pub:
    file: $HOME/.ssh/id_ed25519.pub

Inspecting the /root/.ssh directory of the resulting container:

[root@f89333bda8fa .ssh]# ls -l
ls: cannot access 'id_ed25519': Permission denied
ls: cannot access 'id_ed25519.pub': Permission denied
total 0
-????????? ? ? ? ?            ? id_ed25519
-????????? ? ? ? ?            ? id_ed25519.pub

Output of podman secret ls:

ID          NAME        DRIVER      CREATED     UPDATED

Additional Context I can successfully accomplish this using the following command in bash:

podman secret create ssh-key $HOME/.ssh/id_ed25519
podman secret create ssh-key-pub $HOME/.ssh/id_ed25519.pub

podman create -t --secret ssh-key,target=/root/.ssh/id_ed25519,mode=0600 --secret ssh-key-pub,target=/root/.ssh/id_ed25519.pub,mode=0644 registry.fedoraproject.org/fedora:latest

Runnig the created container and inspecting the /root/.ssh directory confirms that the secrets are working as expected.

Version info

$ podman-compose version
using podman version: 4.4.2
podman-composer version  1.0.3
podman --version 
podman version 4.4.2

Environment:

dgiridharan commented 1 year ago

I'm fairly new to podman and podman-compose. I want to apologize ahead of time in case I'm doing something incorrectly!

I also really love this project and the ease of transitioning from Docker -> Podman. Great work guys!

bugfest commented 1 year ago

Hi @dgiridharan!

This behavior is already fixed in the devel branch - I've used v1.0.3-156-gb8a7593. It was probably fixed at af1034548342672b1b02ead510c8bd5f5abf0da8 (Issue #440). Until a new stable version is published you can get it working by installing the devel version.

Check the installation section or... TLDR:

$ pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

Please close this issue if this answers your case

SnowyJune678 commented 1 year ago

Hello,

I've noticed that file secrets (as reported in the original issue) still does not work in the devel build. I have tested it out with the above development build install instructions, and with the provided tests in the repo, at tests/secrets/docker-compose.yaml.

I have replicated the issue on Oracle Linux 8 and Python 3.9 inside a venv, by downloading the repo, and running the compose file in the above directory. However, I have modified the command directive from

      command:
        - /tmp/print_secrets.sh

to

      command:
        - /bin/sh.

Running podman up generates this output

podman create 
--name=secrets_test_1
--pod=pod_secrets
--label io.podman.compose.config-hash=108022c87892934f145923b1cd45f8d0a719dba9b04b9ef3c9d48856b637ad09
--label io.podman.compose.project=secrets
--label io.podman.compose.version=1.0.7
--label PODMAN_SYSTEMD_UNIT=podman-compose@secrets.service
--label com.docker.compose.project=secrets
--label com.docker.compose.project.working_dir=/home/opc/podmancompose/podman-compose-devel/tests/secrets
--label com.docker.compose.project.config_files=docker-compose.yaml
--label com.docker.compose.container-number=1 
--label com.docker.compose.service=test --tmpfs /run 
--tmpfs /tmp
-v /home/opc/podmancompose/podman-compose-devel/tests/secrets/print_secrets.sh:/tmp/print_secrets.sh:z
--net secrets_default
--network-alias test
--secret my_secret 
--secret my_secret_2
--secret my_secret_3,uid=103,gid=103,mode=400
--volume /home/opc/podmancompose/podman-compose-devel/tests/secrets/my_secret:/run/secrets/file_secret:ro,rprivate,rbind
--volume /home/opc/podmancompose/podman-compose-devel/tests/secrets/my_secret:/run/secrets/custom_name:ro,rprivate,rbind
 --volume /home/opc/podmancompose/podman-compose-devel/tests/secrets/my_secret:/etc/custom_location:ro,rprivate,rbind
--volume /home/opc/podmancompose/podman-compose-devel/tests/secrets/my_secret:/run/secrets/unused_params_warning:ro,rprivate,rbind busybox
 /bin/sh

I believe this means that the file secret simply being mounted without addressing the SELinux context issues, nor is the file being registered as a secret with podman; there were no podman secret commands being issued during startup.

I've included fuller command logs here: https://gist.github.com/SnowyJune678/b173d906ab9b5f65ae1ab2172411b363

brianredbeard commented 4 months ago

Confirmed, it's still creating the mount with the wrong context (as specified here).

$ podman-compose -v
podman-compose version 1.1.0
podman version 4.7.2
A simple compose.yaml for the Odoo CRM ```yaml version: '3.1' services: web: image: odoo:16.0 depends_on: - db ports: - "8070:8069" volumes: - odoo-web-data:/var/lib/odoo - /srv/odoo/config:/etc/odoo - /srv/odoo/data:/mnt/extra-addons - /srv/odoo/export:/mnt/export environment: - PASSWORD_FILE=/run/secrets/postgresql_password secrets: - postgresql_password db: image: postgres:15 environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD_FILE=/run/secrets/postgresql_password - POSTGRES_USER=odoo - PGDATA=/var/lib/postgresql/data/pgdata volumes: - odoo-db-data:/var/lib/postgresql/data/pgdata - /srv/odoo/export:/mnt/export secrets: - postgresql_password volumes: odoo-web-data: odoo-db-data: secrets: postgresql_password: file: /srv/odoo/odoo_pg_pass ```

Attempting to start this fails with the following error:

Searching through the audit logs confirms it's SELinux blocking file access:

 sudo ausearch -m avc -ts recent
----
time->Wed Jul 31 20:40:37 2024
type=AVC msg=audit(1722458437.199:1487761): avc:  denied  { read } for  pid=549571 comm="bash" name="odoo_pg_pass" dev="vda5" ino=4081094 scontext=system_u:system_r:container_t:s0:c99,c289 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0
----
time->Wed Jul 31 20:40:37 2024
type=AVC msg=audit(1722458437.709:1487787): avc:  denied  { read } for  pid=549691 comm="entrypoint.sh" name="odoo_pg_pass" dev="vda5" ino=4081094 scontext=system_u:system_r:container_t:s0:c596,c607 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0
----
time->Wed Jul 31 20:48:21 2024
type=AVC msg=audit(1722458901.922:1488088): avc:  denied  { read } for  pid=550111 comm="bash" name="odoo_pg_pass" dev="vda5" ino=4081094 scontext=system_u:system_r:container_t:s0:c161,c268 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0
----
time->Wed Jul 31 20:48:22 2024
type=AVC msg=audit(1722458902.216:1488098): avc:  denied  { read } for  pid=550185 comm="entrypoint.sh" name="odoo_pg_pass" dev="vda5" ino=4081094 scontext=system_u:system_r:container_t:s0:c646,c879 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0
----
time->Wed Jul 31 20:48:26 2024
type=AVC msg=audit(1722458906.500:1488124): avc:  denied  { read } for  pid=550442 comm="bash" name="odoo_pg_pass" dev="vda5" ino=4081094 scontext=system_u:system_r:container_t:s0:c518,c972 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0
----
time->Wed Jul 31 20:48:26 2024
type=AVC msg=audit(1722458906.622:1488127): avc:  denied  { read } for  pid=550453 comm="bash" name="odoo_pg_pass" dev="vda5" ino=4081094 scontext=system_u:system_r:container_t:s0:c518,c972 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0
----
time->Wed Jul 31 20:48:27 2024
type=AVC msg=audit(1722458907.059:1488153): avc:  denied  { read } for  pid=550573 comm="entrypoint.sh" name="odoo_pg_pass" dev="vda5" ino=4081094 scontext=system_u:system_r:container_t:s0:c704,c844 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0

On a lark, I tried adding ":z" to the file definition for the secret, e.g:

secrets:
  postgresql_password:
    file: /srv/odoo/odoo_pg_pass:z

This resulted in the following error, demonstrating the broken mount options being populated:

podman compose  -f odoo-compose.yaml   up
>>>> Executing external compose provider "/usr/bin/podman-compose". Please refer to the documentation for details. <<<<

54258277838d672e8f72808e182486558f2efa9e906e72939a7fd6dc04d5d7f5
Error: /srv/odoo/odoo_pg_pass:z:/run/secrets/postgresql_password:ro,rprivate,rbind: incorrect volume format, should be [host-dir:]ctr-dir[:option]
Error: /srv/odoo/odoo_pg_pass:z:/run/secrets/postgresql_password:ro,rprivate,rbind: incorrect volume format, should be [host-dir:]ctr-dir[:option]
[db]  | Error: no container with name or ID "root_db_1" found: no such container
[web] | Error: no container with name or ID "root_web_1" found: no such container
orion160 commented 3 months ago

+1

yozachar commented 3 months ago

Files for error re-production

.env

export POSTGRES_USER=admin
export POSTGRES_PASSWORD=admin@123
export POSTGRES_DB=admdb
export POSTGRES_PORT=5432

compose.yaml

# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json

name: mtk

volumes:
  pgv:

secrets:
  postgres_user:
    environment: POSTGRES_USER
  postgres_password:
    environment: POSTGRES_PASSWORD

services:
  postgres:
    image: docker.io/postgres:alpine
    restart: always
    secrets:
      - postgres_user
      - postgres_password
    ports:
      - $POSTGRES_PORT:5432
    environment:
      POSTGRES_USER: /run/secrets/postgres_user
      POSTGRES_PASSWORD: /run/secrets/postgres_password
      POSTGRES_DB: $POSTGRES_DB
    volumes:
      - pgv:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      interval: 1s
      timeout: 5s
      retries: 10

Expected

podman-compose executes podman secret create postgres_user --env POSTGRES_USER under the hood and so:

$ podman secret ls
ID                         NAME               DRIVER      CREATED         UPDATED
c3aaba5b0b1073dbd05bbd831  postgres_password  file        6 seconds ago   6 seconds ago
5f81dc1d2967c9e66900d28a1  postgres_user      file        49 seconds ago  49 seconds ago

Actual

$ podman secret ls
ID                         NAME               DRIVER      CREATED         UPDATED

But even after manually adding the secrets:

console

$ python --version
Python 3.12.5
$ podman-compose --version
podman-compose version 1.2.0
podman version 5.2.0
$ podman-compose up
8000e87526f3d332e77b474daa0438e24ae6f010d27743436ba461e3ffad7f85
Traceback (most recent call last):
  File "~/.local/bin/podman-compose", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "~/.local/share/pipx/venvs/podman-compose/lib/python3.12/site-packages/podman_compose.py", line 3504, in main
    asyncio.run(async_main())
  File "~/.local/share/mise/installs/python/3.12.5/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "~/.local/share/mise/installs/python/3.12.5/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/.local/share/mise/installs/python/3.12.5/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "~/.local/share/pipx/venvs/podman-compose/lib/python3.12/site-packages/podman_compose.py", line 3500, in async_main
    await podman_compose.run()
  File "~/.local/share/pipx/venvs/podman-compose/lib/python3.12/site-packages/podman_compose.py", line 1743, in run
    retcode = await cmd(self, args)
              ^^^^^^^^^^^^^^^^^^^^^
  File "~/.local/share/pipx/venvs/podman-compose/lib/python3.12/site-packages/podman_compose.py", line 2500, in compose_up
    podman_args = await container_to_args(compose, cnt, detached=args.detach)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/.local/share/pipx/venvs/podman-compose/lib/python3.12/site-packages/podman_compose.py", line 1103, in container_to_args
    podman_args.extend(get_secret_args(compose, cnt, secret))
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/.local/share/pipx/venvs/podman-compose/lib/python3.12/site-packages/podman_compose.py", line 646, in get_secret_args
    raise ValueError(
ValueError: ERROR: unparsable secret: "postgres_user", service: "postgres"

On another machine (Windows):

Please ignore the path re-styling

$ podman-compose up
Error: failed to make pod: adding pod to state: name "pod_mtk" is in use: pod already exists
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "~/.local/bin/podman-compose.exe/__main__.py", line 7, in <module>
  File "~/pipx/venvs/podman-compose/Lib/site-packages/podman_compose.py", line 3504, in main
    asyncio.run(async_main())
  File "~/scoop/apps/pyenv/current/pyenv-win/versions/3.12.4/Lib/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "~/scoop/apps/pyenv/current/pyenv-win/versions/3.12.4/Lib/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/scoop/apps/pyenv/current/pyenv-win/versions/3.12.4/Lib/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "~/pipx/venvs/podman-compose/Lib/site-packages/podman_compose.py", line 3500, in async_main
    await podman_compose.run()
  File "~/pipx/venvs/podman-compose/Lib/site-packages/podman_compose.py", line 1743, in run
    retcode = await cmd(self, args)
              ^^^^^^^^^^^^^^^^^^^^^
  File "~/pipx/venvs/podman-compose/Lib/site-packages/podman_compose.py", line 2521, in compose_up
    loop.add_signal_handler(signal.SIGINT, lambda: [t.cancel("User exit") for t in tasks])
  File "~/scoop/apps/pyenv/current/pyenv-win/versions/3.12.4/Lib/asyncio/events.py", line 582, in add_signal_handler
    raise NotImplementedError
NotImplementedError
luckylinux commented 3 days ago

Any News on this ?

I still hit SELinux Access Denied with

podman-compose version 1.2.0
podman version 5.3.1

Do we need to install from the main Branch in order to get a working Version with SELinux ?