323 lines
11 KiB
YAML
323 lines
11 KiB
YAML
---
|
|
version: '3'
|
|
|
|
todo: Collect YUBI_USER_PIN, YUBI_ADMIN_PIN, YUBI_LAST_NAME, YUBI_EMAIL, YUBI_FIRST_NAME, YUBI_TITLE (Principal Software Engineer), YUBI_ALT_NAME, YUBI_ALT_EMAIL, YUBI_ALT_TITLE
|
|
|
|
vars:
|
|
YUBI_MASTER_EMAIL: no-reply@megabyte.space
|
|
YUBI_MASTER_NAME: Megabyte Labs
|
|
|
|
env:
|
|
GNUPGHOME:
|
|
sh: echo "$HOME/.gnupghome"
|
|
MASTER_KEY:
|
|
sh: |
|
|
if [ -f .yubi-masterkey ]; then
|
|
cat .yubi-masterkey
|
|
else
|
|
LC_ALL=C tr -dc '[:upper:]' < /dev/urandom | fold -w 30 | head -n1
|
|
fi
|
|
|
|
tasks:
|
|
add:identities:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
YUBI_ALT_EMAIL:
|
|
sh: jq -r '.YUBI_ALT_EMAIL' .yubi.json
|
|
YUBI_ALT_NAME:
|
|
sh: jq -r '.YUBI_ALT_NAME' .yubi.json
|
|
YUBI_ALT_TITLE:
|
|
sh: jq -r '.YUBI_ALT_TITLE' .yubi.json
|
|
YUBI_EMAIL:
|
|
sh: jq -r '.YUBI_EMAIL' .yubi.json
|
|
YUBI_FIRST_NAME:
|
|
sh: jq -r '.YUBI_FIRST_NAME' .yubi.json
|
|
YUBI_LAST_NAME:
|
|
sh: jq -r '.YUBI_LAST_NAME' .yubi.json
|
|
YUBI_TITLE:
|
|
sh: jq -r '.YUBI_TITLE' .yubi.json
|
|
cmds:
|
|
- echo -e "${YUBI_FIRST_NAME} ${YUBI_LAST_NAME}\n${YUBI_EMAIL}\n${YUBI_TITLE}\n" | gpg --command-fd 0 --pinentry-mode loopback
|
|
--passphrase "$MASTER_KEY" --expert --edit-key "$KEYID" adduid save
|
|
- echo -e "${YUBI_ALT_NAME}\n${YUBI_ALT_EMAIL}\n${YUBI_ALT_TITLE}\n" | gpg --command-fd 0 --pinentry-mode loopback
|
|
--passphrase "$MASTER_KEY" --expert --edit-key "$KEYID" adduid save
|
|
|
|
card:
|
|
vars:
|
|
KEYID:
|
|
sh: gpg --keyid-format long --list-keys {{.YUBI_MASTER_EMAIL}} | grep "pub rsa" | sed 's/pub rsa4096\///' | sed 's/^\([^ ]*\).*/\1/'
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
YUBI_ADMIN_PIN:
|
|
sh: jq -r '.YUBI_ADMIN_PIN' .yubi.json
|
|
YUBI_EMAIL:
|
|
sh: jq -r '.YUBI_EMAIL' .yubi.json
|
|
YUBI_FIRST_NAME:
|
|
sh: jq -r '.YUBI_FIRST_NAME' .yubi.json
|
|
YUBI_LAST_NAME:
|
|
sh: jq -r '.YUBI_LAST_NAME' .yubi.json
|
|
YUBI_USER_PIN:
|
|
sh: jq -r '.YUBI_USER_PIN' .yubi.json
|
|
cmds:
|
|
- cp -rf ~/.gnupg ~/.gnupg.bak
|
|
- task: card:reset
|
|
- echo -e "admin\nkdf-setup\n12345678\n" | gpg --command-fd 0 --pinentry-mode loopback --card-edit
|
|
- echo -e "admin\npasswd\n1\n123456\n${YUBI_USER_PIN}\n${YUBI_USER_PIN}\nq\n" | gpg --command-fd 0 --pinentry-mode loopback --card-edit
|
|
- echo -e "admin\npasswd\n3\n12345678\n${YUBI_ADMIN_PIN}\n${YUBI_ADMIN_PIN}\nq\n" | gpg --command-fd 0 --pinentry-mode loopback --card-edit
|
|
- echo -e "admin\nname\n${YUBI_LAST_NAME}\n${YUBI_FIRST_NAME}\n${YUBI_ADMIN_PIN}\nlang\nen\nlogin\n${YUBI_EMAIL}\nquit" | gpg --command-fd 0 --pinentry-mode loopback --card-edit
|
|
- task: card:keys
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
# - gpg --delete-secret-key "$KEYID"
|
|
# - mv ~/.gnupg ~/.gnupg-generated # TODO
|
|
# - rm -rf ~/.gnupg
|
|
# - mv ~/.gnupg.bak ~/.gnupg
|
|
|
|
card:keys:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
YUBI_ADMIN_PIN:
|
|
sh: jq -r '.YUBI_ADMIN_PIN' .yubi.json
|
|
cmds:
|
|
- echo -e "key 1\nkeytocard\n1\n${MASTER_KEY}\n${YUBI_ADMIN_PIN}\n" | gpg --command-fd 0 --pinentry-mode loopback --edit-key "$KEYID"
|
|
- echo -e "key 2\nkeytocard\n2\n${MASTER_KEY}\n${YUBI_ADMIN_PIN}\n" | gpg --command-fd 0 --pinentry-mode loopback --edit-key "$KEYID"
|
|
- echo -e "key 3\nkeytocard\n3\n${MASTER_KEY}\n${YUBI_ADMIN_PIN}\n" | gpg --command-fd 0 --pinentry-mode loopback --edit-key "$KEYID"
|
|
|
|
card:reset:
|
|
cmds:
|
|
- echo -e "admin\nfactory-reset\ny\nyes\n" | gpg --command-fd 0 --pinentry-mode loopback --card-edit
|
|
status:
|
|
- '[ -n "$DONT_RESET_YUBIKEY" ]'
|
|
|
|
check:entropy:
|
|
vars:
|
|
ENTROPY_AVAIL:
|
|
sh: |
|
|
if [ -f /proc/sys/kernel/random/entropy_avail ]; then
|
|
cat /proc/sys/kernel/random/entropy_avail
|
|
fi
|
|
cmds:
|
|
- |
|
|
if [ '{{.ENTROPY_AVAIL}}' -lt '2000' ]; then
|
|
.config/log error 'The entropy pool value is not high enough. It must be greater than 2000!' && exit 1
|
|
fi
|
|
status:
|
|
- '[ "{{OS}}" != "linux" ]'
|
|
|
|
export:
|
|
vars:
|
|
KEYID:
|
|
sh: gpg --keyid-format long --list-keys {{.YUBI_MASTER_EMAIL}} | grep "pub rsa" | sed 's/pub rsa4096\///' | sed 's/^\([^ ]*\).*/\1/'
|
|
cmds:
|
|
- task: public:export
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
# - task: revocation:export
|
|
# vars:
|
|
# KEYID: '{{.KEYID}}'
|
|
- task: secrets:export
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
- task: public:upload
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
# - task: usb
|
|
- task: card
|
|
# - task: usb:unmount
|
|
|
|
generate:authentication:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
cmds:
|
|
- echo -e "8\nS\nE\nA\nQ\n4096\n1y\n" | gpg --command-fd 0 --pinentry-mode loopback --passphrase "$MASTER_KEY"
|
|
--expert --edit-key "$KEYID" addkey save
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
generate:encryption:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
cmds:
|
|
- echo -e "6\n4096\n1y\n" | gpg --command-fd 0 --pinentry-mode loopback --passphrase "$MASTER_KEY" --expert --edit-key "$KEYID" addkey save
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
generate:master:
|
|
cmds:
|
|
- mkdir -p "$GNUPGHOME" && chmod 700 "$GNUPGHOME"
|
|
- mkdir -p "$GNUPGHOME/private-keys-v1.d"
|
|
- chmod 700 "$GNUPGHOME/private-keys-v1.d"
|
|
# Original: echo -e "8\nE\nS\nQ\n4096\n0\ny\n{{.YUBI_MASTER_NAME}}\n{{.YUBI_MASTER_EMAIL}}\n\no\n" -- removed \ny for macOS
|
|
- echo -e "8\nE\nS\nQ\n4096\n0\n{{.YUBI_MASTER_NAME}}\n{{.YUBI_MASTER_EMAIL}}\n\no\n" | gpg --expert --command-fd 0
|
|
--pinentry-mode loopback --passphrase "$MASTER_KEY" --full-generate-key
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
generate:signing:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
cmds:
|
|
- echo -e "4\n4096\n1y\n" | gpg --command-fd 0 --pinentry-mode loopback --passphrase "$MASTER_KEY" --expert --edit-key "$KEYID" addkey save
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
generate:subkeys:
|
|
vars:
|
|
KEYID:
|
|
sh: gpg --keyid-format long --list-keys {{.YUBI_MASTER_EMAIL}} | grep "pub rsa" | sed 's/pub rsa4096\///' | sed 's/^\([^ ]*\).*/\1/'
|
|
cmds:
|
|
- task: generate:signing
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
- task: generate:encryption
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
- task: generate:authentication
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
- task: add:identities
|
|
vars:
|
|
KEYID: '{{.KEYID}}'
|
|
|
|
prepare:
|
|
desc: Prepares an environment by provisioning all the required software / preliminary steps
|
|
cmds:
|
|
- mkdir -p "$GNUPGHOME" && chmod 700 "$GNUPGHOME"
|
|
- echo '{{.MASTER_KEY}}' > .yubi-masterkey
|
|
- task: prepare:init
|
|
- task: :install:service:start
|
|
vars:
|
|
SERVICE: pcscd
|
|
- task: check:entropy
|
|
- task: generate:master
|
|
- task: generate:subkeys
|
|
vars:
|
|
KEYID:
|
|
sh: gpg --keyid-format long --list-keys {{.YUBI_MASTER_EMAIL}} | grep "pub rsa" | sed 's/pub rsa4096\///' | sed 's/^\([^ ]*\).*/\1/'
|
|
- task: export
|
|
- task: :security:ssh:yubikey
|
|
|
|
prepare:init:
|
|
cmds:
|
|
- task: prepare:init:continue
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
prepare:init:continue:
|
|
deps:
|
|
- :install:requirements:yubikey
|
|
- :security:gpg:conf
|
|
- task: :security:gpg:conf
|
|
vars:
|
|
CONFIG_DIR_PATH:
|
|
sh: echo "$GNUPGHOME"
|
|
- :security:gpg:conf:agent
|
|
- task: :security:gpg:conf:agent
|
|
vars:
|
|
CONFIG_DIR_PATH:
|
|
sh: echo "$GNUPGHOME"
|
|
|
|
public:export:
|
|
todo: This differs from guide
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
cmds:
|
|
- mkdir -p "$GNUPGHOME" && chmod 700 "$GNUPGHOME"
|
|
- gpg --armor --export "$KEYID" > "$GNUPGHOME/gpg-$KEYID-$(date +%F).asc"
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
public:upload:
|
|
cmds:
|
|
- gpg --send-key "$KEYID"
|
|
- gpg --keyserver pgp.mit.edu --send-key "$KEYID"
|
|
- gpg --keyserver keys.gnupg.net --send-key "$KEYID"
|
|
- gpg --keyserver hkps://keyserver.ubuntu.com:443 --send-key "$KEYID"
|
|
status:
|
|
- |
|
|
[ "$(echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1)" != "0" ] || [ -n "$YUBIKEY_BACKUP" ]
|
|
|
|
revocation:export:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
cmds:
|
|
- mkdir -p "$GNUPGHOME" && chmod 700 "$GNUPGHOME"
|
|
- gpg --output $GNUPGHOME/revoke.asc --gen-revoke "$KEYID"
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
secrets:export:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
cmds:
|
|
- mkdir -p "$GNUPGHOME" && chmod 700 "$GNUPGHOME"
|
|
- gpg --armor --export-secret-keys --command-fd 0 --pinentry-mode loopback
|
|
--passphrase "$MASTER_KEY" --expert "$KEYID" > $GNUPGHOME/mastersub.key
|
|
- gpg --armor --export-secret-subkeys --command-fd 0 --pinentry-mode loopback
|
|
--passphrase "$MASTER_KEY" --expert "$KEYID" > $GNUPGHOME/sub.key
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
secure:delete:
|
|
env:
|
|
KEYID: '{{.KEYID}}'
|
|
cmds:
|
|
- sudo srm -rf "$GNUPGHOME" || sudo rm -rf "$GNUPGHOME"
|
|
- gpg --delete-secret-key "$KEYID"
|
|
|
|
stub:
|
|
summary: |
|
|
Run this to re-stub the GPG files to point to the current YubiKey.
|
|
cmds:
|
|
- gpg-connect-agent "scd serialno" "learn --force" /bye
|
|
|
|
usb:
|
|
summary: |
|
|
# Backup Keys (Including Master) to USB and Encrypt
|
|
|
|
This task will partition a USB with two partitions. One partition will
|
|
be encrypted and contain your GPG keys (including the master key). The other
|
|
partition will not be encrypted and contain your public key.
|
|
cmds:
|
|
- task: usb:create
|
|
- task: usb:mount
|
|
- mkdir ~/.gpg-encrypted-storage && cp -rf $GNUPGHOME ~/.gpg-encrypted-storage # TODO /mnt/gpg-encrypted-storage
|
|
- mkdir ~/.gpg-public && cp $GNUPGHOME/gpg-$KEYID* ~/.gpg-public # TODO /mnt/gpg-public
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
usb:create:
|
|
deps:
|
|
- :security:disk:encrypt:create
|
|
- :security:disk:unencrypted:create
|
|
|
|
usb:mount:
|
|
deps:
|
|
- :security:disk:encrypt:mount
|
|
- :security:disk:unencrypted:mount
|
|
|
|
usb:unmount:
|
|
deps:
|
|
- :security:disk:encrypt:unmount
|
|
- :security:disk:unencrypted:unmount
|
|
status:
|
|
- '[ -n "$YUBIKEY_BACKUP" ]'
|
|
|
|
yubikey-agent:
|
|
deps:
|
|
- :install:software:yubikey-agent
|
|
summary: |
|
|
# Sets Up Resident SSH Key
|
|
|
|
According to [this guide](https://github.com/jamesog/yubikey-ssh), the yubikey-agent
|
|
package is a simplest, best way of utilizing a YubiKey for SSH by leveraging
|
|
YubiKey's onboard SSH key generator. By using this method, the private key never leaves
|
|
the YubiKey which increases security tremendously.
|
|
|
|
See: https://github.com/FiloSottile/yubikey-agent
|
|
|
|
A new method is detailed here: https://www.yubico.com/blog/github-now-supports-ssh-security-keys/
|
|
It may be worth migrating to that approach.
|
|
cmds:
|
|
- brew services start yubikey-agent
|
|
- yubikey-agent -setup
|