mirror of
https://github.com/dev-sec/ansible-collection-hardening
synced 2024-11-10 09:14:18 +00:00
INITIAL
This commit is contained in:
commit
bb703c962a
13 changed files with 683 additions and 0 deletions
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
README.pdf
|
||||
README.html
|
||||
shared_test_repo/
|
||||
test/integration
|
||||
.kitchen
|
||||
coverage
|
||||
Vagrantfile.erb
|
||||
|
||||
Gemfile.lock
|
||||
Berksfile.lock
|
||||
|
||||
ansible.cfg
|
||||
hosts
|
||||
default.yml
|
44
.kitchen.yml
Normal file
44
.kitchen.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
driver:
|
||||
name: vagrant
|
||||
vagrantfile_erb: Vagrantfile.erb
|
||||
|
||||
provisioner:
|
||||
name: ansible_playbook
|
||||
test_repo_uri: https://github.com/TelekomLabs/tests-ssh-hardening.git
|
||||
hosts: all
|
||||
|
||||
platforms:
|
||||
- name: ubuntu-12.04
|
||||
driver_config:
|
||||
box: opscode-ubuntu-12.04
|
||||
box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-12.04_chef-provisionerless.box
|
||||
- name: ubuntu-14.04
|
||||
driver_config:
|
||||
box: opscode-ubuntu-14.04
|
||||
box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-14.04_chef-provisionerless.box
|
||||
- name: centos-6.4
|
||||
driver_config:
|
||||
box: opscode-centos-6.4
|
||||
box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_centos-6.4_provisionerless.box
|
||||
- name: centos-6.5
|
||||
driver_config:
|
||||
box: opscode-centos-6.5
|
||||
box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
|
||||
- name: oracle-6.4
|
||||
driver_config:
|
||||
box: oracle-6.4
|
||||
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel64-64.box
|
||||
- name: oracle-6.5
|
||||
driver_config:
|
||||
box: oracle-6.5
|
||||
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel65-64.box
|
||||
|
||||
suites:
|
||||
- name: default
|
||||
roles_path: roles
|
||||
playbook: default.yml
|
||||
hosts: all
|
||||
require_ansible_repo: true
|
||||
ansible_verbose: true
|
||||
ansible_version: 1.9.2
|
29
.kitchen_debian.yml
Normal file
29
.kitchen_debian.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
driver:
|
||||
name: vagrant
|
||||
vagrantfile_erb: Vagrantfile.erb
|
||||
|
||||
provisioner:
|
||||
name: ansible_playbook
|
||||
test_repo_uri: https://github.com/TelekomLabs/tests-ssh-hardening.git
|
||||
hosts: all
|
||||
require_ansible_omnibus: true
|
||||
ansible_omnibus_url: https://raw.githubusercontent.com/rndmh3ro/ansible_debian_install/master/ansible-install.sh
|
||||
|
||||
- name: debian-6
|
||||
driver_config:
|
||||
box: debian-6
|
||||
box_url: https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-6.0.10-amd64_virtualbox.box
|
||||
- name: debian-7
|
||||
driver_config:
|
||||
box: debian-7
|
||||
box_url: https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box
|
||||
|
||||
suites:
|
||||
- name: default
|
||||
roles_path: roles
|
||||
playbook: default.yml
|
||||
hosts: all
|
||||
require_ansible_repo: true
|
||||
ansible_verbose: true
|
||||
ansible_version: 1.9.2
|
31
Gemfile
Normal file
31
Gemfile
Normal file
|
@ -0,0 +1,31 @@
|
|||
# encoding: utf-8
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
group :test do
|
||||
gem 'rake'
|
||||
# gem 'chefspec', '~> 4.2.0'
|
||||
gem 'foodcritic', '~> 4.0'
|
||||
# gem 'thor-foodcritic'
|
||||
# gem 'rubocop', '~> 0.28.0'
|
||||
gem 'coveralls', require: false
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'guard'
|
||||
gem 'guard-rspec'
|
||||
gem 'guard-kitchen'
|
||||
# gem 'guard-rubocop'
|
||||
# gem 'guard-foodcritic'
|
||||
end
|
||||
|
||||
group :integration do
|
||||
gem 'test-kitchen', '~> 1.0'
|
||||
gem 'kitchen-ansible'
|
||||
gem 'kitchen-vagrant'
|
||||
gem 'kitchen-sharedtests', '~> 0.2.0'
|
||||
end
|
||||
|
||||
group :openstack do
|
||||
gem 'kitchen-openstack'
|
||||
end
|
119
README.md
Normal file
119
README.md
Normal file
|
@ -0,0 +1,119 @@
|
|||
# ssh-hardening (Ansible Role)
|
||||
|
||||
## Description
|
||||
|
||||
This role provides secure ssh-client and ssh-server configurations.
|
||||
|
||||
## Requirements
|
||||
|
||||
* Ansible
|
||||
|
||||
## Role Variables
|
||||
* network_ipv6_enable: false - true if IPv6 is needed
|
||||
* ssh_client_cbc_required: false - true if CBC for ciphers is required. This is usually only necessary, if older M2M mechanism need to communicate with SSH, that don't have any of the configured secure ciphers enabled. CBC is a weak alternative. Anything weaker should be avoided and is thus not available.
|
||||
* ssh_server_cbc_required: false
|
||||
* ssh_client_weak_hmac: false - true if weaker HMAC mechanisms are required. This is usually only necessary, if older M2M mechanism need to communicate with SSH, that don't have any of the configured secure HMACs enabled.
|
||||
* ssh_server_weak_hmac: false
|
||||
* ssh_client_weak_kex: false - true if weaker Key-Exchange (KEX) mechanisms are required. This is usually only necessary, if older M2M mechanism need to communicate with SSH, that don't have any of the configured secure KEXs enabled.
|
||||
* ssh_server_weak_kex: false
|
||||
* ssh_ports: ['22'] - ports to which ssh-server should listen to and ssh-client should connect to
|
||||
* ssh_listen_to: ['0.0.0.0'] - one or more ip addresses, to which ssh-server should listen to. Default is empty, but should be configured for security reasons!
|
||||
* ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_dsa_key', '/etc/ssh/ssh_host_ecdsa_key'] # sshd
|
||||
* ssh_client_alive_interval: 600 # sshd
|
||||
* ssh_client_alive_count: 3 # sshd
|
||||
* ssh_remote_hosts: [] - one or more hosts, to which ssh-client can connect to. Default is empty, but should be configured for security reasons!
|
||||
* ssh_allow_root_with_key: false - `false` to disable root login altogether. Set to `true` to allow root to login via key-based mechanism.
|
||||
* ssh_allow_tcp_forwarding: false- `false` to disable TCP Forwarding. Set to `true` to allow TCP Forwarding
|
||||
* ssh_allow_agent_forwarding: false- `false` to disable Agent Forwarding. Set to `true` to allow Agent Forwarding
|
||||
* ssh_use_pam: false - `false` to disable pam authentication
|
||||
* ssh_deny_users: '' # sshd
|
||||
* ssh_allow_users: '' # sshd
|
||||
* ssh_deny_groups: '' # sshd
|
||||
* ssh_allow_groups: '' # sshd
|
||||
* ssh_print_motd: false - `false` to disable printing of the MOTD
|
||||
* ssh_print_last_log: false - `false` to disable display of last login information
|
||||
* ssh_ps53: 'yes'
|
||||
* ssh_ps59: 'sandbox'
|
||||
|
||||
## Example Playbook
|
||||
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- ansible-ssh-hardening
|
||||
|
||||
## Local Testing
|
||||
|
||||
For local testing you can use vagrant and Virtualbox of VMWare to run tests locally. You will have to install Virtualbox and Vagrant on your system. See [Vagrant Downloads](http://downloads.vagrantup.com/) for a vagrant package suitable for your system. For all our tests we use `test-kitchen`. If you are not familiar with `test-kitchen` please have a look at [their guide](http://kitchen.ci/docs/getting-started).
|
||||
|
||||
Next install test-kitchen:
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
gem install bundler
|
||||
bundle install
|
||||
|
||||
# Fetch tests
|
||||
bundle exec thor kitchen:fetch-remote-tests
|
||||
|
||||
# fast test on one machine
|
||||
bundle exec kitchen test default-ubuntu-1204
|
||||
|
||||
# test on all machines except Debian-based machines
|
||||
bundle exec kitchen test
|
||||
|
||||
# test on Debian-based machines
|
||||
KITCHEN_YAML=".kitchen_debian.yml" bundle exec kitchen test
|
||||
|
||||
# for development
|
||||
bundle exec kitchen create default-ubuntu-1204
|
||||
bundle exec kitchen converge default-ubuntu-1204
|
||||
```
|
||||
|
||||
For more information see [test-kitchen](http://kitchen.ci/docs/getting-started)
|
||||
|
||||
## FAQ / Pitfalls
|
||||
|
||||
**I can't log into my account. I have registered the client key, but it still doesn't let me it.**
|
||||
|
||||
If you have exhausted all typical issues (firewall, network, key missing, wrong key, account disabled etc.), it may be that your account is locked. The quickest way to find out is to look at the password hash for your user:
|
||||
|
||||
sudo grep myuser /etc/shadow
|
||||
|
||||
If the hash includes an `!`, your account is locked:
|
||||
|
||||
myuser:!:16280:7:60:7:::
|
||||
|
||||
The proper way to solve this is to unlock the account (`passwd -u myuser`). If the user doesn't have a password, you should can unlock it via:
|
||||
|
||||
usermod -p "*" myuser
|
||||
|
||||
Alternatively, if you intend to use PAM, you enabled it via `ssh_use_pam: true`. PAM will allow locked users to get in with keys.
|
||||
|
||||
|
||||
**Why doesn't my application connect via SSH anymore?**
|
||||
|
||||
Always look into log files first and if possible look at the negotation between client and server that is completed when connecting.
|
||||
|
||||
We have seen some issues in applications (based on python and ruby) that are due to their use of an outdated crypto set. This collides with this hardening module, which reduced the list of ciphers, message authentication codes (MACs) and key exchange (KEX) algorithms to a more secure selection.
|
||||
|
||||
If you find this isn't enough, feel free to activate the attributes `cbc_requires` for ciphers, `weak_hmac` for MACs and `weak_kex`for KEX in the variables `ssh_client` or `ssh_server` based on where you want to support them.
|
||||
|
||||
## Contributing
|
||||
|
||||
See [contributor guideline](CONTRIBUTING.md).
|
||||
|
||||
## License and Author
|
||||
|
||||
* Author:: Sebastian Gumprich <sebastian.gumprich@38.de>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
10
Thorfile
Normal file
10
Thorfile
Normal file
|
@ -0,0 +1,10 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'bundler'
|
||||
require 'bundler/setup'
|
||||
require 'thor/foodcritic'
|
||||
|
||||
require 'kitchen_sharedtests'
|
||||
require 'kitchen/sharedtests_thor_tasks'
|
||||
|
||||
Kitchen::SharedtestsThorTasks.new
|
2
ansible-install.sh
Normal file
2
ansible-install.sh
Normal file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
apt-get install -y py
|
12
roles/ansible-ssh-hardening/tasks/main.yml
Normal file
12
roles/ansible-ssh-hardening/tasks/main.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
- name: add the OS specific variables
|
||||
include_vars: "{{ ansible_os_family }}.yml"
|
||||
|
||||
- name: create sshd_config and set permissions to root/600
|
||||
template: src='opensshd.conf.j2' dest='/etc/ssh/sshd_config' mode=0600 owner=root group=root
|
||||
|
||||
- name: create ssh_config and set permissions to root/644
|
||||
template: src='openssh.conf.j2' dest='/etc/ssh/ssh_config' mode=0644 owner=root group=root
|
||||
|
||||
- name: restart sshd
|
||||
service: name={{ sshd_service_name }} state=restarted
|
146
roles/ansible-ssh-hardening/templates/openssh.conf.j2
Normal file
146
roles/ansible-ssh-hardening/templates/openssh.conf.j2
Normal file
|
@ -0,0 +1,146 @@
|
|||
# {{ansible_managed}}
|
||||
|
||||
# This is the ssh client system-wide configuration file.
|
||||
# See ssh_config(5) for more information on any settings used. Comments will be added only to clarify why a configuration was chosen.
|
||||
#
|
||||
# Created for OpenSSH v5.9
|
||||
|
||||
# Basic configuration
|
||||
# ===================
|
||||
|
||||
# Address family should always be limited to the active network configuration.
|
||||
AddressFamily {% if network_ipv6_enable %}any{% else %}inet{% endif %}
|
||||
|
||||
# Restrict the following configuration to be limited to this Host.
|
||||
{% for host in ssh_remote_hosts %}
|
||||
Host {{host}}
|
||||
{% endfor %}
|
||||
|
||||
# The port at the destination should be defined
|
||||
{% for port in ssh_ports %}
|
||||
Port {{port}}
|
||||
{% endfor %}
|
||||
|
||||
# Identity file configuration. You may restrict available identity files. Otherwise ssh will search for a pattern and use any that matches.
|
||||
#IdentityFile ~/.ssh/identity
|
||||
#IdentityFile ~/.ssh/id_rsa
|
||||
#IdentityFile ~/.ssh/id_dsa
|
||||
|
||||
|
||||
# Security configuration
|
||||
# ======================
|
||||
|
||||
# Set the protocol version to 2 for security reasons. Disables legacy support.
|
||||
Protocol 2
|
||||
|
||||
# Make sure passphrase querying is enabled
|
||||
BatchMode no
|
||||
|
||||
# Prevent IP spoofing by checking to host IP against the `known_hosts` file.
|
||||
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' %}
|
||||
Ciphers {{ciphers_66_weak}}
|
||||
{% else %}
|
||||
Ciphers {{ciphers_53_weak}}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' %}
|
||||
Ciphers {{ciphers_66_default}}
|
||||
{% else %}
|
||||
Ciphers {{ciphers_53_default}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# **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_server_weak_hmac %}
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' %}
|
||||
MACs {{macs_66_weak}}
|
||||
{% elif ansible_os_family == 'RedHat' and ansible_distribution_major_version <= '6' %}
|
||||
MACs {{macs_53_default}}
|
||||
{% elif ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6' %}
|
||||
MACs {{macs_53_default}}
|
||||
{% else %}
|
||||
MACs {{macs_59_weak}}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' %}
|
||||
MACs {{macs_66_default}}
|
||||
{% elif ansible_os_family == 'RedHat' and ansible_distribution_major_version <= '6' %}
|
||||
MACs {{macs_53_default}}
|
||||
{% elif ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6' %}
|
||||
MACs {{macs_53_default}}
|
||||
{% else %}
|
||||
MACs {{macs_59_default}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# 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' -%}
|
||||
{% if ssh_client_weak_kex -%}
|
||||
KexAlgorithms {{kex_66_weak}}
|
||||
{% else -%}
|
||||
KexAlgorithms {{kex_66_default}}
|
||||
{% endif %}
|
||||
{% else -%}
|
||||
{% if ansible_os_family == 'RedHat' or (ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6') -%}
|
||||
#KexAlgorithms
|
||||
{% else -%}
|
||||
KexAlgorithms {{kex_59_default}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
# Disable agent formwarding, since local agent could be accessed through forwarded connection.
|
||||
ForwardAgent no
|
||||
|
||||
# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
|
||||
ForwardX11 no
|
||||
|
||||
# Never use host-based authentication. It can be exploited.
|
||||
HostbasedAuthentication no
|
||||
RhostsRSAAuthentication no
|
||||
|
||||
# Enable RSA authentication via identity files.
|
||||
RSAAuthentication yes
|
||||
|
||||
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
|
||||
PasswordAuthentication no
|
||||
|
||||
# Only use GSSAPIAuthentication if implemented on the network.
|
||||
GSSAPIAuthentication no
|
||||
GSSAPIDelegateCredentials no
|
||||
|
||||
# Disable tunneling
|
||||
Tunnel no
|
||||
|
||||
# Disable local command execution.
|
||||
PermitLocalCommand no
|
||||
|
||||
|
||||
# Misc. configuration
|
||||
# ===================
|
||||
|
||||
# Enable compression. More pressure on the CPU, less on the network.
|
||||
Compression yes
|
||||
|
||||
#EscapeChar ~
|
||||
#VisualHostKey yes
|
231
roles/ansible-ssh-hardening/templates/opensshd.conf.j2
Normal file
231
roles/ansible-ssh-hardening/templates/opensshd.conf.j2
Normal file
|
@ -0,0 +1,231 @@
|
|||
# {{ansible_managed}}
|
||||
|
||||
# This is the ssh client system-wide configuration file.
|
||||
# See sshd_config(5) for more information on any settings used. Comments will be added only to clarify why a configuration was chosen.
|
||||
#
|
||||
# Created for OpenSSH v5.9
|
||||
|
||||
# Basic configuration
|
||||
# ===================
|
||||
|
||||
# Either disable or only allow root login via certificates.
|
||||
{% if ssh_allow_root_with_key -%}
|
||||
PermitRootLogin without-password
|
||||
{% else %}
|
||||
PermitRootLogin no
|
||||
{% endif %}
|
||||
|
||||
# Define which port sshd should listen to. Default to `22`.
|
||||
{% for port in ssh_ports -%}
|
||||
Port {{port}}
|
||||
{% endfor %}
|
||||
|
||||
# Address family should always be limited to the active network configuration.
|
||||
AddressFamily {% if network_ipv6_enable -%}any{% else %}inet{% endif %}
|
||||
|
||||
# Define which addresses sshd should listen to. Default to `0.0.0.0`, ie make sure you put your desired address in here, since otherwise sshd will listen to everyone.
|
||||
{% for address in ssh_listen_to -%}
|
||||
ListenAddress {{address}}
|
||||
{% endfor %}
|
||||
|
||||
# List HostKeys here.
|
||||
{% for key in ssh_host_key_files -%}
|
||||
HostKey {{key}} # Req 20
|
||||
{% endfor %}
|
||||
|
||||
# Security configuration
|
||||
# ======================
|
||||
|
||||
# Set the protocol version to 2 for security reasons. Disables legacy support.
|
||||
Protocol 2
|
||||
|
||||
# Make sure sshd checks file modes and ownership before accepting logins. This prevents accidental misconfiguration.
|
||||
StrictModes yes
|
||||
|
||||
# Logging, obsoletes QuietMode and FascistLogging
|
||||
SyslogFacility AUTH
|
||||
LogLevel VERBOSE
|
||||
|
||||
# Cryptography
|
||||
# ------------
|
||||
|
||||
# **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_server_cbc_required -%}
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' -%}
|
||||
Ciphers {{ciphers_66_weak}}
|
||||
{% else %}
|
||||
Ciphers {{ciphers_53_weak}}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' -%}
|
||||
Ciphers {{ciphers_66_default}}
|
||||
{% else %}
|
||||
Ciphers {{ciphers_53_default}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# **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_server_weak_hmac -%}
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' -%}
|
||||
MACs {{macs_66_weak}}
|
||||
{% elif ansible_os_family == 'RedHat' and ansible_distribution_major_version <= '6' -%}
|
||||
MACs {{macs_53_default}}
|
||||
{% elif ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6' -%}
|
||||
MACs {{macs_53_default}}
|
||||
{% else %}
|
||||
MACs {{macs_59_weak}}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' -%}
|
||||
MACs {{macs_66_default}}
|
||||
{% elif ansible_os_family == 'RedHat' and ansible_distribution_major_version <= '6' -%}
|
||||
MACs {{macs_53_default}}
|
||||
{% elif ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6' -%}
|
||||
MACs {{macs_53_default}}
|
||||
{% else %}
|
||||
MACs {{macs_59_default}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# 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.
|
||||
# based on: https://bettercrypto.org/static/applied-crypto-hardening.pdf
|
||||
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04' -%}
|
||||
{% if ssh_client_weak_kex -%}
|
||||
KexAlgorithms {{kex_66_weak}}
|
||||
{% else -%}
|
||||
KexAlgorithms {{kex_66_default}}
|
||||
{% endif %}
|
||||
{% else -%}
|
||||
{% if ansible_os_family == 'RedHat' or (ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6') -%}
|
||||
#KexAlgorithms
|
||||
{% else -%}
|
||||
KexAlgorithms {{kex_59_default}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# Authentication
|
||||
# --------------
|
||||
|
||||
# Secure Login directives.
|
||||
UseLogin no
|
||||
UsePrivilegeSeparation {% if (ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6') or ansible_os_family == 'RedHat' -%}{{ssh_ps53}}{% else %}{{ssh_ps59}}{% endif %}
|
||||
|
||||
PermitUserEnvironment no
|
||||
LoginGraceTime 30s
|
||||
MaxAuthTries 2
|
||||
MaxSessions 10
|
||||
MaxStartups 10:30:100
|
||||
|
||||
# Enable public key authentication
|
||||
PubkeyAuthentication yes
|
||||
|
||||
# Never use host-based authentication. It can be exploited.
|
||||
IgnoreRhosts yes
|
||||
IgnoreUserKnownHosts yes
|
||||
HostbasedAuthentication no
|
||||
|
||||
# Enable PAM to enforce system wide rules
|
||||
UsePAM {% if ssh_use_pam -%}yes{% else %}no{% endif %}
|
||||
|
||||
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
ChallengeResponseAuthentication no
|
||||
|
||||
# Only enable Kerberos authentication if it is configured.
|
||||
KerberosAuthentication no
|
||||
KerberosOrLocalPasswd no
|
||||
KerberosTicketCleanup yes
|
||||
#KerberosGetAFSToken no
|
||||
|
||||
# Only enable GSSAPI authentication if it is configured.
|
||||
GSSAPIAuthentication no
|
||||
GSSAPICleanupCredentials yes
|
||||
|
||||
# In case you don't use PAM (`UsePAM no`), you can alternatively restrict users and groups here. For key-based authentication this is not necessary, since all keys must be explicitely enabled.
|
||||
{% if ssh_deny_users -%}
|
||||
DenyUsers {{ssh_deny_users}}
|
||||
{% endif %}
|
||||
|
||||
{% if ssh_allow_users -%}
|
||||
AllowUsers {{ssh_allow_users}}
|
||||
{% endif %}
|
||||
|
||||
{% if ssh_deny_groups -%}
|
||||
DenyGroups {{ssh_deny_groups}}
|
||||
{% endif %}
|
||||
|
||||
{% if ssh_deny_groups -%}
|
||||
AllowGroups {{ssh_allow_groups}}
|
||||
{% endif %}
|
||||
|
||||
# Network
|
||||
# -------
|
||||
|
||||
# Disable TCP keep alive since it is spoofable. Use ClientAlive messages instead, they use the encrypted channel
|
||||
TCPKeepAlive no
|
||||
|
||||
# Manage `ClientAlive..` signals via interval and maximum count. This will periodically check up to a `..CountMax` number of times within `..Interval` timeframe, and abort the connection once these fail.
|
||||
ClientAliveInterval {{ssh_client_alive_interval}}
|
||||
ClientAliveCountMax {{ssh_client_alive_count}}
|
||||
|
||||
# Disable tunneling
|
||||
PermitTunnel no
|
||||
|
||||
# Disable forwarding tcp connections.
|
||||
# no real advantage without denied shell access
|
||||
AllowTcpForwarding {% if ssh_allow_tcp_forwarding -%}yes{% else %}no{% endif %}
|
||||
|
||||
# Disable agent formwarding, since local agent could be accessed through forwarded connection.
|
||||
# no real advantage without denied shell access
|
||||
AllowAgentForwarding {% if ssh_allow_agent_forwarding -%}yes{% else %}no{% endif %}
|
||||
|
||||
# Do not allow remote port forwardings to bind to non-loopback addresses.
|
||||
GatewayPorts no
|
||||
|
||||
# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
|
||||
X11Forwarding no
|
||||
X11UseLocalhost yes
|
||||
|
||||
|
||||
# Misc. configuration
|
||||
# ===================
|
||||
|
||||
PrintMotd {% if ssh_print_motd -%}yes{% else %}no{% endif %}
|
||||
|
||||
PrintLastLog {% if ssh_print_last_log -%}yes{% else %}no{% endif %}
|
||||
|
||||
#Banner /etc/ssh/banner.txt
|
||||
#UseDNS yes
|
||||
#PidFile /var/run/sshd.pid
|
||||
#MaxStartups 10
|
||||
#ChrootDirectory none
|
||||
#ChrootDirectory /home/%u
|
||||
|
||||
# Configuration, in case SFTP is used
|
||||
## override default of no subsystems
|
||||
## Subsystem sftp /opt/app/openssh5/libexec/sftp-server
|
||||
#Subsystem sftp internal-sftp -l VERBOSE
|
||||
#
|
||||
## These lines must appear at the *end* of sshd_config
|
||||
#Match Group sftponly
|
||||
#ForceCommand internal-sftp -l VERBOSE
|
||||
#ChrootDirectory /sftpchroot/home/%u
|
||||
#AllowTcpForwarding no
|
||||
#AllowAgentForwarding no
|
||||
#PasswordAuthentication no
|
||||
#PermitRootLogin no
|
||||
#X11Forwarding no
|
1
roles/ansible-ssh-hardening/vars/Debian.yml
Normal file
1
roles/ansible-ssh-hardening/vars/Debian.yml
Normal file
|
@ -0,0 +1 @@
|
|||
sshd_service_name: ssh
|
1
roles/ansible-ssh-hardening/vars/RedHat.yml
Normal file
1
roles/ansible-ssh-hardening/vars/RedHat.yml
Normal file
|
@ -0,0 +1 @@
|
|||
sshd_service_name: sshd
|
43
roles/ansible-ssh-hardening/vars/main.yml
Normal file
43
roles/ansible-ssh-hardening/vars/main.yml
Normal file
|
@ -0,0 +1,43 @@
|
|||
network_ipv6_enable: false # sshd + ssh
|
||||
ssh_client_cbc_required: false # ssh
|
||||
ssh_server_cbc_required: false # sshd
|
||||
ssh_client_weak_hmac: false # ssh
|
||||
ssh_server_weak_hmac: false # sshd
|
||||
ssh_client_weak_kex: false # ssh
|
||||
ssh_server_weak_kex: false # sshd
|
||||
ssh_ports: ['22'] # sshd + ssh
|
||||
ssh_listen_to: ['0.0.0.0'] # sshd
|
||||
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_dsa_key', '/etc/ssh/ssh_host_ecdsa_key'] # sshd
|
||||
ssh_client_alive_interval: 600 # sshd
|
||||
ssh_client_alive_count: 3 # sshd
|
||||
ssh_remote_hosts: [] # ssh
|
||||
ssh_allow_root_with_key: false # sshd
|
||||
ssh_allow_tcp_forwarding: false # sshd
|
||||
ssh_allow_agent_forwarding: false # sshd
|
||||
ssh_use_pam: false # sshd
|
||||
ssh_deny_users: '' # sshd
|
||||
ssh_allow_users: '' # sshd
|
||||
ssh_deny_groups: '' # sshd
|
||||
ssh_allow_groups: '' # sshd
|
||||
ssh_print_motd: false # sshd
|
||||
ssh_print_last_log: false # sshd
|
||||
ssh_ps53: 'yes'
|
||||
ssh_ps59: 'sandbox'
|
||||
|
||||
macs_53_default: 'hmac-ripemd160,hmac-sha1'
|
||||
macs_59_default: 'hmac-sha2-512,hmac-sha2-256,hmac-ripemd160'
|
||||
macs_59_weak: '{{macs_59_default | join(",hmac-sha1")}}'
|
||||
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'
|
||||
macs_66_weak: '{{macs_66_default | join(",hmac-sha1")}}'
|
||||
|
||||
ciphers_53_default: 'aes256-ctr,aes192-ctr,aes128-ctr'
|
||||
ciphers_53_weak: '{{ciphers_53_default | join (",aes256-cbc,aes192-cbc,aes128-cbc")}}'
|
||||
|
||||
ciphers_66_default: 'chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr'
|
||||
ciphers_66_weak: '{{ciphers_66_default | join (",aes256-cbc,aes192-cbc,aes128-cbc")}}'
|
||||
|
||||
kex_59_default: 'diffie-hellman-group-exchange-sha256'
|
||||
kex_59_weak: '{{kex_59_default | join (",diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1")}}'
|
||||
kex_66_default: 'curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256'
|
||||
kex_66_weak: '{{kex_66_default | join (",diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1")}}'
|
||||
|
Loading…
Reference in a new issue