Compare commits
11 commits
63dec2f8b7
...
405fed1fcf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
405fed1fcf | ||
|
|
241f13d136 | ||
|
|
e45275181f | ||
|
|
b807d2142e | ||
|
|
37b8b94c9d | ||
|
|
c53e43f4ce | ||
|
|
3bfc3de6a1 | ||
|
|
9797ac3d4e | ||
|
|
51ae283d6d | ||
|
|
f032517a94 | ||
|
|
857b834232 |
20 changed files with 898 additions and 694 deletions
1358
inventory.yml
1358
inventory.yml
File diff suppressed because it is too large
Load diff
|
|
@ -49,6 +49,7 @@
|
||||||
- lmn_network
|
- lmn_network
|
||||||
- role: up2date_debian
|
- role: up2date_debian
|
||||||
tags: upgrade
|
tags: upgrade
|
||||||
|
- lmn_encrypt
|
||||||
- lmn_sssd
|
- lmn_sssd
|
||||||
- lmn_mount
|
- lmn_mount
|
||||||
- lmn_kde
|
- lmn_kde
|
||||||
|
|
@ -80,15 +81,17 @@
|
||||||
loop_var: rolename
|
loop_var: rolename
|
||||||
when: custom_roles is defined
|
when: custom_roles is defined
|
||||||
|
|
||||||
- name: Final tasks
|
- name: Import role security
|
||||||
ansible.builtin.include_role:
|
ansible.builtin.import_role:
|
||||||
name: "{{ role }}"
|
name: lmn_security
|
||||||
loop_control:
|
|
||||||
loop_var: role
|
- name: Import role finish
|
||||||
loop:
|
ansible.builtin.import_role:
|
||||||
- lmn_security
|
name: lmn_finish
|
||||||
- lmn_finish
|
|
||||||
- lmn_tmpfixes
|
- name: Import role tmpfixes
|
||||||
|
ansible.builtin.import_role:
|
||||||
|
name: lmn_tmpfixes
|
||||||
|
|
||||||
|
|
||||||
- name: Apply roles that must run serial
|
- name: Apply roles that must run serial
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,16 @@ fi
|
||||||
id="$(grep ID "$file" | sed -E "s|^.+ID>([[:digit:]]+)/([[:digit:]]+)</ID.+$|\1:\2|" \
|
id="$(grep ID "$file" | sed -E "s|^.+ID>([[:digit:]]+)/([[:digit:]]+)</ID.+$|\1:\2|" \
|
||||||
| sort -n -t: -k2 | tail -1 )"
|
| sort -n -t: -k2 | tail -1 )"
|
||||||
|
|
||||||
if id | grep -q teachers; then
|
for dir in teachers examusers staff parents; do
|
||||||
NETHOME=/srv/samba/schools/default-school/teachers/$USER
|
if [[ -d "/srv/samba/schools/default-school/${dir}/${USER}" ]]; then
|
||||||
else
|
NETHOME="/srv/samba/schools/default-school/${dir}/${USER}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -z "${NETHOME+x}" ]]; then
|
||||||
NETHOME=(/srv/samba/schools/default-school/students/*/"$USER")
|
NETHOME=(/srv/samba/schools/default-school/students/*/"$USER")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ -d $NETHOME ]] || exit 0
|
[[ -d $NETHOME ]] || exit 0
|
||||||
|
|
||||||
IDENTITY="${id%%:*}"
|
IDENTITY="${id%%:*}"
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@
|
||||||
- okular-extra-backends ## needed for CHM files
|
- okular-extra-backends ## needed for CHM files
|
||||||
- pdf-presenter-console
|
- pdf-presenter-console
|
||||||
- php-cli
|
- php-cli
|
||||||
|
- php-sqlite3
|
||||||
- pipx
|
- pipx
|
||||||
- planner
|
- planner
|
||||||
- pulseview
|
- pulseview
|
||||||
|
|
|
||||||
3
roles/lmn_encrypt/defaults/main.yml
Normal file
3
roles/lmn_encrypt/defaults/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
encrypt_passphrase_initial: Muster!
|
||||||
|
encrypt_tpm2: false
|
||||||
5
roles/lmn_encrypt/handlers/main.yml
Normal file
5
roles/lmn_encrypt/handlers/main.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
- name: Run update-grub
|
||||||
|
ansible.builtin.command: update-grub
|
||||||
|
|
||||||
|
- name: Run update-dracut
|
||||||
|
ansible.builtin.command: dracut -f
|
||||||
45
roles/lmn_encrypt/tasks/main.yml
Normal file
45
roles/lmn_encrypt/tasks/main.yml
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
- name: Find device with LUKS holder
|
||||||
|
vars:
|
||||||
|
partitions: "{{ item.value.partitions | dict2items | selectattr('value.holders', 'search', 'luks|crypt') }}"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
encrypt_device: "/dev/disk/by-id/{{ partitions[0].value.links.ids[0] }}"
|
||||||
|
when:
|
||||||
|
- item.value.partitions is defined
|
||||||
|
- item.value.partitions | dict2items | length > 0
|
||||||
|
loop: "{{ ansible_devices | dict2items }}"
|
||||||
|
|
||||||
|
- name: Get luks slots
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "systemd-cryptenroll {{ encrypt_device }}"
|
||||||
|
register: encrypt_slots_result
|
||||||
|
changed_when: false
|
||||||
|
when: encrypt_device is defined
|
||||||
|
|
||||||
|
- name: Change Password of Luks password slot
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
systemd-run -P --wait
|
||||||
|
-p SetCredential=cryptenroll.passphrase:{{ encrypt_passphrase_initial }}
|
||||||
|
-p SetCredential=cryptenroll.new-passphrase:{{ encrypt_passphrase }}
|
||||||
|
systemd-cryptenroll --password {{ encrypt_device }} --wipe-slot=password
|
||||||
|
no_log: true
|
||||||
|
when:
|
||||||
|
- encrypt_device is defined
|
||||||
|
- encrypt_passphrase is defined
|
||||||
|
- encrypt_slots_result.stdout_lines | length == 2
|
||||||
|
- encrypt_slots_result.stdout_lines[1].startswith(' 0')
|
||||||
|
|
||||||
|
- name: TPM Device Check
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /dev/tpm0
|
||||||
|
register: tpm_device
|
||||||
|
when: encrypt_device is defined
|
||||||
|
|
||||||
|
- name: Include TPM2 role
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tpm2.yml
|
||||||
|
when:
|
||||||
|
- encrypt_device is defined
|
||||||
|
- encrypt_tpm2
|
||||||
|
- tpm_device.stat.exists
|
||||||
42
roles/lmn_encrypt/tasks/tpm2.yml
Normal file
42
roles/lmn_encrypt/tasks/tpm2.yml
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
- name: Install tpm2-tools and dracut
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- tpm2-tools
|
||||||
|
- dracut
|
||||||
|
|
||||||
|
- name: Enable tpm2-tss crypt module on dracut
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /etc/dracut.conf.d/crypt.conf
|
||||||
|
content: add_dracutmodules+=" tpm2-tss crypt "
|
||||||
|
mode: '0644'
|
||||||
|
notify: Run update-dracut
|
||||||
|
|
||||||
|
- name: Comment out root device in crypttab
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
dest: /etc/crypttab
|
||||||
|
regexp: '^([^#].*)'
|
||||||
|
line: '#\1'
|
||||||
|
backrefs: true
|
||||||
|
|
||||||
|
- name: Insert luks support to GRUB_CMDLINE_LINUX
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
dest: /etc/default/grub
|
||||||
|
regexp: '^(GRUB_CMDLINE_LINUX=).*'
|
||||||
|
line: '\1"rd.auto rd.luks=1"'
|
||||||
|
backrefs: true
|
||||||
|
notify: Run update-grub
|
||||||
|
|
||||||
|
- name: Insert TPM2 to Luks slot
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
systemd-run -P --wait
|
||||||
|
-p SetCredential=cryptenroll.passphrase:{{ encrypt_passphrase | default(encrypt_passphrase_initial) }}
|
||||||
|
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 {{ encrypt_device }} --wipe-slot=tpm2
|
||||||
|
no_log: true
|
||||||
|
when: "'tpm2' not in encrypt_slots_result.stdout"
|
||||||
|
|
||||||
|
# - name: Update TPM2 Luks slot
|
||||||
|
# ansible.builtin.command:
|
||||||
|
# cmd: systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7+8 --unlock-tpm2-device=auto {{ encrypt_device }} --wipe-slot=tpm2
|
||||||
|
# when: not grub_config.changed
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
---
|
---
|
||||||
exam_mode: true
|
exam_mode: true
|
||||||
|
exam_teacherpc_last_digit: 80
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,25 @@
|
||||||
- pam-exec.sh
|
- pam-exec.sh
|
||||||
- rmexam
|
- rmexam
|
||||||
|
|
||||||
|
- name: Append teacherPC to exam_destination_allowed_ipv4 addresses
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
exam_destination_allowed_ipv4: "{{ exam_destination_allowed_ipv4 + [ ansible_default_ipv4.address[:-1] ~ exam_teacherpc_last_digit ] }}"
|
||||||
|
when:
|
||||||
|
- exam_destination_allowed_ipv4 is defined
|
||||||
|
- exam_destination_allowed_ipv4 | length > 0
|
||||||
|
|
||||||
|
- name: Install no-way-out-policy
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: no-way-out.xml.j2
|
||||||
|
dest: "/etc/firewalld/policies/no-way-out-{{ item }}.xml"
|
||||||
|
mode: '0644'
|
||||||
|
loop:
|
||||||
|
- HOST
|
||||||
|
- libvirt
|
||||||
|
when:
|
||||||
|
- exam_destination_allowed_ipv4 is defined
|
||||||
|
- exam_destination_allowed_ipv4 | length > 0
|
||||||
|
|
||||||
- name: Enable login script via pam_exec.so
|
- name: Enable login script via pam_exec.so
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
dest: /etc/pam.d/common-session
|
dest: /etc/pam.d/common-session
|
||||||
|
|
|
||||||
10
roles/lmn_exam/templates/no-way-out.xml.j2
Normal file
10
roles/lmn_exam/templates/no-way-out.xml.j2
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<policy target="REJECT">
|
||||||
|
{% for address in exam_destination_allowed_ipv4 %}
|
||||||
|
<rule family="ipv4">
|
||||||
|
<destination address="{{ address }}"/>
|
||||||
|
<accept/>
|
||||||
|
</rule>
|
||||||
|
{% endfor %}
|
||||||
|
<ingress-zone name="{{ item }}"/>
|
||||||
|
<egress-zone name="ANY"/>
|
||||||
|
</policy>
|
||||||
4
roles/lmn_finish/handlers/main.yml
Normal file
4
roles/lmn_finish/handlers/main.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
- name: Reboot client
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "shutdown -r -t 60"
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
- "{{ extra_pkgs }}"
|
- "{{ extra_pkgs }}"
|
||||||
- "{{ extra_pkgs1 }}"
|
- "{{ extra_pkgs1 }}"
|
||||||
- "{{ extra_pkgs2 }}"
|
- "{{ extra_pkgs2 }}"
|
||||||
|
tags:
|
||||||
|
- baseinstall
|
||||||
|
|
||||||
- name: Add backports for {{ ansible_distribution_release }}
|
- name: Add backports for {{ ansible_distribution_release }}
|
||||||
ansible.builtin.apt_repository:
|
ansible.builtin.apt_repository:
|
||||||
|
|
@ -27,6 +29,18 @@
|
||||||
- "{{ extra_pkgs_bpo2 }}"
|
- "{{ extra_pkgs_bpo2 }}"
|
||||||
when: extra_pkgs_bpo | length > 0 or extra_pkgs_bpo1 | length > 0 or extra_pkgs_bpo2 | length > 0
|
when: extra_pkgs_bpo | length > 0 or extra_pkgs_bpo1 | length > 0 or extra_pkgs_bpo2 | length > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Check if former ansible-stamp exists
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /var/local/ansible-stamps
|
||||||
|
register: stamp_exists
|
||||||
|
|
||||||
|
- name: Trigger Reboot if no former ansible-run is found
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "First Ansible-Run on Client - Reboot handler started"
|
||||||
|
changed_when: not stamp_exists.stat.exists
|
||||||
|
notify: "Reboot client"
|
||||||
|
|
||||||
- name: Timestamp successfull run and send up-to-date report
|
- name: Timestamp successfull run and send up-to-date report
|
||||||
ansible.builtin.shell:
|
ansible.builtin.shell:
|
||||||
cmd: date --iso-8601=seconds >> /var/local/ansible-stamps && /usr/local/sbin/reporter
|
cmd: date --iso-8601=seconds >> /var/local/ansible-stamps && /usr/local/sbin/reporter
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
dest: /etc/profile.d/lmn-logout.sh
|
dest: /etc/profile.d/lmn-logout.sh
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
content: |
|
content: |
|
||||||
[[ "${UID}" -gt 10000 ]] && ! findmnt "/lmn/media/${USER}/home" > /dev/null && exit 0
|
|
||||||
{% if localhome_logout_missing_serverhome %}
|
{% if localhome_logout_missing_serverhome %}
|
||||||
[[ "${UID}" -gt 10000 ]] && ! findmnt /srv/samba/schools/default-school > /dev/null && exit 0
|
[[ "${UID}" -gt 10000 ]] && ! findmnt /srv/samba/schools/default-school > /dev/null && exit 0
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,8 @@
|
||||||
src: reporter.j2
|
src: reporter.j2
|
||||||
dest: /usr/local/sbin/reporter
|
dest: /usr/local/sbin/reporter
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
tags:
|
||||||
|
- baseinstall
|
||||||
|
|
||||||
- name: Provide services and timers for reporter
|
- name: Provide services and timers for reporter
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
|
|
@ -177,12 +179,16 @@
|
||||||
- reporter.service
|
- reporter.service
|
||||||
- reporter.timer
|
- reporter.timer
|
||||||
when: misc_reporter
|
when: misc_reporter
|
||||||
|
tags:
|
||||||
|
- baseinstall
|
||||||
|
|
||||||
- name: Enable reporter.timer
|
- name: Enable reporter.timer
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
name: reporter.timer
|
name: reporter.timer
|
||||||
enabled: true
|
enabled: true
|
||||||
when: misc_reporter
|
when: misc_reporter
|
||||||
|
tags:
|
||||||
|
- baseinstall
|
||||||
|
|
||||||
# Prepare CloneScreen on Presenter PCs
|
# Prepare CloneScreen on Presenter PCs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
key: "{{ item }}"
|
key: "{{ item }}"
|
||||||
loop: "{{ keys2deploy }}"
|
loop: "{{ keys2deploy }}"
|
||||||
when: keys2deploy is defined
|
when: keys2deploy is defined
|
||||||
|
tags:
|
||||||
|
- baseinstall
|
||||||
|
|
||||||
- name: Allow sudo without password for ansible
|
- name: Allow sudo without password for ansible
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
|
|
@ -14,12 +16,16 @@
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: '0700'
|
mode: '0700'
|
||||||
|
tags:
|
||||||
|
- baseinstall
|
||||||
|
|
||||||
- name: Disable ansible user login
|
- name: Disable ansible user login
|
||||||
ansible.builtin.user:
|
ansible.builtin.user:
|
||||||
name: ansible
|
name: ansible
|
||||||
password_lock: true
|
password_lock: true
|
||||||
when: security_defaultuser_login_disable
|
when: security_defaultuser_login_disable
|
||||||
|
tags:
|
||||||
|
- baseinstall
|
||||||
|
|
||||||
- name: Limit SSH access to user ansible
|
- name: Limit SSH access to user ansible
|
||||||
ansible.builtin.blockinfile:
|
ansible.builtin.blockinfile:
|
||||||
|
|
|
||||||
2
roles/lmn_sssd/defaults/main.yml
Normal file
2
roles/lmn_sssd/defaults/main.yml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
sssd_domjoin_user: global-admin
|
||||||
|
|
@ -13,12 +13,23 @@
|
||||||
mode: '0600'
|
mode: '0600'
|
||||||
notify: Restart sssd
|
notify: Restart sssd
|
||||||
|
|
||||||
## Either one of the variables is defined:
|
- name: Check if the machine account password and the join are still valid
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: adcli testjoin -D {{ domain | upper }}
|
||||||
|
register: adcli_test_result
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
# If domjoin not valid:
|
||||||
- name: Join the domain
|
- name: Join the domain
|
||||||
ansible.builtin.shell:
|
ansible.builtin.shell:
|
||||||
cmd: >
|
cmd: >
|
||||||
echo "{{ ansible_cmdline.adpw | default('') + adpw.user_input | default('') }}" |
|
echo "{{ ad_passwd }}" | adcli join --stdin-password -U {{ ad_user }} {{ domain | upper }}
|
||||||
adcli join --stdin-password -U global-admin {{ domain | upper }}
|
no_log: true
|
||||||
when: >
|
vars:
|
||||||
ansible_cmdline.adpw | default('') | length > 0 or
|
- ad_user: "{{ 'global-admin' if (adpw.user_input | default(ansible_cmdline.adpw) | default('') | length > 0) else sssd_domjoin_user }}"
|
||||||
adpw.user_input | default('') | length > 0
|
- ad_passwd: "{{ adpw.user_input | default('') if adpw.user_input | length > 0 else ansible_cmdline.adpw | default(sssd_domjoin_passwd) | default('') }}"
|
||||||
|
when:
|
||||||
|
- adpw.user_input | length > 0 or
|
||||||
|
ansible_cmdline.adpw | default(sssd_domjoin_passwd) | default('') | length > 0
|
||||||
|
- adcli_test_result.rc != 0
|
||||||
|
|
|
||||||
|
|
@ -346,11 +346,16 @@ if ! virsh --connect="${QEMU}" list | grep "${VM_NAME}-clone"; then
|
||||||
virsh --connect=qemu:///session undefine --nvram "${VM_NAME}-clone" || echo "${VM_NAME}-clone did not exist"
|
virsh --connect=qemu:///session undefine --nvram "${VM_NAME}-clone" || echo "${VM_NAME}-clone did not exist"
|
||||||
#trap exit_script SIGHUP SIGINT SIGTERM
|
#trap exit_script SIGHUP SIGINT SIGTERM
|
||||||
|
|
||||||
if id | grep -q teachers; then
|
for dir in teachers examusers staff parents; do
|
||||||
NETHOME=/srv/samba/schools/default-school/teachers/$USER
|
if [[ -d "/srv/samba/schools/default-school/${dir}/${USER}" ]]; then
|
||||||
else
|
NETHOME="/srv/samba/schools/default-school/${dir}/${USER}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -z "${NETHOME+x}" ]]; then
|
||||||
NETHOME=(/srv/samba/schools/default-school/students/*/"$USER")
|
NETHOME=(/srv/samba/schools/default-school/students/*/"$USER")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${HOME}" != "${NETHOME}" ]]; then
|
if [[ "${HOME}" != "${NETHOME}" ]]; then
|
||||||
VMINFO_DIR="${HOME}"
|
VMINFO_DIR="${HOME}"
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,12 @@ def main():
|
||||||
vminfo['User'] = environ.get('USER')
|
vminfo['User'] = environ.get('USER')
|
||||||
vminfo['Groups'] = get_groups(environ.get('USER'))
|
vminfo['Groups'] = get_groups(environ.get('USER'))
|
||||||
|
|
||||||
if 'teachers' in vminfo['Groups']:
|
for dir in ['teachers','examusers','staff','parents']:
|
||||||
nethome = f"/srv/samba/schools/default-school/teachers/{vminfo['User']}"
|
potential_path = f"/srv/samba/schools/default-school/{dir}/{vminfo['User']}"
|
||||||
else:
|
if path.isdir(potential_path):
|
||||||
|
nethome = potential_path
|
||||||
|
break
|
||||||
|
if not nethome:
|
||||||
result = subprocess.run(['find', '/srv/samba/schools/default-school/students/', '-name', vminfo['User'], '-maxdepth', '2', '-type', 'd'], capture_output=True, text=True, check=False)
|
result = subprocess.run(['find', '/srv/samba/schools/default-school/students/', '-name', vminfo['User'], '-maxdepth', '2', '-type', 'd'], capture_output=True, text=True, check=False)
|
||||||
nethome = result.stdout.splitlines()[0]
|
nethome = result.stdout.splitlines()[0]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue