diff options
Diffstat (limited to 'ansible/roles/certs/tasks/main.yml')
-rw-r--r-- | ansible/roles/certs/tasks/main.yml | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/ansible/roles/certs/tasks/main.yml b/ansible/roles/certs/tasks/main.yml new file mode 100644 index 0000000..e83a640 --- /dev/null +++ b/ansible/roles/certs/tasks/main.yml | |||
@@ -0,0 +1,153 @@ | |||
1 | --- | ||
2 | - name: remove default ubuntu key | ||
3 | file: | ||
4 | path: /etc/ssl/private/ssl-cert-snakeoil.key | ||
5 | state: absent | ||
6 | |||
7 | - name: create cert maint group | ||
8 | group: | ||
9 | name: certmaint | ||
10 | gid: 1070 | ||
11 | state: present | ||
12 | |||
13 | - name: create cert maint user | ||
14 | user: | ||
15 | name: certmaint | ||
16 | uid: 1070 | ||
17 | group: ssl-cert | ||
18 | groups: | ||
19 | - certmaint | ||
20 | shell: /bin/sh | ||
21 | create_home: yes | ||
22 | state: present | ||
23 | |||
24 | #- name: allow certmaint to maint certs and keys (default) | ||
25 | # acl: | ||
26 | # path: /etc/ssl/ | ||
27 | # etype: user | ||
28 | # entity: certmaint | ||
29 | # permissions: rw | ||
30 | # default: yes | ||
31 | # recursive: yes | ||
32 | # state: present | ||
33 | # no_log: true | ||
34 | |||
35 | #- name: allow certmaint to maint certs and keys (actual certs) | ||
36 | # acl: | ||
37 | # path: /etc/ssl/ | ||
38 | # etype: user | ||
39 | # entity: certmaint | ||
40 | # permissions: rwx | ||
41 | # state: present | ||
42 | # no_log: true | ||
43 | |||
44 | #- name: allow certmaint to maint certs and keys (actual keys) | ||
45 | # acl: | ||
46 | # path: /etc/ssl/private/ | ||
47 | # etype: user | ||
48 | # entity: certmaint | ||
49 | # permissions: rwx | ||
50 | # state: present | ||
51 | # no_log: true | ||
52 | |||
53 | # Keys are private: only owner can read/write, and only group can read | ||
54 | - name: populate required keys (common types) | ||
55 | copy: | ||
56 | src: "tls/private/{{ item[0] }}-key.{{ item[1] }}.pem" | ||
57 | dest: /etc/ssl/private/ | ||
58 | mode: 0640 | ||
59 | owner: certmaint | ||
60 | group: ssl-cert | ||
61 | loop: "{{ certs.required |product(certs.keyTypes) |list }}" | ||
62 | when: certs.required[0] is string | ||
63 | |||
64 | |||
65 | # Certs are owned by 'certmaint' so user 'certmaint' can update them over scp | ||
66 | # Certs are public (obviously) | ||
67 | - name: populate required certs (common types) | ||
68 | copy: | ||
69 | src: "tls/{{ item[0] }}-cert-combined.{{ item[1] }}.pem" | ||
70 | dest: /etc/ssl/ | ||
71 | mode: 0644 | ||
72 | owner: certmaint | ||
73 | loop: "{{ certs.required |product(certs.keyTypes) |list }}" | ||
74 | when: certs.required[0] is string | ||
75 | |||
76 | |||
77 | |||
78 | # Keys are private: only owner can read/write, and only group can read | ||
79 | - name: populate required keys (specific types) | ||
80 | copy: | ||
81 | src: "tls/private/{{ item.host }}-key.{{ item.type }}.pem" | ||
82 | dest: /etc/ssl/private/ | ||
83 | mode: 0640 | ||
84 | owner: certmaint | ||
85 | group: ssl-cert | ||
86 | loop: "{{ certs.required }}" | ||
87 | when: certs.required[0] is mapping | ||
88 | |||
89 | # Certs are owned by 'certmaint' so user 'certmaint' can update them over scp | ||
90 | # Certs are public (obviously) | ||
91 | - name: populate required certs (specific types) | ||
92 | copy: | ||
93 | src: "tls/{{ item.host }}-cert-combined.{{ item.type }}.pem" | ||
94 | dest: /etc/ssl/ | ||
95 | mode: 0644 | ||
96 | owner: certmaint | ||
97 | loop: "{{ certs.required }}" | ||
98 | when: certs.required[0] is mapping | ||
99 | |||
100 | |||
101 | |||
102 | - name: plop LE cert chain | ||
103 | copy: | ||
104 | src: "tls/lets-encrypt-x3-cross-signed.pem" | ||
105 | dest: /etc/ssl/ | ||
106 | mode: 0644 | ||
107 | owner: certmaint | ||
108 | |||
109 | - name: plop remote LE challenge redirector | ||
110 | copy: | ||
111 | src: leforward.py | ||
112 | dest: /usr/local/bin/ | ||
113 | mode: 0755 | ||
114 | when: | ||
115 | - certs.receiver is defined and certs.receiver | ||
116 | |||
117 | |||
118 | # Retrieve all users on this host (creates variable 'passwd' containing results) | ||
119 | - name: get all user details so we can populate home directories | ||
120 | getent: | ||
121 | database: passwd | ||
122 | |||
123 | # Copy users/hostname/username contents into remote home directory | ||
124 | - name: verify explicit user keys exist as expected | ||
125 | copy: | ||
126 | src: "users/{{ inventory_hostname }}/{{ item }}/" | ||
127 | # [item][4] is [username][homedir] where /etc/passwd is tokenized on ':' | ||
128 | # and username becomes the key with remaining fields indexed by integers | ||
129 | dest: "{{ getent_passwd[item][4] }}" | ||
130 | mode: 0600 | ||
131 | owner: "{{ item }}" | ||
132 | directory_mode: 0700 | ||
133 | loop: "{{ certs.sshKeysForUsers }}" | ||
134 | |||
135 | # TODO: we could make one key per action then restrict actions by ssh key. | ||
136 | # (postfix key, dovecot key, nginx key, leforward key) | ||
137 | - name: verify certmaint receiver key exists | ||
138 | copy: | ||
139 | src: "users/certmaint/" | ||
140 | dest: "{{ getent_passwd[item][4] }}" | ||
141 | mode: 0600 | ||
142 | owner: "{{ item }}" | ||
143 | directory_mode: 0700 | ||
144 | loop: | ||
145 | - certmaint | ||
146 | |||
147 | - name: allow certmaint group to sudo reload relevant services | ||
148 | lineinfile: | ||
149 | path: /etc/sudoers.d/certmaint_reloads | ||
150 | regexp: "^%certmaint" | ||
151 | line: "%certmaint ALL = (root) NOPASSWD: /usr/sbin/service postfix reload, /usr/sbin/service dovecot reload, /usr/sbin/service nginx reload" | ||
152 | create: yes | ||
153 | mode: 0440 | ||