Skip to content

Commit

Permalink
Merge pull request dev-sec#139 from dev-sec/macs_kex_ciphers
Browse files Browse the repository at this point in the history
Macs kex ciphers
  • Loading branch information
atomic111 authored Dec 29, 2017
2 parents 2c89462 + ebcd942 commit 115fd37
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 149 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ script:
- 'docker run --detach --volume="${PWD}":/etc/ansible/roles/ansible-ssh-hardening:ro ${run_opts} rndmh3ro/docker-${distro}-ansible:${version} "${init}" > "${container_id}"'

# Test role.
- 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-ssh-hardening/default_custom.yml'
- 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-ssh-hardening/default.yml'

# Verify role
Expand Down
47 changes: 1 addition & 46 deletions default.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with custom settings
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
hosts: localhost
pre_tasks:
- package: name="{{item}}" state=installed
Expand All @@ -19,48 +19,3 @@

roles:
- ansible-ssh-hardening
vars:
network_ipv6_enable: true
ssh_allow_root_with_key: true
ssh_allow_tcp_forwarding: true
ssh_gateway_ports: true
ssh_allow_agent_forwarding: true
ssh_server_permit_environment_vars: ['PWD','HTTP_PROXY']
ssh_client_alive_interval: 100
ssh_client_alive_count: 10
ssh_client_password_login: true
ssh_client_cbc_required: true
ssh_client_weak_kex: true
ssh_challengeresponseauthentication: true
ssh_compression: true
ssh_allow_users: 'root kitchen vagrant'
ssh_allow_groups: 'root kitchen vagrant'
ssh_deny_users: 'foo bar'
ssh_deny_groups: 'foo bar'
ssh_authorized_keys_file: '/etc/ssh/authorized_keys/%u'
ssh_max_auth_retries: 10
ssh_permit_tunnel: true
ssh_print_motd: true
ssh_print_last_log: true
ssh_banner: true
ssh_server_password_login: true
ssh_server_weak_hmac: true
sftp_enabled: true
ssh_server_match_group:
- group: 'root'
rules: 'AllowTcpForwarding yes'
ssh_server_match_user:
- user: 'root'
rules: 'AllowTcpForwarding yes'
ssh_remote_hosts:
- names: ['example.com', 'example2.com']
options: ['Port 2222', 'ForwardAgent yes']
- names: ['example3.com']
options: ['StrictHostKeyChecking no']
ssh_use_dns: true
ssh_use_pam: true

- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
hosts: localhost
roles:
- ansible-ssh-hardening
62 changes: 62 additions & 0 deletions default_custom.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with custom settings
hosts: localhost
pre_tasks:
- package: name="{{item}}" state=installed
with_items:
- "openssh-clients"
- "openssh-server"
ignore_errors: true
- apt: name="{{item}}" state=installed update_cache=true
with_items:
- "openssh-client"
- "openssh-server"
ignore_errors: true
- file: path="/var/run/sshd" state=directory
- name: create ssh host keys
command: "ssh-keygen -A"
when: not ((ansible_os_family in ['Oracle Linux', 'RedHat']) and ansible_distribution_major_version < '7')

roles:
- ansible-ssh-hardening
vars:
network_ipv6_enable: true
ssh_allow_root_with_key: true
ssh_allow_tcp_forwarding: true
ssh_gateway_ports: true
ssh_allow_agent_forwarding: true
ssh_server_permit_environment_vars: ['PWD','HTTP_PROXY']
ssh_client_alive_interval: 100
ssh_client_alive_count: 10
ssh_client_password_login: true
ssh_client_cbc_required: true
ssh_client_weak_kex: true
ssh_challengeresponseauthentication: true
ssh_compression: true
ssh_allow_users: 'root kitchen vagrant'
ssh_allow_groups: 'root kitchen vagrant'
ssh_deny_users: 'foo bar'
ssh_deny_groups: 'foo bar'
ssh_authorized_keys_file: '/etc/ssh/authorized_keys/%u'
ssh_max_auth_retries: 10
ssh_permit_tunnel: true
ssh_print_motd: true
ssh_print_last_log: true
ssh_banner: true
ssh_server_password_login: true
ssh_server_weak_hmac: true
sftp_enabled: true
ssh_server_enabled: false
ssh_server_match_group:
- group: 'root'
rules: 'AllowTcpForwarding yes'
ssh_server_match_user:
- user: 'root'
rules: 'AllowTcpForwarding yes'
ssh_remote_hosts:
- names: ['example.com', 'example2.com']
options: ['Port 2222', 'ForwardAgent yes']
- names: ['example3.com']
options: ['StrictHostKeyChecking no']
ssh_use_dns: true
ssh_use_pam: true
13 changes: 11 additions & 2 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ ssh_server_permit_environment_vars: false
ssh_ps53: 'yes'
ssh_ps59: 'sandbox'

ssh_macs: []
ssh_ciphers: []
ssh_kex: []

ssh_macs_53_default:
- hmac-ripemd160
- hmac-sha1
Expand All @@ -141,11 +145,16 @@ ssh_macs_59_weak: "{{ ssh_macs_59_default + ['hmac-sha1'] }}"
ssh_macs_66_default:
- hmac-sha2-512-etm@openssh.com
- hmac-sha2-256-etm@openssh.com
- hmac-ripemd160-etm@openssh.com
- umac-128-etm@openssh.com
- hmac-sha2-512
- hmac-sha2-256
- hmac-ripemd160

ssh_macs_76_default:
- hmac-sha2-512-etm@openssh.com
- hmac-sha2-256-etm@openssh.com
- umac-128-etm@openssh.com
- hmac-sha2-512
- hmac-sha2-256

ssh_macs_66_weak: "{{ ssh_macs_66_default + ['hmac-sha1'] }}"

Expand Down
98 changes: 98 additions & 0 deletions tasks/crypto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---

- name: set hostkeys according to openssh-version
set_fact:
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key']
when: sshd_version.stdout >= '6.3' and not ssh_host_key_files

- name: set hostkeys according to openssh-version
set_fact:
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key']
when: sshd_version.stdout >= '6.0' and not ssh_host_key_files

- name: set hostkeys according to openssh-version
set_fact:
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key']
when: sshd_version.stdout >= '5.3' and not ssh_host_key_files

###

- name: set weak macs according to openssh-version if openssh >= 7.6
set_fact:
ssh_macs: "{{ssh_macs_76_default}}"
when: sshd_version.stdout >= '7.6' and not ssh_macs

- name: set weak macs according to openssh-version if openssh >= 6.6
set_fact:
ssh_macs: "{{ssh_macs_66_weak}}"
when: sshd_version.stdout >= '6.6' and ssh_server_weak_hmac and not ssh_macs

- name: set macs according to openssh-version if openssh >= 6.6
set_fact:
ssh_macs: "{{ssh_macs_66_default}}"
when: sshd_version.stdout >= '6.6' and not ssh_macs

- name: set weak macs according to openssh-version
set_fact:
ssh_macs: "{{ssh_macs_59_weak}}"
when: sshd_version.stdout >= '5.9' and ssh_server_weak_hmac and not ssh_macs

- name: set macs according to openssh-version
set_fact:
ssh_macs: "{{ssh_macs_59_default}}"
when: sshd_version.stdout >= '5.9' and not ssh_macs

- name: set macs according to openssh-version
set_fact:
ssh_macs: "{{ssh_macs_53_default}}"
when: sshd_version.stdout >= '5.3' and not ssh_macs

- name: set macs according to openssh-version
set_fact:
ssh_macs: "{{ssh_macs_53_default}}"
when: sshd_version.stdout >= '5.3' and not ssh_macs

###

- name: set weak ciphers according to openssh-version if openssh >= 6.6
set_fact:
ssh_ciphers: "{{ssh_ciphers_66_weak}}"
when: sshd_version.stdout >= '6.6' and ssh_server_cbc_required and not ssh_ciphers

- name: set ciphers according to openssh-version if openssh >= 6.6
set_fact:
ssh_ciphers: "{{ssh_ciphers_66_default}}"
when: sshd_version.stdout >= '6.6' and not ssh_ciphers

- name: set weak ciphers according to openssh-version
set_fact:
ssh_ciphers: "{{ssh_ciphers_53_weak}}"
when: sshd_version.stdout >= '5.3' and ssh_server_cbc_required and not ssh_ciphers

- name: set ciphers according to openssh-version
set_fact:
ssh_ciphers: "{{ssh_ciphers_53_default}}"
when: sshd_version.stdout >= '5.3' and not ssh_ciphers

###

- name: set weak kex according to openssh-version if openssh >= 6.6
set_fact:
ssh_kex: "{{ssh_kex_66_weak}}"
when: sshd_version.stdout >= '6.6' and ssh_server_weak_hmac and not ssh_kex

- name: set kex according to openssh-version if openssh >= 6.6
set_fact:
ssh_kex: "{{ssh_kex_66_default}}"
when: sshd_version.stdout >= '6.6' and not ssh_kex

- name: set weak kex according to openssh-version
set_fact:
ssh_kex: "{{ssh_kex_59_weak}}"
when: sshd_version.stdout >= '5.9' and ssh_server_weak_hmac and not ssh_kex

- name: set kex according to openssh-version
set_fact:
ssh_kex: "{{ssh_kex_59_default}}"
when: sshd_version.stdout >= '5.9' and not ssh_kex

15 changes: 1 addition & 14 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,7 @@
register: sshd_version
check_mode: no

- name: set hostkeys according to openssh-version
set_fact:
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key']
when: sshd_version.stdout >= '6.3' and not ssh_host_key_files

- name: set hostkeys according to openssh-version
set_fact:
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key']
when: sshd_version.stdout >= '6.0' and not ssh_host_key_files

- name: set hostkeys according to openssh-version
set_fact:
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key']
when: sshd_version.stdout >= '5.3' and not ssh_host_key_files
- include: crypto.yml

- name: create revoked_keys and set permissions to root/600
template: src='revoked_keys.j2' dest='/etc/ssh/revoked_keys' mode=0600 owner="{{ ssh_owner }}" group="{{ ssh_group }}"
Expand Down
54 changes: 10 additions & 44 deletions templates/openssh.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -45,68 +45,34 @@ CheckHostIP yes
# Always ask before adding keys to the `known_hosts` file. Do not set to `yes`.
StrictHostKeyChecking ask


# **Ciphers** -- If your clients don't support CTR (eg older versions), cbc will be added
# CBC: is true if you want to connect with OpenSSL-base libraries
# eg ruby Net::SSH::Transport::CipherFactory requires cbc-versions of the given openssh ciphers to work
# -- see: (http://net-ssh.github.com/net-ssh/classes/Net/SSH/Transport/CipherFactory.html)
#
{% if ssh_client_cbc_required -%}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') or (ansible_distribution == 'Debian' and ansible_distribution_version >= '8') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version >= '7') or (ansible_distribution == 'FreeBSD' and ansible_distribution_version >= '11') -%}
Ciphers {{ ssh_ciphers_66_weak | join(',') }}
{% else -%}
Ciphers {{ ssh_ciphers_53_weak | join(',') }}
{% endif %}
{% else -%}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') or (ansible_distribution == 'Debian' and ansible_distribution_version >= '8') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version >= '7') or (ansible_distribution == 'FreeBSD' and ansible_distribution_version >= '11') -%}
Ciphers {{ ssh_ciphers_66_default | join(',') }}
{% else -%}
Ciphers {{ ssh_ciphers_53_default | join(',') }}
{% endif %}
{% endif %}

{# This outputs "Ciphers <list-of-ciphers>" if ssh_ciphers is defined or "#Ciphers" if ssh_ciphers is undefined #}
{{ "Ciphers "+ssh_ciphers| join(',') if ssh_ciphers else "Ciphers"|comment }}

# **Hash algorithms** -- Make sure not to use SHA1 for hashing, unless it is really necessary.
# Weak HMAC is sometimes required if older package versions are used
# eg Ruby's Net::SSH at around 2.2.* doesn't support sha2 for hmac, so this will have to be set true in this case.
#
{% if ssh_client_weak_hmac -%}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') or (ansible_distribution == 'Debian' and ansible_distribution_version >= '8') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version >= '7') or (ansible_distribution == 'FreeBSD' and ansible_distribution_version >= '11') -%}
MACs {{ ssh_macs_66_weak | join(',') }}
{% elif ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version <= '6' -%}
MACs {{ ssh_macs_53_default | join(',') }}
{% endif %}
{% else -%}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') or (ansible_distribution == 'Debian' and ansible_distribution_version >= '8') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version >= '7') or (ansible_distribution == 'FreeBSD' and ansible_distribution_version >= '11') -%}
MACs {{ ssh_macs_66_default | join(',') }}
{% elif ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version <= '6' -%}
MACs {{ ssh_macs_53_default | join(',') }}
{% else -%}
MACs {{ ssh_macs_59_default | join(',') }}
{% endif %}
{% endif %}

{# This outputs "MACs <list-of-macs>" if ssh_macs is defined or "#MACs" if ssh_macs is undefined #}
{{ "MACs "+ssh_macs| join(',') if ssh_macs else "MACs"|comment }}

# Alternative setting, if OpenSSH version is below v5.9
#MACs hmac-ripemd160

# **Key Exchange Algorithms** -- Make sure not to use SHA1 for kex, unless it is really necessary
# Weak kex is sometimes required if older package versions are used
# eg ruby's Net::SSH at around 2.2.* doesn't support sha2 for kex, so this will have to be set true in this case.
#
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') or (ansible_distribution == 'Debian' and ansible_distribution_version >= '8') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version >= '7') or (ansible_distribution == 'FreeBSD' and ansible_distribution_version >= '11') -%}
{% if ssh_client_weak_kex -%}
KexAlgorithms {{ ssh_kex_66_weak | join(',') }}
{% else -%}
KexAlgorithms {{ ssh_kex_66_default | join(',') }}
{% endif %}
{% else -%}
{% if ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version <= '6' -%}
#KexAlgorithms
{% elif ssh_client_weak_kex -%}
KexAlgorithms {{ ssh_kex_59_weak | join(',') }}
{% else -%}
KexAlgorithms {{ ssh_kex_59_default | join(',') }}
{% endif %}
{% endif %}
# based on: https://bettercrypto.org/static/applied-crypto-hardening.pdf

{# This outputs "KexAlgorithms <list-of-algos>" if ssh_kex is defined or "#KexAlgorithms" if ssh_kex is undefined #}
{{ "KexAlgorithms "+ssh_kex| join(',') if ssh_kex else "KexAlgorithms"|comment }}

# Disable agent forwarding, since local agent could be accessed through forwarded connection.
ForwardAgent no
Expand Down
Loading

0 comments on commit 115fd37

Please sign in to comment.