-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnew-vm-setup.yml
More file actions
478 lines (417 loc) · 14.8 KB
/
Copy pathnew-vm-setup.yml
File metadata and controls
478 lines (417 loc) · 14.8 KB
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
- name: New VM setup
hosts: "{{ target_hosts }}"
become: true
gather_facts: true
tasks:
# Ensure admin user exists and has SSH access before hardening
- name: Create admin user
user:
name: "{{ admin_user }}"
groups: wheel
password: ''
- name: Deploy admin user SSH key
authorized_key:
user: "{{ admin_user }}"
state: present
key: "{{ admin_ssh_key }}"
# SSHD hardening
- name: Remove problematic 01-permitrootlogin.conf drop-in if present
file:
path: /etc/ssh/sshd_config.d/01-permitrootlogin.conf
state: absent
- name: Set PermitRootLogin no
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
- name: Set PasswordAuthentication no
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PasswordAuthentication'
line: 'PasswordAuthentication no'
- name: Set KbdInteractiveAuthentication no
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?KbdInteractiveAuthentication'
line: 'KbdInteractiveAuthentication no'
- name: Set MaxAuthTries 3
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?MaxAuthTries'
line: 'MaxAuthTries 3'
- name: Set LogLevel VERBOSE
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?LogLevel'
line: 'LogLevel VERBOSE'
- name: Set LoginGraceTime 30
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?LoginGraceTime'
line: 'LoginGraceTime 30'
- name: Set GSSAPIAuthentication no
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?GSSAPIAuthentication'
line: 'GSSAPIAuthentication no'
- name: Disable GSSAPIAuthentication in 50-redhat.conf if present
lineinfile:
path: /etc/ssh/sshd_config.d/50-redhat.conf
regexp: '^GSSAPIAuthentication'
line: 'GSSAPIAuthentication no'
failed_when: false
- name: Set AllowUsers
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?AllowUsers'
line: 'AllowUsers {{ allowed_users }}'
- name: Restart sshd
service:
name: sshd
state: restarted
- name: Force new SSH connection
meta: reset_connection
- name: Verify SSH access still works
shell: echo ok
register: ssh_verify
changed_when: false
# Firewall
- name: Set default zone to drop
command: firewall-cmd --set-default-zone=drop
changed_when: true
- name: Allow SSH permanently
command: firewall-cmd --permanent --add-service=ssh
changed_when: true
- name: Reload firewall
command: firewall-cmd --reload
changed_when: true
# EPEL for RHEL/CentOS (needed for buildbot-worker and fail2ban)
- name: Enable CRB repo on CentOS Stream
command: dnf config-manager --set-enabled crb
when: ansible_distribution == 'CentOS'
failed_when: false
- name: Enable CodeReady Builder on RHEL
shell: subscription-manager repos --enable codeready-builder-for-rhel-{{ ansible_distribution_major_version }}-{{ ansible_architecture }}-rpms
when: ansible_distribution == 'RedHat'
failed_when: false
- name: Install EPEL release RPM
command: dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm
args:
creates: /etc/yum.repos.d/epel.repo
when: ansible_distribution in ['RedHat', 'CentOS']
- name: Install EPEL Next release RPM on CentOS Stream 9 and older
command: dnf -y install https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm
args:
creates: /etc/yum.repos.d/epel-next.repo
when:
- ansible_distribution == 'CentOS'
- ansible_distribution_major_version | int < 10
# Automatic updates
- name: Install dnf-automatic (dnf4)
package:
name: dnf-automatic
state: present
when: ansible_distribution != 'Fedora'
failed_when: false
- name: Enable dnf-automatic-install timer (RHEL 8)
systemd:
name: dnf-automatic-install.timer
enabled: true
state: started
when: ansible_distribution == 'RedHat' and ansible_distribution_major_version == '8'
failed_when: false
- name: Enable dnf-automatic timer (CentOS Stream / RHEL 9+)
systemd:
name: dnf-automatic.timer
enabled: true
state: started
when: ansible_distribution == 'CentOS' or (ansible_distribution == 'RedHat' and ansible_distribution_major_version | int >= 9)
failed_when: false
- name: Enable dnf5-automatic timer (Fedora)
systemd:
name: dnf5-automatic.timer
enabled: true
state: started
when: ansible_distribution == 'Fedora'
failed_when: false
# Sudoers
- name: Set passwordless sudo for admin user
copy:
content: "{{ admin_user }} ALL=(ALL) NOPASSWD: ALL\n"
dest: "/etc/sudoers.d/{{ admin_user }}"
mode: '0440'
# fail2ban (after EPEL since it comes from EPEL on RHEL/CentOS)
- name: Install fail2ban
package:
name: fail2ban
state: present
- name: Create jail.local for sshd
copy:
content: |
[sshd]
enabled = true
maxretry = 3
bantime = 3600
findtime = 600
dest: /etc/fail2ban/jail.local
mode: '0644'
- name: Enable and start fail2ban
systemd:
name: fail2ban
enabled: true
state: restarted
# Build dependencies for CPython
- name: Install dnf builddep plugin (dnf4)
package:
name: dnf-plugins-core
state: present
when: ansible_distribution != 'Fedora'
failed_when: false
- name: Install dnf builddep plugin (dnf5)
package:
name: dnf5-plugins
state: present
when: ansible_distribution == 'Fedora'
failed_when: false
- name: Install CPython build dependencies
command: dnf builddep -y python3
changed_when: false
- name: Install additional build tools
package:
name:
- git
- perf
- clang
- buildbot-worker
state: present
- name: Install SystemTap packages for CPython test_dtrace
package:
name:
- systemtap-client
- systemtap-runtime
- systemtap-devel
- kernel-devel
state: present
when: not (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version | int <= 8)
- name: Allow buildbot worker to run SystemTap tests without sudo
user:
name: buildbot-worker
groups:
- stapusr
- stapdev
append: true
when: not (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version | int <= 8)
notify: Restart buildbot worker
# FIPS workaround: patch Twisted PB auth to allow MD5 for non-security use
# See https://github.com/twisted/twisted/pull/11883
# Must be done before starting the worker service
- name: Find Twisted pb.py location
shell: find /usr -path '*/twisted/spread/pb.py' 2>/dev/null | head -1
register: twisted_pb_path
changed_when: false
when: fips_mode | default(false)
- name: Patch Twisted MD5 calls for FIPS compatibility
shell: |
sed -i 's/m = md5()/m = md5(usedforsecurity=False)/g' "{{ twisted_pb_path.stdout }}"
sed -i 's/md5(crap)/md5(crap, usedforsecurity=False)/g' "{{ twisted_pb_path.stdout }}"
sed -i 's/md5(password)/md5(password, usedforsecurity=False)/g' "{{ twisted_pb_path.stdout }}"
sed -i 's/md = md5()/md = md5(usedforsecurity=False)/g' "{{ twisted_pb_path.stdout }}"
when: fips_mode | default(false) and twisted_pb_path.stdout | length > 0
# Buildbot worker setup
- name: Ensure /var/lib/buildbot/worker is owned by buildbot-worker
file:
path: /var/lib/buildbot/worker
state: directory
owner: buildbot-worker
group: buildbot-worker
mode: '0755'
- name: Check available space on /var and /home
shell: |
var_avail=$(df -BG --output=avail /var | tail -1 | tr -d ' G')
home_avail=$(df -BG --output=avail /home 2>/dev/null | tail -1 | tr -d ' G')
var_dev=$(df --output=source /var | tail -1)
home_dev=$(df --output=source /home 2>/dev/null | tail -1)
if [ "$var_dev" != "$home_dev" ] && [ "${home_avail:-0}" -gt "$var_avail" ]; then
echo "/home/buildbot-worker"
else
echo "/var/lib/buildbot/worker"
fi
register: worker_basedir
changed_when: false
- name: Create worker base directory if using /home
file:
path: /home/buildbot-worker
state: directory
owner: buildbot-worker
group: buildbot-worker
mode: '0755'
when: worker_basedir.stdout == '/home/buildbot-worker'
- name: Create buildbot worker
command: >
buildbot-worker create-worker
{{ worker_basedir.stdout }}/{{ worker_name }}
buildbot.python.org:9020
{{ worker_name }}
{{ worker_password }}
args:
creates: "{{ worker_basedir.stdout }}/{{ worker_name }}/buildbot.tac"
become_user: buildbot-worker
- name: Create symlink for split disk layout
block:
- name: Ensure /var/lib/buildbot/worker exists
file:
path: /var/lib/buildbot/worker
state: directory
- name: Symlink worker directory to /var/lib/buildbot/worker
file:
src: "/home/buildbot-worker/{{ worker_name }}"
dest: "/var/lib/buildbot/worker/{{ worker_name }}"
state: link
when: worker_basedir.stdout == '/home/buildbot-worker'
- name: Set delete_leftover_dirs in buildbot.tac
lineinfile:
path: "{{ worker_basedir.stdout }}/{{ worker_name }}/buildbot.tac"
regexp: '^delete_leftover_dirs'
line: 'delete_leftover_dirs = 1'
- name: Set keepalive in buildbot.tac
lineinfile:
path: "{{ worker_basedir.stdout }}/{{ worker_name }}/buildbot.tac"
regexp: '^keepalive'
line: 'keepalive = 60'
- name: Set worker info/admin
copy:
content: "{{ worker_admin }}"
dest: "{{ worker_basedir.stdout }}/{{ worker_name }}/info/admin"
owner: buildbot-worker
group: buildbot-worker
when: worker_admin is defined
- name: Set worker info/host
copy:
content: "{{ worker_host }}"
dest: "{{ worker_basedir.stdout }}/{{ worker_name }}/info/host"
owner: buildbot-worker
group: buildbot-worker
when: worker_host is defined
- name: Enable and start buildbot worker service
systemd:
name: "buildbot-worker@{{ worker_name }}.service"
enabled: true
state: started
daemon_reload: true
# Log management: use a drop-in because newer Fedora (systemd 256+)
# no longer ships /etc/systemd/journald.conf
- name: Create journald drop-in directory
file:
path: /etc/systemd/journald.conf.d
state: directory
mode: '0755'
- name: Set journald max disk usage
copy:
content: |
[Journal]
SystemMaxUse=500M
dest: /etc/systemd/journald.conf.d/99-buildbot.conf
mode: '0644'
notify: Restart journald
# Kernel cleanup
- name: Set installonly_limit for old kernels
lineinfile:
path: /etc/dnf/dnf.conf
regexp: '^#?installonly_limit='
line: 'installonly_limit=3'
# Performance tuning
- name: Install tuned
package:
name: tuned
state: present
- name: Enable tuned
systemd:
name: tuned
enabled: true
state: started
- name: Set throughput-performance tuned profile
command: tuned-adm profile throughput-performance
changed_when: false
# fstrim for qcow2 disk reclaim
- name: Enable fstrim timer
systemd:
name: fstrim.timer
enabled: true
state: started
# Firmware cleanup: VMs have no WiFi/GPU/audio hardware
- name: Remove unnecessary firmware packages
package:
name:
- amd-gpu-firmware
- nvidia-gpu-firmware
- atheros-firmware
- intel-gpu-firmware
- intel-audio-firmware
- iwlax2xx-firmware
- iwl7260-firmware
- iwl6050-firmware
- iwl6000g2b-firmware
- iwl6000g2a-firmware
- iwl5150-firmware
- iwl5000-firmware
- iwl4965-firmware
- iwl3945-firmware
- iwl2030-firmware
- iwl2000-firmware
- iwl1000-firmware
- iwl105-firmware
- iwl100-firmware
- iwl135-firmware
- brcmfmac-firmware
- mt7xxx-firmware
- tiwilink-firmware
- atmel-firmware
- libertas-firmware
- zd1211-firmware
- realtek-firmware
state: absent
when: ansible_virtualization_role == 'guest'
failed_when: false
- name: Remove fwupd on Fedora
package:
name: fwupd
state: absent
when: ansible_virtualization_role == 'guest' and ansible_distribution == 'Fedora'
failed_when: false
# On RHEL 8 / CentOS Stream 9, fwupd removal cascades into shim-*
# (EFI boot chain), so only remove the flashrom plugin
- name: Remove fwupd-plugin-flashrom on RHEL/CentOS
package:
name:
- fwupd-plugin-flashrom
- flashrom
state: absent
when: ansible_virtualization_role == 'guest' and ansible_distribution in ['RedHat', 'CentOS']
failed_when: false
# Boot cleanup: keep only the newest rescue kernel pair
- name: Remove duplicate rescue kernels from /boot
shell: |
rescue_kernels=$(ls -t /boot/vmlinuz-0-rescue-* 2>/dev/null)
count=$(echo "$rescue_kernels" | grep -c . 2>/dev/null || echo 0)
if [ "$count" -le 1 ]; then
echo "No duplicate rescue kernels"
exit 0
fi
echo "$rescue_kernels" | tail -n +2 | while read -r kernel; do
machine_id=$(echo "$kernel" | sed 's|/boot/vmlinuz-0-rescue-||')
echo "Removing rescue pair for: $machine_id"
rm -f "/boot/vmlinuz-0-rescue-${machine_id}"
rm -f "/boot/initramfs-0-rescue-${machine_id}.img"
done
register: rescue_cleanup
changed_when: "'Removing' in rescue_cleanup.stdout"
failed_when: false
handlers:
- name: Restart buildbot worker
systemd:
name: "buildbot-worker@{{ worker_name }}.service"
state: restarted
- name: Restart journald
systemd:
name: systemd-journald
state: restarted