life-church: add thinkcenter-xrdp (install/enable/verify xrdp + ssl-cert fix + Cinnamon session)
This commit is contained in:
parent
0139c376b5
commit
dbef6bc979
185
life-church/playbooks/thinkcenter-xrdp.yml
Normal file
185
life-church/playbooks/thinkcenter-xrdp.yml
Normal file
@ -0,0 +1,185 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# life-church/playbooks/thinkcenter-xrdp.yml
|
||||
# Install (if missing) + configure + enable xrdp on thinkcenter. Convergent:
|
||||
# safe to run whether xrdp is absent or already set up. thinkcenter ONLY.
|
||||
# CHANGES the system. become password from Infisical /lc-hosts at runtime.
|
||||
#
|
||||
# What it guarantees:
|
||||
# - xrdp + xorgxrdp installed (+ pipewire-module-xrdp so RDP has audio).
|
||||
# - the `xrdp` service user is in the `ssl-cert` group (classic xrdp gotcha:
|
||||
# without it xrdp can't read /etc/xrdp/key.pem and sessions fail).
|
||||
# - a per-user ~/.xsession selects Cinnamon for the RDP login.
|
||||
# - xrdp + xrdp-sesman enabled at boot AND started now.
|
||||
# - listening on 3389; UFW rule added only if UFW is active.
|
||||
#
|
||||
# UNDO:
|
||||
# sudo systemctl disable --now xrdp xrdp-sesman
|
||||
# sudo gpasswd -d xrdp ssl-cert # (only if you want to revert the group)
|
||||
# sudo apt remove --purge xrdp xorgxrdp
|
||||
# rm -f ~<user>/.xsession
|
||||
# ============================================================================
|
||||
|
||||
# --- Play 1 (localhost): fetch thinkcenter sudo pass from Infisical ----------
|
||||
- name: "thinkcenter xrdp — resolve become password from Infisical"
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: "[resolve] Infisical creds from env"
|
||||
ansible.builtin.set_fact:
|
||||
infisical_client_id: "{{ lookup('env','INFISICAL_CLIENT_ID') }}"
|
||||
infisical_client_secret: "{{ lookup('env','INFISICAL_CLIENT_SECRET') }}"
|
||||
infisical_project_id: "{{ lookup('env','INFISICAL_PROJECT_ID') }}"
|
||||
infisical_url: "{{ lookup('env','INFISICAL_API_URL') | default('http://192.168.122.41:8080', true) }}"
|
||||
infisical_env_slug: "{{ lookup('env','INFISICAL_ENV_SLUG') | default('prod', true) }}"
|
||||
|
||||
- name: "[resolve] Assert Infisical creds present"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- infisical_client_id | length > 0
|
||||
- infisical_client_secret | length > 0
|
||||
- infisical_project_id | length > 0
|
||||
fail_msg: "Infisical creds missing from Semaphore environment 'infisical-dev'."
|
||||
|
||||
- name: "[infisical] Log in"
|
||||
infisical.vault.login:
|
||||
url: "{{ infisical_url }}"
|
||||
auth_method: universal_auth
|
||||
universal_auth_client_id: "{{ infisical_client_id }}"
|
||||
universal_auth_client_secret: "{{ infisical_client_secret }}"
|
||||
register: infisical_login
|
||||
no_log: true
|
||||
|
||||
- name: "[infisical] Read /lc-hosts"
|
||||
infisical.vault.read_secrets:
|
||||
login_data: "{{ infisical_login.login_data }}"
|
||||
project_id: "{{ infisical_project_id }}"
|
||||
env_slug: "{{ infisical_env_slug }}"
|
||||
path: "/lc-hosts"
|
||||
as_dict: true
|
||||
register: lc_secrets
|
||||
no_log: true
|
||||
|
||||
- name: "[set] Stash thinkcenter sudo pass + login user"
|
||||
ansible.builtin.set_fact:
|
||||
thinkcenter_become_pass: "{{ lc_secrets.secrets['THINKCENTER_SUDO_PASS'] }}"
|
||||
thinkcenter_login_user: "{{ lc_secrets.secrets['THINKCENTER_USER'] }}"
|
||||
no_log: true
|
||||
|
||||
# --- Play 2: xrdp on thinkcenter ONLY ----------------------------------------
|
||||
- name: "Install + configure + enable xrdp on thinkcenter"
|
||||
hosts: thinkcenter
|
||||
gather_facts: true
|
||||
become: true
|
||||
vars:
|
||||
ansible_become_pass: "{{ hostvars['localhost'].thinkcenter_become_pass }}"
|
||||
rdp_user: "{{ hostvars['localhost'].thinkcenter_login_user }}"
|
||||
xrdp_packages:
|
||||
- xrdp # the RDP server + sesman
|
||||
- xorgxrdp # Xorg backend for xrdp
|
||||
- pipewire-module-xrdp # audio redirection through PipeWire in RDP sessions
|
||||
xrdp_session_cmd: "cinnamon-session-cinnamon2d" # lightweight Cinnamon over RDP
|
||||
tasks:
|
||||
- name: "[safety] Confirm we are on thinkcenter"
|
||||
ansible.builtin.assert:
|
||||
that: inventory_hostname == 'thinkcenter'
|
||||
fail_msg: "Refusing to run — this play is scoped to thinkcenter only."
|
||||
|
||||
- name: "[apt] Install xrdp packages (no-op if already present)"
|
||||
ansible.builtin.apt:
|
||||
name: "{{ xrdp_packages }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
register: xrdp_pkg
|
||||
|
||||
- name: "[tls] Add xrdp service user to ssl-cert group (so it can read key.pem)"
|
||||
ansible.builtin.user:
|
||||
name: xrdp
|
||||
groups: ssl-cert
|
||||
append: true
|
||||
register: sslcert_grp
|
||||
|
||||
- name: "[session] Set Cinnamon as the RDP session for {{ rdp_user }} (~/.xsession)"
|
||||
ansible.builtin.copy:
|
||||
dest: "/home/{{ rdp_user }}/.xsession"
|
||||
owner: "{{ rdp_user }}"
|
||||
group: "{{ rdp_user }}"
|
||||
mode: "0644"
|
||||
content: "{{ xrdp_session_cmd }}\n"
|
||||
register: xsession
|
||||
|
||||
# Cinnamon uses D-Bus/PolicyKit; the common xrdp fix is a polkit rule so the
|
||||
# RDP session isn't blocked on colord authentication prompts.
|
||||
- name: "[polkit] Allow colord actions in xrdp sessions (avoids auth popup loop)"
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Allow Colord all Users]
|
||||
Identity=unix-user:*
|
||||
Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile
|
||||
ResultAny=no
|
||||
ResultInactive=no
|
||||
ResultActive=yes
|
||||
register: polkit_rule
|
||||
|
||||
- name: "[services] Enable + start xrdp and xrdp-sesman"
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{ item }}"
|
||||
enabled: true
|
||||
state: started
|
||||
loop:
|
||||
- xrdp
|
||||
- xrdp-sesman
|
||||
register: xrdp_services
|
||||
|
||||
- name: "[services] Restart xrdp if config/group changed this run"
|
||||
ansible.builtin.systemd_service:
|
||||
name: xrdp
|
||||
state: restarted
|
||||
when: sslcert_grp.changed or xsession.changed or polkit_rule.changed or xrdp_pkg.changed
|
||||
|
||||
- name: "[firewall] Is UFW active?"
|
||||
ansible.builtin.command: ufw status
|
||||
register: ufw_status
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: "[firewall] Allow RDP 3389/tcp when UFW is active"
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "3389"
|
||||
proto: tcp
|
||||
when: "'Status: active' in (ufw_status.stdout | default(''))"
|
||||
|
||||
- name: "[verify] xrdp listening on 3389?"
|
||||
ansible.builtin.shell: "ss -tlnp | grep -q ':3389' && echo listening || echo not-listening"
|
||||
register: rdp_listen
|
||||
changed_when: false
|
||||
|
||||
- name: "[verify] Service states"
|
||||
ansible.builtin.shell: "systemctl is-active xrdp xrdp-sesman | tr '\n' ' '"
|
||||
register: svc_active
|
||||
changed_when: false
|
||||
|
||||
- name: "[verify] Assert xrdp is up and listening"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'listening' in rdp_listen.stdout"
|
||||
- "'active' in svc_active.stdout"
|
||||
fail_msg: "xrdp is not listening on 3389 or a service is not active ({{ svc_active.stdout }})."
|
||||
success_msg: "xrdp is enabled, active, and listening on 3389."
|
||||
|
||||
- name: "[report] xrdp summary"
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "===== thinkcenter xrdp ====="
|
||||
- "packages changed this run : {{ xrdp_pkg.changed }}"
|
||||
- "xrdp added to ssl-cert : {{ sslcert_grp.changed }}"
|
||||
- ".xsession set for {{ rdp_user }} : {{ xsession.changed }}"
|
||||
- "colord polkit rule changed : {{ polkit_rule.changed }}"
|
||||
- "services (xrdp sesman) : {{ svc_active.stdout | trim }}"
|
||||
- "3389 listen : {{ rdp_listen.stdout }}"
|
||||
- "Connect via RDP to 100.96.78.26 (mesh) or 192.168.68.51 (LAN) as {{ rdp_user }}."
|
||||
- "NOTE: log out of the local console session first — xorgxrdp can't attach to an already-active seat0 login."
|
||||
Loading…
Reference in New Issue
Block a user