From f159ed886f6262e66fbf95cf08c032694fcbf9cf Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 16 Oct 2022 00:32:44 -0400 Subject: [PATCH] Add a linux gpg role. --- .../environments/laptop/host_vars/odolinux | 3 + ansible/playbook.yaml | 1 + ansible/roles/gpg/files/gpg-agent.conf | 6 ++ ansible/roles/gpg/files/gpg.asc | 34 +++++++ ansible/roles/gpg/files/gpg.conf | 90 +++++++++++++++++++ ansible/roles/gpg/files/scdaemon.conf | 1 + ansible/roles/gpg/files/yubikey_relearn_keys | 10 +++ ansible/roles/gpg/meta/main.yaml | 2 + ansible/roles/gpg/tasks/common.yaml | 14 +++ ansible/roles/gpg/tasks/freebsd.yaml | 41 +++++++++ ansible/roles/gpg/tasks/linux.yaml | 29 ++++++ ansible/roles/gpg/tasks/main.yaml | 1 + ansible/roles/gpg/tasks/peruser.yaml | 29 ++++++ ansible/roles/gpg/tasks/peruser_freebsd.yaml | 0 ansible/roles/gpg/tasks/peruser_linux.yaml | 45 ++++++++++ .../roles/package_manager/tasks/linux.yaml | 4 +- 16 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 ansible/roles/gpg/files/gpg-agent.conf create mode 100644 ansible/roles/gpg/files/gpg.asc create mode 100644 ansible/roles/gpg/files/gpg.conf create mode 100644 ansible/roles/gpg/files/scdaemon.conf create mode 100644 ansible/roles/gpg/files/yubikey_relearn_keys create mode 100644 ansible/roles/gpg/meta/main.yaml create mode 100644 ansible/roles/gpg/tasks/common.yaml create mode 100644 ansible/roles/gpg/tasks/freebsd.yaml create mode 100644 ansible/roles/gpg/tasks/linux.yaml create mode 100644 ansible/roles/gpg/tasks/main.yaml create mode 100644 ansible/roles/gpg/tasks/peruser.yaml create mode 100644 ansible/roles/gpg/tasks/peruser_freebsd.yaml create mode 100644 ansible/roles/gpg/tasks/peruser_linux.yaml diff --git a/ansible/environments/laptop/host_vars/odolinux b/ansible/environments/laptop/host_vars/odolinux index 43ec843..f3b011a 100644 --- a/ansible/environments/laptop/host_vars/odolinux +++ b/ansible/environments/laptop/host_vars/odolinux @@ -18,3 +18,6 @@ zfs_snapshot_datasets: - zroot/linux/archmain/home - zroot/linux/archmain/be graphics_driver: "intel" +build_user: + name: talexander + group: talexander diff --git a/ansible/playbook.yaml b/ansible/playbook.yaml index e11bd86..172ed7e 100644 --- a/ansible/playbook.yaml +++ b/ansible/playbook.yaml @@ -15,3 +15,4 @@ - ntp - build - graphics + - gpg diff --git a/ansible/roles/gpg/files/gpg-agent.conf b/ansible/roles/gpg/files/gpg-agent.conf new file mode 100644 index 0000000..1679e6d --- /dev/null +++ b/ansible/roles/gpg/files/gpg-agent.conf @@ -0,0 +1,6 @@ +enable-ssh-support +write-env-file +use-standard-socket +default-cache-ttl 600 +max-cache-ttl 7200 +display :0 diff --git a/ansible/roles/gpg/files/gpg.asc b/ansible/roles/gpg/files/gpg.asc new file mode 100644 index 0000000..c6de310 --- /dev/null +++ b/ansible/roles/gpg/files/gpg.asc @@ -0,0 +1,34 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEXZwWGhYJKwYBBAHaRw8BAQdAfv7qozKkmf4D+5PDzADsMm4aAKDGLha7+Cu0 +0H+RsWG0HVRvbSBBbGV4YW5kZXIgPHRvbUBmaXp6LmJ1eno+iJAEExYIADgWIQS4 +SBWTY8KHeReVS+En3kDZuEVcGwUCXZwWGgIbAwULCQgHAgYVCAkKCwIEFgIDAQIe +AQIXgAAKCRAn3kDZuEVcG9glAQDX3Bzaz9sQpycc40LeLxSKQsWplfJigfr8wWOg +C15TywEAqkTtCrTNsltdZERLMre7qnv/6RSo54OW0C4pdN7UUAa0HlRvbSBBbGV4 +YW5kZXIgPHdvcmtAZml6ei5idXp6PoiQBBMWCAA4FiEEuEgVk2PCh3kXlUvhJ95A +2bhFXBsFAl+w+R0CGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQJ95A2bhF +XBt6fgD+NOYnw9gz5K/q3H5LE/JvqzCSHezJmeGgif0CuU4m1/MA+gPDKME7syEt +JsTpELEMrxWWpDW0tD/W1iJE7roGYPQPtB9Ub20gQWxleGFuZGVyIDx0b21AaGFy +bW9uaWMuYWk+iJAEExYIADgWIQS4SBWTY8KHeReVS+En3kDZuEVcGwUCX7D5RAIb +AwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRAn3kDZuEVcGzjDAP9pM1ScstOk +ti+oRAsNSk8qsjIsCT9O5voDS0Q7plWlcwD/btKVFO9tPLsXhyvdB+NSwueVs7TA +kRVjlW3hktpefg24OARdnBYaEgorBgEEAZdVAQUBAQdArbTYQgDBMG7EBFTKA6+f +4CWgwl26Lf2b6cyCGfUw2j4DAQgHiHgEGBYIACAWIQS4SBWTY8KHeReVS+En3kDZ +uEVcGwUCXZwWGgIbDAAKCRAn3kDZuEVcG03MAQCrkjrE+MhtvbfGaHGHlwz9QnF0 +Z519YzK8Xr8m0O+09QEA9BFCfkAzBM4D4JKeWJh/tmN9U6UexzLrRdY+W9cugAm4 +MwRdnBbKFgkrBgEEAdpHDwEBB0A/IgvgQaDhPkk72raSlUPLZaMyJfPedlfBhbgY +uhNiSIj1BBgWCAAmAhsCFiEEuEgVk2PCh3kXlUvhJ95A2bhFXBsFAl+w+hYFCQe4 +fcwAgXYgBBkWCAAdFiEEgeZEOZZ1UC6xJRa606F5yaU8Dt4FAl2cFsoACgkQ06F5 +yaU8Dt6MngD+Krs3aYyHH6i85ebVESgBI8XeXhgACM4exepw+0UcoYkBAKK4DvV3 +oJD6o1ku6Rr8pUH962SQm8PO9pO2JBBAb6ADCRAn3kDZuEVcG9uAAP43vUsbe24/ +6tjEezAW0a4L2E1u4HNU8t53lolngs1kswEAy1HBdYEMR9TovX/kMeBHLcz1J2pM +VRSV0JnJhj5eZwa4MwRdnBcBFgkrBgEEAdpHDwEBB0BrvpOZa4q6JHVuc1XUVQTq +hDgLwD5SJBvzHSTXPYOZMoh+BBgWCAAmAhsgFiEEuEgVk2PCh3kXlUvhJ95A2bhF +XBsFAl+w+hYFCQe4fZUACgkQJ95A2bhFXBs3NgEA3SFYTgRVstidfoEpEZV4DdSL +kXaOwN3Eyba4UniClyMA/2CCxQt24vu19TyvUtOXWCp9Zi8SyIqoeiXQ4ZmhhnQO +uDgEXZwXKBIKKwYBBAGXVQEFAQEHQA7S3cFTEu6iROopVyF4UBl3hQrEAbOc9CW+ +xXKFZYgSAwEIB4h+BBgWCAAmAhsMFiEEuEgVk2PCh3kXlUvhJ95A2bhFXBsFAl+w ++hcFCQe4fW4ACgkQJ95A2bhFXBtUXAEAyEJCUNVSJ7qvQv5IXuwbYTX2Mh7JU3+F +GJHO7AWBXCQA/2aLAi9kYmz9ba770XYwTeBZIv9Y6UIwIwVmFdYHC/EM +=a/z4 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/ansible/roles/gpg/files/gpg.conf b/ansible/roles/gpg/files/gpg.conf new file mode 100644 index 0000000..8788234 --- /dev/null +++ b/ansible/roles/gpg/files/gpg.conf @@ -0,0 +1,90 @@ +# +# This is an implementation of the Riseup OpenPGP Best Practices +# https://help.riseup.net/en/security/message-security/openpgp/best-practices +# + + +#----------------------------- +# default key +#----------------------------- + +# The default key to sign with. If this option is not used, the default key is +# the first key found in the secret keyring + +#default-key 0xD8692123C4065DEA5E0F3AB5249B39D24F25E3B6 + + +#----------------------------- +# behavior +#----------------------------- + +# Disable inclusion of the version string in ASCII armored output +no-emit-version + +# Disable comment string in clear text signatures and ASCII armored messages +no-comments + +# Display long key IDs +keyid-format 0xlong + +# List all keys (or the specified ones) along with their fingerprints +with-fingerprint + +# Display the calculated validity of user IDs during key listings +list-options show-uid-validity +verify-options show-uid-validity + +# Try to use the GnuPG-Agent. With this option, GnuPG first tries to connect to +# the agent before it asks for a passphrase. +use-agent + + +#----------------------------- +# keyserver +#----------------------------- + +# This is the server that --recv-keys, --send-keys, and --search-keys will +# communicate with to receive keys from, send keys to, and search for keys on +#keyserver hkps://hkps.pool.sks-keyservers.net + +# Provide a certificate store to override the system default +# Get this from https://sks-keyservers.net/sks-keyservers.netCA.pem +#keyserver-options ca-cert-file=/usr/local/etc/ssl/certs/hkps.pool.sks-keyservers.net.pem + +# Set the proxy to use for HTTP and HKP keyservers - default to the standard +# local Tor socks proxy +# It is encouraged to use Tor for improved anonymity. Preferrably use either a +# dedicated SOCKSPort for GnuPG and/or enable IsolateDestPort and +# IsolateDestAddr +#keyserver-options http-proxy=socks5-hostname://127.0.0.1:9050 + +# Don't leak DNS, see https://trac.torproject.org/projects/tor/ticket/2846 +# keyserver-options no-try-dns-srv + +# When using --refresh-keys, if the key in question has a preferred keyserver +# URL, then disable use of that preferred keyserver to refresh the key from +# keyserver-options no-honor-keyserver-url + +# When searching for a key with --search-keys, include keys that are marked on +# the keyserver as revoked +# keyserver-options include-revoked + + +#----------------------------- +# algorithm and ciphers +#----------------------------- + +# list of personal digest preferences. When multiple digests are supported by +# all recipients, choose the strongest one +personal-cipher-preferences AES256 AES192 AES CAST5 + +# list of personal digest preferences. When multiple ciphers are supported by +# all recipients, choose the strongest one +personal-digest-preferences SHA512 SHA384 SHA256 SHA224 + +# message digest algorithm used when signing a key +cert-digest-algo SHA512 + +# This preference list is used for new keys and becomes the default for +# "setpref" in the edit menu +default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed diff --git a/ansible/roles/gpg/files/scdaemon.conf b/ansible/roles/gpg/files/scdaemon.conf new file mode 100644 index 0000000..eb818dd --- /dev/null +++ b/ansible/roles/gpg/files/scdaemon.conf @@ -0,0 +1 @@ +disable-ccid diff --git a/ansible/roles/gpg/files/yubikey_relearn_keys b/ansible/roles/gpg/files/yubikey_relearn_keys new file mode 100644 index 0000000..730560e --- /dev/null +++ b/ansible/roles/gpg/files/yubikey_relearn_keys @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# +# GPG associates token serial numbers with keys. When switching to +# another hardware token, run this script to associate the new token +# with the keys. +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +gpg-connect-agent "scd serialno" "learn --force" /bye diff --git a/ansible/roles/gpg/meta/main.yaml b/ansible/roles/gpg/meta/main.yaml new file mode 100644 index 0000000..655446a --- /dev/null +++ b/ansible/roles/gpg/meta/main.yaml @@ -0,0 +1,2 @@ +dependencies: + - users diff --git a/ansible/roles/gpg/tasks/common.yaml b/ansible/roles/gpg/tasks/common.yaml new file mode 100644 index 0000000..d7c1735 --- /dev/null +++ b/ansible/roles/gpg/tasks/common.yaml @@ -0,0 +1,14 @@ +- import_tasks: tasks/freebsd.yaml + when: 'os_flavor == "freebsd"' + +- import_tasks: tasks/linux.yaml + when: 'os_flavor == "linux"' + +- include_tasks: + file: tasks/peruser.yaml + apply: + become: yes + become_user: "{{ initialize_user }}" + loop: "{{ users | dict2items | community.general.json_query('[?value.initialize==`true`].key') }}" + loop_control: + loop_var: initialize_user diff --git a/ansible/roles/gpg/tasks/freebsd.yaml b/ansible/roles/gpg/tasks/freebsd.yaml new file mode 100644 index 0000000..7fcf6b4 --- /dev/null +++ b/ansible/roles/gpg/tasks/freebsd.yaml @@ -0,0 +1,41 @@ +- name: Install packages + package: + name: + - gnupg + - pcsc-tools + - ccid + # - linux_libusb + - pinentry + - pinentry-qt5 state: present + +- name: Create directories + file: + name: "{{ item }}" + state: directory + mode: 0755 + owner: root + group: wheel + loop: + - /usr/local/etc/devd + +- name: Install service configuration + copy: + src: "files/intel_{{ item }}_rc.conf" + dest: "/etc/rc.conf.d/{{ item }}" + mode: 0644 + owner: root + group: wheel + loop: + - pcscd + +- name: Install devd Configuration + copy: + src: "files/{{ item.src }}" + dest: "{{ item.dest }}" + mode: 0644 + owner: root + group: wheel + notify: restart devd + loop: + - src: pcscd.conf + dest: /usr/local/etc/devd/pcscd.conf diff --git a/ansible/roles/gpg/tasks/linux.yaml b/ansible/roles/gpg/tasks/linux.yaml new file mode 100644 index 0000000..80ed12d --- /dev/null +++ b/ansible/roles/gpg/tasks/linux.yaml @@ -0,0 +1,29 @@ +- name: Install packages + package: + name: + - gnupg + - pcsc-tools + - ccid + - libusb-compat + - pinentry + state: present + +- name: Enable pcscd + systemd: + name: "{{ item }}" + state: started + enabled: yes + daemon_reload: yes + loop: + - pcscd.socket + +- name: Install scripts + copy: + src: "files/{{ item.src }}" + dest: "{{ item.dest }}" + mode: 0755 + owner: "{{ build_user.name }}" + group: "{{ build_user.group }}" + loop: + - src: yubikey_relearn_keys + dest: /usr/local/bin/yubikey_relearn_keys diff --git a/ansible/roles/gpg/tasks/main.yaml b/ansible/roles/gpg/tasks/main.yaml new file mode 100644 index 0000000..5c1df6c --- /dev/null +++ b/ansible/roles/gpg/tasks/main.yaml @@ -0,0 +1 @@ +- import_tasks: tasks/common.yaml diff --git a/ansible/roles/gpg/tasks/peruser.yaml b/ansible/roles/gpg/tasks/peruser.yaml new file mode 100644 index 0000000..111e886 --- /dev/null +++ b/ansible/roles/gpg/tasks/peruser.yaml @@ -0,0 +1,29 @@ +- include_role: + name: per_user + +# - name: Create directories +# file: +# name: "{{ account_homedir.stdout }}/{{ item }}" +# state: directory +# mode: 0700 +# owner: "{{ account_name.stdout }}" +# group: "{{ group_name.stdout }}" +# loop: +# - ".config/foo" + +# - name: Copy files +# copy: +# src: "files/{{ item.src }}" +# dest: "{{ account_homedir.stdout }}/{{ item.dest }}" +# mode: 0600 +# owner: "{{ account_name.stdout }}" +# group: "{{ group_name.stdout }}" +# loop: +# - src: foo.conf +# dest: .config/foo/foo.conf + +- import_tasks: tasks/peruser_freebsd.yaml + when: 'os_flavor == "freebsd"' + +- import_tasks: tasks/peruser_linux.yaml + when: 'os_flavor == "linux"' diff --git a/ansible/roles/gpg/tasks/peruser_freebsd.yaml b/ansible/roles/gpg/tasks/peruser_freebsd.yaml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/roles/gpg/tasks/peruser_linux.yaml b/ansible/roles/gpg/tasks/peruser_linux.yaml new file mode 100644 index 0000000..9893d22 --- /dev/null +++ b/ansible/roles/gpg/tasks/peruser_linux.yaml @@ -0,0 +1,45 @@ +- name: Enable the gpg user agent + systemd: + name: "{{ item }}" + state: started + enabled: yes + daemon_reload: yes + scope: user + loop: + - gpg-agent.socket + - gpg-agent-ssh.socket + +- name: Create gpg config directory + file: + name: "{{ account_homedir.stdout }}/.gnupg" + state: directory + mode: 0700 + owner: "{{ account_name.stdout }}" + group: "{{ group_name.stdout }}" + +- name: Configure gpg + copy: + src: "files/{{ item.src }}" + dest: "{{ account_homedir.stdout }}/{{ item.dest }}" + mode: 0600 + owner: "{{ account_name.stdout }}" + group: "{{ group_name.stdout }}" + loop: + - src: gpg.conf + dest: .gnupg/gpg.conf + - src: gpg-agent.conf + dest: .gnupg/gpg-agent.conf + - src: scdaemon.conf + dest: .gnupg/scdaemon.conf + +- name: Check trusted gpg keys + command: gpg --list-public-keys --keyid-format LONG + register: gpgkeys + changed_when: false + check_mode: no + +- name: Import public key for yubikey + command: gpg --import + when: '"cv25519/B0B50C7FDDE009E5" not in gpgkeys.stdout' + args: + stdin: "{{ lookup('file', 'gpg.asc') }}" diff --git a/ansible/roles/package_manager/tasks/linux.yaml b/ansible/roles/package_manager/tasks/linux.yaml index 66fa244..3997a97 100644 --- a/ansible/roles/package_manager/tasks/linux.yaml +++ b/ansible/roles/package_manager/tasks/linux.yaml @@ -1,6 +1,6 @@ - name: Put in custom config directory copy: - src: "files/{{ pacman_conf }}/pacman.conf" + src: "files/pacman.conf" dest: /etc/pacman.conf mode: 0644 owner: root @@ -8,7 +8,7 @@ - name: Put in mirrolist copy: - src: "files/{{ pacman_conf }}/mirrorlist" + src: "files/mirrorlist" dest: /etc/pacman.d/mirrorlist mode: 0644 owner: root