-
Notifications
You must be signed in to change notification settings - Fork 11
/
setup-password-manager.yml
162 lines (138 loc) · 5.25 KB
/
setup-password-manager.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
- name: Get information about ansible control machine
hosts: localhost
gather_facts: yes
- hosts: all
gather_facts: no
tasks:
- name: ensure that localhost is not skipped
assert:
that:
- '"ansible_hostname" in hostvars.localhost'
msg:
- Hostvars from localhost are required to run some tasks.
- Make sure to include localhost when using --limit.
- name: Setup password store
hosts: all
vars:
control_machine_name: "{{ hostvars.localhost.ansible_hostname }}"
control_machine_address: "{{ control_machine_name }}.local"
# Use ~ instead of ansible_env.HOME because it must expand differently
# on src and dest host in sync tasks
gpg_exchange_dir: "~/.gnupg/import-export/"
gpg_rsynced_dirs:
- ~/.gnupg/private-keys-v1.d/
- ~/.gnupg/openpgp-revocs.d/
roles:
- known-hosts
tags: sync
tasks:
- name: install apt packages
apt:
name:
- expect # for automatic ssh key unlocking
- gnupg2 # I want to be able to use gpg2 command for compatibility
- git
- xclip # for putting password in clipboard
- pass
- pinentry-tty # for unlocking keys in agent without gui
- pwgen # password generator
- oathtool # for generating one-time passwords
become: yes
- name: ensure directories exist
file:
dest: "{{ item }}"
state: directory
mode: 0700
loop:
- ~/.ssh/
- ~/.ssh/keys/
- ~/.gnupg/
- "{{ gpg_exchange_dir }}"
- ~/.gnupg/openpgp-revocs.d/
- ~/.gnupg/private-keys-v1.d/
- name: Two-way sync - pull data from nodes
tags: never # Run only when explicitly called with --tags sync.
block:
- name: pull private keys and revocation certs
synchronize:
# Trailing slash is important!
src: "{{ item }}/"
dest: "{{ item }}/"
mode: pull
loop: "{{ gpg_rsynced_dirs }}"
- name: export pubring and ownertrust
shell: |
gpg2 --export --armor > {{ gpg_exchange_dir }}/{{ inventory_hostname }}_pubring.asc &&
gpg2 --export-ownertrust > {{ gpg_exchange_dir }}/{{ inventory_hostname }}_ownertrust
- name: pull pubrings and ownertrusts
fetch:
src: "{{ item }}"
# Trailing slash is important!
dest: "{{ gpg_exchange_dir }}/"
flat: yes
loop:
- "{{ gpg_exchange_dir }}/{{ inventory_hostname }}_pubring.asc"
- "{{ gpg_exchange_dir }}/{{ inventory_hostname }}_ownertrust"
- delegate_to: localhost
run_once: yes
block:
- name: import pubrings to control machine
shell: gpg2 --import {{ gpg_exchange_dir }}/*_pubring.asc
- name: import ownertrusts to control machine
shell: gpg2 --import-ownertrust {{ item }}
with_fileglob: "{{ gpg_exchange_dir }}/*_ownertrust"
- name: sync private keys and revocation certs
synchronize:
# trailing slash is important
src: "{{ item }}/"
dest: "{{ item }}/"
mode: push
loop: "{{ gpg_rsynced_dirs }}"
- name: export control machine pubring and ownertrust
shell: |
gpg2 --export --armor > {{ gpg_exchange_dir }}/{{ control_machine_name }}_pubring.asc &&
gpg2 --export-ownertrust > {{ gpg_exchange_dir }}/{{ control_machine_name }}_ownertrust
delegate_to: localhost
run_once: yes
- name: sync pubring and ownertrust
synchronize:
src: "{{ item }}"
dest: "{{ item }}"
mode: push
loop:
- "{{ gpg_exchange_dir }}/{{ control_machine_name }}_pubring.asc"
- "{{ gpg_exchange_dir }}/{{ control_machine_name }}_ownertrust"
- name: import pubring and ownertrust
shell: |
gpg2 --import {{ gpg_exchange_dir }}/{{ control_machine_name }}_pubring.asc &&
gpg2 --import-ownertrust {{ gpg_exchange_dir }}/{{ control_machine_name }}_ownertrust
- name: clone password store
git:
repo: [email protected]:jan-warchol/password-store.git
dest: "{{ passwordstore_path }}"
update: no # "yes" can reset --hard unpushed commits
recursive: no # "offline" module requires special steps
- name: setup symbolic link
file:
src: "{{ passwordstore_path }}"
dest: "{{ ansible_env.HOME }}/.password-store"
state: link
force: no
- name: configure git user email
git_config:
key: user.email
value: [email protected]
repo: "{{ passwordstore_path }}"
- name: clone special submodule with top-secret passwords
git:
accept_hostkey: yes # low risk since it's over LAN
# FIXME: passwordstore_path should be taken from control machine hostvars
repo: jan@{{ control_machine_address }}:{{ passwordstore_path }}/offline
dest: "{{ passwordstore_path }}/offline"
# doesn't make sense to clone repo into itself
when: inventory_hostname != control_machine_name
- name: configure git user email
git_config:
key: user.email
value: [email protected]
repo: "{{ passwordstore_path }}/offline"