- name: Install terminal prerequisites become: true apt: name: - openssh-server state: present update_cache: true - name: Ensure sshd drop-in directory exists become: true file: path: /etc/ssh/sshd_config.d state: directory mode: "0755" - name: Configure courseware loopback-only sshd policy become: true template: src: sshd-courseware-terminal.conf.j2 dest: /etc/ssh/sshd_config.d/50-courseware-terminal.conf mode: "0644" register: courseware_terminal_sshd_config - name: Ensure sshd runtime directory exists become: true file: path: /run/sshd state: directory mode: "0755" - name: Validate sshd configuration become: true command: argv: - /usr/sbin/sshd - -t - -f - /etc/ssh/sshd_config changed_when: false - name: Start and enable sshd with systemd when available become: true systemd: name: ssh state: started enabled: true when: ansible_service_mgr == "systemd" - name: Check systemd sshd listener policy become: true command: ss -ltn register: courseware_terminal_systemd_ss_listeners changed_when: false when: ansible_service_mgr == "systemd" - name: Restart sshd with systemd when listener policy is not active become: true systemd: name: ssh state: restarted enabled: true when: - ansible_service_mgr == "systemd" - >- '0.0.0.0:22' not in courseware_terminal_systemd_ss_listeners.stdout or '[::]:22' in courseware_terminal_systemd_ss_listeners.stdout - name: Check for running sshd when systemd is unavailable become: true command: pgrep -x sshd register: courseware_terminal_sshd_pid changed_when: false failed_when: false when: ansible_service_mgr != "systemd" - name: Reload running sshd when config changed outside systemd become: true command: pkill -HUP -x sshd when: - ansible_service_mgr != "systemd" - courseware_terminal_sshd_pid.rc == 0 - courseware_terminal_sshd_config.changed - name: Start sshd when it is not already running outside systemd become: true command: argv: - /usr/sbin/sshd when: - ansible_service_mgr != "systemd" - courseware_terminal_sshd_pid.rc != 0 - name: Create contained WeTTY directory file: path: "{{ courseware_wetty_dir }}" state: directory mode: "0755" - name: Install contained WeTTY runtime command: argv: - npm - install - "{{ courseware_wetty_spec }}" args: chdir: "{{ courseware_wetty_dir }}" creates: "{{ courseware_wetty_dir }}/node_modules/.bin/wetty" environment: PATH: "{{ courseware_node_runtime_bin_dir }}:{{ ansible_env.PATH }}" - name: Check sshd listener become: true command: ss -ltn register: courseware_terminal_ss_listeners changed_when: false - name: Assert sshd accepts LAN and loopback clients assert: that: - "'0.0.0.0:22' in courseware_terminal_ss_listeners.stdout" - "'[::]:22' not in courseware_terminal_ss_listeners.stdout" fail_msg: "sshd must listen on 0.0.0.0:22 so VPN/LAN SSH clients and local WeTTY can connect." - name: Assert WeTTY binary exists stat: path: "{{ courseware_wetty_dir }}/node_modules/.bin/wetty" register: courseware_wetty_bin_stat - name: Fail when WeTTY installation is incomplete fail: msg: "WeTTY was not installed under {{ courseware_wetty_dir }}." when: not courseware_wetty_bin_stat.stat.exists