Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSHD Improvements #401

Merged
merged 13 commits into from
Oct 19, 2023
Merged

Conversation

cleberb
Copy link
Contributor

@cleberb cleberb commented Sep 28, 2023

  • Add options:

    • sshd_deny_groups
    • sshd_deny_users
    • sshd_host_keys_files
    • sshd_host_keys_group
    • sshd_host_keys_mode
    • sshd_host_keys_owner
    • sshd_listen
    • sshd_match_addresses
    • sshd_match_groups
    • sshd_match_local_ports
    • sshd_match_users
    • sshd_print_pam_motd
    • sshd_sftp_enabled
    • sshd_sftp_only_chroot
    • sshd_sftp_only_chroot_dir
    • sshd_sftp_only_group
    • sshd_sftp_subsystem
    • sshd_syslog_facility
    • sshd_use_privilege_separation
  • Change options:

    • String to boolean:
      • sshd_allow_agent_forwarding
      • sshd_challenge_response_authentication
      • sshd_compression
      • sshd_gssapi_authentication
      • sshd_hostbased_authentication
      • sshd_ignore_rhosts
      • sshd_ignore_user_known_hosts
      • sshd_kerberos_authentication
      • sshd_password_authentication
      • sshd_permit_empty_passwords
      • sshd_permit_root_login
      • sshd_permit_user_environment
      • sshd_print_last_log
      • sshd_print_motd
      • sshd_strict_modes
      • sshd_tcp_keep_alive
      • sshd_use_dns
      • sshd_use_pam
      • sshd_x11_forwarding
    • String to list:
      • sshd_allow_groups
      • sshd_allow_users
      • sshd_ca_signature_algorithms
      • sshd_ciphers
      • sshd_host_key_algorithms
      • sshd_kex_algorithms
      • sshd_macs
      • sshd_ports

- Add options:
  - sshd_deny_groups
  - sshd_deny_users
  - sshd_host_keys_files
  - sshd_host_keys_group
  - sshd_host_keys_mode
  - sshd_host_keys_owner
  - sshd_listen
  - sshd_match_addresses
  - sshd_match_groups
  - sshd_match_local_ports
  - sshd_match_users
  - sshd_print_pam_motd
  - sshd_sftp_enabled
  - sshd_sftp_only_chroot
  - sshd_sftp_only_chroot_dir
  - sshd_sftp_only_group
  - sshd_sftp_subsystem
  - sshd_syslog_facility
  - sshd_use_privilege_separation

- Change options:
  - String to boolean:
    - sshd_allow_agent_forwarding
    - sshd_challenge_response_authentication
    - sshd_compression
    - sshd_gssapi_authentication
    - sshd_hostbased_authentication
    - sshd_ignore_rhosts
    - sshd_ignore_user_known_hosts
    - sshd_kerberos_authentication
    - sshd_password_authentication
    - sshd_permit_empty_passwords
    - sshd_permit_root_login
    - sshd_permit_user_environment
    - sshd_print_last_log
    - sshd_print_motd
    - sshd_strict_modes
    - sshd_tcp_keep_alive
    - sshd_use_dns
    - sshd_use_pam
    - sshd_x11_forwarding
  - String to list:
    - sshd_allow_groups
    - sshd_allow_users
    - sshd_ca_signature_algorithms
    - sshd_ciphers
    - sshd_host_key_algorithms
    - sshd_kex_algorithms
    - sshd_macs
    - sshd_ports
@konstruktoid
Copy link
Owner

Thanks again! Really nice improvements. I'll run some tests and get back to you.

Copy link
Owner

@konstruktoid konstruktoid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konstruktoid
Copy link
Owner

Failing test:

TASK [ansible-role-hardening : Allow sshd port from administrator networks] ****
fatal: [almalinux8]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'sshd_port' is undefined. 'sshd_port' is undefined\n\nThe error appears to be in '[...]ansible-role-hardening/tasks/ufw.yml': line 117, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Allow sshd port from administrator networks\n  ^ here\n"}

https://github.com/konstruktoid/ansible-role-hardening/blob/master/tasks/ufw.yml#L117-L129

@cleberb
Copy link
Contributor Author

cleberb commented Sep 29, 2023

Have a look at the lint errors https://github.com/konstruktoid/ansible-role-hardening/actions/runs/6343295236/job/17253219427?pr=401#step:4:22

Fixed, but after updating ansible-lint a new rule will be implemented which will require a very large update to the code:

var-naming[no-role-prefix]: Variables names from within roles should use hardening_ as a prefix. (vars: issue_template)

More details at: https://ansible.readthedocs.io/projects/lint/rules/var-naming/

@konstruktoid
Copy link
Owner

Fixed, but after updating ansible-lint a new rule will be implemented which will require a very large update to the code:

var-naming[no-role-prefix]: Variables names from within roles should use hardening_ as a prefix. (vars: issue_template)

More details at: https://ansible.readthedocs.io/projects/lint/rules/var-naming/

yeah, but ignore that one for now

@cleberb
Copy link
Contributor Author

cleberb commented Sep 29, 2023

Failing test:

TASK [ansible-role-hardening : Allow sshd port from administrator networks] ****
fatal: [almalinux8]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'sshd_port' is undefined. 'sshd_port' is undefined\n\nThe error appears to be in '[...]ansible-role-hardening/tasks/ufw.yml': line 117, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Allow sshd port from administrator networks\n  ^ here\n"}

https://github.com/konstruktoid/ansible-role-hardening/blob/master/tasks/ufw.yml#L117-L129

Updated, it took some work to adjust the molecule, I need you to carry out the appropriate tests.

@konstruktoid
Copy link
Owner

Great job, please fix the conflicts and I believe we're ready to test.

@konstruktoid
Copy link
Owner

Awesome!
I'll start the testing.

@konstruktoid
Copy link
Owner

failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}

Full task log:

TASK [ansible-role-hardening : Allow sshd port from administrator networks] ****
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux8] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [bookworm] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["/", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["/", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["/", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from / to any port 22 proto tcp comment 'ansible managed'"], "item": ["/", 22], "msg": "ERROR: Bad source address\n"}
failed: [jammy] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from / to any port 22 proto tcp comment 'ansible managed'"], "item": ["/", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}

@konstruktoid
Copy link
Owner

I believe that the time debugging this would be a lot shorter if you ran your branch locally on a VM

@cleberb
Copy link
Contributor Author

cleberb commented Oct 1, 2023

failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}

Full task log:

TASK [ansible-role-hardening : Allow sshd port from administrator networks] ****
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux8] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [bookworm] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["/", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "item": [".", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [bookworm] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [jammy] (item=['.', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from . to any port 22 proto tcp comment 'ansible managed'"], "item": [".", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["/", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["/", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from / to any port 22 proto tcp comment 'ansible managed'"], "item": ["/", 22], "msg": "ERROR: Bad source address\n"}
failed: [jammy] (item=['/', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from / to any port 22 proto tcp comment 'ansible managed'"], "item": ["/", 22], "msg": "ERROR: Bad source address\n"}
failed: [almalinux9] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [almalinux8] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "item": ["0", 22], "msg": "Failed to find required executable \"ufw\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
failed: [focal] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}
failed: [jammy] (item=['0', 22]) => {"ansible_loop_var": "item", "changed": false, "commands": ["/usr/sbin/ufw status verbose", "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw limit from 0 to any port 22 proto tcp comment 'ansible managed'"], "item": ["0", 22], "msg": "ERROR: Bad source address\n"}

My test with ansible 2.15.4 and options -vvv --check:

changed: [teste] => (item=['192.168.0.1/24', 22]) => {
    "ansible_loop_var": "item",
    "changed": true,
    "commands": [
        "/usr/sbin/ufw status verbose",
        "/usr/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules",
        "/usr/sbin/ufw --version",
        "/usr/sbin/ufw --dry-run limit from 192.168.0.1/24 to any port 22 proto tcp comment 'ansible managed'"
    ],
    "invocation": {
        "module_args": {
            "comment": "ansible managed",
            "default": null,
            "delete": false,
            "direction": null,
            "from_ip": "192.168.0.1/24",
            "from_port": null,
            "insert": null,
            "insert_relative_to": "zero",
            "interface": null,
            "interface_in": null,
            "interface_out": null,
            "log": false,
            "logging": null,
            "name": null,
            "port": "22",
            "proto": "tcp",
            "route": false,
            "rule": "limit",
            "src": "192.168.0.1/24",
            "state": null,
            "to_ip": "any",
            "to_port": "22"
        }
    },
    "item": [
        "192.168.0.1/24",
        22
    ]
}

The task below (ufw.yml) has been edited, and the product option has been included.

NOTE: I need to correct the order of the task in the file, as I changed it during the test and did not return it.

- name: Allow sshd port from administrator networks
  become: true
  community.general.ufw:
    rule: limit
    src: "{{ item.0 }}"
    port: "{{ item.1 | int }}"
    proto: tcp
    comment: ansible managed
  loop: "{{ sshd_admin_net | product(sshd_ports) | list }}"
  tags:
    - ufw
    - M1037

A search for the variable sshd_admin_net, I see it defined in several files with a value in string format, but even before I edited the value was already in list format:

# grep 'sshd_admin_net: \"' * -R
molecule/almalinux/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/almalinux/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/debian/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/debian/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/debian/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/ubuntu/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/ubuntu/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/ubuntu/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/ubuntu/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/redhat/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/single/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/default/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/default/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/default/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/default/molecule.yml: sshd_admin_net: "0.0.0.0/0"
molecule/default/molecule.yml: sshd_admin_net: "0.0.0.0/0"

I will edit the fixes as soon as possible.

@konstruktoid
Copy link
Owner

What's the purpose of sshd_config_force_replace? Seems like https://github.com/konstruktoid/ansible-role-hardening/pull/401/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R589 can be reworded as configure-ssh?

@cleberb
Copy link
Contributor Author

cleberb commented Oct 1, 2023

What's the purpose of sshd_config_force_replace? Seems like https://github.com/konstruktoid/ansible-role-hardening/pull/401/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R589 can be reworded as configure-ssh?

Text include in README:

sshd_config_d_force_clear force clear directory /etc/sshd_config.d. Default: false.

sshd_config_force_replace force replace configuration file /etc/sshd_config. Default: false.

Note

By default, the role checks whether the directory /etc/sshd_config.d exists and whether it is linked via the Include parameter in the /etc/sshd_config file, if so, an additional configuration file is created in / etc/sshd_config.d, if not, the /etc/sshd_config file is overwritten.

Warning

If any sshd_match_(users|groups|addresses|local_ports) parameters is set, the value true will be implicit.

@konstruktoid
Copy link
Owner

Ah, so even if the Include statement is present, you got the option to overwrite the sshd_config file.

@konstruktoid
Copy link
Owner

Needed to make the following changes.

diff --git a/README.md b/README.md
index 40977b4..f6bf46e 100644
--- a/README.md
+++ b/README.md
@@ -584,13 +584,13 @@ connection.
 
 `sshd_required_rsa_size`, RequiredRSASize, will only be set if SSH version is higher than 9.1.
 
-`sshd_config_d_force_clear` force clear directory `/etc/sshd_config.d`. Default: `false`.
+`sshd_config_d_force_clear` force clear directory `/etc/ssh/sshd_config.d`. Default: `false`.
 
-`sshd_config_force_replace` force replace configuration file `/etc/sshd_config`. Default: `false`.
+`sshd_config_force_replace` force replace configuration file `/etc/ssh/sshd_config`. Default: `false`.
 
 > **Note**
 >
-> By default, the role checks whether the directory `/etc/sshd_config.d` exists and whether it is linked via the `Include` parameter in the `/etc/sshd_config` file, if so, an additional configuration file is created in `/ etc/sshd_config.d`, if not, the `/etc/sshd_config` file is overwritten.
+> By default, the role checks whether the directory `/etc/ssh/sshd_config.d` exists and whether it is linked via the `Include` parameter in the `/etc/ssh/sshd_config` file, if so, an additional configuration file is created in `/etc/ssh/sshd_config.d`, if not, the `/etc/ssh/sshd_config` file is overwritten.
 
 > **Warning**
 >
diff --git a/tasks/sshconfig.yml b/tasks/sshconfig.yml
index 511f096..85a5db1 100644
--- a/tasks/sshconfig.yml
+++ b/tasks/sshconfig.yml
@@ -93,6 +93,7 @@
     - sshd_config
 
 - name: Set default for sshd_host_keys_files if not supplied
+  become: yes
   when: not sshd_host_keys_files
   tags:
     - sshd
@@ -140,6 +141,7 @@
       loop: "{{ sshd_host_keys_files }}"
 
 - name: Disable PAM dynamic MOTD
+  become: true
   community.general.pamd:
     name: sshd
     type: session
@@ -226,7 +228,7 @@
     owner: root
     group: root
     validate: "/usr/sbin/sshd -T -C user=root -C host=localhost -C addr=localhost -C lport=22 -f %s"
-  when: not ( sshd_config_force_replace | bool ) or sshd_config_d.stat.exists and grep_include.rc == 0
+  when: not ( sshd_config_force_replace | bool ) and sshd_config_d.stat.exists and grep_include.rc == 0
   notify:
     - Restart sshd service
     - Restart ssh service

@konstruktoid
Copy link
Owner

konstruktoid commented Oct 1, 2023

TASK [Set sshd_config_parameters RequiredRSASize] ******************************
skipping: [almalinux8]
skipping: [almalinux9]
fatal: [bookworm]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ sshd_config_parameters + ['RequiredRSASize ' + sshd_required_rsa_size] }}): can only concatenate str (not \"int\") to str. can only concatenate str (not \"int\") to str"}
skipping: [focal]
skipping: [jammy]

Debian Bookworm: OpenSSH_9.2, OpenSSL 3.0.9 30 May 2023

AlmaLinux9: OpenSSH_8.7p1, OpenSSL 3.0.7 1 Nov 2022
AlmaLinux8: OpenSSH_8.0p1, OpenSSL 1.1.1k FIPS 25 Mar 2021
Ubuntu Jammy: OpenSSH_8.9p1 Ubuntu-3ubuntu0.4, OpenSSL 3.0.2 15 Mar 2022

@konstruktoid
Copy link
Owner

What's this?

$ git grep DebianBanner
molecule/default/verify.yml:          - DebianBanner {{ 'yes' if (sshd_debian_banner | bool) else 'no' }}
templates/etc/ssh/sshd_config.j2:DebianBanner {{ 'yes' if (sshd_debian_banner | bool) else 'no' }}

failed: [almalinux8] (item=DebianBanner no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "DebianBanner no", "msg": "line added"}

@konstruktoid
Copy link
Owner

failed: [almalinux8] (item=  AllowTcpForwarding no ) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "  AllowTcpForwarding no ", "msg": "line added"}
failed: [almalinux8] (item=DebianBanner no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "DebianBanner no", "msg": "line added"}

@cleberb
Copy link
Contributor Author

cleberb commented Oct 1, 2023

What's this?

$ git grep DebianBanner
molecule/default/verify.yml:          - DebianBanner {{ 'yes' if (sshd_debian_banner | bool) else 'no' }}
templates/etc/ssh/sshd_config.j2:DebianBanner {{ 'yes' if (sshd_debian_banner | bool) else 'no' }}

failed: [almalinux8] (item=DebianBanner no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "DebianBanner no", "msg": "line added"}

https://manpages.debian.org/buster/openssh-server/sshd_config.5.en.html#DebianBanner

I have to see how to limit the debian family.

@konstruktoid
Copy link
Owner

Great work.

Just some verification failing, everything else looks good.

ok: [bookworm] => (item=PubkeyAuthentication yes)
failed: [jammy] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [focal] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [bookworm] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
ok: [almalinux9] => (item=MaxStartups 10:30:60)
ok: [focal] => (item=X11UseLocalhost yes)
failed: [focal] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [jammy] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [bookworm] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
ok: [bookworm] => (item=StrictModes yes)

@cleberb
Copy link
Contributor Author

cleberb commented Oct 1, 2023

Great work.

Just some verification failing, everything else looks good.

ok: [bookworm] => (item=PubkeyAuthentication yes)
failed: [jammy] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [focal] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [bookworm] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
ok: [almalinux9] => (item=MaxStartups 10:30:60)
ok: [focal] => (item=X11UseLocalhost yes)
failed: [focal] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [jammy] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
failed: [bookworm] (item=no) => {"ansible_loop_var": "item", "backup": "", "changed": true, "failed_when_result": true, "item": "no", "msg": "line added"}
ok: [bookworm] => (item=StrictModes yes)

I believe I have to do the version treatments that are present in the template. I will also perform an isolated test of checking the parameters, to see if there are any code errors.

item=no is strange :/

@konstruktoid
Copy link
Owner

Yeah, it was a strange error message, will take a look as well as soon as possible.

@cleberb
Copy link
Contributor Author

cleberb commented Oct 2, 2023

Do you think a test is necessary for this task?

- name: Disable PAM dynamic MOTD
  become: true
  community.general.pamd:
    name: sshd
    type: session
    control: optional
    module_path: pam_motd.so
    state: absent
    backup: true
  when:
    - sshd_use_pam | bool
    - not (sshd_print_pam_motd | bool)
  tags:
    - sshd

@konstruktoid
Copy link
Owner

konstruktoid commented Oct 2, 2023

I would like an explanation for this 😆 :

-        line: "{{ item | indent(4) }}"
+        line: "    {{ item }}"

Me too! 😆
but indent(4) fails while four spaces doesn't.

@konstruktoid
Copy link
Owner

Do you think a test is necessary for this task?

- name: Disable PAM dynamic MOTD
  become: true
  community.general.pamd:
    name: sshd
    type: session
    control: optional
    module_path: pam_motd.so
    state: absent
    backup: true
  when:
    - sshd_use_pam | bool
    - not (sshd_print_pam_motd | bool)
  tags:
    - sshd

Nah, lets skip it.

I'm going to go through all tests and tasks after the merge anyway, in order to have similar tasks and tests as the ones you've made

@konstruktoid
Copy link
Owner

I would like an explanation for this 😆 :

-        line: "{{ item | indent(4) }}"
+        line: "    {{ item }}"

Me too! 😆 but indent(4) fails while four spaces doesn't.

@cleberb, this works:

line: "{{ item | indent(4,true) }}"

@cleberb
Copy link
Contributor Author

cleberb commented Oct 2, 2023

I would like an explanation for this 😆 :

-        line: "{{ item | indent(4) }}"
+        line: "    {{ item }}"

Me too! 😆 but indent(4) fails while four spaces doesn't.

@cleberb, this works:

line: "{{ item | indent(4,true) }}"

In the template, if used indent(4,true), it generates 8 initial spaces. I don't understand the documentation for this option yet.

To avoid doubts, we will leave the space characters as they were before. 👍

@konstruktoid
Copy link
Owner

I only tested it in a task to be fair.

molecule/default/verify.yml Outdated Show resolved Hide resolved
molecule/default/verify.yml Outdated Show resolved Hide resolved
- Update logic `verify.yml`
- Fix/change option `KbdInteractiveAuthentication`
@konstruktoid
Copy link
Owner

Just a last suggestion regarding sftp

@cleberb
Copy link
Contributor Author

cleberb commented Oct 11, 2023

Just a last suggestion regarding sftp

What would be the suggestion?

@konstruktoid
Copy link
Owner

I have no idea where the rest of the text went, but since we set a system wide umask, I suggest we remove the -u option

@konstruktoid
Copy link
Owner

Great! I'll tox --recreate -epy311-ansible8 &> verify.log and have a look later on.

@konstruktoid
Copy link
Owner

Task Verify sshd runtime configuration still fails:

[WARNING]: conditional statements should not include jinja2 templating
delimiters such as {{ }} or {% %}. Found: {%- set lower_parameter = item.split(
)[0] | lower -%} {{ ( item | regex_replace('^[^\ ]+', lower_parameter) ) not in
sshd_config.stdout_lines }}
failed: [jammy] (item=AcceptEnv LANG LC_*) => {"ansible_loop_var": "item", "changed": false, "cmd": ["sshd", "-T"], "delta": "0:00:00.062700", "end": "2023-10-11 21:47:23.980246", "failed_when_result": true, "item": "AcceptEnv LANG LC_*", "msg": "", "rc": 0, "start": "2023-10-11 21:47:23.917546", "stderr": "", "stderr_lines": [], "stdout": "port 22\naddressfamily inet\nlistenaddress 0.0.0.0:22\nusepam yes\nlogingracetime 20\nx11displayoffset 10\nmaxauthtries 3\nmaxsessions 3\nclientaliveinterval 200\nclientalivecountmax 1\nstreamlocalbindmask 0177\npermitrootlogin no\nignorerhosts yes\nignoreuserknownhosts yes\nhostbasedauthentication no\nhostbasedusesnamefrompacketonly no\npubkeyauthentication yes\nkerberosauthentication no\nkerberosorlocalpasswd yes\nkerberosticketcleanup yes\ngssapiauthentication no\ngssapicleanupcredentials yes\ngssapikeyexchange no\ngssapistrictacceptorcheck yes\ngssapistorecredentialsonrekey no\ngssapikexalgorithms gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1-\npasswordauthentication no\nkbdinteractiveauthentication no\nprintmotd no\nprintlastlog yes\nx11forwarding no\nx11uselocalhost yes\npermittty yes\npermituserrc yes\nstrictmodes yes\ntcpkeepalive no\npermitemptypasswords no\ncompression no\ngatewayports no\nusedns no\nallowtcpforwarding no\nallowagentforwarding no\ndisableforwarding no\nallowstreamlocalforwarding yes\nstreamlocalbindunlink no\nfingerprinthash SHA256\nexposeauthinfo no\npidfile /run/sshd.pid\nmodulifile /etc/ssh/moduli\nxauthlocation /usr/bin/xauth\nciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr\nmacs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256\nbanner /etc/issue.net\nforcecommand none\nchrootdirectory none\ntrustedusercakeys none\nrevokedkeys none\nsecuritykeyprovider internal\nauthorizedprincipalsfile none\nversionaddendum none\nauthorizedkeyscommand none\nauthorizedkeyscommanduser none\nauthorizedprincipalscommand none\nauthorizedprincipalscommanduser none\nhostkeyagent none\nkexalgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256\ncasignaturealgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa\nhostbasedacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256\nhostkeyalgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256\npubkeyacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256\nloglevel VERBOSE\nsyslogfacility AUTH\nauthorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2\nhostkey /etc/ssh/ssh_host_rsa_key\nhostkey /etc/ssh/ssh_host_ecdsa_key\nhostkey /etc/ssh/ssh_host_ed25519_key\nallowusers vagrant\nallowgroups vagrant\nallowgroups sudo\nacceptenv LANG\nacceptenv LC_*\nacceptenv LANG\nacceptenv LC_*\nauthenticationmethods any\nsubsystem sftp internal-sftp -f LOCAL6 -l INFO\nmaxstartups 10:30:60\npersourcemaxstartups none\npersourcenetblocksize 32:128\npermittunnel no\nipqos lowdelay throughput\nrekeylimit 536870912 3600\npermitopen any\npermitlisten any\npermituserenvironment no\npubkeyauthoptions none", "stdout_lines": ["port 22", "addressfamily inet", "listenaddress 0.0.0.0:22", "usepam yes", "logingracetime 20", "x11displayoffset 10", "maxauthtries 3", "maxsessions 3", "clientaliveinterval 200", "clientalivecountmax 1", "streamlocalbindmask 0177", "permitrootlogin no", "ignorerhosts yes", "ignoreuserknownhosts yes", "hostbasedauthentication no", "hostbasedusesnamefrompacketonly no", "pubkeyauthentication yes", "kerberosauthentication no", "kerberosorlocalpasswd yes", "kerberosticketcleanup yes", "gssapiauthentication no", "gssapicleanupcredentials yes", "gssapikeyexchange no", "gssapistrictacceptorcheck yes", "gssapistorecredentialsonrekey no", "gssapikexalgorithms gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1-", "passwordauthentication no", "kbdinteractiveauthentication no", "printmotd no", "printlastlog yes", "x11forwarding no", "x11uselocalhost yes", "permittty yes", "permituserrc yes", "strictmodes yes", "tcpkeepalive no", "permitemptypasswords no", "compression no", "gatewayports no", "usedns no", "allowtcpforwarding no", "allowagentforwarding no", "disableforwarding no", "allowstreamlocalforwarding yes", "streamlocalbindunlink no", "fingerprinthash SHA256", "exposeauthinfo no", "pidfile /run/sshd.pid", "modulifile /etc/ssh/moduli", "xauthlocation /usr/bin/xauth", "ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr", "macs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256", "banner /etc/issue.net", "forcecommand none", "chrootdirectory none", "trustedusercakeys none", "revokedkeys none", "securitykeyprovider internal", "authorizedprincipalsfile none", "versionaddendum none", "authorizedkeyscommand none", "authorizedkeyscommanduser none", "authorizedprincipalscommand none", "authorizedprincipalscommanduser none", "hostkeyagent none", "kexalgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256", "casignaturealgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa", "hostbasedacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256", "hostkeyalgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256", "pubkeyacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256", "loglevel VERBOSE", "syslogfacility AUTH", "authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2", "hostkey /etc/ssh/ssh_host_rsa_key", "hostkey /etc/ssh/ssh_host_ecdsa_key", "hostkey /etc/ssh/ssh_host_ed25519_key", "allowusers vagrant", "allowgroups vagrant", "allowgroups sudo", "acceptenv LANG", "acceptenv LC_*", "acceptenv LANG", "acceptenv LC_*", "authenticationmethods any", "subsystem sftp internal-sftp -f LOCAL6 -l INFO", "maxstartups 10:30:60", "persourcemaxstartups none", "persourcenetblocksize 32:128", "permittunnel no", "ipqos lowdelay throughput", "rekeylimit 536870912 3600", "permitopen any", "permitlisten any", "permituserenvironment no", "pubkeyauthoptions none"]}

Add it as task you to see what you get:

    - name: Verify sshd runtime configuration
      become: true
      environment:
        PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      ansible.builtin.command: sshd -T
      check_mode: false
      register: sshd_config
      changed_when: false
      failed_when: >-
        {%- set lower_parameter = item.split( )[0] | lower -%}
        {{ ( item | regex_replace('^[^\ ]+', lower_parameter) ) not in sshd_config.stdout_lines }}
      loop: "{{ (sshd_config_parameters | reject('regex', 'Allowgroups ') | list) + ['allowgroups vagrant', 'allowgroups sudo'] }}"

@konstruktoid
Copy link
Owner

Closes #408

@konstruktoid konstruktoid linked an issue Oct 12, 2023 that may be closed by this pull request
@cleberb
Copy link
Contributor Author

cleberb commented Oct 12, 2023

Task Verify sshd runtime configuration still fails:

[WARNING]: conditional statements should not include jinja2 templating
delimiters such as {{ }} or {% %}. Found: {%- set lower_parameter = item.split(
)[0] | lower -%} {{ ( item | regex_replace('^[^\ ]+', lower_parameter) ) not in
sshd_config.stdout_lines }}
failed: [jammy] (item=AcceptEnv LANG LC_*) => {"ansible_loop_var": "item", "changed": false, "cmd": ["sshd", "-T"], "delta": "0:00:00.062700", "end": "2023-10-11 21:47:23.980246", "failed_when_result": true, "item": "AcceptEnv LANG LC_*", "msg": "", "rc": 0, "start": "2023-10-11 21:47:23.917546", "stderr": "", "stderr_lines": [], "stdout": "port 22\naddressfamily inet\nlistenaddress 0.0.0.0:22\nusepam yes\nlogingracetime 20\nx11displayoffset 10\nmaxauthtries 3\nmaxsessions 3\nclientaliveinterval 200\nclientalivecountmax 1\nstreamlocalbindmask 0177\npermitrootlogin no\nignorerhosts yes\nignoreuserknownhosts yes\nhostbasedauthentication no\nhostbasedusesnamefrompacketonly no\npubkeyauthentication yes\nkerberosauthentication no\nkerberosorlocalpasswd yes\nkerberosticketcleanup yes\ngssapiauthentication no\ngssapicleanupcredentials yes\ngssapikeyexchange no\ngssapistrictacceptorcheck yes\ngssapistorecredentialsonrekey no\ngssapikexalgorithms gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1-\npasswordauthentication no\nkbdinteractiveauthentication no\nprintmotd no\nprintlastlog yes\nx11forwarding no\nx11uselocalhost yes\npermittty yes\npermituserrc yes\nstrictmodes yes\ntcpkeepalive no\npermitemptypasswords no\ncompression no\ngatewayports no\nusedns no\nallowtcpforwarding no\nallowagentforwarding no\ndisableforwarding no\nallowstreamlocalforwarding yes\nstreamlocalbindunlink no\nfingerprinthash SHA256\nexposeauthinfo no\npidfile /run/sshd.pid\nmodulifile /etc/ssh/moduli\nxauthlocation /usr/bin/xauth\nciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr\nmacs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256\nbanner /etc/issue.net\nforcecommand none\nchrootdirectory none\ntrustedusercakeys none\nrevokedkeys none\nsecuritykeyprovider internal\nauthorizedprincipalsfile none\nversionaddendum none\nauthorizedkeyscommand none\nauthorizedkeyscommanduser none\nauthorizedprincipalscommand none\nauthorizedprincipalscommanduser none\nhostkeyagent none\nkexalgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256\ncasignaturealgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa\nhostbasedacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256\nhostkeyalgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256\npubkeyacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256\nloglevel VERBOSE\nsyslogfacility AUTH\nauthorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2\nhostkey /etc/ssh/ssh_host_rsa_key\nhostkey /etc/ssh/ssh_host_ecdsa_key\nhostkey /etc/ssh/ssh_host_ed25519_key\nallowusers vagrant\nallowgroups vagrant\nallowgroups sudo\nacceptenv LANG\nacceptenv LC_*\nacceptenv LANG\nacceptenv LC_*\nauthenticationmethods any\nsubsystem sftp internal-sftp -f LOCAL6 -l INFO\nmaxstartups 10:30:60\npersourcemaxstartups none\npersourcenetblocksize 32:128\npermittunnel no\nipqos lowdelay throughput\nrekeylimit 536870912 3600\npermitopen any\npermitlisten any\npermituserenvironment no\npubkeyauthoptions none", "stdout_lines": ["port 22", "addressfamily inet", "listenaddress 0.0.0.0:22", "usepam yes", "logingracetime 20", "x11displayoffset 10", "maxauthtries 3", "maxsessions 3", "clientaliveinterval 200", "clientalivecountmax 1", "streamlocalbindmask 0177", "permitrootlogin no", "ignorerhosts yes", "ignoreuserknownhosts yes", "hostbasedauthentication no", "hostbasedusesnamefrompacketonly no", "pubkeyauthentication yes", "kerberosauthentication no", "kerberosorlocalpasswd yes", "kerberosticketcleanup yes", "gssapiauthentication no", "gssapicleanupcredentials yes", "gssapikeyexchange no", "gssapistrictacceptorcheck yes", "gssapistorecredentialsonrekey no", "gssapikexalgorithms gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1-", "passwordauthentication no", "kbdinteractiveauthentication no", "printmotd no", "printlastlog yes", "x11forwarding no", "x11uselocalhost yes", "permittty yes", "permituserrc yes", "strictmodes yes", "tcpkeepalive no", "permitemptypasswords no", "compression no", "gatewayports no", "usedns no", "allowtcpforwarding no", "allowagentforwarding no", "disableforwarding no", "allowstreamlocalforwarding yes", "streamlocalbindunlink no", "fingerprinthash SHA256", "exposeauthinfo no", "pidfile /run/sshd.pid", "modulifile /etc/ssh/moduli", "xauthlocation /usr/bin/xauth", "ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr", "macs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256", "banner /etc/issue.net", "forcecommand none", "chrootdirectory none", "trustedusercakeys none", "revokedkeys none", "securitykeyprovider internal", "authorizedprincipalsfile none", "versionaddendum none", "authorizedkeyscommand none", "authorizedkeyscommanduser none", "authorizedprincipalscommand none", "authorizedprincipalscommanduser none", "hostkeyagent none", "kexalgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256", "casignaturealgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa", "hostbasedacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256", "hostkeyalgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256", "pubkeyacceptedalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256", "loglevel VERBOSE", "syslogfacility AUTH", "authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2", "hostkey /etc/ssh/ssh_host_rsa_key", "hostkey /etc/ssh/ssh_host_ecdsa_key", "hostkey /etc/ssh/ssh_host_ed25519_key", "allowusers vagrant", "allowgroups vagrant", "allowgroups sudo", "acceptenv LANG", "acceptenv LC_*", "acceptenv LANG", "acceptenv LC_*", "authenticationmethods any", "subsystem sftp internal-sftp -f LOCAL6 -l INFO", "maxstartups 10:30:60", "persourcemaxstartups none", "persourcenetblocksize 32:128", "permittunnel no", "ipqos lowdelay throughput", "rekeylimit 536870912 3600", "permitopen any", "permitlisten any", "permituserenvironment no", "pubkeyauthoptions none"]}

Add it as task you to see what you get:

    - name: Verify sshd runtime configuration
      become: true
      environment:
        PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      ansible.builtin.command: sshd -T
      check_mode: false
      register: sshd_config
      changed_when: false
      failed_when: >-
        {%- set lower_parameter = item.split( )[0] | lower -%}
        {{ ( item | regex_replace('^[^\ ]+', lower_parameter) ) not in sshd_config.stdout_lines }}
      loop: "{{ (sshd_config_parameters | reject('regex', 'Allowgroups ') | list) + ['allowgroups vagrant', 'allowgroups sudo'] }}"

Runtime show: "acceptenv LANG", "acceptenv LC_*"

I will agree as soon as possible.

@cleberb
Copy link
Contributor Author

cleberb commented Oct 13, 2023

I believe it has become more organized and it will be easier to make changes in the future. Some values were ignored because it would take too much work to be handled dynamically.

@konstruktoid
Copy link
Owner

I believe it has become more organized and it will be easier to make changes in the future. Some values were ignored because it would take too much work to be handled dynamically.

Absolutely, thanks for the great work.

@konstruktoid
Copy link
Owner

diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml
index bd10e6a..299be25 100644
--- a/molecule/default/verify.yml
+++ b/molecule/default/verify.yml
@@ -373,6 +373,7 @@
         - rekeylimit
         # listenaddress: runtime returns values addresses and ports(Ex: 0.0.0.0:22), ports is optional and can have multiple values.
         - listenaddress
+        - debianbanner
 
     - name: Verify sshd runtime configuration
       become: true

@cleberb
Copy link
Contributor Author

cleberb commented Oct 15, 2023

diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml
index bd10e6a..299be25 100644
--- a/molecule/default/verify.yml
+++ b/molecule/default/verify.yml
@@ -373,6 +373,7 @@
         - rekeylimit
         # listenaddress: runtime returns values addresses and ports(Ex: 0.0.0.0:22), ports is optional and can have multiple values.
         - listenaddress
+        - debianbanner
 
     - name: Verify sshd runtime configuration
       become: true

This option is filtered by the distribution, has there been an error with it?

@konstruktoid
Copy link
Owner

Yeah, the sshd runtime check doesn't catch it. I don't believe it's in the output.

@konstruktoid
Copy link
Owner

$ lsb_release -d
Description:	Ubuntu 22.04.3 LTS
$ sudo grep -Ri banner /etc/ssh/* | grep -v '#'
/etc/ssh/sshd_config.d/01-hardening.conf:Banner /etc/issue.net
/etc/ssh/sshd_config.d/01-hardening.conf:DebianBanner no
$ sudo sshd -T | grep -i banner
banner /etc/issue.net
$
$ sudo systemctl restart ssh
$ sudo grep -Ri banner /etc/ssh/* | grep -v '#'
/etc/ssh/sshd_config.d/01-hardening.conf:Banner /etc/issue.net
/etc/ssh/sshd_config.d/01-hardening.conf:DebianBanner yes
$ sudo systemctl restart ssh
$ sudo sshd -T | grep -i banner
banner /etc/issue.net


- name: Set sshd_config_parameters AcceptEnv
ansible.builtin.set_fact:
sshd_config_parameters: "{{ sshd_config_parameters + ['AcceptEnv ' + sshd_authentication_methods] }}"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml
index b78df3a..02078d9 100644
--- a/molecule/default/verify.yml
+++ b/molecule/default/verify.yml
@@ -275,7 +275,7 @@
 
     - name: Set sshd_config_parameters AcceptEnv
       ansible.builtin.set_fact:
-        sshd_config_parameters: "{{ sshd_config_parameters + ['AcceptEnv ' + sshd_authentication_methods] }}"
+        sshd_config_parameters: "{{ sshd_config_parameters + ['AcceptEnv ' + sshd_accept_env] }}"
       when: sshd_accept_env is defined and sshd_accept_env | length != 0
 
     - name: Set sshd_config_parameters AuthenticationMethods

molecule/default/verify.yml Outdated Show resolved Hide resolved
- IgnoreRhosts {{ 'yes' if (sshd_ignore_rhosts | bool) else 'no' }}
- IgnoreUserKnownHosts {{ 'yes' if (sshd_ignore_user_known_hosts | bool) else 'no' }}
- >-
{%- if ssh_installed_version is version('8.7', '>=') -%}
KbdInteractiveAuthentication {{ 'yes' if (sshd_kbd_interactive_authentication | bool) else 'no' }}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 This will close #408

sshd_sftp_only_chroot: true
sshd_sftp_only_chroot_dir: '%h'
sshd_sftp_only_group: ''
sshd_sftp_subsystem: internal-sftp -f LOCAL6 -l INFO -u 0027
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we set the umask on system level I think we should remove -u 0027

@konstruktoid
Copy link
Owner

Thanks for the massive work, looks good now.

@konstruktoid konstruktoid merged commit 7e2869f into konstruktoid:master Oct 19, 2023
1 check passed
@cleberb cleberb deleted the sshd_improvements branch October 19, 2023 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace the deprecated ChallengeResponseAuthentication
2 participants