When we run docker login, we will often see a warning message that our password is saved encrypted in the Docker configuration file.
The warning might be ignored if the account and password to the operating system is not shared with others. However, if it is a shared account, docker login might put your docker account and password in danger. If we check the JSON file, we would find there is an unencrypted representing our password there.
$ docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: leimao Password: WARNING! Your password will be stored unencrypted in /home/leimao/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded # Passwork saved as an unencrypted string in "auth". $ cat /home/leimao/.docker/config.json { "auths": { "https://index.docker.io/v1/": { "auth": "xxxxxxxxxxxxxxxxxxxxxxxx" } }, "HttpHeaders": { "User-Agent": "Docker-Client/19.03.12 (linux)" } } # Docker logout to remove the saved credentials. $ docker logout
# Install the standard Unix password manager. $ sudo apt-get install pass
# Download and install docker-credential-pass. # The latest version is v0.6.3. $ cd ~/Downloads/ $ wget https://github.com/docker/docker-credential-helpers/releases/download/v0.6.3/docker-credential-pass-v0.6.3-amd64.tar.gz $ tar -xvf docker-credential-pass-v0.6.3-amd64.tar.gz # Open ~/.bashrc to modify the $PATH or move the docker-credential-pass to the $PATH. $ sudo rm /usr/bin/docker-credential-pass $ sudo mv docker-credential-pass /usr/bin/ $ chmod +x /usr/bin/docker-credential-pass
# Docker credentials helper have no credentials saved yet. $ docker-credential-pass list {}
# This might be necessary if the following step hangs forever. # $ sudo apt-get install rng-tools
# Generate encryption keys. $ gpg --generate-key gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg --full-generate-key"for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: leimao Email address: dukeleimao@gmail.com You selected this USER-ID: "leimao <dukeleimao@gmail.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O # Following the instruction to reate the password to the user ID.
# Initialize the password manager for the encryption key. $ pass init dukeleimao@gmail.com mkdir: created directory '/home/leimao/.password-store/' Password store initialized for dukeleimao@gmail.com
# Add "credsStore": "pass" to the JSON file. # So that Docker knows it has to use docker-credential-pass to manage credentials. $ vim ~/.docker/config.json
# Now we could safely login. $ docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: leimao Password: Login Succeeded $ docker-credential-pass list {"https://index.docker.io/v1/":"leimao"} # The password is no longer saved in the Docker configuration. $ cat ~/.docker/config.json { "auths": { "https://index.docker.io/v1/": {} }, "HttpHeaders": { "User-Agent": "Docker-Client/19.03.12 (linux)" }, "credsStore": "pass" }
Caveats
If we happen to screw anything up, we could restart by deleting the related files.
1
$ rm -rf ~/.docker/ ~/.password-store/ ~/.gnupg/
In some scenarios, especially when we SSH remotely, even with the Docker credentials helper correctly set up, we might still not be able to access the content in the Docker registry.
1 2
$ docker pull leimao/xxxxx:1.0 Error response from daemon: pull access denied for leimao/xxxxx, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
This is because gpg was not correctly invoked. This could be resolved by setting the environment variable GPG_TTY.
1
$ export GPG_TTY=$(tty)
If you are curious about what tty is, you might check via the following command.
1 2 3
$ tty --help Usage: tty [OPTION]... Print the file name of the terminal connected to standard input.