containers / podman

Podman: A tool for managing OCI containers and pods.
https://podman.io
Apache License 2.0
23.83k stars 2.42k forks source link

Podman login with credential-helper-pass failed to start gpg-agent #19382

Open fishy opened 1 year ago

fishy commented 1 year ago

Issue Description

When trying to use podman pull/login with credential-helper-pass, it hangs for a few seconds then finally give the following errors:

Error: get credentials: 1 error occurred:
        * error getting credentials - err: exit status 1, out: `exit status 2: gpg: error running '/usr/bin/gpg-agent': exit status 2
gpg: failed to start agent '/usr/bin/gpg-agent': General error
gpg: can't connect to the agent: General error
gpg: decryption failed: No secret key`

Steps to reproduce the issue

Steps to reproduce the issue

  1. Initialize the auth.json file:
    $ cat /run/user/1000/containers/auth.json 
    {
        "credHelpers": {
                "docker.io": "pass"
        }
    }
  2. podman login for the first time to store the auth into pass:
    $ podman login --verbose docker.io
    Username: fishy
    Password: 
    Used:  /run/user/1000/containers/auth.json
    Login Succeeded!
  3. verify that it's stored inside pass (ZG9ja2VyLmlv is the base64 of docker.io):
    $ pass ls docker-credential-helpers/ZG9ja2VyLmlv
    docker-credential-helpers/ZG9ja2VyLmlv
    └── fishy
  4. login again:
    $ podman login --verbose docker.io
    Error: get credentials: 1 error occurred:
        * error getting credentials - err: exit status 1, out: `exit status 2: gpg: error running '/usr/bin/gpg-agent': exit status 2
    gpg: failed to start agent '/usr/bin/gpg-agent': General error
    gpg: can't connect to the agent: General error
    gpg: decryption failed: No secret key`

Describe the results you received

gpg-agent failed

Describe the results you expected

gpg-agent successfully prompt for passphrase

podman info output

$ podman info
host:
  arch: amd64
  buildahVersion: 1.28.2
  cgroupControllers:
  - cpu
  - memory
  - pids
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon_2.1.6+ds1-1_amd64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.6, commit: unknown'
  cpuUtilization:
    idlePercent: 99.43
    systemPercent: 0.2
    userPercent: 0.37
  cpus: 12
  distribution:
    codename: trixie
    distribution: debian
    version: unknown
  eventLogger: journald
  hostname: perch
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 6.3.0-1-amd64
  linkmode: dynamic
  logDriver: journald
  memFree: 4766781440
  memTotal: 16362147840
  networkBackend: cni
  ociRuntime:
    name: crun
    package: crun_1.8.5-1_amd64
    path: /usr/bin/crun
    version: |-
      crun version 1.8.5
      commit: b6f80f766c9a89eb7b1440c0a70ab287434b17ed
      rundir: /run/user/1000/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +WASM:wasmedge +YAJL
  os: linux
  remoteSocket:
    exists: true
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns_1.2.0-1_amd64
    version: |-
      slirp4netns version 1.2.0
      commit: 656041d45cfca7a4176f6b7eed9e4fe6c11e8383
      libslirp: 4.7.0
      SLIRP_CONFIG_VERSION_MAX: 4
      libseccomp: 2.5.4
  swapFree: 15715528704
  swapTotal: 16773017600
  uptime: 218h 25m 54.00s (Approximately 9.08 days)
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries: {}
store:
  configFile: /home/fishy/.config/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions:
    overlay.mount_program:
      Executable: /usr/bin/fuse-overlayfs
      Package: fuse-overlayfs_1.10-1_amd64
      Version: |-
        fusermount3 version: 3.14.0
        fuse-overlayfs: version 1.10
        FUSE library version 3.14.0
        using FUSE kernel interface version 7.31
  graphRoot: /home/fishy/.local/share/containers/storage
  graphRootAllocated: 233595908096
  graphRootUsed: 137269542912
  graphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 2
  runRoot: /run/user/1000/containers
  volumePath: /home/fishy/.local/share/containers/storage/volumes
version:
  APIVersion: 4.3.1
  Built: 0
  BuiltTime: Wed Dec 31 16:00:00 1969
  GitCommit: ""
  GoVersion: go1.19.8
  Os: linux
  OsArch: linux/amd64
  Version: 4.3.1


### Podman in a container

No

### Privileged Or Rootless

Rootless

### Upstream Latest Release

No

### Additional environment details

Additional environment details

### Additional information

It also looks like `podman login` in particular ignores `~/.config/containers/auth.json` file and I have to update `/run/user/1000/containers/auth.json` to make sure that `podman login` uses the correct credential helper. `podman pull` does respect `~/.config/containers/auth.json`.
fishy commented 1 year ago

copying my additional information section answer here as it's not formatted correctly in the original description:

It also looks like podman login in particular ignores ~/.config/containers/auth.json file and I have to update /run/user/1000/containers/auth.json to make sure that podman login uses the correct credential helper. podman pull does respect ~/.config/containers/auth.json.

please let me know if you prefer me to open a separated issue for it.

rhatdan commented 1 year ago

@mtrmac @vrothberg Where are you supposed to setup auth helpers in Linux?

rhatdan commented 1 year ago
man container-registries.conf
DESCRIPTION
       The CONTAINERS-REGISTRIES configuration file is a system-wide  configu‐
       ration file for container image registries. The file format is TOML.

       Container engines will use the $HOME/.config/containers/registries.conf
       if it exists, otherwise they will use /etc/containers/registries.conf

   GLOBAL SETTINGS
       unqualified-search-registries
              An array of host[:port] registries to try when  pulling  an  un‐
              qualified image, in order.

       credential-helpers
              An  array of default credential helpers used as external creden‐
              tial stores.  Note that  "containers-auth.json"  is  a  reserved
              value to use auth files as specified in containers-auth.json(5).
              The credential helpers are set  to  ["containers-auth.json"]  if
              none are specified.
mtrmac commented 1 year ago

On the substance of the issue, rootless Podman runs in a fairly unusual process environment.

E.g. see the past comment in https://github.com/containers/podman/issues/4123#issuecomment-772763894 .

I don’t know much about diagnosing GPG error states. “General error” is not very helpful.

fishy commented 1 year ago

setting GPG_TTY doesn't help in my case, still getting the same error:

$ GPG_TTY=$(tty) podman login --verbose docker.io
Error: get credentials: 1 error occurred:
        * error getting credentials - err: exit status 1, out: `exit status 2: gpg: error running '/usr/bin/gpg-agent': exit status 2
gpg: failed to start agent '/usr/bin/gpg-agent': General error
gpg: can't connect to the agent: General error
gpg: decryption failed: No secret key`

(I also tried first export GPG_TTY then run podman login, same error)

github-actions[bot] commented 1 year ago

A friendly reminder that this issue had no activity for 30 days.

devrite commented 7 months ago

I also get an error with gpg and a gpg compatible card (needs a pin to enter). docker login works flawlessly also with pulling or pushing as well as querying the password via the helper (or pass directly). It opens up the GUI pinentry program or whatever is set.

But when using podman pull <image> you get an error like below if I do not kill the gpg-agent and set GPG_TTY. If I do not set it I immediately aborts with the error below and if I set it but do not kill the agent. It asks to reinsert the keycard. It seems podman can't access the agent and tries to start a new one or so and only one of them is managing the card (using libccid not pcscd).

I migrated from 4.X (4.6 and 4.9) to 5.0.2. I did not have this issues before, but I might not have used it with a card at that time and had the images available. So there is the chance that this issue only affects keycards but not keys, except for the fact you have to set GPG_TTY and it can't use the GUI-pinentry.

Errors below and podman info.

Error: initializing source docker://<image>: getting username and password: 1 error occurred:
        * error getting credentials - err: exit status 1, out: `exit status 2: gpg: decryption failed: No secret key`
host:
  arch: amd64
  buildahVersion: 1.35.3
  cgroupControllers:
  - memory
  - pids
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: Unknown
    path: /usr/local/libexec/podman/conmon
    version: 'conmon version 2.1.10, commit: 2dcd736e46ded79a53339462bc251694b150f870'
  cpuUtilization:
    idlePercent: 96.05
    systemPercent: 1
    userPercent: 2.95
  cpus: 8
  databaseBackend: sqlite
  distribution:
    codename: jammy
    distribution: ubuntu
    version: "22.04"
  eventLogger: journald
  freeLocks: 2048
  hostname: l1as11
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 6.5.0-27-generic
  linkmode: dynamic
  logDriver: journald
  memFree: 629104640
  memTotal: 16561168384
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: Unknown
    package: Unknown
    path: /usr/local/libexec/podman/netavark
    version: netavark 1.10.3
  ociRuntime:
    name: crun
    package: Unknown
    path: /usr/local/bin/crun
    version: |-
      crun version 1.14.4.0.0.0.31-3767
      commit: 37670c8d569f082e373451e0ca619e8619069a49
      rundir: /run/user/1000/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +YAJL
  os: linux
  pasta:
    executable: /usr/bin/pasta
    package: passt_954589b-1_all
    version: |
      pasta 2024_03_26.4988e2b-12-g954589b
      Copyright Red Hat
      GNU General Public License, version 2 or later
        <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
  remoteSocket:
    exists: false
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns_1.0.1-2_amd64
    version: |-
      slirp4netns version 1.0.1
      commit: 6a7b16babc95b6a3056b33fb45b74a6f62262dd4
      libslirp: 4.6.1
  swapFree: 0
  swapTotal: 0
  uptime: 28h 8m 23.00s (Approximately 1.17 days)
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  search:
  - docker.io
  - quay.io
store:
  configFile: /home/user/.config/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /home/user/.local/share/containers/storage
  graphRootAllocated: 369393504256
  graphRootUsed: 230303305728
  graphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Supports shifting: "false"
    Supports volatile: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 2
  runRoot: /run/user/1000/containers
  transientStore: false
  volumePath: /home/user/.local/share/containers/storage/volumes
version:
  APIVersion: 5.0.2
  Built: 1713512036
  BuiltTime: Fri Apr 19 09:33:56 2024
  GitCommit: 3304dd95b8978a8346b96b7d43134990609b3b29
  GoVersion: go1.22.2
  Os: linux
  OsArch: linux/amd64
  Version: 5.0.2
Ubuntu 22.04

So again as a workaround set the TTY and kill the agent if necessary.