# RDP Thin Client System - Complete Setup Vollständiges Ansible-Deployment für dedizierte RDP-Thin-Clients auf Debian 13 (Trixie). ## Features - Headless Auto-Login - Profilbasierte RDP-Verbindungen - Audio/Mikrofon-Weiterleitung (Bluetooth-Headsets!) - USB/Smart-Card Redirection - Python-GUI für Profilverwaltung - Tastenkombination zum Session-Verlassen (Strg+Alt+Q) - Bluetooth-Manager-Integration --- ## 1. Verzeichnisstruktur rdp-thin-client/ ├── ansible/ │ ├── playbook.yml # Hauptinstallation │ ├── inventory.ini # Deine Clients │ └── group_vars/all.yml # Globale Variablen ├── files/ │ ├── rdp-profile-manager.py # GUI für Profile │ ├── rdp-launcher.sh      # FreeRDP-Wrapper │ ├── session-watcher.py   # Tastenkombination überwachen │ └── branding/                      # FreeRDP-Wrapper │ ├── boot-logo.png │ ├── boot-logocreator.html #boot logo creator tool in webbrowser │ ├── grub-background.png │ └── login-background.png └── config/ └── profiles.ini.example ## 2. Ansible Inventory ansible/inventory.ini: ```ini [rdp_clients] thin-client-01 ansible_host=192.168.1.101 thin-client-02 ansible_host=192.168.1.102 thin-client-03 ansible_host=192.168.1.103 [rdp_clients:vars] ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa ``` --- ## 3. Ansible Variables **ansible/group_vars/all.yml:** ```yaml --- # System User thin_client_user: rdpuser thin_client_password: "{{ 'rdpuser' | password_hash('sha512') }}" # Display Manager display_manager: lightdm # RDP Client rdp_client: freerdp # Audio System audio_system: pipewire # Profile Directory profile_dir: /home/{{ thin_client_user }}/.config/rdp-profiles profile_file: "{{ profile_dir }}/profiles.ini" # Exit Hotkey exit_hotkey: "Control+Alt+q" # Packages base_packages: - xorg - openbox - lightdm - python3 - python3-tk - python3-configparser - freerdp2-x11 - pulseaudio - pipewire - pipewire-pulse - pipewire-audio - bluez - blueman - pcscd - libpcsclite1 - libccid - xinput - xdotool - pcmanfm - lxterminal ``` --- ### 4. Playbook ```yaml --- - name: Setup RDP Thin Client hosts: rdp_clients become: yes tasks: # === BASE SYSTEM === - name: Update APT cache apt: update_cache: yes cache_valid_time: 3600 - name: Install base packages apt: name: "{{ base_packages }}" state: present - name: Create thin client user user: name: "{{ thin_client_user }}" password: "{{ thin_client_password }}" shell: /bin/bash groups: audio,video,bluetooth,plugdev append: yes - name: Configure auto-login for LightDM copy: dest: /etc/lightdm/lightdm.conf.d/50-autologin.conf content: | [Seat:*] autologin-user={{ thin_client_user }} autologin-user-timeout=0 user-session=openbox # === OPENBOX CONFIGURATION === - name: Create openbox config directory file: path: /home/{{ thin_client_user }}/.config/openbox state: directory owner: "{{ thin_client_user }}" group: "{{ thin_client_user }}" mode: '0755' - name: Configure Openbox autostart copy: dest: /home/{{ thin_client_user }}/.config/openbox/autostart owner: "{{ thin_client_user }}" group: "{{ thin_client_user }}" mode: '0755' content: | #!/bin/bash # Start PipeWire pipewire & pipewire-pulse & # Start Bluetooth blueman-applet & # Start Session Watcher (monitors exit hotkey) /usr/local/bin/session-watcher.py & # Start RDP Launcher /usr/local/bin/rdp-launcher.sh & - name: Configure Openbox menu (right-click context menu) copy: dest: /home/{{ thin_client_user }}/.config/openbox/menu.xml owner: "{{ thin_client_user }}" group: "{{ thin_client_user }}" content: | /usr/local/bin/rdp-profile-manager.py blueman-manager pcmanfm lxterminal systemctl reboot systemctl poweroff # === AUDIO CONFIGURATION === - name: Enable PipeWire services for user systemd: name: "{{ item }}" enabled: yes scope: user daemon_reload: yes loop: - pipewire.service - pipewire-pulse.service become_user: "{{ thin_client_user }}" # === BLUETOOTH CONFIGURATION === - name: Enable Bluetooth service systemd: name: bluetooth enabled: yes state: started # === SMART CARD CONFIGURATION === - name: Enable pcscd service systemd: name: pcscd enabled: yes state: started # === PROFILE DIRECTORY === - name: Create RDP profile directory file: path: "{{ profile_dir }}" state: directory owner: "{{ thin_client_user }}" group: "{{ thin_client_user }}" mode: '0755' - name: Create empty profiles.ini if not exists copy: dest: "{{ profile_file }}" owner: "{{ thin_client_user }}" group: "{{ thin_client_user }}" mode: '0644' content: | # RDP Profile Configuration # Auto-generated by RDP Thin Client Setup force: no # === COPY SCRIPTS === - name: Copy RDP Profile Manager copy: src: ../src/rdp-profile-manager.py dest: /usr/local/bin/rdp-profile-manager.py mode: '0755' - name: Copy RDP Launcher copy: src: ../src/rdp-launcher.sh dest: /usr/local/bin/rdp-launcher.sh mode: '0755' - name: Copy Session Watcher copy: src: ../src/session-watcher.py dest: /usr/local/bin/session-watcher.py mode: '0755' # === CLEANUP === - name: Remove unnecessary packages apt: name: - gnome-* - libreoffice-* state: absent autoremove: yes - name: Disable unnecessary services systemd: name: "{{ item }}" enabled: no state: stopped loop: - ModemManager - cups ignore_errors: yes handlers: - name: Reboot system reboot: msg: "Rebooting to apply thin client configuration" reboot_timeout: 300 ``` ### 5. Ansible installieren und RDP-Client Debian Hosts vorbereiten bash ```bash # Ansible installieren sudo apt update sudo apt install ansible sshpass # SSH-Keys generieren (falls noch nicht vorhanden) ssh-keygen -t rsa -b 4096 # SSH-Keys auf Thin Clients kopieren ssh-copy-id root@192.168.1.101 ssh-copy-id root@192.168.1.102 ssh-copy-id root@192.168.1.1 ``` ```bash cd rdp-thin-client/ansible # Syntax-Check ansible-playbook -i inventory.ini playbook.yml --syntax-check # Dry-Run (Check Mode) ansible-playbook -i inventory.ini playbook.yml --check # Deployment ausführen ansible-playbook -i inventory.ini playbook.yml # Nur bestimmte Hosts ansible-playbook -i inventory.ini playbook.yml --limit thin-client-01 # Mit Verbose-Output ansible-playbook -i inventory.ini playbook.yml -vvv ```