天天看点

docker登录密码错误_Docker Login登录凭证安全存储

Docker利用docker login命令来校验用户镜像仓库的登录凭证,实际并不是真正意义上的登录(Web Login),仅仅是一种登录凭证的试探校验,如果用户名密码正确,Docker则会把用户名、密码 以及仓库域名等信息进行base64编码保存在Docker的配置文件中,在Linux中文件路径是$HOME/.docker/config.json。

登录Docker官方镜像仓库

[[email protected] ~]# docker login -u lovemm -p mylovemm520WARNING! Using --password via the CLI is insecure. Use --password-stdin.WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
           

指定域名登录其它仓库

[[email protected] ~]# docker login hub.test.company.comUsername: lovemmPassword: WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
           

查看/root/.docker/config.json文件(文件中数据非真实数据)

[[email protected] ~]# cat .docker/config.json{ "auths": { "https://index.docker.io/v1/": { "auth": "zZW46a2luluZ2ZzZW4xMDI2Z2Za2" }, "hub.test.company.com": { "auth": "0xVWYWRtaW46zzOKhkaOeVpaGJ3bz0YUmhjbmt0VFds=" } }, "HttpHeaders": { "User-Agent": "Docker-Client/18.09.2 (linux)" }}
           

用户名密码可直接通过如下命令解码为明文

echo 'zZW46a2luluZ2ZzZW4xMDI2Z2Za2' | base64 --decode
           

从config.json数据结构可知,Docker针对每一个镜像仓库,只会保存最近一次有效的用户名密码,之后执行docker login $domain会直接使用config.json中对应域名的用户名密码进行登录。 当处理完毕之后,可以执行docker logout hub.test.company.com将指定仓库的用户登录凭证从config.json中删除。

[[email protected] ~]# docker logout Removing login credentials for https://index.docker.io/v1/
           

Docker直接将仓库的用户名密码明文保存在配置文件中非常不安全,除非用户每次在与镜像仓库交互完成之后手动执行docker logout删除,这种明文密码很容易被他人窃取, Docker也考虑到这一点,针对不同的平台,其提供了不同的辅助工具将仓库的登录凭证保存到其他安全系数高的存储中。

  • D-Bus Secret Service
  • Apple macOS keychain
  • Microsoft Windows Credential Manager
  • pass

以上辅助工具均可在docker github下载,地址: https://github.com/docker/docker-credential-helpers/releases

docker登录密码错误_Docker Login登录凭证安全存储

docker在Linux平台上支持pass、secret service,其中pass依赖了gpg,下面在以CentOS系统为例,将Docker的Credential store切换到pass存储,不再写入config.json文件中。

  • 检查gpg
[[email protected] ~]# gpg --version gpg (GnuPG) 2.0.22 libgcrypt 1.5.3 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later  This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: ~/.gnupg Supported algorithms: Pubkey: RSA, ?, ?, ELG, DSA Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB, BZIP2
           
  • 安装pass
yum install -y pass
           

安装完成之后通过如下命令验证

[[email protected] ~]# pass version ============================================ = pass: the standard unix password manager = = = = v1.7.3 = = = = Jason A. Donenfeld = = [email protected] = = = = http://www.passwordstore.org/ = ============================================
           

执行pass的基本命令

[[email protected] ~]# pass Error: password store is empty. Try "pass init". [[email protected] ~] pass init Usage: pass init [--path=subfolder,-p subfolder] gpg-id...
           

从上面的输出信息可知,pass init需要一个gpg-id,通过gpg生成一个key即可。

  • gpg生成key

先查看是否已有gpg key

[[email protected] ~]# gpg --list-keys
           

当前没有生成任何key,下面通过命令生成一个key,生成key是一个交互过程,需要输入key类型、长度、过期时间等相关信息,请记住设置的操作密码,类似Java中的keystore也有个密码。

[[email protected] ~]# gpg --gen-key gpg (GnuPG) 2.0.22; Copyright (C) 2013 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. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire  = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 0 Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: kingfsen Email address: [email protected] Comment:  You selected this USER-ID: "kingfsen " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a Passphrase to protect your secret key. ┌─────────────────────────────────────────────────────┐ │ Enter passphrase │ │ │ │ │ │ Passphrase **************__________________________ │ │ │ │  │ └─────────────────────────────────────────────────────┘ ─────────────────────────────────────────────────────┐ │ Please re-enter this passphrase │ │ │ │ Passphrase **************__________________________ │ │ │ │  │ └─────────────────────────────────────────────────────┘
           

密码输入之后,很快就会生成key了。

We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: key 5BAC1C87 marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/5BAC1C87 2019-05-11 Key fingerprint = E3E2 B354 73DD D511 3059 E213 1A08 85F9 5BAC 1C87 uid kingfsen  sub 4096R/69AA61E2 2019-05-11
           

注意:如果系统上没有安装rng-tools,gpg在生成key的最后这一步会卡住,无法进行操作了。

安装rng-tools包

ubuntu

# apt-get install rng-tools # rng -r /dev/urandom
           

centos

# yum install -y rng-tools # rngd -r /dev/urandom
           
  • pass初始化

查看gpg已生成的key

[[email protected] ~]# gpg --list-keys /root/.gnupg/pubring.gpg ------------------------ pub 4096R/5BAC1C87 2019-05-11 uid kingfsen  sub 4096R/69AA61E2 2019-05-11
           

执行命令初始化pass

[[email protected] ~]# pass init "5BAC1C87"Password store initialized for 5BAC1C87
           

执行pass insert命令验证是否成功

[[email protected] ~]# pass init 5BAC1C87Password store initialized for 5BAC1C87You have new mail in /var/spool/mail/root[[email protected] ~]# pass insert Gmail/[email protected] password for Gmail/[email protected]: Retype password for Gmail/[email protected]: [[email protected] ~]# pass show Gmail/[email protected] ────────────────────────────────────────────────────────────────────────────────────┐│ Please enter the passphrase to unlock the secret key for the OpenPGP certificate: ││ "kingfsen " ││ 4096-bit RSA key, ID 69AA61E2, ││ created 2019-05-11 (main key ID 5BAC1C87). ││ ││ ││ Passphrase **************_________________________________________________________ ││ ││  │└────────────────────────────────────────────────────────────────────────────────────┘sun1026
           

pass已经可以用于管理敏感信息了。

  • 安装Docker Credential辅助工具
[[email protected] ~]# wget https://github.com/docker/docker-credential-helpers/releases/download/v0.6.0/docker-credential-pass-v0.6.0-amd64.tar.gz [[email protected] ~]# tar -xf docker-credential-pass-v0.6.0-amd64.tar.gz [[email protected] ~]# chmod +x docker-credential-pass[[email protected] ~]# mv docker-credential-pass /usr/local/bin/[[email protected] ~]# docker-credential-pass Usage: docker-credential-pass [[email protected] ~]# docker-credential-pass version0.6.0
           
  • 修改Docker配置

清空.docker/config.json文件内容,然后将下面配置写入config.json文件中,注意credsStore是各辅助安装包名字的尾缀

{ "credsStore": "pass"}
           

config.json保存之后,执行docker login操作试试。

[[email protected] ~]# docker login hub.test.company.com -u 2000014559Password: Error saving credentials: error storing credentials - err: exit status 1, out: `pass store is uninitialized`
           

报错了,这是因为还没有初始化docker password store,辅助工具并不会自动初始化,需要手动操作。

  • 初始化docker password store

执行pass insert插入docker password store条目,密码:pass is initialized

[[email protected] ~]# pass insert docker-credential-helpers/docker-pass-initialized-checkAn entry already exists for docker-credential-helpers/docker-pass-initialized-check. Overwrite it? [y/N] yEnter password for docker-credential-helpers/docker-pass-initialized-check: Retype password for docker-credential-helpers/docker-pass-initialized-check: 
           

通过如下命令验证是否初始化成功,请注意输出结果,pass show执行的过程中无需输入密码。

[[email protected] ~]# pass show docker-credential-helpers/docker-pass-initialized-checkpass is initialized[[email protected] ~]# docker-credential-pass list{}
           

再次执行docker login登录镜像仓库,同时查看$HOME/.docker/config.json文件内容。

[[email protected] ~]# docker login hub.test.company.com -u 2000014559Password: Login SucceededYou have new mail in /var/spool/mail/root[[email protected] ~]# cat .docker/config.json{ "auths": { "hub.test.company.com": {} }, "HttpHeaders": { "User-Agent": "Docker-Client/18.09.2 (linux)" }, "credsStore": "pass"}
           

用户名、密码此时并未保存在config.json中,而是保存在加密文件中了。

[[email protected] ~]# docker-credential-pass list{"hub.test.company.com":"2000014559"}[[email protected] ~]# passPassword Store├── docker-credential-helpers│ └── aHViLmtjrzXSe3l1bi5jb20=│ └── 2000014559└── Gmail └── [email protected]
           

aHViLmtjrzXSe3l1bi5jb20=就是仓库域名的base64编码值,查看原始密码信息。

[[email protected] ~]# pass show docker-credential-helpers/aHViLmtjrzXSe3l1bi5jb20=/2000014559
           

保存密码文件路径

[[email protected] aHViLmtjrzXSe3l1bi5jb20=]# pwd/root/.password-store/docker-credential-helpers/aHViLmtjrzXSe3l1bi5jb20=[[email protected] aHViLmtjrzXSe3l1bi5jb20=]# ls2000014559.gpg