--- # vim: set expandtab tabstop=2 shiftwidth=2: - name: 'check sshd include option' tags: sshd command: 'sshd -o "include /dev/null"' register: sshd_include_option_check failed_when: 'sshd_include_option_check.rc not in [1,255] or sshd_include_option_check.stderr not in ["Include directive not supported as a command-line option", "command-line: line 0: Bad configuration option: include"]' - name: Use only supported Ciphers, Kex Algorithms and Macs of the configured ones tags: sshd set_fact: sshd_ciphers_: '{{cd|join(",")}}' sshd_kex_algorithms_: '{{kd|join(",")}}' sshd_macs_: '{{md|join(",")}}' sshd_include_option: '{{sshd_include_option_check.stderr == "Include directive not supported as a command-line option"}}' vars: ca: '{{ sshd_ciphers }}' cb: '{{ ca | type_debug }}' cc: '{% if "list" == cb %}{{ ca }}{% elif "str" == cb %}{{ ca.split( ",") }}{%else%}{{null|mandatory()}}{% endif %}' cd: "{{ lookup( 'ansible.builtin.pipe', 'ssh -Q cipher').split( '\n') | intersect( cc) }}" ka: '{{ sshd_kex_algorithms }}' kb: '{{ ka | type_debug }}' kc: '{% if "list" == kb %}{{ ka }}{% elif "str" == kb %}{{ ka.split( ",") }}{%else%}{{null|mandatory()}}{% endif %}' kd: "{{ lookup( 'ansible.builtin.pipe', 'ssh -Q kex').split( '\n') | intersect( kc) }}" ma: '{{ sshd_macs }}' mb: '{{ ma | type_debug }}' mc: '{% if "list" == mb %}{{ ma }}{% elif "str" == mb %}{{ ma.split( ",") }}{%else%}{{null|mandatory()}}{% endif %}' md: "{{ lookup( 'ansible.builtin.pipe', 'ssh -Q mac').split( '\n') | intersect( mc) }}" failed_when: - '[] == sshd_ciphers_' - '[] == sshd_kex_algorithms_' - '[] == sshd_macs_' - when: 'true == sshd_include_option' tags: sshd block: - name: '/etc/ssh/sshd_config.d' tags: sshd file: state: directory path: '/etc/ssh/sshd_config.d' owner: root group: root mode: 0644 - name: 'sshd_config.d/99-default.conf' tags: sshd template: src: 'sshd-default.conf.j2' dest: '/etc/ssh/sshd_config.d/99-default.conf' owner: root group: root mode: 0644 - lineinfile: path: /etc/ssh/sshd_config insertbefore: BOF regexp: '^\s*include\s+/etc/ssh/sshd_config.d/' line: 'include /etc/ssh/sshd_config.d/*.conf' firstmatch: true tags: sshd - when: 'false == sshd_include_option' tags: sshd block: - name: sshd_config tags: sshd lineinfile: path: /etc/ssh/sshd_config insertafter: '^\s*#\s*{{item.key}}\s+' regexp: '^\s*{{item.key}}\s' line: '{{item.key}} {{item.value}}' with_dict: Port: '{{sshd_port|default(22)}}' PermitRootLogin: '{{sshd_permit_root_login}}' StrictModes: 'yes' PubkeyAuthentication: 'yes' KerberosAuthentication: '{{sshd_kerberos_authentication}}' GSSAPIAuthentication: '{{sshd_gssapi_authentication}}' TCPKeepAlive: 'yes' Ciphers: '{{sshd_ciphers_}}' MACs: '{{sshd_macs_}}' KexAlgorithms: '{{sshd_kex_algorithms_}}' - name: sshd_config tags: sshd lineinfile: path: /etc/ssh/sshd_config insertbefore: '\s*#?\s*HostKey\s+' regexp: '^# HostKeys for protocol' line: '# HostKeys for protocol' - name: sshd_config - prefer ed25519 tags: sshd lineinfile: path: /etc/ssh/sshd_config insertafter: '^# HostKeys for protocol' regexp: '^\s*HostKey\s+/etc/ssh/ssh_host_ed25519_key\s*$' line: 'HostKey /etc/ssh/ssh_host_ed25519_key' - name: sshd_config - fallback rsa tags: sshd lineinfile: path: /etc/ssh/sshd_config insertafter: '^\s*HostKey\s+/etc/ssh/ssh_host_ed25519_key\s*$' regexp: '^\s*HostKey\s+/etc/ssh/ssh_host_rsa_key\s*$' line: 'HostKey /etc/ssh/ssh_host_rsa_key' - name: 'sshd_config - absent dsa / ecdsa' tags: sshd lineinfile: path: /etc/ssh/sshd_config state: absent regexp: '{{item}}' with_list: - '^\s*HostKey\s+/etc/ssh/ssh_host_dsa_key\s*$' - '^\s*HostKey\s+/etc/ssh/ssh_host_ecdsa_key\s*$'