diff --git a/roles/gnupg/defaults/main.yml b/roles/gnupg/defaults/main.yml new file mode 100644 index 0000000..948ed2b --- /dev/null +++ b/roles/gnupg/defaults/main.yml @@ -0,0 +1,26 @@ +--- + +gpg_config_folder: ~/.gnupg +gpg_config_file: "{{ gpg_config_folder }}/gpg.conf" +gpg_agent_config_file: "{{ gpg_config_folder }}/gpg-agent.conf" +gpg_agent_sshcontrol_file: "{{ gpg_config_folder }}/sshcontrol" +gpg_configure_agent_script: "{{ gpg_config_folder }}/gpg-configure-as-ssh-agent.sh" + +gpg_keygrips_for_ssh: [] + +gpg_config_cert_digest_algo: SHA256 +gpg_config_emit_version: false +gpg_config_comments: false +gpg_config_ignore_time_conflict: false +gpg_config_allow_freeform_uid: true +gpg_config_keyid_format: 0xlong +gpg_config_with_fingerprint: true + +gpg_config_keyserver: hkps://keys.openpgp.org +gpg_config_keyserver_options: [] + +gpg_agent_config_cache_ttl: 300 +gpg_agent_config_cache_ttl_ssh: 300 +gpg_agent_config_enable_ssh_support: false +gpg_agent_config_ignore_cache_for_signing: true +gpg_agent_config_allow_external_cache: false diff --git a/roles/gnupg/files/gpg-configure-ssh-auth-socket.sh b/roles/gnupg/files/gpg-configure-ssh-auth-socket.sh new file mode 100644 index 0000000..0f9b7b1 --- /dev/null +++ b/roles/gnupg/files/gpg-configure-ssh-auth-socket.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +rc=$(pgrep gpg-agent) +if [ "$rc" != 0 ]; then + export GPG_AGENT_INFO + export SSH_AUTH_SOCK + export SSH_AGENT_PID +else + eval $(gpg-agent --daemon) +fi + +gpg-connect-agent /bye +export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) diff --git a/roles/gnupg/tasks/main.yml b/roles/gnupg/tasks/main.yml new file mode 100644 index 0000000..2e5b62e --- /dev/null +++ b/roles/gnupg/tasks/main.yml @@ -0,0 +1,53 @@ +--- + +- name: Ensure gnupg is installed (RedHat*) + package: + name: gnupg2 + state: latest + become: true + when: ansible_os_family == "RedHat" + +- name: Ensure gnupg is installed (Arch) + package: + name: gnupg + state: latest + become: true + when: ansible_os_family == "Archlinux" + +- name: Ensure ~/.gnupg folder exists with correct permissions + file: + path: "{{ gpg_config_folder }}" + state: directory + mode: 0700 + +- name: Ensure gpg.conf is templated + template: + src: gpg.conf.j2 + dest: "{{ gpg_config_file }}" + +- name: Configure gpg-agent.conf (agent configuration) + template: + src: gpg-agent.conf.j2 + dest: "{{ gpg_agent_config_file }}" + +# attempt to bootstrap the supplied keys here, so the keygrip can be retrieved + +- name: Configure sshcontrol (in order for gpg-agent to act as ssh-agent) + template: + src: sshcontrol.j2 + dest: "{{ gpg_agent_sshcontrol_file }}" + when: gpg_agent_config_enable_ssh_support + +- name: Copy gnupg_agent script, which makes gpg-agent responsible for ssh-auth + copy: + src: gpg-configure-ssh-auth-socket.sh + dest: "{{ gpg_configure_agent_script }}" + mode: 0700 + when: gpg_agent_config_enable_ssh_support + +- name: Ensure gnupg_agent script is included in bashrc + lineinfile: + path: "~/.bashrc" + line: "source {{ gpg_configure_agent_script }}" + state: present + when: gpg_agent_config_enable_ssh_support diff --git a/roles/gnupg/templates/gpg-agent.conf.j2 b/roles/gnupg/templates/gpg-agent.conf.j2 new file mode 100644 index 0000000..f9c344c --- /dev/null +++ b/roles/gnupg/templates/gpg-agent.conf.j2 @@ -0,0 +1,13 @@ +default-cache-ttl {{ gpg_agent_config_cache_ttl }} +default-cache-ttl-ssh {{ gpg_agent_config_cache_ttl_ssh }} +max-cache-ttl {{ gpg_agent_config_cache_ttl }} +max-cache-ttl-ssh {{ gpg_agent_config_cache_ttl_ssh }} +{% if not gpg_agent_config_allow_external_cache %} +no-allow-external-cache +{% endif %} +{% if gpg_agent_config_enable_ssh_support %} +enable-ssh-support +{% endif %} +{% if gpg_agent_config_ignore_cache_for_signing %} +ignore-cache-for-signing +{% endif %} diff --git a/roles/gnupg/templates/gpg.conf.j2 b/roles/gnupg/templates/gpg.conf.j2 new file mode 100644 index 0000000..1d2e12b --- /dev/null +++ b/roles/gnupg/templates/gpg.conf.j2 @@ -0,0 +1,29 @@ +{% if not gpg_config_emit_version %} +no-emit-version +{% endif %} +{% if not gpg_config_comments %} +no-comments +{% endif %} +cert-digest-algo {{ gpg_config_cert_digest_algo }} +personal-cipher-preferences AES AES256 AES192 CAST5 +personal-digest-preferences SHA256 SHA512 SHA384 SHA224 +{% if gpg_config_ignore_time_conflict %} +ignore-time-conflict +{% endif %} + +# How to render keys +keyid-format {{ gpg_config_keyid_format }} +{% if gpg_config_with_fingerprint %} +with-fingerprint +{% endif %} +{% if gpg_config_allow_freeform_uid %} +allow-freeform-uid +{% endif %} + +# Keyserver settings +{% if gpg_config_keyserver %} +keyserver {{ gpg_config_keyserver }} +{% endif %} +{% if gpg_config_keyserver_options %} +keyserver-options {{ gpg_config_keyserver_options | join(' ') }} +{% endif%} diff --git a/roles/gnupg/templates/sshcontrol.j2 b/roles/gnupg/templates/sshcontrol.j2 new file mode 100644 index 0000000..662d34e --- /dev/null +++ b/roles/gnupg/templates/sshcontrol.j2 @@ -0,0 +1,14 @@ +# List of allowed ssh keys. Only keys present in this file are used +# in the SSH protocol. The ssh-add tool may add new entries to this +# file to enable them; you may also add them manually. Comment +# lines, like this one, as well as empty lines are ignored. Lines do +# have a certain length limit but this is not serious limitation as +# the format of the entries is fixed and checked by gpg-agent. A +# non-comment line starts with optional white spaces, followed by the +# keygrip of the key given as 40 hex digits, optionally followed by a +# caching TTL in seconds, and another optional field for arbitrary +# flags. Prepend the keygrip with an '!' mark to disable it. + +{% for keygrip in gpg_keygrips_for_ssh %} +{{ keygrip }} +{% endfor %}