Updated Ansible roles
This commit is contained in:
parent
3b81fa38ae
commit
8a2933414b
133 changed files with 2949 additions and 897 deletions
10
README.md
10
README.md
|
@ -86,7 +86,15 @@ Now access the admin panel with the user account you created earlier: http://loc
|
|||
|
||||
We use [Ansible](https://www.ansible.com) and [Docker Compose](https://docs.docker.com/compose/reference/overview/) for automated deployment.
|
||||
|
||||
To use Docker Compose to deploy the site, copy `ansible/roles/web/templates/docker-compose.j2` to `/docker-compose.yml` and fill in all `{{ variables }}`. This is done automatically in Ansible.
|
||||
To use Docker Compose to manually deploy the site, copy `ansible/roles/web/templates/docker-compose.j2` to `/docker-compose.yml` and fill in all `{{ variables }}`. This can also be done automatically in Ansible.
|
||||
|
||||
Install or update the following roles from [Ansible Galaxy](https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html) to use our scripts:
|
||||
|
||||
```
|
||||
ansible-galaxy install \
|
||||
dev-sec.nginx-hardening dev-sec.ssh-hardening dev-sec.os-hardening \
|
||||
geerlingguy.nodejs geerlingguy.certbot
|
||||
```
|
||||
|
||||
To do production deployments, you need to obtain SSH and vault keys from your system administrator (who has followed the Ansible guide to set up a vault..), and place these in a `.keys` folder. To deploy a site:
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[defaults]
|
||||
retry_files_enabled = False
|
||||
roles_path = ansible/roles
|
||||
roles_path = ansible/roles:~/.ansible/roles
|
||||
vault_password_file = .keys/ansible.vault
|
||||
|
|
40
ansible/roles/dev-sec.nginx-hardening/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
40
ansible/roles/dev-sec.nginx-hardening/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Actual behavior**
|
||||
<!--- Paste verbatim command output between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
**Example Playbook**
|
||||
<!--- Paste an example playbook that can be used to reproduce the problem between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
|
||||
**OS / Environment**
|
||||
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->
|
||||
|
||||
**Ansible Version**
|
||||
<!--- Paste verbatim output from "ansible --version" between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
|
||||
**Role Version**
|
||||
<!--- Paste version of the role between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
17
ansible/roles/dev-sec.nginx-hardening/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
ansible/roles/dev-sec.nginx-hardening/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -0,0 +1 @@
|
|||
unreleased=false
|
12
ansible/roles/dev-sec.nginx-hardening/.gitignore
vendored
12
ansible/roles/dev-sec.nginx-hardening/.gitignore
vendored
|
@ -1,13 +1,3 @@
|
|||
README.pdf
|
||||
README.html
|
||||
shared_test_repo/
|
||||
test/integration
|
||||
.kitchen
|
||||
coverage
|
||||
Vagrantfile.erb
|
||||
|
||||
Gemfile.lock
|
||||
Berksfile.lock
|
||||
|
||||
ansible.cfg
|
||||
hosts
|
||||
Gemfile.lock
|
||||
|
|
|
@ -1,18 +1,28 @@
|
|||
---
|
||||
driver:
|
||||
name: vagrant
|
||||
driver_config:
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
vagrantfiles:
|
||||
- kitchen_vagrant_block.rb
|
||||
|
||||
provisioner:
|
||||
name: ansible_playbook
|
||||
test_repo_uri: https://github.com/hardening-io/tests-ssh-hardening.git
|
||||
hosts: all
|
||||
require_ansible_repo: false
|
||||
require_ansible_omnibus: true
|
||||
require_chef_for_busser: false
|
||||
require_ruby_for_busser: false
|
||||
ansible_verbose: true
|
||||
roles_path: ../ansible-ssh-hardening/
|
||||
roles_path: ../ansible-nginx-hardening/
|
||||
requirements_path: requirements.yml
|
||||
playbook: default.yml
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
|
||||
transport:
|
||||
max_ssh_sessions: 5
|
||||
|
||||
platforms:
|
||||
- name: ubuntu-12.04
|
||||
|
@ -23,6 +33,10 @@ platforms:
|
|||
driver_config:
|
||||
box: opscode-ubuntu-14.04
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-14.04_chef-provisionerless.box
|
||||
- name: ubuntu-16.04
|
||||
driver_config:
|
||||
box: opscode-ubuntu-16.04
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-16.04_chef-provisionerless.box
|
||||
- name: centos-6.4
|
||||
driver_config:
|
||||
box: opscode-centos-6.4
|
||||
|
@ -31,6 +45,12 @@ platforms:
|
|||
driver_config:
|
||||
box: opscode-centos-6.5
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
|
||||
- name: centos-6.8
|
||||
driver_config:
|
||||
box: bento/centos-6.8
|
||||
- name: centos-7
|
||||
driver_config:
|
||||
box: bento/centos-7.2
|
||||
- name: oracle-6.4
|
||||
driver_config:
|
||||
box: oracle-6.4
|
||||
|
@ -39,14 +59,9 @@ platforms:
|
|||
driver_config:
|
||||
box: oracle-6.5
|
||||
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel65-64.box
|
||||
- name: debian-6
|
||||
- name: oracle-7
|
||||
driver_config:
|
||||
box: debian-6
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-6.0.10_chef-provisionerless.box
|
||||
- name: debian-7
|
||||
driver_config:
|
||||
box: debian-7
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8_chef-provisionerless.box
|
||||
box: boxcutter/ol72
|
||||
- name: debian-8
|
||||
driver_config:
|
||||
box: debian-8
|
||||
|
@ -56,10 +71,7 @@ verifier:
|
|||
name: inspec
|
||||
sudo: true
|
||||
inspec_tests:
|
||||
- https://github.com/dev-sec/tests-ssh-hardening
|
||||
- https://github.com/dev-sec/nginx-baseline/
|
||||
|
||||
suites:
|
||||
- name: nginx-ansible_1.9
|
||||
provisioner:
|
||||
ansible_version: 1.9.4
|
||||
- name: nginx-ansible_latest
|
||||
- name: nginx
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
driver:
|
||||
name: docker
|
||||
use_sudo: false
|
||||
privileged: true
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
|
||||
transport:
|
||||
max_ssh_sessions: 5
|
||||
|
@ -10,51 +13,104 @@ provisioner:
|
|||
name: ansible_playbook
|
||||
hosts: all
|
||||
require_ansible_repo: false
|
||||
require_ansible_omnibus: true
|
||||
require_chef_for_busser: false
|
||||
require_ruby_for_busser: false
|
||||
ansible_verbose: true
|
||||
ansible_diff: true
|
||||
requirements_path: requirements.yml
|
||||
|
||||
roles_path: ../ansible-nginx-hardening/
|
||||
playbook: default.yml
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
playbook: tests/test.yml
|
||||
requirements_path: requirements.yml
|
||||
galaxy_ignore_certs: true
|
||||
|
||||
platforms:
|
||||
- name: ubuntu-12.04
|
||||
- name: centos6-ansible-latest
|
||||
driver:
|
||||
image: ubuntu:12.04
|
||||
- name: ubuntu-14.04
|
||||
image: rndmh3ro/docker-centos6-ansible:latest
|
||||
platform: centos
|
||||
- name: centos7-ansible-latest
|
||||
driver:
|
||||
image: ubuntu:14.04
|
||||
- name: ubuntu-16.04
|
||||
image: rndmh3ro/docker-centos7-ansible:latest
|
||||
platform: centos
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
- name: oracle6-ansible-latest
|
||||
driver:
|
||||
image: ubuntu:16.04
|
||||
- name: centos-6.7
|
||||
image: rndmh3ro/docker-oracle6-ansible:latest
|
||||
platform: centos
|
||||
- name: oracle7-ansible-latest
|
||||
driver:
|
||||
image: centos:6.7
|
||||
- name: centos-6.8
|
||||
image: rndmh3ro/docker-oracle7-ansible:latest
|
||||
run_command: /sbin/init
|
||||
platform: centos
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
- name: ubuntu1404-ansible-latest
|
||||
driver:
|
||||
image: centos:6.8
|
||||
- name: centos-7
|
||||
image: rndmh3ro/docker-ubuntu1404-ansible:latest
|
||||
platform: ubuntu
|
||||
- name: ubuntu1604-ansible-latest
|
||||
driver:
|
||||
image: centos:7
|
||||
privileged: true
|
||||
run_command: /usr/sbin/init
|
||||
- name: debian-7
|
||||
image: rndmh3ro/docker-ubuntu1604-ansible:latest
|
||||
platform: ubuntu
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- systemctl enable ssh.service
|
||||
- name: ubuntu1804-ansible-latest
|
||||
driver:
|
||||
image: debian:7
|
||||
- name: debian-8
|
||||
image: rndmh3ro/docker-ubuntu1804-ansible:latest
|
||||
platform: ubuntu
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- systemctl enable ssh.service
|
||||
- name: debian8-ansible-latest
|
||||
driver:
|
||||
image: debian:8
|
||||
image: rndmh3ro/docker-debian8-ansible:latest
|
||||
platform: debian
|
||||
- name: debian9-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-debian9-ansible:latest
|
||||
platform: debian
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- apt install -y systemd-sysv
|
||||
- systemctl enable ssh.service
|
||||
- name: amazon-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-amazon-ansible:latest
|
||||
platform: centos
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
|
||||
verifier:
|
||||
name: inspec
|
||||
sudo: true
|
||||
inspec_tests:
|
||||
- https://github.com/dev-sec/tests-nginx-hardening
|
||||
- ../nginx-baseline
|
||||
#- https://github.com/dev-sec/nginx-baseline
|
||||
controls:
|
||||
- nginx-01
|
||||
- nginx-02
|
||||
- nginx-03
|
||||
- nginx-04
|
||||
- nginx-05
|
||||
- nginx-06
|
||||
- nginx-07
|
||||
- nginx-08
|
||||
- nginx-09
|
||||
- nginx-10
|
||||
- nginx-12
|
||||
- nginx-13
|
||||
- nginx-14
|
||||
- nginx-15
|
||||
- nginx-17
|
||||
|
||||
suites:
|
||||
- name: nginx-ansible_1.9
|
||||
provisioner:
|
||||
ansible_version: 1.9.4
|
||||
- name: nginx-ansible_latest
|
||||
- name: nginx
|
||||
|
|
|
@ -1,23 +1,72 @@
|
|||
---
|
||||
notifications:
|
||||
webhooks: https://galaxy.ansible.com/api/v1/notifications/
|
||||
language: python
|
||||
python: "2.7"
|
||||
services: docker
|
||||
|
||||
env:
|
||||
- ANSIBLE_VERSION=latest
|
||||
- ANSIBLE_VERSION=1.9.4
|
||||
- distro: centos6
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: centos7
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
version: latest
|
||||
|
||||
- distro: oracle6
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
# - distro: oracle7
|
||||
# init: /usr/lib/systemd/systemd
|
||||
# run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
# version: latest
|
||||
|
||||
- distro: ubuntu1404
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: ubuntu1604
|
||||
version: latest
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: ubuntu1804
|
||||
version: latest
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: debian8
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: debian9
|
||||
version: latest
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
# - distro: amazon
|
||||
# init: /lib/systemd/systemd
|
||||
# version: latest
|
||||
# run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq python-apt python-pycurl
|
||||
install:
|
||||
- if [ "$ANSIBLE_VERSION" = "latest" ]; then pip install ansible; else pip install ansible==$ANSIBLE_VERSION; fi
|
||||
- echo -e 'localhost ansible_connection=local' > spec/inventory
|
||||
- echo -e '[defaults]\nroles_path = ../\nhostfile = ./spec/inventory' > ansible.cfg
|
||||
# Pull container
|
||||
- 'docker pull rndmh3ro/docker-${distro}-ansible:${version}'
|
||||
|
||||
script:
|
||||
- ansible-galaxy install -r requirements.yml
|
||||
- ansible-playbook --syntax-check spec/travis.yml
|
||||
- ansible-playbook --sudo -v --diff spec/travis.yml
|
||||
- ansible-playbook --sudo -v --diff spec/travis.yml --extra-vars "nginx_remove_default_site=false"
|
||||
- container_id=$(mktemp)
|
||||
# Run container in detached state.
|
||||
- 'docker run --detach --volume="${PWD}":/etc/ansible/roles/ansible-nginx-hardening:ro ${run_opts} rndmh3ro/docker-${distro}-ansible:${version} "${init}" > "${container_id}"'
|
||||
|
||||
# Install ansible galaxy requirements
|
||||
- 'docker exec "$(cat ${container_id})" ansible-galaxy -c install -r /etc/ansible/roles/ansible-nginx-hardening/requirements.yml -p /etc/ansible/roles/'
|
||||
|
||||
# Test role.
|
||||
- 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-nginx-hardening/tests/test.yml -vv'
|
||||
|
||||
# Verify role
|
||||
#- 'inspec exec https://github.com/dev-sec/nginx-baseline/ -t docker://$(cat ${container_id}) --controls=nginx-01 nginx-02 nginx-03 nginx-04 nginx-05 nginx-06 nginx-07 nginx-08 nginx-09 nginx-10 nginx-12 nginx-13 nginx-14 nginx-15 nginx-17 --no-distinct-exit'
|
||||
- 'inspec exec https://github.com/dev-sec/nginx-baseline/ -t docker://$(cat ${container_id}) --controls=nginx-01 nginx-02 nginx-03 nginx-05 nginx-06 nginx-07 nginx-08 nginx-09 nginx-10 nginx-12 nginx-13 nginx-15 nginx-17 --no-distinct-exit'
|
||||
|
||||
notifications:
|
||||
webhooks: https://galaxy.ansible.com/api/v1/notifications/
|
||||
|
|
|
@ -1,5 +1,32 @@
|
|||
# Change Log
|
||||
|
||||
## [2.0.0](https://github.com/dev-sec/ansible-nginx-hardening/tree/2.0.0) (2018-09-08)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-nginx-hardening/compare/1.0.2...2.0.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Update readme to include baselines [\#10](https://github.com/dev-sec/ansible-nginx-hardening/issues/10)
|
||||
- Update testing, remove useless params, style update [\#18](https://github.com/dev-sec/ansible-nginx-hardening/pull/18) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Update README.md [\#14](https://github.com/dev-sec/ansible-nginx-hardening/pull/14) ([vishesh92](https://github.com/vishesh92))
|
||||
- Add comment filter to {{ansible\_managed}} string [\#12](https://github.com/dev-sec/ansible-nginx-hardening/pull/12) ([fazlearefin](https://github.com/fazlearefin))
|
||||
- use new Docker images [\#8](https://github.com/dev-sec/ansible-nginx-hardening/pull/8) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Running kitchen verify asks for 'roots' password [\#11](https://github.com/dev-sec/ansible-nginx-hardening/issues/11)
|
||||
- Fix duplicate ssl\_prefer\_server\_ciphers error [\#16](https://github.com/dev-sec/ansible-nginx-hardening/pull/16) ([oakey-b1](https://github.com/oakey-b1))
|
||||
|
||||
## [1.0.2](https://github.com/dev-sec/ansible-nginx-hardening/tree/1.0.2) (2016-10-24)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-nginx-hardening/compare/1.0.1...1.0.2)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Syntax Error while loading YAML in defaults/main.yml [\#6](https://github.com/dev-sec/ansible-nginx-hardening/issues/6)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- remove tabs. fix \#6 [\#7](https://github.com/dev-sec/ansible-nginx-hardening/pull/7) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
## [1.0.1](https://github.com/dev-sec/ansible-nginx-hardening/tree/1.0.1) (2016-09-23)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-nginx-hardening/compare/1.0.0...1.0.1)
|
||||
|
||||
|
@ -20,4 +47,4 @@
|
|||
## [1.0.0](https://github.com/dev-sec/ansible-nginx-hardening/tree/1.0.0) (2016-08-11)
|
||||
|
||||
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
|
@ -2,25 +2,6 @@
|
|||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
|
||||
gem 'rack', '< 2.0'
|
||||
gem 'ruby_dep', '< 1.4.0'
|
||||
gem 'listen', '< 3.0.0'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'rake'
|
||||
gem 'foodcritic', '~> 4.0'
|
||||
gem 'thor-foodcritic'
|
||||
gem 'coveralls', require: false
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'guard'
|
||||
gem 'guard-rspec'
|
||||
gem 'guard-kitchen'
|
||||
end
|
||||
|
||||
group :integration do
|
||||
gem 'test-kitchen', '~> 1.0'
|
||||
gem 'kitchen-ansible'
|
||||
|
@ -32,10 +13,10 @@ group :integration do
|
|||
gem 'kitchen-docker'
|
||||
end
|
||||
|
||||
group :openstack do
|
||||
gem 'kitchen-openstack'
|
||||
end
|
||||
|
||||
group :tools do
|
||||
gem 'github_changelog_generator', '~> 1'
|
||||
end
|
||||
|
||||
gem 'kitchen-dokken'
|
||||
|
||||
gem 'rb-readline'
|
||||
|
|
|
@ -6,17 +6,17 @@
|
|||
|
||||
## Description
|
||||
|
||||
This role provides secure nginx configuration.
|
||||
This role provides secure nginx configuration. It is intended to be compliant with the [DevSec Nginx Baseline](https://github.com/dev-sec/nginx-baseline).
|
||||
|
||||
It works with the following nginx-roles, including, but not limited to:
|
||||
* [geerlinggux.nginx](https://galaxy.ansible.com/geerlingguy/nginx/)
|
||||
* [geerlingguy.nginx](https://galaxy.ansible.com/geerlingguy/nginx/)
|
||||
* [jdauphant.nginx](https://galaxy.ansible.com/jdauphant/nginx/)
|
||||
* [franklinkim.nginx](https://galaxy.ansible.com/franklinkim/nginx/)
|
||||
|
||||
**NOTE: This role does not work with nginx 1.0.15 or older! Please use the latest version from the official nginx repositories!**
|
||||
## Requirements
|
||||
|
||||
* Ansible
|
||||
* Ansible >= 2.5
|
||||
|
||||
## Role Variables
|
||||
|
||||
|
@ -35,10 +35,10 @@ It works with the following nginx-roles, including, but not limited to:
|
|||
| [nginx_limit_conn_zone][] | `$binary_remote_addr zone=default:10m` | Sets parameters for a shared memory zone that will keep states for various keys. |
|
||||
| [nginx_limit_conn][] | `default 5` | Sets the shared memory zone and the maximum allowed number of connections for a given key value. |
|
||||
| [nginx_add_header][] | `[ "X-Frame-Options SAMEORIGIN", "X-Content-Type-Options nosniff", "X-XSS-Protection \"1; mode=block\"" ]` |Adds the specified field to a response header provided that the response code equals 200, 201, 204, 206, 301, 302, 303, 304, or 307. |
|
||||
| [nginx_ssl_protocols][] | `TLSv1 TLSv1.1 TLSv1.2` | Specifies the SSL protocol which should be used. |
|
||||
| [nginx_ssl_protocols][] | `TLSv1.2` | Specifies the SSL protocol which should be used. |
|
||||
| [nginx_ssl_ciphers][] | *see defaults.yml* | Specifies the TLS ciphers which should be used. |
|
||||
| [nginx_ssl_prefer_server_ciphers][] | `on` | Specifies that server ciphers should be preferred over client ciphers when using the TLS protocols. Set to false to disable it. |
|
||||
| [nginx_dh-size][] | `2048` | Specifies the length of DH parameters for EDH ciphers. |
|
||||
| [nginx_dh_size][] | `2048` | Specifies the length of DH parameters for EDH ciphers. |
|
||||
|
||||
## Example Playbook
|
||||
|
||||
|
@ -96,7 +96,7 @@ See [contributor guideline](CONTRIBUTING.md).
|
|||
|
||||
## License and Author
|
||||
|
||||
* Author:: Sebastian Gumprich <sebastian.gumprich@38.de>
|
||||
* Author:: Sebastian Gumprich
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -130,4 +130,4 @@ limitations under the License.
|
|||
[nginx_ssl_protocols]: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols
|
||||
[nginx_ssl_ciphers]: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers
|
||||
[nginx_ssl_prefer_server_ciphers]: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers
|
||||
[nginx_dh-size]: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam
|
||||
[nginx_dh_size]: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam
|
||||
|
|
14
ansible/roles/dev-sec.nginx-hardening/ansible.cfg
Normal file
14
ansible/roles/dev-sec.nginx-hardening/ansible.cfg
Normal file
|
@ -0,0 +1,14 @@
|
|||
# config file for ansible -- http://ansible.com/
|
||||
# ==============================================
|
||||
|
||||
# nearly all parameters can be overridden in ansible-playbook
|
||||
# or with command line flags. ansible will read ANSIBLE_CONFIG,
|
||||
# ansible.cfg in the current working directory, .ansible.cfg in
|
||||
# the home directory or /etc/ansible/ansible.cfg, whichever it
|
||||
# finds first
|
||||
|
||||
[defaults]
|
||||
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d by {uid} on {host}
|
||||
|
||||
role_path = /vagrant
|
||||
scp_if_ssh = True
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
- name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings
|
||||
hosts: localhost
|
||||
roles:
|
||||
- geerlingguy.nginx
|
||||
- ansible-nginx-hardening
|
|
@ -17,10 +17,13 @@ nginx_add_header: [
|
|||
# disable content-type sniffing
|
||||
"X-Content-Type-Options nosniff",
|
||||
# XSS filter
|
||||
"X-XSS-Protection \"1; mode=block\"" ]
|
||||
"X-XSS-Protection \"1; mode=block\"",
|
||||
"Strict-Transport-Security max-age=15768000",
|
||||
"Content-Security-Policy \"script-src 'self'; object-src 'self'\"" ]
|
||||
|
||||
nginx_ssl_protocols: "TLSv1 TLSv1.1 TLSv1.2"
|
||||
nginx_ssl_ciphers: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
|
||||
nginx_set_cookie_flag: "* HttpOnly secure"
|
||||
nginx_ssl_prefer_server_ciphers: "on"
|
||||
nginx_dh_param: "{{nginx_root_dir}}/dh{{nginx_dh_size}}.pem"
|
||||
nginx_ssl_protocols: "TLSv1.2"
|
||||
nginx_ssl_ciphers: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
|
||||
nginx_ssl_session_tickets: "off"
|
||||
nginx_dh_size: "2048"
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
- name: reload nginx
|
||||
service: name={{ nginx_service_name }} state=reloaded
|
||||
- name: restart nginx
|
||||
service:
|
||||
name: "nginx"
|
||||
state: restarted
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# This is a Vagrant block to allow proxy settings to be carried into Kitchen
|
||||
# You need this for all of yum/apt etc. to work!
|
||||
unless ENV['http_proxy'].empty? || Vagrant.has_plugin?("vagrant-proxyconf")
|
||||
raise "Missing required plugin 'vagrant-proxyconf' to support HTTP(S) proxies, run `vagrant plugin install vagrant-proxyconf`"
|
||||
end
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
config.proxy.http = "#{ENV['http_proxy']}"
|
||||
config.proxy.https = "#{ENV['https_proxy']}"
|
||||
config.proxy.no_proxy = "localhost,127.0.0.1"
|
||||
|
||||
# You may have vagrant-vbguest plugin installed to keep your images up to date
|
||||
# - but will probably have VBoxAddition build issues with the foreign boxes listed in .kitchen.vagrant.yml
|
||||
config.vbguest.auto_update = false
|
||||
end
|
|
@ -1 +1 @@
|
|||
{install_date: 'Sun Apr 23 07:59:34 2017', version: 1.0.2}
|
||||
{install_date: 'Mon Dec 17 12:48:14 2018', version: 2.1.0}
|
||||
|
|
|
@ -4,7 +4,7 @@ galaxy_info:
|
|||
description: 'This Ansible role provides secure nginx configurations. http://dev-sec.io/'
|
||||
company: Hardening Framework Team
|
||||
license: Apache License 2.0
|
||||
min_ansible_version: '1.9'
|
||||
min_ansible_version: '2.5'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
|
@ -15,10 +15,12 @@ galaxy_info:
|
|||
- precise
|
||||
- trusty
|
||||
- xenial
|
||||
- bionic
|
||||
- name: Debian
|
||||
versions:
|
||||
- wheezy
|
||||
- jessie
|
||||
- stretch
|
||||
galaxy_tags:
|
||||
- system
|
||||
- security
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
- src: nginxinc.nginx
|
||||
- src: geerlingguy.nginx
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
- hosts: localhost
|
||||
roles:
|
||||
- geerlingguy.nginx
|
||||
- ansible-nginx-hardening
|
|
@ -1,35 +1,80 @@
|
|||
---
|
||||
- name: add the OS specific variables
|
||||
include_vars: "{{ ansible_os_family }}.yml"
|
||||
|
||||
- name: config should not be worldwide read- or writeable
|
||||
file: path="/etc/nginx" mode="o-rw" owner="root" group="root" recurse=yes
|
||||
file:
|
||||
path: "/etc/nginx"
|
||||
mode: "o-rw"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
recurse: yes
|
||||
|
||||
- name: create additional configuration
|
||||
template: src="hardening.conf.j2" dest="{{nginx_config_conf_dir}}/90.hardening.conf" owner="root" group="root"
|
||||
notify: reload nginx
|
||||
template:
|
||||
src: "hardening.conf.j2"
|
||||
dest: "/etc/nginx/conf.d/90.hardening.conf"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
|
||||
- name: change configuration in main nginx.conf
|
||||
lineinfile: dest="/etc/nginx/nginx.conf" regexp="^\s*server_tokens" line="server_tokens {{nginx_server_tokens}};" insertafter="http {"
|
||||
notify: reload nginx
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*server_tokens'
|
||||
line: " server_tokens {{ nginx_server_tokens }};"
|
||||
insertafter: "http {"
|
||||
notify: restart nginx
|
||||
|
||||
- name: change ssl_protocols in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*ssl_protocols'
|
||||
line: " ssl_protocols {{ nginx_ssl_protocols }};"
|
||||
insertafter: "http {"
|
||||
notify: restart nginx
|
||||
|
||||
- name: change ssl_prefer_server_ciphers in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*ssl_prefer_server_ciphers'
|
||||
line: " ssl_prefer_server_ciphers {{ nginx_ssl_prefer_server_ciphers }};"
|
||||
insertafter: "http {"
|
||||
notify: restart nginx
|
||||
|
||||
- name: change client_max_body_size in main nginx.conf
|
||||
lineinfile: dest="/etc/nginx/nginx.conf" regexp="^\s*client_max_body_size" line="client_max_body_size {{nginx_client_max_body_size}};" insertafter="http {"
|
||||
notify: reload nginx
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*client_max_body_size'
|
||||
line: " client_max_body_size {{ nginx_client_max_body_size }};"
|
||||
insertafter: "http {"
|
||||
notify: restart nginx
|
||||
|
||||
- name: change client_body_buffer_size in main nginx.conf
|
||||
lineinfile: dest="/etc/nginx/nginx.conf" regexp="^\s*client_body_buffer_size" line="client_body_buffer_size {{nginx_client_body_buffer_size}};" insertafter="http {"
|
||||
notify: reload nginx
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*client_body_buffer_size'
|
||||
line: " client_body_buffer_size {{ nginx_client_body_buffer_size }};"
|
||||
insertafter: "http {"
|
||||
notify: restart nginx
|
||||
|
||||
- name: change keepalive_timeout in main nginx.conf
|
||||
lineinfile: dest="/etc/nginx/nginx.conf" regexp="^\s*keepalive_timeout" line="keepalive_timeout {{nginx_keepalive_timeout}};" insertafter="http {"
|
||||
notify: reload nginx
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*keepalive_timeout'
|
||||
line: " keepalive_timeout {{ nginx_keepalive_timeout }};"
|
||||
insertafter: "http {"
|
||||
notify: restart nginx
|
||||
|
||||
- name: remove default.conf
|
||||
file: path="{{nginx_default_conf}}" state=absent
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
when: nginx_remove_default_site
|
||||
notify: reload nginx
|
||||
notify: restart nginx
|
||||
loop:
|
||||
- "/etc/nginx/conf.d/default.conf"
|
||||
- "/etc/nginx/sites-enabled/default"
|
||||
|
||||
- name: generate dh group
|
||||
command: openssl dhparam -out {{nginx_dh_param}} {{nginx_dh_size}} creates={{nginx_dh_param}}
|
||||
notify: reload nginx
|
||||
command: "openssl dhparam -out /etc/nginx/dh{{ nginx_dh_size }}.pem {{ nginx_dh_size }}"
|
||||
args:
|
||||
creates: "/etc/nginx/dh{{ nginx_dh_size }}.pem"
|
||||
notify: restart nginx
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
# {{ansible_managed}}
|
||||
# {{ ansible_managed|comment }}
|
||||
# Additional configuration for Nginx.
|
||||
|
||||
client_header_buffer_size {{nginx_client_header_buffer_size}};
|
||||
large_client_header_buffers {{nginx_large_client_header_buffers}};
|
||||
client_body_timeout {{nginx_client_body_timeout}};
|
||||
client_header_timeout {{nginx_client_header_timeout}};
|
||||
send_timeout {{nginx_send_timeout}};
|
||||
limit_conn_zone {{nginx_limit_conn_zone}};
|
||||
limit_conn {{nginx_limit_conn}};
|
||||
ssl_protocols {{nginx_ssl_protocols}};
|
||||
ssl_ciphers {{nginx_ssl_ciphers}};
|
||||
ssl_dhparam {{nginx_dh_param}};
|
||||
ssl_prefer_server_ciphers {{nginx_ssl_prefer_server_ciphers}};
|
||||
client_header_buffer_size {{ nginx_client_header_buffer_size }};
|
||||
large_client_header_buffers {{ nginx_large_client_header_buffers }};
|
||||
client_body_timeout {{ nginx_client_body_timeout }};
|
||||
client_header_timeout {{ nginx_client_header_timeout }};
|
||||
send_timeout {{ nginx_send_timeout }};
|
||||
limit_conn_zone {{ nginx_limit_conn_zone }};
|
||||
limit_conn {{ nginx_limit_conn }};
|
||||
ssl_ciphers '{{ nginx_ssl_ciphers }}';
|
||||
ssl_session_tickets {{ nginx_ssl_session_tickets }};
|
||||
ssl_dhparam /etc/nginx/dh{{ nginx_dh_size }}.pem;
|
||||
{% for header in nginx_add_header %}
|
||||
add_header {{header}};
|
||||
add_header {{ header }};
|
||||
{% endfor %}
|
||||
|
|
25
ansible/roles/dev-sec.nginx-hardening/tests/test.yml
Normal file
25
ansible/roles/dev-sec.nginx-hardening/tests/test.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
- name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings
|
||||
hosts: localhost
|
||||
vars:
|
||||
- nginx_ppa_use: true
|
||||
- nginx_ppa_version: stable
|
||||
pre_tasks:
|
||||
- apt_repository:
|
||||
repo: "deb http://ftp.debian.org/debian jessie-backports main"
|
||||
state: present
|
||||
when: ansible_distribution == 'Debian' and ansible_distribution_major_version == '8'
|
||||
- set_fact:
|
||||
nginx_default_release: "jessie-backports"
|
||||
when: ansible_distribution == 'Debian' and ansible_distribution_major_version == '8'
|
||||
- package: name="{{item}}" state=installed
|
||||
with_items:
|
||||
- "systemd"
|
||||
ignore_errors: true
|
||||
- apt: name="{{item}}" state=installed update_cache=true
|
||||
with_items:
|
||||
- "systemd"
|
||||
ignore_errors: true
|
||||
roles:
|
||||
- geerlingguy.nginx
|
||||
- ansible-nginx-hardening
|
|
@ -1,4 +0,0 @@
|
|||
nginx_root_dir: '/etc/nginx'
|
||||
nginx_config_conf_dir: '/etc/nginx/conf.d'
|
||||
nginx_default_conf: '/etc/nginx/sites-enabled/default'
|
||||
nginx_service_name: 'nginx'
|
|
@ -1,4 +0,0 @@
|
|||
nginx_root_dir: '/etc/nginx'
|
||||
nginx_config_conf_dir: '/etc/nginx/conf.d'
|
||||
nginx_default_conf: '/etc/nginx/conf.d/default.conf'
|
||||
nginx_service_name: 'nginx'
|
|
@ -1,4 +0,0 @@
|
|||
nginx_root_dir: '/etc/nginx'
|
||||
nginx_config_conf_dir: '/etc/nginx/conf.d'
|
||||
nginx_default_conf: '/etc/nginx/conf.d/default.conf'
|
||||
nginx_service_name: 'nginx'
|
|
@ -0,0 +1 @@
|
|||
---
|
35
ansible/roles/dev-sec.os-hardening/.gitattributes
vendored
Normal file
35
ansible/roles/dev-sec.os-hardening/.gitattributes
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
# These files are text and should be normalized (Convert crlf => lf)
|
||||
*.php text eol=lf
|
||||
*.css text eol=lf
|
||||
*.js text eol=lf
|
||||
*.htm text eol=lf
|
||||
*.html text eol=lf
|
||||
*.xml text eol=lf
|
||||
*.txt text eol=lf
|
||||
*.ini text eol=lf
|
||||
*.inc text eol=lf
|
||||
.htaccess text eol=lf
|
||||
*.pp text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.yaml text eol=lf
|
||||
*.sh text eol=lf
|
||||
|
||||
# These files are binary and should be left untouched
|
||||
# (binary is a macro for -text -diff)
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.ico binary
|
||||
*.mov binary
|
||||
*.mp4 binary
|
||||
*.mp3 binary
|
||||
*.flv binary
|
||||
*.fla binary
|
||||
*.swf binary
|
||||
*.gz binary
|
||||
*.zip binary
|
||||
*.7z binary
|
||||
*.ttf binary
|
||||
*.rpm binary
|
||||
|
40
ansible/roles/dev-sec.os-hardening/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
40
ansible/roles/dev-sec.os-hardening/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Actual behavior**
|
||||
<!--- Paste verbatim command output between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
**Example Playbook**
|
||||
<!--- Paste an example playbook that can be used to reproduce the problem between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
|
||||
**OS / Environment**
|
||||
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->
|
||||
|
||||
**Ansible Version**
|
||||
<!--- Paste verbatim output from "ansible --version" between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
|
||||
**Role Version**
|
||||
<!--- Paste version of the role between quotes -->
|
||||
```paste below
|
||||
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
17
ansible/roles/dev-sec.os-hardening/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
ansible/roles/dev-sec.os-hardening/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -24,51 +24,39 @@ transport:
|
|||
max_ssh_sessions: 5
|
||||
|
||||
platforms:
|
||||
- name: ubuntu-12.04
|
||||
driver_config:
|
||||
box: opscode-ubuntu-12.04
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-12.04_chef-provisionerless.box
|
||||
- name: ubuntu-14.04
|
||||
- name: ubuntu14.04
|
||||
driver_config:
|
||||
box: opscode-ubuntu-14.04
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-14.04_chef-provisionerless.box
|
||||
- name: ubuntu-16.04
|
||||
- name: ubuntu16.04
|
||||
driver_config:
|
||||
box: opscode-ubuntu-16.04
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-16.04_chef-provisionerless.box
|
||||
- name: centos-6.4
|
||||
- name: ubuntu18.04
|
||||
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
|
||||
box: ubuntu/bionic64
|
||||
- name: centos6
|
||||
driver_config:
|
||||
box: opscode-centos-6.5
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
|
||||
- name: centos-6.8
|
||||
box: bento/centos-6.9
|
||||
- name: centos7
|
||||
driver_config:
|
||||
box: bento/centos-6.8
|
||||
- name: centos-7
|
||||
driver_config:
|
||||
box: bento/centos-7.2
|
||||
- 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
|
||||
box: bento/centos-7.3
|
||||
- name: oracle6
|
||||
driver_config:
|
||||
box: oracle-6.5
|
||||
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel65-64.box
|
||||
- name: oracle-7
|
||||
- name: oracle7
|
||||
driver_config:
|
||||
box: boxcutter/ol72
|
||||
- name: debian-7
|
||||
- name: debian7
|
||||
driver_config:
|
||||
box: debian-7
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8_chef-provisionerless.box
|
||||
- name: debian-8
|
||||
box: bento/debian-7.11
|
||||
- name: debian8
|
||||
driver_config:
|
||||
box: debian-8
|
||||
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-8.1_chef-provisionerless.box
|
||||
box: bento/debian-8.8
|
||||
- name: debian9
|
||||
driver_config:
|
||||
box: bento/debian-9.0
|
||||
|
||||
verifier:
|
||||
name: inspec
|
||||
|
|
|
@ -21,9 +21,7 @@ provisioner:
|
|||
roles_path: ../ansible-os-hardening/
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
playbook: default.yml
|
||||
ansible_extra_flags:
|
||||
- "--skip-tags=sysctl"
|
||||
playbook: tests/test.yml
|
||||
|
||||
platforms:
|
||||
- name: centos6-ansible-latest
|
||||
|
@ -34,6 +32,10 @@ platforms:
|
|||
driver:
|
||||
image: rndmh3ro/docker-centos7-ansible:latest
|
||||
platform: centos
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
- name: oracle6-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-oracle6-ansible:latest
|
||||
|
@ -41,11 +43,11 @@ platforms:
|
|||
- name: oracle7-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-oracle7-ansible:latest
|
||||
run_command: /sbin/init
|
||||
platform: centos
|
||||
- name: ubuntu1204-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-ubuntu1204-ansible:latest
|
||||
platform: ubuntu
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
- name: ubuntu1404-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-ubuntu1404-ansible:latest
|
||||
|
@ -54,6 +56,16 @@ platforms:
|
|||
driver:
|
||||
image: rndmh3ro/docker-ubuntu1604-ansible:latest
|
||||
platform: ubuntu
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- systemctl enable ssh.service
|
||||
- name: ubuntu1804-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-ubuntu1804-ansible:latest
|
||||
platform: ubuntu
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- systemctl enable ssh.service
|
||||
- name: debian7-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-debian7-ansible:latest
|
||||
|
@ -66,6 +78,18 @@ platforms:
|
|||
driver:
|
||||
image: rndmh3ro/docker-debian9-ansible:latest
|
||||
platform: debian
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- apt install -y systemd-sysv
|
||||
- systemctl enable ssh.service
|
||||
- name: amazon-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-amazon-ansible:latest
|
||||
platform: centos
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
|
||||
verifier:
|
||||
name: inspec
|
||||
|
|
|
@ -7,7 +7,7 @@ env:
|
|||
init: /sbin/init
|
||||
|
||||
- distro: centos7
|
||||
init: /usr/lib/systemd/systemd
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
version: latest
|
||||
|
||||
|
@ -15,23 +15,24 @@ env:
|
|||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: oracle7
|
||||
init: /usr/lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
# - distro: oracle7
|
||||
# init: /lib/systemd/systemd
|
||||
# run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
# version: latest
|
||||
|
||||
- distro: ubuntu1404
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: ubuntu1604
|
||||
version: latest
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: ubuntu1404
|
||||
- distro: ubuntu1804
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: ubuntu1204
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: debian7
|
||||
version: latest
|
||||
|
@ -40,12 +41,18 @@ env:
|
|||
- distro: debian8
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: debian9
|
||||
version: latest
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: amazon
|
||||
init: /lib/systemd/systemd
|
||||
version: latest
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
before_install:
|
||||
# Pull container
|
||||
- 'docker pull rndmh3ro/docker-${distro}-ansible:${version}'
|
||||
|
@ -55,11 +62,11 @@ script:
|
|||
# Run container in detached state.
|
||||
- 'docker run --detach --volume="${PWD}":/etc/ansible/roles/ansible-os-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-os-hardening/default.yml --skip-tags "sysctl"'
|
||||
# Test role.
|
||||
- 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-os-hardening/tests/test.yml --diff --skip-tags "sysctl"'
|
||||
|
||||
# Verify role
|
||||
- 'inspec exec https://github.com/dev-sec/linux-baseline/ -t docker://$(cat ${container_id}) --controls=os-01 os-02 os-03 os-04 os-05 os-06 os-07 package-01 package-02 package-03 package-04 package-05 package-06'
|
||||
# Verify role
|
||||
- 'inspec exec https://github.com/dev-sec/linux-baseline/ -t docker://$(cat ${container_id}) --controls=os-01 os-02 os-03 os-04 os-05 os-05b os-06 os-07 os-09 os-10 os-11 package-01 package-02 package-03 package-05 package-06 package-08 package-09 --no-distinct-exit'
|
||||
|
||||
notifications:
|
||||
webhooks: https://galaxy.ansible.com/api/v1/notifications/
|
||||
|
|
|
@ -1,5 +1,143 @@
|
|||
# Change Log
|
||||
|
||||
## [5.0.0](https://github.com/dev-sec/ansible-os-hardening/tree/5.0.0) (2018-09-02)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/4.3.0...5.0.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Warning about "include" for tasks for ansible-playbook 2.4.0 \(devel f0a5854e39\) [\#131](https://github.com/dev-sec/ansible-os-hardening/issues/131)
|
||||
- fix problems with efi and vfat [\#190](https://github.com/dev-sec/ansible-os-hardening/pull/190) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- added os\_hardening\_enabled flag [\#186](https://github.com/dev-sec/ansible-os-hardening/pull/186) ([jcheroske](https://github.com/jcheroske))
|
||||
- add amazon run opts to travis [\#183](https://github.com/dev-sec/ansible-os-hardening/pull/183) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- use package instead of yum and apt [\#180](https://github.com/dev-sec/ansible-os-hardening/pull/180) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- add oracle7 to travis [\#178](https://github.com/dev-sec/ansible-os-hardening/pull/178) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- fix wrong permissions passwdqc \#170 [\#176](https://github.com/dev-sec/ansible-os-hardening/pull/176) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- ipv4 forwarding comment is inconsistent with example [\#174](https://github.com/dev-sec/ansible-os-hardening/pull/174) ([carchrae](https://github.com/carchrae))
|
||||
- Rename pam\_passwdqd.j2 to pam\_passwdqc.j2 [\#172](https://github.com/dev-sec/ansible-os-hardening/pull/172) ([martinbydefault](https://github.com/martinbydefault))
|
||||
- Use package state 'present' since 'installed' is deprecated [\#168](https://github.com/dev-sec/ansible-os-hardening/pull/168) ([Normo](https://github.com/Normo))
|
||||
- Update syntax to Ansible 2.4 [\#161](https://github.com/dev-sec/ansible-os-hardening/pull/161) ([thomasjpfan](https://github.com/thomasjpfan))
|
||||
- add amazon linux testing [\#160](https://github.com/dev-sec/ansible-os-hardening/pull/160) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Add support for Amazon Linux [\#158](https://github.com/dev-sec/ansible-os-hardening/pull/158) ([woneill](https://github.com/woneill))
|
||||
- install and configure auditd - fix inspec package-08 [\#144](https://github.com/dev-sec/ansible-os-hardening/pull/144) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Remove deprecated include for static tasks and use instead import\_tasks fix \#131 [\#132](https://github.com/dev-sec/ansible-os-hardening/pull/132) ([HelioCampos](https://github.com/HelioCampos))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- minimize\_access: maximum recursion depth exceeded on Ansible 2.5 [\#171](https://github.com/dev-sec/ansible-os-hardening/issues/171)
|
||||
- wrong permissions passwdqc [\#170](https://github.com/dev-sec/ansible-os-hardening/issues/170)
|
||||
- Update deprecated `include` statements [\#166](https://github.com/dev-sec/ansible-os-hardening/issues/166)
|
||||
- Strongly recommend against disabling vfat by default [\#162](https://github.com/dev-sec/ansible-os-hardening/issues/162)
|
||||
- System completely unresponsive after role execution [\#145](https://github.com/dev-sec/ansible-os-hardening/issues/145)
|
||||
- do not install passwdqc on amazon linux [\#189](https://github.com/dev-sec/ansible-os-hardening/pull/189) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- add back run opts for debian 8 in travis [\#184](https://github.com/dev-sec/ansible-os-hardening/pull/184) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Fix core dump config file creation when core dumps are disabled [\#182](https://github.com/dev-sec/ansible-os-hardening/pull/182) ([Normo](https://github.com/Normo))
|
||||
- change minimize access method [\#181](https://github.com/dev-sec/ansible-os-hardening/pull/181) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
## [4.3.0](https://github.com/dev-sec/ansible-os-hardening/tree/4.3.0) (2018-01-03)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/4.3.1...4.3.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Update some RH settings in this role [\#155](https://github.com/dev-sec/ansible-os-hardening/issues/155)
|
||||
- Removal of core dump hardening configuration if core dumps are allowed [\#129](https://github.com/dev-sec/ansible-os-hardening/issues/129)
|
||||
- Don't create home for system accounts [\#156](https://github.com/dev-sec/ansible-os-hardening/pull/156) ([oakey-b1](https://github.com/oakey-b1))
|
||||
- Prevent disabling of filesystems via whitelist [\#153](https://github.com/dev-sec/ansible-os-hardening/pull/153) ([manuelprinz](https://github.com/manuelprinz))
|
||||
- Add kernel hardening settings from Ubuntu /etc/sysctl.d [\#150](https://github.com/dev-sec/ansible-os-hardening/pull/150) ([kravietz](https://github.com/kravietz))
|
||||
- Removal of core dump hardening configuration if core dumps are allowed [\#146](https://github.com/dev-sec/ansible-os-hardening/pull/146) ([martinbydefault](https://github.com/martinbydefault))
|
||||
- add missing sysctl parameter [\#143](https://github.com/dev-sec/ansible-os-hardening/pull/143) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- update readme [\#139](https://github.com/dev-sec/ansible-os-hardening/pull/139) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- bug in ufw.j2 template [\#151](https://github.com/dev-sec/ansible-os-hardening/issues/151)
|
||||
- replace single ticks with double ticks. fix \#151 [\#152](https://github.com/dev-sec/ansible-os-hardening/pull/152) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- fixed tag [\#149](https://github.com/dev-sec/ansible-os-hardening/pull/149) ([martinbydefault](https://github.com/martinbydefault))
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- ansible hardening fails on ubuntu 16.04 with msg": "ERROR! 'sysctl\_rhel\_config' is undefined [\#147](https://github.com/dev-sec/ansible-os-hardening/issues/147)
|
||||
- Enhancement: Test with TestInfra and Molecule [\#128](https://github.com/dev-sec/ansible-os-hardening/issues/128)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- move defaults to os-specific vars [\#157](https://github.com/dev-sec/ansible-os-hardening/pull/157) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
## [4.3.1](https://github.com/dev-sec/ansible-os-hardening/tree/4.3.1) (2017-09-13)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/4.2.0...4.3.1)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- os\_security\_kernel\_enable\_sysrq is not implemented [\#115](https://github.com/dev-sec/ansible-os-hardening/issues/115)
|
||||
|
||||
## [4.2.0](https://github.com/dev-sec/ansible-os-hardening/tree/4.2.0) (2017-08-08)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/4.1.0...4.2.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- add modprobe template, control os-10 [\#138](https://github.com/dev-sec/ansible-os-hardening/pull/138) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- new task for delete netrc files, control os-09 [\#137](https://github.com/dev-sec/ansible-os-hardening/pull/137) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- add passwd task, control os-03 [\#136](https://github.com/dev-sec/ansible-os-hardening/pull/136) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- remove prelink package, control package-09 [\#135](https://github.com/dev-sec/ansible-os-hardening/pull/135) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- style update [\#134](https://github.com/dev-sec/ansible-os-hardening/pull/134) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Fix ansible.cfg and use comment filter [\#130](https://github.com/dev-sec/ansible-os-hardening/pull/130) ([fazlearefin](https://github.com/fazlearefin))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Why is rsync removed? [\#141](https://github.com/dev-sec/ansible-os-hardening/issues/141)
|
||||
- playbook makes OS undetectable [\#124](https://github.com/dev-sec/ansible-os-hardening/issues/124)
|
||||
- Centos7/RHEL7: Exec shield is enabled by default and not manageable anymore by sysctl.conf [\#118](https://github.com/dev-sec/ansible-os-hardening/issues/118)
|
||||
- Remove rsync from package blacklist [\#142](https://github.com/dev-sec/ansible-os-hardening/pull/142) ([duk3luk3](https://github.com/duk3luk3))
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- remove execshield sysctl-parameter on rhel7 [\#119](https://github.com/dev-sec/ansible-os-hardening/pull/119) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
## [4.1.0](https://github.com/dev-sec/ansible-os-hardening/tree/4.1.0) (2017-06-27)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/4.0.0...4.1.0)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Change system accounts not on the user provided ignore-list items are not JSON serializable [\#125](https://github.com/dev-sec/ansible-os-hardening/issues/125)
|
||||
- Could not find gem 'ruby \(\>= 2.1.0\)' [\#116](https://github.com/dev-sec/ansible-os-hardening/issues/116)
|
||||
- The task sysctl fails when /etc/initramfs-tools is not present [\#111](https://github.com/dev-sec/ansible-os-hardening/issues/111)
|
||||
- Deprecation warning always\_run [\#103](https://github.com/dev-sec/ansible-os-hardening/issues/103)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Enhancement: Pin python dependencies for development and testing [\#127](https://github.com/dev-sec/ansible-os-hardening/issues/127)
|
||||
- Update readme to include baselines [\#122](https://github.com/dev-sec/ansible-os-hardening/issues/122)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Converts set to JSON-serializable list [\#126](https://github.com/dev-sec/ansible-os-hardening/pull/126) ([pestaa](https://github.com/pestaa))
|
||||
- add more sysctl settings, allow overwriting [\#120](https://github.com/dev-sec/ansible-os-hardening/pull/120) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
## [4.0.0](https://github.com/dev-sec/ansible-os-hardening/tree/4.0.0) (2017-03-14)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/3.2.0...4.0.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Description of the Ansible roles of dev-sec says "This Ansible playbook" [\#97](https://github.com/dev-sec/ansible-os-hardening/issues/97)
|
||||
- install initramfs-tools [\#114](https://github.com/dev-sec/ansible-os-hardening/pull/114) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- omit empty variables [\#106](https://github.com/dev-sec/ansible-os-hardening/pull/106) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- The role fails when conditionally included [\#105](https://github.com/dev-sec/ansible-os-hardening/issues/105)
|
||||
- omit empty variables [\#106](https://github.com/dev-sec/ansible-os-hardening/pull/106) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Error running on RHEL 7 due to syntax issues [\#112](https://github.com/dev-sec/ansible-os-hardening/issues/112)
|
||||
- disable password age [\#109](https://github.com/dev-sec/ansible-os-hardening/issues/109)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- change shadow owner in debian systems [\#117](https://github.com/dev-sec/ansible-os-hardening/pull/117) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Rhel7 [\#113](https://github.com/dev-sec/ansible-os-hardening/pull/113) ([tyrken](https://github.com/tyrken))
|
||||
- use new Docker images [\#110](https://github.com/dev-sec/ansible-os-hardening/pull/110) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Don’t refer to this role as "playbook" in the role description [\#104](https://github.com/dev-sec/ansible-os-hardening/pull/104) ([ypid](https://github.com/ypid))
|
||||
|
||||
## [3.2.0](https://github.com/dev-sec/ansible-os-hardening/tree/3.2.0) (2016-10-24)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/3.1.0...3.2.0)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## Description
|
||||
|
||||
This roles provides numerous security-related configurations, providing all-round base protection.
|
||||
This role provides numerous security-related configurations, providing all-round base protection. It is intended to be compliant with the [DevSec Linux Baseline](https://github.com/dev-sec/linux-baseline).
|
||||
|
||||
It configures:
|
||||
|
||||
|
@ -16,9 +16,10 @@ It configures:
|
|||
* Shadow password suite configuration
|
||||
* Configures system path permissions
|
||||
* Disable core dumps via soft limits
|
||||
* Restrict Root Logins to System Console
|
||||
* Restrict root Logins to System Console
|
||||
* Set SUIDs
|
||||
* Configures kernel parameters via sysctl
|
||||
* Install and configure auditd
|
||||
|
||||
It will not:
|
||||
|
||||
|
@ -27,7 +28,12 @@ It will not:
|
|||
|
||||
## Requirements
|
||||
|
||||
* Ansible 2.2.1
|
||||
* Ansible 2.5.0
|
||||
|
||||
## Warning
|
||||
|
||||
If you're using inspec to test your machines after applying this role, please make sure to add the connecting user to the `os_ignore_users`-variable.
|
||||
Otherwise inspec will fail. For more information, see [issue #124](https://github.com/dev-sec/ansible-os-hardening/issues/124).
|
||||
|
||||
## Variables
|
||||
|
||||
|
@ -46,7 +52,6 @@ It will not:
|
|||
| `os_auth_pam_passwdqc_options`| "min=disabled,disabled,16,12,8" | set to any option line (as a string) that you want to pass to passwdqc|
|
||||
| `os_security_users_allow`| [] | list of things, that a user is allowed to do. May contain `change_user`.
|
||||
| `os_security_kernel_enable_module_loading`| true | true if you want to allowed to change kernel modules once the system is running (eg `modprobe`, `rmmod`)|
|
||||
| `os_security_kernel_enable_sysrq`| false | sysrq is a 'magical' key combo you can hit which the kernel will respond to regardless of whatever else it is doing, unless it is completely locked up. |
|
||||
| `os_security_kernel_enable_core_dump`| false | kernel is crashing or otherwise misbehaving and a kernel core dump is created |
|
||||
| `os_security_suid_sgid_enforce`| true | true if you want to reduce SUID/SGID bits. There is already a list of items which are searched for configured, but you can also add your own|
|
||||
| `os_security_suid_sgid_blacklist`| [] | a list of paths which should have their SUID/SGID bits removed|
|
||||
|
@ -57,7 +62,8 @@ It will not:
|
|||
| `ufw_ipt_sysctl` | '' | by default it disables IPT_SYSCTL in /etc/default/ufw. If you want to overwrite /etc/sysctl.conf values using ufw - set it to your sysctl dictionary, for example `/etc/ufw/sysctl.conf`
|
||||
| `ufw_default_input_policy` | DROP | set default input policy of ufw to `DROP` |
|
||||
| `ufw_default_output_policy` | ACCEPT | set default output policy of ufw to `ACCEPT` |
|
||||
| `ufw_default_forward_policy` | DROP| set default forward policy of ufw to `DROP` |
|
||||
| `ufw_default_forward_policy` | DROP | set default forward policy of ufw to `DROP` |
|
||||
| `os_auditd_enabled` | true | Set to false to disable installing and configuring auditd. |
|
||||
|
||||
## Packages
|
||||
|
||||
|
@ -69,68 +75,44 @@ We remove the following packages:
|
|||
* ypserv ([NSA](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf), Chapter 3.2.4)
|
||||
* telnet-server ([NSA](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf), Chapter 3.2.2)
|
||||
* rsh-server ([NSA](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf), Chapter 3.2.3)
|
||||
* prelink ([open-scap](https://static.open-scap.org/ssg-guides/ssg-sl7-guide-ospp-rhel7-server.html#xccdf_org.ssgproject.content_rule_disable_prelink))
|
||||
|
||||
## Disabled filesystems
|
||||
|
||||
We disable the following filesystems, because they're most likely not used:
|
||||
|
||||
* "cramfs"
|
||||
* "freevxfs"
|
||||
* "jffs2"
|
||||
* "hfs"
|
||||
* "hfsplus"
|
||||
* "squashfs"
|
||||
* "udf"
|
||||
* "vfat" # only if uefi is not in use
|
||||
|
||||
To prevent some of the filesystems from being disabled, add them to the `os_filesystem_whitelist` variable.
|
||||
|
||||
## Example Playbook
|
||||
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- dev-sec.os-hardening
|
||||
|
||||
```yaml
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- dev-sec.os-hardening
|
||||
```
|
||||
|
||||
## Changing sysctl variables
|
||||
|
||||
If you want to overwrite sysctl-variables, you have to overwrite the *whole* dict, or else only the single overwritten will be actually used.
|
||||
So for example if you want to change the IPv4 traffic forwarding variable to `1`, you must pass the whole dict like this:
|
||||
If you want to override sysctl-variables, you can use the `sysctl_overwrite` variable (in older versions you had to override the whole `sysctl_dict`).
|
||||
So for example if you want to change the IPv4 traffic forwarding variable to `1`, do it like this:
|
||||
|
||||
```
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- dev-sec.os-hardening
|
||||
vars:
|
||||
sysctl_config:
|
||||
# Disable IPv4 traffic forwarding.
|
||||
net.ipv4.ip_forward: 1
|
||||
|
||||
# Disable IPv6 traffic forwarding.
|
||||
net.ipv6.conf.all.forwarding: 0
|
||||
|
||||
# ignore RAs on Ipv6.
|
||||
net.ipv6.conf.all.accept_ra: 0
|
||||
net.ipv6.conf.default.accept_ra: 0
|
||||
|
||||
# Enable RFC-recommended source validation feature.
|
||||
net.ipv4.conf.all.rp_filter: 1
|
||||
net.ipv4.conf.default.rp_filter: 1
|
||||
|
||||
# Reduce the surface on SMURF attacks.
|
||||
# Make sure to ignore ECHO broadcasts, which are only required in broad network analysis.
|
||||
net.ipv4.icmp_echo_ignore_broadcasts: 1
|
||||
|
||||
# There is no reason to accept bogus error responses from ICMP, so ignore them instead.
|
||||
net.ipv4.icmp_ignore_bogus_error_responses: 1
|
||||
|
||||
# Limit the amount of traffic the system uses for ICMP.
|
||||
net.ipv4.icmp_ratelimit: 100
|
||||
|
||||
# Adjust the ICMP ratelimit to include ping, dst unreachable,
|
||||
# source quench, ime exceed, param problem, timestamp reply, information reply
|
||||
net.ipv4.icmp_ratemask: 88089
|
||||
|
||||
# Disable IPv6
|
||||
net.ipv6.conf.all.disable_ipv6: 1
|
||||
|
||||
# Protect against wrapping sequence numbers at gigabit speeds
|
||||
net.ipv4.tcp_timestamps: 0
|
||||
|
||||
# Define restriction level for announcing the local source IP
|
||||
net.ipv4.conf.all.arp_ignore: 1
|
||||
|
||||
# Define mode for sending replies in response to
|
||||
# received ARP requests that resolve local target IP addresses
|
||||
net.ipv4.conf.all.arp_announce: 2
|
||||
|
||||
# RFC 1337 fix F1
|
||||
net.ipv4.tcp_rfc1337: 1
|
||||
```yaml
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- dev-sec.os-hardening
|
||||
vars:
|
||||
sysctl_overwrite:
|
||||
# Enable IPv4 traffic forwarding.
|
||||
net.ipv4.ip_forward: 1
|
||||
```
|
||||
|
||||
Alternatively you can change Ansible's [hash-behaviour](https://docs.ansible.com/ansible/intro_configuration.html#hash-behaviour) to `merge`, then you only have to overwrite the single hash you need to. But please be aware that changing the hash-behaviour changes it for all your playbooks and is not recommended by Ansible.
|
||||
|
@ -152,27 +134,27 @@ bundle install
|
|||
### Testing with Docker
|
||||
```
|
||||
# fast test on one machine
|
||||
bundle exec kitchen test default-ubuntu-1204
|
||||
bundle exec kitchen test default-ubuntu-1404
|
||||
|
||||
# test on all machines
|
||||
bundle exec kitchen test
|
||||
|
||||
# for development
|
||||
bundle exec kitchen create default-ubuntu-1204
|
||||
bundle exec kitchen converge default-ubuntu-1204
|
||||
bundle exec kitchen create default-ubuntu-1404
|
||||
bundle exec kitchen converge default-ubuntu-1404
|
||||
```
|
||||
|
||||
### Testing with Virtualbox
|
||||
```
|
||||
# fast test on one machine
|
||||
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test default-ubuntu-1204
|
||||
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test default-ubuntu-1404
|
||||
|
||||
# test on all machines
|
||||
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test
|
||||
|
||||
# for development
|
||||
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen create default-ubuntu-1204
|
||||
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen converge default-ubuntu-1204
|
||||
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen create default-ubuntu-1404
|
||||
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen converge default-ubuntu-1404
|
||||
```
|
||||
For more information see [test-kitchen](http://kitchen.ci/docs/getting-started)
|
||||
|
||||
|
@ -185,7 +167,7 @@ This role is mostly based on guides by:
|
|||
* [Arch Linux wiki, Sysctl hardening](https://wiki.archlinux.org/index.php/Sysctl)
|
||||
* [NSA: Guide to the Secure Configuration of Red Hat Enterprise Linux 5](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf)
|
||||
* [Ubuntu Security/Features](https://wiki.ubuntu.com/Security/Features)
|
||||
* [Deutsche Telekom, Group IT Security, Security Requirements (German)](http://www.telekom.com/static/-/155996/7/technische-sicherheitsanforderungen-si)
|
||||
* [Deutsche Telekom, Group IT Security, Security Requirements (German)](https://www.telekom.com/psa)
|
||||
|
||||
Thanks to all of you!
|
||||
## Contributing
|
||||
|
@ -194,7 +176,7 @@ See [contributor guideline](CONTRIBUTING.md).
|
|||
|
||||
## License and Author
|
||||
|
||||
* Author:: Sebastian Gumprich <sebastian.gumprich@38.de>
|
||||
* Author:: Sebastian Gumprich
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
# finds first
|
||||
|
||||
[defaults]
|
||||
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d by {uid} on {host}
|
||||
|
||||
ansible_managed = Ansible managed: {file} modified by {uid} on {host}
|
||||
# additional paths to search for roles in, colon separated
|
||||
roles_path = ../
|
||||
|
||||
[ssh_connection]
|
||||
scp_if_ssh = True
|
||||
|
|
|
@ -3,6 +3,15 @@
|
|||
hosts: localhost
|
||||
roles:
|
||||
- ansible-os-hardening
|
||||
pre_tasks:
|
||||
- name: Run the equivalent of "apt-get update" as a separate step
|
||||
apt:
|
||||
update_cache: yes
|
||||
when: ansible_os_family == 'Debian'
|
||||
- name: Install firefox to get Xorg
|
||||
package:
|
||||
name: firefox
|
||||
state: present
|
||||
vars:
|
||||
os_security_users_allow: change_user
|
||||
os_security_kernel_enable_core_dump: false
|
||||
|
@ -13,8 +22,53 @@
|
|||
os_auth_allow_homeless: true
|
||||
os_security_suid_sgid_blacklist: ['/bin/umount']
|
||||
os_security_suid_sgid_whitelist: ['/usr/bin/rlogin']
|
||||
os_filesystem_whitelist: ['vfat']
|
||||
sysctl_config:
|
||||
net.ipv4.ip_forward: 0
|
||||
net.ipv6.conf.all.forwarding: 0
|
||||
net.ipv6.conf.all.accept_ra: 0
|
||||
net.ipv6.conf.default.accept_ra: 0
|
||||
net.ipv4.conf.all.rp_filter: 1
|
||||
net.ipv4.conf.default.rp_filter: 1
|
||||
net.ipv4.icmp_echo_ignore_broadcasts: 1
|
||||
net.ipv4.icmp_ignore_bogus_error_responses: 1
|
||||
net.ipv4.icmp_ratelimit: 100
|
||||
net.ipv4.icmp_ratemask: 88089
|
||||
net.ipv6.conf.all.disable_ipv6: 1
|
||||
net.ipv4.conf.all.arp_ignore: 1
|
||||
net.ipv4.conf.all.arp_announce: 2
|
||||
net.ipv4.conf.all.shared_media: 1
|
||||
net.ipv4.conf.default.shared_media: 1
|
||||
net.ipv4.conf.all.accept_source_route: 0
|
||||
net.ipv4.conf.default.accept_source_route: 0
|
||||
net.ipv4.conf.default.accept_redirects: 0
|
||||
net.ipv4.conf.all.accept_redirects: 0
|
||||
net.ipv4.conf.all.secure_redirects: 0
|
||||
net.ipv4.conf.default.secure_redirects: 0
|
||||
net.ipv6.conf.default.accept_redirects: 0
|
||||
net.ipv6.conf.all.accept_redirects: 0
|
||||
net.ipv4.conf.all.send_redirects: 0
|
||||
net.ipv4.conf.default.send_redirects: 0
|
||||
net.ipv4.conf.all.log_martians: 1
|
||||
net.ipv6.conf.default.router_solicitations: 0
|
||||
net.ipv6.conf.default.accept_ra_rtr_pref: 0
|
||||
net.ipv6.conf.default.accept_ra_pinfo: 0
|
||||
net.ipv6.conf.default.accept_ra_defrtr: 0
|
||||
net.ipv6.conf.default.autoconf: 0
|
||||
net.ipv6.conf.default.dad_transmits: 0
|
||||
net.ipv6.conf.default.max_addresses: 1
|
||||
kernel.sysrq: 0
|
||||
fs.suid_dumpable: 0
|
||||
kernel.randomize_va_space: 2
|
||||
|
||||
|
||||
- name: wrapper playbook for kitchen testing "ansible-os-hardening"
|
||||
hosts: localhost
|
||||
pre_tasks:
|
||||
- name: Run the equivalent of "apt-get update" as a separate step
|
||||
apt:
|
||||
update_cache: yes
|
||||
when: ansible_os_family == 'Debian'
|
||||
roles:
|
||||
- ansible-os-hardening
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
os_desktop_enable: false
|
||||
os_env_extra_user_paths: []
|
||||
os_env_umask: '027'
|
||||
os_auth_pw_max_age: 60
|
||||
os_auth_pw_min_age: 7 # discourage password cycling
|
||||
os_auth_retries: 5
|
||||
|
@ -11,18 +10,12 @@ os_auth_pam_passwdqc_enable: true
|
|||
os_auth_pam_passwdqc_options: 'min=disabled,disabled,16,12,8' # used in RHEL6
|
||||
os_auth_pam_pwquality_options: 'try_first_pass retry=3 type=' # used in RHEL7
|
||||
os_auth_root_ttys: [console, tty1, tty2, tty3, tty4, tty5, tty6]
|
||||
os_auth_uid_min: 1000
|
||||
os_auth_gid_min: 1000
|
||||
os_auth_sys_uid_min: 100
|
||||
os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 100
|
||||
os_auth_sys_gid_max: 999
|
||||
|
||||
os_chfn_restrict: ''
|
||||
# may contain: change_user
|
||||
os_security_users_allow: []
|
||||
# specify system accounts those login should not be disabled and password not changed
|
||||
os_ignore_users: ['vagrant']
|
||||
os_ignore_users: ['vagrant', 'kitchen']
|
||||
os_security_kernel_enable_module_loading: true
|
||||
os_security_kernel_enable_core_dump: false
|
||||
os_security_suid_sgid_enforce: true
|
||||
|
@ -34,7 +27,7 @@ os_security_suid_sgid_remove_from_unknown: false
|
|||
|
||||
# remove packages with known issues
|
||||
os_security_packages_clean: true
|
||||
os_security_packages_list: ['xinetd','inetd','ypserv','telnet-server','rsh-server','rsync']
|
||||
os_security_packages_list: ['xinetd','inetd','ypserv','telnet-server','rsh-server', 'prelink']
|
||||
|
||||
# Allow interactive startup (rhel, centos)
|
||||
os_security_init_prompt: true
|
||||
|
@ -58,61 +51,202 @@ ufw_default_application_policy: 'SKIP'
|
|||
ufw_manage_builtins: 'no'
|
||||
ufw_ipt_modules: 'nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns'
|
||||
|
||||
# CAUTION
|
||||
# If you want to overwrite sysctl-variables,
|
||||
# you have to overwrite the *whole* dict, or else only the single overwritten will be actually used.
|
||||
|
||||
sysctl_config:
|
||||
# Disable IPv4 traffic forwarding.
|
||||
# Disable IPv4 traffic forwarding. | sysctl-01
|
||||
net.ipv4.ip_forward: 0
|
||||
|
||||
# Disable IPv6 traffic forwarding.
|
||||
# Disable IPv6 traffic forwarding. | sysctl-19
|
||||
net.ipv6.conf.all.forwarding: 0
|
||||
|
||||
# ignore RAs on Ipv6.
|
||||
# ignore RAs on Ipv6. | sysctl-25
|
||||
net.ipv6.conf.all.accept_ra: 0
|
||||
net.ipv6.conf.default.accept_ra: 0
|
||||
|
||||
# Enable RFC-recommended source validation feature.
|
||||
# Enable RFC-recommended source validation feature. | sysctl-02
|
||||
net.ipv4.conf.all.rp_filter: 1
|
||||
net.ipv4.conf.default.rp_filter: 1
|
||||
|
||||
# Reduce the surface on SMURF attacks.
|
||||
# Reduce the surface on SMURF attacks. | sysctl-04
|
||||
# Make sure to ignore ECHO broadcasts, which are only required in broad network analysis.
|
||||
net.ipv4.icmp_echo_ignore_broadcasts: 1
|
||||
|
||||
# There is no reason to accept bogus error responses from ICMP, so ignore them instead.
|
||||
# There is no reason to accept bogus error responses from ICMP, so ignore them instead. | sysctl-03
|
||||
net.ipv4.icmp_ignore_bogus_error_responses: 1
|
||||
|
||||
# Limit the amount of traffic the system uses for ICMP.
|
||||
# Limit the amount of traffic the system uses for ICMP. | sysctl-05
|
||||
net.ipv4.icmp_ratelimit: 100
|
||||
|
||||
# Adjust the ICMP ratelimit to include ping, dst unreachable,
|
||||
# source quench, ime exceed, param problem, timestamp reply, information reply
|
||||
# source quench, ime exceed, param problem, timestamp reply, information reply | sysctl-06
|
||||
net.ipv4.icmp_ratemask: 88089
|
||||
|
||||
# Disable IPv6
|
||||
# Disable IPv6 | sysctl-18
|
||||
net.ipv6.conf.all.disable_ipv6: 1
|
||||
|
||||
# Protect against wrapping sequence numbers at gigabit speeds
|
||||
# Protect against wrapping sequence numbers at gigabit speeds | sysctl-07
|
||||
net.ipv4.tcp_timestamps: 0
|
||||
|
||||
# Define restriction level for announcing the local source IP
|
||||
# Define restriction level for announcing the local source IP | sysctl-08
|
||||
net.ipv4.conf.all.arp_ignore: 1
|
||||
|
||||
# Define mode for sending replies in response to
|
||||
# received ARP requests that resolve local target IP addresses
|
||||
# received ARP requests that resolve local target IP addresses | sysctl-09
|
||||
net.ipv4.conf.all.arp_announce: 2
|
||||
|
||||
# RFC 1337 fix F1
|
||||
# RFC 1337 fix F1 | sysctl-10
|
||||
net.ipv4.tcp_rfc1337: 1
|
||||
|
||||
# CAUTION
|
||||
# If you want to overwrite sysctl-variables,
|
||||
# you have to overwrite the *whole* dict, or else only the single overwritten will be actually used.
|
||||
# Send(router) or accept(host) RFC1620 shared media redirects | sysctl-12
|
||||
net.ipv4.conf.all.shared_media: 1
|
||||
net.ipv4.conf.default.shared_media: 1
|
||||
|
||||
sysctl_rhel_config:
|
||||
# ExecShield protection against buffer overflows
|
||||
kernel.exec-shield: 1
|
||||
# Syncookies is used to prevent SYN-flooding attacks.
|
||||
net.ipv4.tcp_syncookies: 1
|
||||
# Accepting source route can lead to malicious networking behavior,
|
||||
# so disable it if not needed. | sysctl-13
|
||||
net.ipv4.conf.all.accept_source_route: 0
|
||||
net.ipv4.conf.default.accept_source_route: 0
|
||||
|
||||
# Accepting redirects can lead to malicious networking behavior, so disable
|
||||
# it if not needed. | sysctl-13 | sysctl-14 | sysctl-15 | sysctl-20
|
||||
net.ipv4.conf.default.accept_redirects: 0
|
||||
net.ipv4.conf.all.accept_redirects: 0
|
||||
net.ipv4.conf.all.secure_redirects: 0
|
||||
net.ipv4.conf.default.secure_redirects: 0
|
||||
net.ipv6.conf.default.accept_redirects: 0
|
||||
net.ipv6.conf.all.accept_redirects: 0
|
||||
|
||||
# For non-routers: don't send redirects, these settings are 0 | sysctl-16
|
||||
net.ipv4.conf.all.send_redirects: 0
|
||||
net.ipv4.conf.default.send_redirects: 0
|
||||
|
||||
# log martian packets | sysctl-17
|
||||
net.ipv4.conf.all.log_martians: 1
|
||||
net.ipv4.conf.default.log_martians: 1
|
||||
|
||||
# ipv6 config
|
||||
# Disable acceptance of IPv6 router solicitations messages | sysctl-21
|
||||
net.ipv6.conf.default.router_solicitations: 0
|
||||
|
||||
# Disable Accept Router Preference from router advertisement | sysctl-22
|
||||
net.ipv6.conf.default.accept_ra_rtr_pref: 0
|
||||
|
||||
# Disable learning Prefix Information from router advertisement | sysctl-23
|
||||
net.ipv6.conf.default.accept_ra_pinfo: 0
|
||||
|
||||
# Disable learning Hop limit from router advertisement | sysctl-24
|
||||
net.ipv6.conf.default.accept_ra_defrtr: 0
|
||||
|
||||
# Disable IPv6 autoconfiguration | sysctl-26
|
||||
net.ipv6.conf.default.autoconf: 0
|
||||
|
||||
# Disable neighbor solicitations to send out per address | sysctl-27
|
||||
net.ipv6.conf.default.dad_transmits: 0
|
||||
|
||||
# Assign one global unicast IPv6 addresses to each interface | sysctl-28
|
||||
net.ipv6.conf.default.max_addresses: 1
|
||||
|
||||
# This settings controls how the kernel behaves towards module changes at
|
||||
# runtime. Setting to 1 will disable module loading at runtime.
|
||||
# Setting it to 0 is actually never supported. | sysctl-29
|
||||
# kernel.modules_disabled: 1
|
||||
|
||||
# Magic Sysrq should be disabled, but can also be set to a safe value if so
|
||||
# desired for physical machines. It can allow a safe reboot if the system hangs
|
||||
# and is a 'cleaner' alternative to hitting the reset button. | sysctl-30
|
||||
# The following values are permitted:
|
||||
# * **0** - disable sysrq
|
||||
# * **1** - enable sysrq completely
|
||||
# * **>1** - bitmask of enabled sysrq functions:
|
||||
# * **2** - control of console logging level
|
||||
# * **4** - control of keyboard (SAK, unraw)
|
||||
# * **8** - debugging dumps of processes etc.
|
||||
# * **16** - sync command
|
||||
# * **32** - remount read-only
|
||||
# * **64** - signalling of processes (term, kill, oom-kill)
|
||||
# * **128** - reboot/poweroff
|
||||
# * **256** - nicing of all RT tasks
|
||||
kernel.sysrq: 0
|
||||
|
||||
# Prevent core dumps with SUID. These are usually only
|
||||
# needed by developers and may contain sensitive information. | sysctl-31
|
||||
fs.suid_dumpable: 0
|
||||
|
||||
# Virtual memory regions protection | sysctl-32
|
||||
kernel.randomize_va_space: 2
|
||||
|
||||
kernel.core_uses_pid: 1
|
||||
|
||||
# When an attacker is trying to exploit the local kernel, it is often
|
||||
# helpful to be able to examine where in memory the kernel, modules,
|
||||
# and data structures live. As such, kernel addresses should be treated
|
||||
# as sensitive information.
|
||||
#
|
||||
# Many files and interfaces contain these addresses (e.g. /proc/kallsyms,
|
||||
# /proc/modules, etc), and this setting can censor the addresses. A value
|
||||
# of "0" allows all users to see the kernel addresses. A value of "1"
|
||||
# limits visibility to the root user, and "2" blocks even the root user.
|
||||
kernel.kptr_restrict: 1
|
||||
|
||||
# The PTRACE system is used for debugging. With it, a single user process
|
||||
# can attach to any other dumpable process owned by the same user. In the
|
||||
# case of malicious software, it is possible to use PTRACE to access
|
||||
# credentials that exist in memory (re-using existing SSH connections,
|
||||
# extracting GPG agent information, etc).
|
||||
#
|
||||
# A PTRACE scope of "0" is the more permissive mode. A scope of "1" limits
|
||||
# PTRACE only to direct child processes (e.g. "gdb name-of-program" and
|
||||
# "strace -f name-of-program" work, but gdb's "attach" and "strace -fp $PID"
|
||||
# do not). The PTRACE scope is ignored when a user has CAP_SYS_PTRACE, so
|
||||
# "sudo strace -fp $PID" will work as before. For more details see:
|
||||
# https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace
|
||||
#
|
||||
# For applications launching crash handlers that need PTRACE, exceptions can
|
||||
# be registered by the debugee by declaring in the segfault handler
|
||||
# specifically which process will be using PTRACE on the debugee:
|
||||
# prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);
|
||||
#
|
||||
# In general, PTRACE is not needed for the average running Ubuntu system.
|
||||
# To that end, the default is to set the PTRACE scope to "1". This value
|
||||
# may not be appropriate for developers or servers with only admin accounts.
|
||||
# kernel.yama.ptrace_scope = 1
|
||||
kernel.yama.ptrace_scope: 1
|
||||
|
||||
# Protect the zero page of memory from userspace mmap to prevent kernel
|
||||
# NULL-dereference attacks against potential future kernel security
|
||||
# vulnerabilities. (Added in kernel 2.6.23.)
|
||||
#
|
||||
# While this default is built into the Ubuntu kernel, there is no way to
|
||||
# restore the kernel default if the value is changed during runtime; for
|
||||
# example via package removal (e.g. wine, dosemu). Therefore, this value
|
||||
# is reset to the secure default each time the sysctl values are loaded.
|
||||
vm.mmap_min_addr: 65536
|
||||
|
||||
# These settings eliminate an entire class of security vulnerability:
|
||||
# time-of-check-time-of-use cross-privilege attacks using guessable
|
||||
# filenames (generally seen as "/tmp file race" vulnerabilities).
|
||||
fs.protected_hardlinks: 1
|
||||
fs.protected_symlinks: 1
|
||||
|
||||
# Do not delete the following line or otherwise the playbook will fail
|
||||
# at task 'create a combined sysctl-dict if overwrites are defined'
|
||||
sysctl_overwrite:
|
||||
|
||||
# disable unused filesystems
|
||||
os_unused_filesystems:
|
||||
- "cramfs"
|
||||
- "freevxfs"
|
||||
- "jffs2"
|
||||
- "hfs"
|
||||
- "hfsplus"
|
||||
- "squashfs"
|
||||
- "udf"
|
||||
- "vfat"
|
||||
|
||||
# whitelist for used filesystems
|
||||
os_filesystem_whitelist: []
|
||||
|
||||
# Set to false to turn the role into a no-op. Useful when using
|
||||
# the Ansible role dependency mechanism.
|
||||
os_hardening_enabled: true
|
||||
|
||||
# Set to false to disable installing and configuring auditd.
|
||||
os_auditd_enabled: true
|
||||
|
|
|
@ -1 +1 @@
|
|||
{install_date: 'Sun Apr 23 07:59:14 2017', version: 4.0.0}
|
||||
{install_date: 'Mon Dec 17 12:48:33 2018', version: 5.1.0}
|
||||
|
|
|
@ -4,7 +4,7 @@ galaxy_info:
|
|||
description: 'This Ansible role provides numerous security-related configurations, providing all-round base protection.'
|
||||
company: Hardening Framework Team
|
||||
license: Apache License 2.0
|
||||
min_ansible_version: '2.2.1'
|
||||
min_ansible_version: '2.5'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
|
@ -15,10 +15,12 @@ galaxy_info:
|
|||
- precise
|
||||
- trusty
|
||||
- xenial
|
||||
- bionic
|
||||
- name: Debian
|
||||
versions:
|
||||
- wheezy
|
||||
- jessie
|
||||
- name: Amazon
|
||||
galaxy_tags:
|
||||
- system
|
||||
- security
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
---
|
||||
- name: remove packages
|
||||
apt: name='{{item}}' state=removed
|
||||
- name: remove deprecated or insecure packages | package-01 - package-09
|
||||
apt:
|
||||
name: '{{ item }}'
|
||||
state: 'absent'
|
||||
with_items:
|
||||
- "{{os_security_packages_list}}"
|
||||
when: os_security_packages_clean
|
||||
- '{{ os_security_packages_list }}'
|
||||
when: 'os_security_packages_clean'
|
||||
|
|
14
ansible/roles/dev-sec.os-hardening/tasks/auditd.yml
Normal file
14
ansible/roles/dev-sec.os-hardening/tasks/auditd.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
|
||||
- name: install auditd package | package-08
|
||||
package:
|
||||
name: '{{ auditd_package }}'
|
||||
state: 'present'
|
||||
|
||||
- name: configure auditd | package-08
|
||||
template:
|
||||
src: 'etc/audit/auditd.conf.j2'
|
||||
dest: '/etc/audit/auditd.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0640'
|
12
ansible/roles/dev-sec.os-hardening/tasks/find_files.yml
Normal file
12
ansible/roles/dev-sec.os-hardening/tasks/find_files.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
- name: find directories for minimizing access
|
||||
find:
|
||||
paths: '{{ outer_item }}'
|
||||
recurse: yes
|
||||
register: minimize_access_directories
|
||||
|
||||
- name: minimize access on found files
|
||||
file:
|
||||
path: '{{ item.path }}'
|
||||
mode: 'go-w'
|
||||
state: file
|
||||
with_items: '{{ minimize_access_directories.files }}'
|
60
ansible/roles/dev-sec.os-hardening/tasks/hardening.yml
Normal file
60
ansible/roles/dev-sec.os-hardening/tasks/hardening.yml
Normal file
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
- name: Set OS family dependent variables
|
||||
include_vars: '{{ ansible_os_family }}.yml'
|
||||
tags: always
|
||||
|
||||
- name: Set OS dependent variables
|
||||
include_vars: '{{ item }}'
|
||||
with_first_found:
|
||||
- files:
|
||||
- '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml'
|
||||
- '{{ ansible_distribution }}.yml'
|
||||
- '{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml'
|
||||
skip: true
|
||||
tags: always
|
||||
|
||||
- import_tasks: auditd.yml
|
||||
tags: auditd
|
||||
when: os_auditd_enabled
|
||||
|
||||
- import_tasks: limits.yml
|
||||
tags: limits
|
||||
|
||||
- import_tasks: login_defs.yml
|
||||
tags: login_defs
|
||||
|
||||
- import_tasks: minimize_access.yml
|
||||
tags: minimize_access
|
||||
|
||||
- import_tasks: pam.yml
|
||||
tags: pam
|
||||
|
||||
- import_tasks: modprobe.yml
|
||||
tags: modprobe
|
||||
|
||||
- import_tasks: profile.yml
|
||||
tags: profile
|
||||
|
||||
- import_tasks: securetty.yml
|
||||
tags: securetty
|
||||
|
||||
- import_tasks: suid_sgid.yml
|
||||
when: os_security_suid_sgid_enforce
|
||||
tags: suid_sgid
|
||||
|
||||
- import_tasks: sysctl.yml
|
||||
tags: sysctl
|
||||
|
||||
- import_tasks: user_accounts.yml
|
||||
tags: user_accounts
|
||||
|
||||
- import_tasks: rhosts.yml
|
||||
tags: rhosts
|
||||
|
||||
- import_tasks: yum.yml
|
||||
when: ansible_os_family == 'RedHat'
|
||||
tags: yum
|
||||
|
||||
- import_tasks: apt.yml
|
||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
||||
tags: apt
|
|
@ -1,9 +1,34 @@
|
|||
---
|
||||
|
||||
- name: create limits.d-directory if it does not exist
|
||||
file: path='/etc/security/limits.d' owner=root group=root mode=0755 state=directory
|
||||
when: os_security_kernel_enable_core_dump
|
||||
- block:
|
||||
- name: create limits.d-directory if it does not exist | sysctl-31a, sysctl-31b
|
||||
file:
|
||||
path: '/etc/security/limits.d'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0755'
|
||||
state: 'directory'
|
||||
|
||||
- name: create sane limits.conf
|
||||
template: src='limits.conf.j2' dest='/etc/security/limits.d/10.hardcore.conf' owner=root group=root mode=0440
|
||||
when: os_security_kernel_enable_core_dump
|
||||
- name: create aditional limits config file -> 10.hardcore.conf | sysctl-31a, sysctl-31b
|
||||
pam_limits:
|
||||
dest: '/etc/security/limits.d/10.hardcore.conf'
|
||||
domain: '*'
|
||||
limit_type: hard
|
||||
limit_item: core
|
||||
value: 0
|
||||
comment: Prevent core dumps for all users. These are usually only needed by developers and may contain sensitive information
|
||||
|
||||
- name: set 10.hardcore.conf perms to 0400 and root ownership
|
||||
file:
|
||||
path: /etc/security/limits.d/10.hardcore.conf
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0440'
|
||||
|
||||
when: 'not os_security_kernel_enable_core_dump'
|
||||
|
||||
- name: remove 10.hardcore.conf config file
|
||||
file:
|
||||
path: /etc/security/limits.d/10.hardcore.conf
|
||||
state: absent
|
||||
when: 'os_security_kernel_enable_core_dump'
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
---
|
||||
- name: create login.defs
|
||||
template: src='login.defs.j2' dest='/etc/login.defs' owner=root group=root mode=0444
|
||||
- name: create login.defs | os-05, os-05b
|
||||
template:
|
||||
src: 'etc/login.defs.j2'
|
||||
dest: '/etc/login.defs'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0444'
|
||||
|
||||
|
|
|
@ -1,43 +1,4 @@
|
|||
---
|
||||
- name: add the OS specific variables
|
||||
include_vars: "{{ ansible_os_family }}.yml"
|
||||
tags: always
|
||||
|
||||
- include: limits.yml
|
||||
tags: limits
|
||||
|
||||
- include: login_defs.yml
|
||||
tags: login_defs
|
||||
|
||||
- include: minimize_access.yml
|
||||
tags: minimize_acces
|
||||
|
||||
- include: pam.yml
|
||||
tags: pam
|
||||
|
||||
- include: profile.yml
|
||||
tags: profile
|
||||
|
||||
- include: securetty.yml
|
||||
tags: securetty
|
||||
|
||||
- include: suid_sgid.yml
|
||||
when: os_security_suid_sgid_enforce
|
||||
tags: suid_sgid
|
||||
|
||||
- include: sysctl.yml
|
||||
tags: sysctl
|
||||
|
||||
- include: user_accounts.yml
|
||||
tags: user_accounts
|
||||
|
||||
- include: rhosts.yml
|
||||
tags: rhosts
|
||||
|
||||
- include: yum.yml
|
||||
when: ansible_os_family == 'RedHat'
|
||||
tags: yum
|
||||
|
||||
- include: apt.yml
|
||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
||||
tags: apt
|
||||
- include_tasks: hardening.yml
|
||||
when: os_hardening_enabled
|
||||
|
|
|
@ -1,26 +1,35 @@
|
|||
---
|
||||
# Using a two-pass approach for checking directories in order to support symlinks.
|
||||
- name: find directories for minimizing access
|
||||
stat:
|
||||
path: "{{ item }}"
|
||||
register: minimize_access_directories
|
||||
with_items:
|
||||
- include_tasks: find_files.yml
|
||||
loop_control:
|
||||
loop_var: outer_item
|
||||
loop:
|
||||
- '/usr/local/sbin'
|
||||
- '/usr/local/bin'
|
||||
- '/usr/sbin'
|
||||
- '/usr/bin'
|
||||
- '/sbin'
|
||||
- '/bin'
|
||||
- '{{os_env_extra_user_paths}}'
|
||||
- '{{ os_env_extra_user_paths }}'
|
||||
|
||||
- name: minimize access
|
||||
file: path='{{item.stat.path}}' mode='go-w' recurse=yes
|
||||
when: item.stat.isdir
|
||||
with_items: "{{ minimize_access_directories.results }}"
|
||||
- name: change shadow ownership to root and mode to 0600 | os-02
|
||||
file:
|
||||
dest: '/etc/shadow'
|
||||
owner: '{{ os_shadow_perms.owner }}'
|
||||
group: '{{ os_shadow_perms.group }}'
|
||||
mode: '{{ os_shadow_perms.mode }}'
|
||||
|
||||
- name: change shadow ownership to root and mode to 0600 | DTAG SEC Req 3.21-7
|
||||
file: dest='/etc/shadow' owner={{ os_shadow_perms.owner }} group={{ os_shadow_perms.group }} mode={{ os_shadow_perms.mode }}
|
||||
- name: change passwd ownership to root and mode to 0644 | os-03
|
||||
file:
|
||||
dest: '/etc/passwd'
|
||||
owner: '{{ os_passwd_perms.owner }}'
|
||||
group: '{{ os_passwd_perms.group }}'
|
||||
mode: '{{ os_passwd_perms.mode }}'
|
||||
|
||||
- name: change su-binary to only be accessible to user and group root
|
||||
file: dest='/bin/su' owner=root group=root mode=0750
|
||||
when: os_security_users_allow != None
|
||||
file:
|
||||
dest: '/bin/su'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0750'
|
||||
when: '"change_user" not in os_security_users_allow'
|
||||
|
|
24
ansible/roles/dev-sec.os-hardening/tasks/modprobe.yml
Normal file
24
ansible/roles/dev-sec.os-hardening/tasks/modprobe.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
- name: install modprobe to disable filesystems | os-10
|
||||
package:
|
||||
name: '{{modprobe_package}}'
|
||||
state: 'present'
|
||||
|
||||
- name: check if efi is installed
|
||||
stat:
|
||||
path: "/sys/firmware/efi"
|
||||
register: efi_installed
|
||||
|
||||
- name: remove vfat from fs-list if efi is used
|
||||
set_fact:
|
||||
os_unused_filesystems: "{{ os_unused_filesystems | difference('vfat') }}"
|
||||
when: efi_installed.stat.isdir is defined and efi_installed.stat.isdir
|
||||
|
||||
- name: disable unused filesystems | os-10
|
||||
template:
|
||||
src: 'etc/modprobe.d/modprobe.j2'
|
||||
dest: '/etc/modprobe.d/dev-sec.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0640'
|
||||
|
|
@ -6,56 +6,94 @@
|
|||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: remove pam ccreds on Debian systems
|
||||
apt: name='{{os_packages_pam_ccreds}}' state=absent
|
||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
||||
|
||||
- name: remove pam ccreds on Redhat systems
|
||||
yum: name='{{os_packages_pam_ccreds}}' state=absent
|
||||
when: ansible_os_family == 'RedHat'
|
||||
# the reason for this is so a user cannot connect to a server,
|
||||
# that isn't connected to an LDAP server anymore.
|
||||
# normally caching credentials shouldn't be necessary for most machines.
|
||||
# removing it provides some more security while not removing usability.
|
||||
- name: remove pam ccreds to disable password caching
|
||||
package:
|
||||
name: '{{ os_packages_pam_ccreds }}'
|
||||
state: 'absent'
|
||||
|
||||
- name: remove pam_cracklib, because it does not play nice with passwdqc
|
||||
apt: name='{{os_packages_pam_cracklib}}' state=absent
|
||||
apt:
|
||||
name: '{{ os_packages_pam_cracklib }}'
|
||||
state: 'absent'
|
||||
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: install the package for strong password checking
|
||||
apt: name='{{os_packages_pam_passwdqc}}' state='installed' update_cache='yes'
|
||||
apt:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'present'
|
||||
update_cache: 'yes'
|
||||
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: configure passwdqc
|
||||
template: src='pam_passwdqd.j2' mode=0640 owner=root group=root dest='{{passwdqc_path}}'
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_passwdqd.j2'
|
||||
dest: '{{ passwdqc_path }}'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: remove passwdqc
|
||||
apt: name='{{os_packages_pam_passwdqc}}' state='absent'
|
||||
apt:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'absent'
|
||||
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and not os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: install tally2
|
||||
apt: name='libpam-modules' state='installed'
|
||||
apt:
|
||||
name: 'libpam-modules'
|
||||
state: 'present'
|
||||
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and not os_auth_pam_passwdqc_enable and os_auth_retries > 0
|
||||
|
||||
- name: configure tally2
|
||||
template: src='pam_tally2.j2' dest='{{tally2_path}}' mode=0640 owner=root group=root
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_tally2.j2'
|
||||
dest: '{{ tally2_path }}'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and not os_auth_pam_passwdqc_enable and os_auth_retries > 0
|
||||
|
||||
- name: delete tally2 when retries is 0
|
||||
file: path='{{tally2_path}}' state=absent
|
||||
file:
|
||||
path: '{{ tally2_path }}'
|
||||
state: 'absent'
|
||||
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and not os_auth_pam_passwdqc_enable and os_auth_retries == 0
|
||||
|
||||
- name: remove pam_cracklib, because it does not play nice with passwdqc
|
||||
yum: name='{{os_packages_pam_cracklib}}' state='absent'
|
||||
when: (ansible_os_family == 'RedHat' and ansible_distribution_version < '7') and os_auth_pam_passwdqc_enable
|
||||
yum:
|
||||
name: '{{ os_packages_pam_cracklib }}'
|
||||
state: 'absent'
|
||||
when: (ansible_os_family == 'RedHat' and ansible_distribution_version < '7' and not ansible_distribution == 'Amazon') and os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: install the package for strong password checking
|
||||
yum: name='{{os_packages_pam_passwdqc}}' state='installed'
|
||||
when: (ansible_os_family == 'RedHat' and ansible_distribution_version < '7') and os_auth_pam_passwdqc_enable
|
||||
yum:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'present'
|
||||
when: (ansible_os_family == 'RedHat' and ansible_distribution_version < '7' and not ansible_distribution == 'Amazon') and os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: remove passwdqc
|
||||
yum: name='{{os_packages_pam_passwdqc}}' state='absent'
|
||||
yum:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'absent'
|
||||
when: ansible_os_family == 'RedHat' and not os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: configure passwdqc and tally via central system-auth confic
|
||||
template: src='rhel_system_auth.j2' dest='/etc/pam.d/system-auth-ac' mode=0640 owner=root group=root
|
||||
template:
|
||||
src: 'etc/pam.d/rhel_system_auth.j2'
|
||||
dest: '/etc/pam.d/system-auth-ac'
|
||||
mode: '0640'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
|
||||
- name: NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512
|
||||
template: src='rhel_libuser.conf.j2' dest='/etc/libuser.conf' mode=0640 owner=root group=root
|
||||
template:
|
||||
src: 'etc/rhel_libuser.conf.j2'
|
||||
dest: '/etc/libuser.conf'
|
||||
mode: '0640'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
---
|
||||
- name: create profile.conf
|
||||
template: src='profile.conf.j2' dest='/etc/profile.d/pinerolo_profile.sh' owner=root group=root mode=0750
|
||||
- name: add pinerolo_profile.sh to profile.d
|
||||
template:
|
||||
src: 'etc/profile.d/profile.conf.j2'
|
||||
dest: '/etc/profile.d/pinerolo_profile.sh'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0750'
|
||||
when: not os_security_kernel_enable_core_dump
|
||||
|
||||
- name: remove pinerolo_profile.sh from profile.d
|
||||
file:
|
||||
path: /etc/profile.d/pinerolo_profile.sh
|
||||
state: absent
|
||||
when: os_security_kernel_enable_core_dump
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
---
|
||||
- name: Get user accounts | DTAG SEC Req 3.21-4
|
||||
- name: Get user accounts | os-09
|
||||
command: "awk -F: '{print $1}' /etc/passwd"
|
||||
changed_when: False
|
||||
check_mode: no
|
||||
check_mode: False
|
||||
register: users
|
||||
|
||||
- name: delete rhosts-files from system | DTAG SEC Req 3.21-4
|
||||
file: dest='~{{ item }}/.rhosts' state=absent
|
||||
with_items: '{{ users.stdout_lines | default(omit) }}'
|
||||
- name: delete rhosts-files from system | os-09
|
||||
file:
|
||||
dest: '~{{ item }}/.rhosts'
|
||||
state: 'absent'
|
||||
with_flattened: '{{ users.stdout_lines | default([]) }}'
|
||||
|
||||
- name: delete hosts.equiv from system | DTAG SEC Req 3.21-4
|
||||
file: dest='/etc/hosts.equiv' state=absent
|
||||
- name: delete hosts.equiv from system | os-01
|
||||
file:
|
||||
dest: '/etc/hosts.equiv'
|
||||
state: 'absent'
|
||||
|
||||
- name: delete .netrc-files from system | os-09
|
||||
file:
|
||||
dest: '~{{ item }}/.netrc'
|
||||
state: 'absent'
|
||||
with_flattened: '{{ users.stdout_lines | default([]) }}'
|
|
@ -1,3 +1,8 @@
|
|||
---
|
||||
- name: create securetty
|
||||
template: src='securetty.j2' dest='/etc/securetty' owner=root group=root mode=0400
|
||||
template:
|
||||
src: 'etc/securetty.j2'
|
||||
dest: '/etc/securetty'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0400'
|
||||
|
|
|
@ -1,24 +1,32 @@
|
|||
---
|
||||
- name: remove suid/sgid bit from binaries in blacklist
|
||||
file: path='{{item}}' mode='a-s' state=file follow=yes
|
||||
- name: remove suid/sgid bit from binaries in blacklist | os-06
|
||||
file:
|
||||
path: '{{ item }}'
|
||||
mode: 'a-s'
|
||||
state: 'file'
|
||||
follow: 'yes'
|
||||
failed_when: false
|
||||
with_items:
|
||||
with_flattened:
|
||||
- '{{ os_security_suid_sgid_system_blacklist }}'
|
||||
- '{{ os_security_suid_sgid_blacklist }}'
|
||||
|
||||
- name: find binaries with suid/sgid set
|
||||
- name: find binaries with suid/sgid set | os-06
|
||||
shell: find / -xdev \( -perm -4000 -o -perm -2000 \) -type f ! -path '/proc/*' -print 2>/dev/null
|
||||
register: sbit_binaries
|
||||
when: os_security_suid_sgid_remove_from_unknown
|
||||
changed_when: False
|
||||
|
||||
- name: gather files from which to remove suids/sgids and remove system white-listed files
|
||||
- name: gather files from which to remove suids/sgids and remove system white-listed files | os-06
|
||||
set_fact:
|
||||
suid: '{{ sbit_binaries.stdout_lines | difference(os_security_suid_sgid_system_whitelist) }}'
|
||||
when: os_security_suid_sgid_remove_from_unknown
|
||||
|
||||
- name: remove suid/sgid bit from all binaries except in system and user whitelist
|
||||
file: path='{{item}}' mode='a-s' state=file follow=yes
|
||||
with_items:
|
||||
- '{{ suid | default(omit) | difference(os_security_suid_sgid_whitelist) }}'
|
||||
- name: remove suid/sgid bit from all binaries except in system and user whitelist | os-06
|
||||
file:
|
||||
path: '{{ item }}'
|
||||
mode: 'a-s'
|
||||
state: 'file'
|
||||
follow: 'yes'
|
||||
with_flattened:
|
||||
- '{{ suid | default([]) | difference(os_security_suid_sgid_whitelist) }}'
|
||||
when: os_security_suid_sgid_remove_from_unknown
|
||||
|
|
|
@ -1,17 +1,34 @@
|
|||
---
|
||||
- name: protect sysctl.conf
|
||||
file: path='/etc/sysctl.conf' owner=root group=root mode=0440
|
||||
file:
|
||||
path: '/etc/sysctl.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0440'
|
||||
|
||||
- name: NSA 2.2.4.1 Set Daemon umask, do config for rhel-family
|
||||
template: src='rhel_sysconfig_init.j2' dest='/etc/sysconfig/init' owner=root group=root mode=0544
|
||||
when: ansible_distribution == 'RedHat' or ansible_distribution == 'Fedora' or ansible_distribution == 'CentOS'
|
||||
- name: set Daemon umask, do config for rhel-family | NSA 2.2.4.1
|
||||
template:
|
||||
src: 'etc/sysconfig/rhel_sysconfig_init.j2'
|
||||
dest: '/etc/sysconfig/init'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0544'
|
||||
when: ansible_distribution == 'RedHat' or ansible_distribution == 'Fedora' or ansible_distribution == 'CentOS' or ansible_distribution == 'Amazon'
|
||||
|
||||
- name: install initramfs-tools
|
||||
apt: name='initramfs-tools' state=installed update_cache=true
|
||||
apt:
|
||||
name: 'initramfs-tools'
|
||||
state: 'present'
|
||||
update_cache: true
|
||||
when: ansible_os_family == 'Debian' and os_security_kernel_enable_module_loading
|
||||
|
||||
- name: rebuild initramfs with starting pack of modules, if module loading at runtime is disabled
|
||||
template: src='modules.j2' dest='/etc/initramfs-tools/modules' owner=root group=root mode=0440
|
||||
template:
|
||||
src: 'etc/initramfs-tools/modules.j2'
|
||||
dest: '/etc/initramfs-tools/modules'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0440'
|
||||
when: ansible_os_family == 'Debian' and os_security_kernel_enable_module_loading
|
||||
register: initramfs
|
||||
|
||||
|
@ -19,6 +36,11 @@
|
|||
command: 'update-initramfs -u'
|
||||
when: initramfs.changed
|
||||
|
||||
- name: create a combined sysctl-dict if overwrites are defined
|
||||
set_fact:
|
||||
sysctl_config: '{{ sysctl_config | combine(sysctl_overwrite) }}'
|
||||
when: sysctl_overwrite | default()
|
||||
|
||||
- name: Change various sysctl-settings, look at the sysctl-vars file for documentation
|
||||
sysctl:
|
||||
name: '{{ item.key }}'
|
||||
|
@ -29,7 +51,7 @@
|
|||
ignoreerrors: yes
|
||||
with_dict: '{{ sysctl_config }}'
|
||||
|
||||
- name: Change various sysctl-settings on rhel-hosts, look at the sysctl-vars file for documentation
|
||||
- name: Change various sysctl-settings on rhel6-hosts or older, look at the sysctl-vars file for documentation
|
||||
sysctl:
|
||||
name: '{{ item.key }}'
|
||||
value: '{{ item.value }}'
|
||||
|
@ -37,9 +59,11 @@
|
|||
reload: yes
|
||||
ignoreerrors: yes
|
||||
with_dict: '{{ sysctl_rhel_config }}'
|
||||
when: ansible_distribution == 'RedHat' or ansible_distribution == 'Fedora' or ansible_distribution == 'CentOS'
|
||||
when: ((ansible_distribution == 'RedHat' or ansible_distribution == 'Fedora' or ansible_distribution == 'CentOS') and ansible_distribution_major_version < '7') or ansible_distribution == 'Amazon'
|
||||
|
||||
- name: Apply ufw defaults
|
||||
template: src="ufw.j2" dest=/etc/default/ufw
|
||||
template:
|
||||
src: 'etc/default/ufw.j2'
|
||||
dest: '/etc/default/ufw'
|
||||
when: ufw_manage_defaults and (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu')
|
||||
tags: ufw
|
||||
|
|
|
@ -1,35 +1,45 @@
|
|||
---
|
||||
|
||||
- name: get UID_MIN from login.defs
|
||||
shell: awk '/^\s*UID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs removes=/etc/login.defs
|
||||
shell: awk '/^\s*UID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs
|
||||
args:
|
||||
removes: /etc/login.defs
|
||||
register: uid_min
|
||||
check_mode: no
|
||||
check_mode: False
|
||||
changed_when: False
|
||||
|
||||
- name: calculate UID_MAX from UID_MIN by substracting 1
|
||||
set_fact: uid_max='{{ uid_min.stdout | int - 1 }}'
|
||||
set_fact:
|
||||
uid_max: '{{ uid_min.stdout | int - 1 }}'
|
||||
when: uid_min is defined
|
||||
|
||||
- name: set UID_MAX on Debian-systems if no login.defs exist
|
||||
set_fact: uid_max='999'
|
||||
set_fact:
|
||||
uid_max: '999'
|
||||
when: ansible_os_family == 'Debian' and not uid_min
|
||||
|
||||
- name: set UID_MAX on other systems if no login.defs exist
|
||||
set_fact: uid_max='499'
|
||||
set_fact:
|
||||
uid_max: '499'
|
||||
when: not uid_min
|
||||
|
||||
- name: get all system accounts
|
||||
command: awk -F'':'' '{ if ( $3 <= {{uid_max|quote}} ) print $1}' /etc/passwd removes=/etc/passwd
|
||||
command: awk -F'':'' '{ if ( $3 <= {{ uid_max|quote }} ) print $1}' /etc/passwd
|
||||
args:
|
||||
removes: /etc/passwd
|
||||
changed_when: False
|
||||
check_mode: no
|
||||
check_mode: False
|
||||
register: sys_accs
|
||||
|
||||
- name: remove always ignored system accounts from list
|
||||
set_fact:
|
||||
sys_accs_cond: '{{sys_accs.stdout_lines | difference(os_always_ignore_users) }}'
|
||||
check_mode: no
|
||||
sys_accs_cond: '{{ sys_accs.stdout_lines | difference(os_always_ignore_users) }}'
|
||||
check_mode: False
|
||||
|
||||
- name: change system accounts not on the user provided ignore-list
|
||||
user: name='{{item}}' shell='{{os_nologin_shell_path}}' password='*'
|
||||
with_items:
|
||||
- '{{sys_accs_cond | default(omit) | difference(os_ignore_users) }}'
|
||||
user:
|
||||
name: '{{ item }}'
|
||||
shell: '{{ os_nologin_shell_path }}'
|
||||
password: '*'
|
||||
createhome: False
|
||||
with_flattened:
|
||||
- '{{ sys_accs_cond | default([]) | difference(os_ignore_users) | list }}'
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
---
|
||||
- name: remove unused repositories
|
||||
file: name='/etc/yum.repos.d/{{item}}.repo' state=absent
|
||||
file:
|
||||
name: '/etc/yum.repos.d/{{ item }}.repo'
|
||||
state: 'absent'
|
||||
with_items:
|
||||
- 'CentOS-Debuginfo'
|
||||
- 'CentOS-Media'
|
||||
|
@ -13,24 +15,33 @@
|
|||
register: yum_repos
|
||||
|
||||
- name: check if rhnplugin.conf exists
|
||||
stat: path='/etc/yum/pluginconf.d/rhnplugin.conf'
|
||||
stat:
|
||||
path: '/etc/yum/pluginconf.d/rhnplugin.conf'
|
||||
register: rhnplugin_file
|
||||
|
||||
# for the "default([])" see here:
|
||||
# for the 'default([])' see here:
|
||||
# https://github.com/dev-sec/ansible-os-hardening/issues/99 and
|
||||
# https://stackoverflow.com/questions/37067827/ansible-deprecation-warning-for-undefined-variable-despite-when-clause
|
||||
- name: activate gpg-check for yum-repos
|
||||
replace: dest='{{item}}' regexp='^\s*gpgcheck=0' replace='gpgcheck=1'
|
||||
with_items:
|
||||
replace:
|
||||
dest: '{{ item }}'
|
||||
regexp: '^\s*gpgcheck: 0'
|
||||
replace: 'gpgcheck: 1'
|
||||
with_flattened:
|
||||
- '/etc/yum.conf'
|
||||
- '{{ yum_repos.stdout_lines| default([]) }}'
|
||||
|
||||
- name: activate gpg-check for yum rhn if it exists
|
||||
replace: dest='/etc/yum/pluginconf.d/rhnplugin.conf' regexp='^\s*gpgcheck=0' replace='gpgcheck=1'
|
||||
replace:
|
||||
dest: '/etc/yum/pluginconf.d/rhnplugin.conf'
|
||||
regexp: '^\s*gpgcheck: 0'
|
||||
replace: 'gpgcheck: 1'
|
||||
when: rhnplugin_file.stat.exists
|
||||
|
||||
- name: remove packages
|
||||
yum: name='{{item}}' state=removed
|
||||
- name: remove deprecated or insecure packages | package-01 - package-09
|
||||
yum:
|
||||
name: '{{ item }}'
|
||||
state: 'absent'
|
||||
with_items:
|
||||
- "{{os_security_packages_list}}"
|
||||
- '{{ os_security_packages_list }}'
|
||||
when: os_security_packages_clean
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
log_file = /var/log/audit/audit.log
|
||||
log_format = RAW
|
||||
log_group = root
|
||||
priority_boost = 4
|
||||
flush = INCREMENTAL
|
||||
freq = 20
|
||||
num_logs = 5
|
||||
disp_qos = lossy
|
||||
dispatcher = /sbin/audispd
|
||||
name_format = NONE
|
||||
##name = mydomain
|
||||
max_log_file = 6
|
||||
max_log_file_action = keep_logs
|
||||
space_left = 75
|
||||
space_left_action = SYSLOG
|
||||
action_mail_acct = root
|
||||
admin_space_left = 50
|
||||
admin_space_left_action = SUSPEND
|
||||
disk_full_action = SUSPEND
|
||||
disk_error_action = SUSPEND
|
||||
##tcp_listen_port =
|
||||
tcp_listen_queue = 5
|
||||
tcp_max_per_addr = 1
|
||||
##tcp_client_ports = 1024-65535
|
||||
tcp_client_max_idle = 0
|
||||
enable_krb5 = no
|
||||
krb5_principal = auditd
|
||||
##krb5_key_file = /etc/audit/audit.key
|
|
@ -1,3 +1,4 @@
|
|||
# {{ ansible_managed | comment }}
|
||||
# /etc/default/ufw
|
||||
#
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# {{ ansible_managed }}
|
||||
# {{ ansible_managed | comment }}
|
||||
# This file contains the names of kernel modules that should be loaded at boot time, one per line. Lines beginning with "#" are ignored.
|
||||
#
|
||||
# A list of all available kernel modules kann be found with `find /lib/modules/$(uname -r)/kernel/`
|
|
@ -1,21 +1,22 @@
|
|||
# {{ ansible_managed | comment }}
|
||||
# Configuration control definitions for the login package.
|
||||
#
|
||||
#
|
||||
# Three items must be defined: `MAIL_DIR`, `ENV_SUPATH`, and `ENV_PATH`. If unspecified, some arbitrary (and possibly incorrect) value will be assumed. All other items are optional - if not specified then the described action or option will be inhibited.
|
||||
#
|
||||
#
|
||||
# Comment lines (lines beginning with `#`) and blank lines are ignored.
|
||||
#
|
||||
#-- Modified for Linux. --marekm
|
||||
|
||||
# *REQUIRED for useradd/userdel/usermod*
|
||||
#
|
||||
#
|
||||
# Directory where mailboxes reside, _or_ name of file, relative to the home directory. If you _do_ define `MAIL_DIR` and `MAIL_FILE`, `MAIL_DIR` takes precedence.
|
||||
# Essentially:
|
||||
#
|
||||
#
|
||||
# * `MAIL_DIR` defines the location of users mail spool files (for mbox use) by appending the username to `MAIL_DIR` as defined below.
|
||||
# * `MAIL_FILE` defines the location of the users mail spool files as the fully-qualified filename obtained by prepending the user home directory before `$MAIL_FILE`
|
||||
#
|
||||
# *NOTE*: This is no more used for setting up users MAIL environment variable which is, starting from shadow 4.0.12-1 in Debian, entirely the job of the pam_mail PAM modules.
|
||||
#
|
||||
#
|
||||
# See default PAM configuration files provided for login, su, etc.
|
||||
# This is a temporary situation: setting these variables will soon move to `/etc/default/useradd` and the variables will then be no more supported
|
||||
MAIL_DIR /var/mail
|
||||
|
@ -25,7 +26,7 @@ MAIL_DIR /var/mail
|
|||
FAILLOG_ENAB yes
|
||||
|
||||
# Enable display of unknown usernames when login failures are recorded.
|
||||
#
|
||||
#
|
||||
# *WARNING*: Unknown usernames may become world readable. See #290803 and #298773 for details about how this could become a security concern
|
||||
LOG_UNKFAIL_ENAB no
|
||||
|
||||
|
@ -84,7 +85,7 @@ KILLCHAR 025
|
|||
# Prefix these values with `0` to get octal, `0x` to get hexadecimal.
|
||||
# `022` is the "historical" value in Debian for UMASK
|
||||
# `027`, or even `077`, could be considered better for privacy.
|
||||
UMASK {{os_env_umask}}
|
||||
UMASK {{ os_env_umask }}
|
||||
|
||||
# Enable setting of the umask group bits to be the same as owner bits (examples: `022` -> `002`, `077` -> `007`) for non-root users, if the uid is the same as gid, and username is the same as the primary group name.
|
||||
# If set to yes, userdel will remove the user´s group if it contains no more members, and useradd will create by default a group with the name of the user.
|
||||
|
@ -95,33 +96,33 @@ USERGROUPS_ENAB yes
|
|||
# -----------------------
|
||||
|
||||
# Maximum number of days a password may be used.
|
||||
PASS_MAX_DAYS {{os_auth_pw_max_age}}
|
||||
PASS_MAX_DAYS {{ os_auth_pw_max_age }}
|
||||
|
||||
# Minimum number of days allowed between password changes.
|
||||
PASS_MIN_DAYS {{os_auth_pw_min_age}}
|
||||
PASS_MIN_DAYS {{ os_auth_pw_min_age }}
|
||||
|
||||
# Number of days warning given before a password expires.
|
||||
PASS_WARN_AGE 7
|
||||
|
||||
# Min/max values for automatic uid selection in useradd
|
||||
UID_MIN {{os_auth_uid_min}}
|
||||
UID_MIN {{ os_auth_uid_min }}
|
||||
UID_MAX 60000
|
||||
# System accounts
|
||||
SYS_UID_MIN {{os_auth_sys_uid_min}}
|
||||
SYS_UID_MAX {{os_auth_sys_uid_max}}
|
||||
SYS_UID_MIN {{ os_auth_sys_uid_min }}
|
||||
SYS_UID_MAX {{ os_auth_sys_uid_max }}
|
||||
|
||||
# Min/max values for automatic gid selection in groupadd
|
||||
GID_MIN {{os_auth_gid_min}}
|
||||
GID_MIN {{ os_auth_gid_min }}
|
||||
GID_MAX 60000
|
||||
# System accounts
|
||||
SYS_GID_MIN {{os_auth_sys_gid_min}}
|
||||
SYS_GID_MAX {{os_auth_sys_gid_max}}
|
||||
SYS_GID_MIN {{ os_auth_sys_gid_min }}
|
||||
SYS_GID_MAX {{ os_auth_sys_gid_max }}
|
||||
|
||||
# Max number of login retries if password is bad. This will most likely be overriden by PAM, since the default pam_unix module has it's own built in of 3 retries. However, this is a safe fallback in case you are using an authentication module that does not enforce PAM_MAXTRIES.
|
||||
LOGIN_RETRIES {{os_auth_retries}}
|
||||
LOGIN_RETRIES {{ os_auth_retries }}
|
||||
|
||||
# Max time in seconds for login
|
||||
LOGIN_TIMEOUT {{os_auth_timeout}}
|
||||
LOGIN_TIMEOUT {{ os_auth_timeout }}
|
||||
|
||||
# Which fields may be changed by regular users using chfn - use any combination of letters "frwh" (full name, room number, work phone, home phone). If not defined, no changes are allowed.
|
||||
# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
|
|
@ -0,0 +1,5 @@
|
|||
{{ ansible_managed | comment }}
|
||||
|
||||
{% for fs in os_unused_filesystems | difference(os_filesystem_whitelist) %}
|
||||
install {{fs}} /bin/true
|
||||
{% endfor %}
|
|
@ -1,9 +1,8 @@
|
|||
# {{ ansible_managed }}
|
||||
#---
|
||||
# {{ ansible_managed | comment }}
|
||||
|
||||
#%PAM-1.0
|
||||
{% if os_auth_retries > 0 %}
|
||||
auth required pam_tally2.so deny={{os_auth_retries}} onerr=fail unlock_time={{os_auth_lockout_time}}
|
||||
auth required pam_tally2.so deny={{ os_auth_retries }} onerr=fail unlock_time={{ os_auth_lockout_time }}
|
||||
{% endif %}
|
||||
auth required pam_env.so
|
||||
auth sufficient pam_unix.so nullok try_first_pass
|
||||
|
@ -18,11 +17,11 @@ account sufficient pam_localuser.so
|
|||
account sufficient pam_succeed_if.so uid < 500 quiet
|
||||
account required pam_permit.so
|
||||
|
||||
{% if os_auth_pam_passwdqc_enable %}
|
||||
{%- if ansible_os_family == 'RedHat' and ansible_distribution_version >= '7' %}
|
||||
password required pam_pwquality.so {{os_auth_pam_pwquality_options}}
|
||||
{% if (os_auth_pam_passwdqc_enable|bool) %}
|
||||
{%- if ((ansible_os_family == 'RedHat' and ansible_distribution_version >= '7') or ansible_distribution == 'Amazon') %}
|
||||
password required pam_pwquality.so {{ os_auth_pam_pwquality_options }}
|
||||
{%- else %}
|
||||
password requisite pam_passwdqc.so {{os_auth_pam_passwdqc_options}}
|
||||
password requisite pam_passwdqc.so {{ os_auth_pam_passwdqc_options }}
|
||||
{%- endif %}
|
||||
{% else %}
|
||||
password requisite pam_cracklib.so try_first_pass retry=3 type=
|
|
@ -1,4 +1,4 @@
|
|||
# {{ ansible_managed }}
|
||||
# {{ ansible_managed | comment }}
|
||||
|
||||
# Disable core dumps via soft limits for all users. Compliance to this setting is voluntary and can be modified by users up to a hard limit. This setting is a sane default.
|
||||
ulimit -S -c 0 > /dev/null 2>&1
|
|
@ -1,6 +1,6 @@
|
|||
# See libuser.conf(5) for more information.
|
||||
|
||||
# {{ ansible_managed }}
|
||||
# {{ ansible_managed | comment }}
|
||||
|
||||
# Do not modify the default module list if you care about unattended calls
|
||||
# to programs (i.e., scripts) working!
|
|
@ -1,4 +1,4 @@
|
|||
# {{ ansible_managed }}
|
||||
# {{ ansible_managed | comment }}
|
||||
|
||||
|
||||
# A list of TTYs, from which root can log in
|
|
@ -1,4 +1,4 @@
|
|||
# {{ ansible_managed }}
|
||||
# {{ ansible_managed | comment }}
|
||||
|
||||
# color => new RH6.0 bootup
|
||||
# verbose => old-style bootup
|
||||
|
@ -18,7 +18,7 @@ SETCOLOR_WARNING="echo -en \\033[0;33m"
|
|||
# terminal sequence to reset to the default color.
|
||||
SETCOLOR_NORMAL="echo -en \\033[0;39m"
|
||||
# Set to anything other than 'no' to allow hotkey interactive startup...
|
||||
PROMPT={{ 'yes' if os_security_init_prompt else 'no' }}
|
||||
PROMPT={{ 'yes' if (os_security_init_prompt|bool) else 'no' }}
|
||||
# Set to 'yes' to allow probing for devices with swap signatures
|
||||
AUTOSWAP=no
|
||||
# What ttys should gettys be started on?
|
|
@ -1,3 +0,0 @@
|
|||
# {{ansible_managed}}
|
||||
# Prevent core dumps for all users. These are usually only needed by developers and may contain sensitive information.
|
||||
* hard core 0
|
|
@ -4,4 +4,4 @@ Priority: 1024
|
|||
Conflicts: cracklib
|
||||
Password-Type: Primary
|
||||
Password:
|
||||
requisite pam_passwdqc.so {{os_auth_pam_passwdqc_options}}
|
||||
requisite pam_passwdqc.so {{ os_auth_pam_passwdqc_options }}
|
|
@ -4,7 +4,7 @@ Priority: 1024
|
|||
Conflicts: cracklib
|
||||
Auth-Type: Primary
|
||||
Auth-Initial:
|
||||
required pam_tally2.so deny={{os_auth_retries}} onerr=fail unlock_time={{os_auth_lockout_time}}
|
||||
required pam_tally2.so deny={{ os_auth_retries }} onerr=fail unlock_time={{ os_auth_lockout_time }}
|
||||
Account-Type: Primary
|
||||
Account-Initial:
|
||||
required pam_tally2.so
|
74
ansible/roles/dev-sec.os-hardening/tests/test.yml
Normal file
74
ansible/roles/dev-sec.os-hardening/tests/test.yml
Normal file
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
- name: wrapper playbook for kitchen testing "ansible-os-hardening" with custom vars for testing
|
||||
hosts: localhost
|
||||
roles:
|
||||
- ansible-os-hardening
|
||||
pre_tasks:
|
||||
- name: Run the equivalent of "apt-get update" as a separate step
|
||||
apt:
|
||||
update_cache: yes
|
||||
when: ansible_os_family == 'Debian'
|
||||
- name: create recursing symlink to test minimize access
|
||||
shell: "rm -f /usr/bin/zzz && ln -s /usr/bin /usr/bin/zzz"
|
||||
vars:
|
||||
os_security_users_allow: change_user
|
||||
os_security_kernel_enable_core_dump: true
|
||||
os_security_suid_sgid_remove_from_unknown: true
|
||||
os_auth_pam_passwdqc_enable: false
|
||||
os_desktop_enable: true
|
||||
os_env_extra_user_paths: ['/home']
|
||||
os_auth_allow_homeless: true
|
||||
os_security_suid_sgid_blacklist: ['/bin/umount']
|
||||
os_security_suid_sgid_whitelist: ['/usr/bin/rlogin']
|
||||
os_filesystem_whitelist: ['vfat']
|
||||
sysctl_config:
|
||||
net.ipv4.ip_forward: 0
|
||||
net.ipv6.conf.all.forwarding: 0
|
||||
net.ipv6.conf.all.accept_ra: 0
|
||||
net.ipv6.conf.default.accept_ra: 0
|
||||
net.ipv4.conf.all.rp_filter: 1
|
||||
net.ipv4.conf.default.rp_filter: 1
|
||||
net.ipv4.icmp_echo_ignore_broadcasts: 1
|
||||
net.ipv4.icmp_ignore_bogus_error_responses: 1
|
||||
net.ipv4.icmp_ratelimit: 100
|
||||
net.ipv4.icmp_ratemask: 88089
|
||||
net.ipv6.conf.all.disable_ipv6: 1
|
||||
net.ipv4.conf.all.arp_ignore: 1
|
||||
net.ipv4.conf.all.arp_announce: 2
|
||||
net.ipv4.conf.all.shared_media: 1
|
||||
net.ipv4.conf.default.shared_media: 1
|
||||
net.ipv4.conf.all.accept_source_route: 0
|
||||
net.ipv4.conf.default.accept_source_route: 0
|
||||
net.ipv4.conf.default.accept_redirects: 0
|
||||
net.ipv4.conf.all.accept_redirects: 0
|
||||
net.ipv4.conf.all.secure_redirects: 0
|
||||
net.ipv4.conf.default.secure_redirects: 0
|
||||
net.ipv6.conf.default.accept_redirects: 0
|
||||
net.ipv6.conf.all.accept_redirects: 0
|
||||
net.ipv4.conf.all.send_redirects: 0
|
||||
net.ipv4.conf.default.send_redirects: 0
|
||||
net.ipv4.conf.all.log_martians: 1
|
||||
net.ipv6.conf.default.router_solicitations: 0
|
||||
net.ipv6.conf.default.accept_ra_rtr_pref: 0
|
||||
net.ipv6.conf.default.accept_ra_pinfo: 0
|
||||
net.ipv6.conf.default.accept_ra_defrtr: 0
|
||||
net.ipv6.conf.default.autoconf: 0
|
||||
net.ipv6.conf.default.dad_transmits: 0
|
||||
net.ipv6.conf.default.max_addresses: 1
|
||||
kernel.sysrq: 0
|
||||
fs.suid_dumpable: 0
|
||||
kernel.randomize_va_space: 2
|
||||
|
||||
|
||||
- name: wrapper playbook for kitchen testing "ansible-os-hardening"
|
||||
hosts: localhost
|
||||
vars:
|
||||
- os_auditd_enabled: false
|
||||
pre_tasks:
|
||||
- name: Run the equivalent of "apt-get update" as a separate step
|
||||
apt:
|
||||
update_cache: yes
|
||||
when: ansible_os_family == 'Debian'
|
||||
roles:
|
||||
- ansible-os-hardening
|
||||
|
9
ansible/roles/dev-sec.os-hardening/vars/Amazon.yml
Normal file
9
ansible/roles/dev-sec.os-hardening/vars/Amazon.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
# system accounts that do not get their login disabled and pasword changed
|
||||
os_always_ignore_users: ['root','sync','shutdown','halt', 'ec2-user']
|
||||
|
||||
sysctl_rhel_config:
|
||||
# ExecShield protection against buffer overflows
|
||||
kernel.exec-shield: 1
|
||||
# Syncookies is used to prevent SYN-flooding attacks.
|
||||
net.ipv4.tcp_syncookies: 1
|
|
@ -5,10 +5,27 @@ passwdqc_path: '/usr/share/pam-configs/passwdqc'
|
|||
tally2_path: '/usr/share/pam-configs/tally2'
|
||||
os_nologin_shell_path: '/usr/sbin/nologin'
|
||||
|
||||
auditd_package: 'auditd'
|
||||
modprobe_package: 'kmod'
|
||||
|
||||
# Different distros use different standards for /etc/shadow perms, e.g.
|
||||
# RHEL derivatives use root:root 0600, whereas Debian-based use root:shadow 0640.
|
||||
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
|
||||
# You must provide key/value pairs for owner, group, and mode if overriding.
|
||||
os_shadow_perms:
|
||||
owner: root
|
||||
group: shadow
|
||||
mode: "0640"
|
||||
mode: '0640'
|
||||
|
||||
os_passwd_perms:
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
os_env_umask: '027'
|
||||
|
||||
os_auth_uid_min: 1000
|
||||
os_auth_gid_min: 1000
|
||||
os_auth_sys_uid_min: 100
|
||||
os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 100
|
||||
os_auth_sys_gid_max: 999
|
||||
|
|
|
@ -4,9 +4,23 @@ os_packages_pam_cracklib: 'pam_cracklib'
|
|||
os_nologin_shell_path: '/sbin/nologin'
|
||||
|
||||
# Different distros use different standards for /etc/shadow perms, e.g.
|
||||
# RHEL derivatives use root:root 0600, whereas Debian-based use root:shadow 0640.
|
||||
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
|
||||
# You must provide key/value pairs for owner, group, and mode if overriding.
|
||||
os_shadow_perms:
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
mode: '0000'
|
||||
|
||||
os_passwd_perms:
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
os_env_umask: '077'
|
||||
|
||||
os_auth_uid_min: 1000
|
||||
os_auth_gid_min: 1000
|
||||
os_auth_sys_uid_min: 201
|
||||
os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 201
|
||||
os_auth_sys_gid_max: 999
|
||||
|
|
7
ansible/roles/dev-sec.os-hardening/vars/RedHat-6.yml
Normal file
7
ansible/roles/dev-sec.os-hardening/vars/RedHat-6.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
|
||||
sysctl_rhel_config:
|
||||
# ExecShield protection against buffer overflows
|
||||
kernel.exec-shield: 1
|
||||
# Syncookies is used to prevent SYN-flooding attacks.
|
||||
net.ipv4.tcp_syncookies: 1
|
|
@ -1,12 +1,31 @@
|
|||
---
|
||||
|
||||
modprobe_package: 'module-init-tools'
|
||||
auditd_package: 'audit'
|
||||
|
||||
os_packages_pam_ccreds: 'pam_ccreds'
|
||||
os_packages_pam_passwdqc: 'pam_passwdqc'
|
||||
os_packages_pam_cracklib: 'pam_cracklib'
|
||||
os_nologin_shell_path: '/sbin/nologin'
|
||||
|
||||
# Different distros use different standards for /etc/shadow perms, e.g.
|
||||
# RHEL derivatives use root:root 0600, whereas Debian-based use root:shadow 0640.
|
||||
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
|
||||
# You must provide key/value pairs for owner, group, and mode if overriding.
|
||||
os_shadow_perms:
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
mode: '0000'
|
||||
|
||||
os_passwd_perms:
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
os_env_umask: '077'
|
||||
|
||||
os_auth_uid_min: 1000
|
||||
os_auth_gid_min: 1000
|
||||
os_auth_sys_uid_min: 201
|
||||
os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 201
|
||||
os_auth_sys_gid_max: 999
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# adjust values for blacklist/whitelist instead, they can override system_blacklist/whitelist
|
||||
|
||||
# list of suid/sgid entries that must be removed
|
||||
os_security_suid_sgid_system_blacklist:
|
||||
os_security_suid_sgid_system_blacklist:
|
||||
# blacklist as provided by NSA
|
||||
- '/usr/bin/rcp'
|
||||
- '/usr/bin/rlogin'
|
||||
|
@ -43,6 +43,7 @@ os_security_suid_sgid_system_whitelist:
|
|||
- '/bin/mount'
|
||||
- '/bin/ping'
|
||||
- '/bin/su'
|
||||
- '/usr/bin/su'
|
||||
- '/bin/umount'
|
||||
- '/sbin/pam_timestamp_check'
|
||||
- '/sbin/unix_chkpwd'
|
||||
|
@ -108,4 +109,3 @@ os_security_suid_sgid_system_whitelist:
|
|||
|
||||
# system accounts that do not get their login disabled and pasword changed
|
||||
os_always_ignore_users: ['root','sync','shutdown','halt']
|
||||
|
||||
|
|
37
ansible/roles/dev-sec.ssh-hardening/.kitchen.aws.yml
Normal file
37
ansible/roles/dev-sec.ssh-hardening/.kitchen.aws.yml
Normal file
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
driver:
|
||||
name: ec2
|
||||
vpc_id: "vpc-4ef2ce26"
|
||||
subnet_id: "subnet-b477b7df"
|
||||
region: eu-central-1
|
||||
|
||||
transport:
|
||||
max_ssh_sessions: 5
|
||||
|
||||
provisioner:
|
||||
name: ansible_playbook
|
||||
hosts: all
|
||||
require_ansible_repo: false
|
||||
require_chef_for_busser: false
|
||||
require_ruby_for_busser: false
|
||||
require_ansible_omnibus: true
|
||||
ansible_verbose: true
|
||||
ansible_diff: true
|
||||
hosts: all
|
||||
roles_path: ../ansible-ssh-hardening/
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
playbook: default.yml
|
||||
|
||||
platforms:
|
||||
- name: centos-7
|
||||
- name: ubuntu-16.04
|
||||
|
||||
verifier:
|
||||
name: inspec
|
||||
sudo: true
|
||||
inspec_tests:
|
||||
- https://github.com/dev-sec/tests-ssh-hardening
|
||||
|
||||
suites:
|
||||
- name: os
|
|
@ -16,7 +16,7 @@ provisioner:
|
|||
require_ruby_for_busser: false
|
||||
ansible_verbose: true
|
||||
roles_path: ../ansible-ssh-hardening/
|
||||
playbook: default.yml
|
||||
playbook: tests/default.yml
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
|
||||
|
|
|
@ -9,10 +9,6 @@ driver:
|
|||
transport:
|
||||
max_ssh_sessions: 5
|
||||
|
||||
transport:
|
||||
max_ssh_sessions: 5
|
||||
|
||||
|
||||
provisioner:
|
||||
name: ansible_playbook
|
||||
hosts: all
|
||||
|
@ -25,7 +21,8 @@ provisioner:
|
|||
roles_path: ../ansible-ssh-hardening/
|
||||
http_proxy: <%= ENV['http_proxy'] || nil %>
|
||||
https_proxy: <%= ENV['https_proxy'] || nil %>
|
||||
playbook: default.yml
|
||||
playbook: tests/default.yml
|
||||
ansible_diff: true
|
||||
ansible_extra_flags:
|
||||
- "--skip-tags=sysctl"
|
||||
|
||||
|
@ -38,6 +35,10 @@ platforms:
|
|||
driver:
|
||||
image: rndmh3ro/docker-centos7-ansible:latest
|
||||
platform: centos
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
- name: oracle6-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-oracle6-ansible:latest
|
||||
|
@ -45,11 +46,11 @@ platforms:
|
|||
- name: oracle7-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-oracle7-ansible:latest
|
||||
run_command: /sbin/init
|
||||
platform: centos
|
||||
- name: ubuntu1204-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-ubuntu1204-ansible:latest
|
||||
platform: ubuntu
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
- name: ubuntu1404-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-ubuntu1404-ansible:latest
|
||||
|
@ -58,6 +59,9 @@ platforms:
|
|||
driver:
|
||||
image: rndmh3ro/docker-ubuntu1604-ansible:latest
|
||||
platform: ubuntu
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- systemctl enable ssh.service
|
||||
- name: debian7-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-debian7-ansible:latest
|
||||
|
@ -66,10 +70,22 @@ platforms:
|
|||
driver:
|
||||
image: rndmh3ro/docker-debian8-ansible:latest
|
||||
platform: debian
|
||||
#- name: debian9-ansible-latest
|
||||
# driver:
|
||||
# image: rndmh3ro/docker-debian9-ansible:latest
|
||||
# platform: debian
|
||||
- name: debian9-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-debian9-ansible:latest
|
||||
platform: debian
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- apt install -y systemd-sysv
|
||||
- systemctl enable ssh.service
|
||||
- name: amazon-ansible-latest
|
||||
driver:
|
||||
image: rndmh3ro/docker-amazon-ansible:latest
|
||||
platform: centos
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
|
||||
- systemctl enable sshd.service
|
||||
|
||||
verifier:
|
||||
name: inspec
|
||||
|
|
|
@ -15,10 +15,10 @@ env:
|
|||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: oracle7
|
||||
init: /usr/lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
version: latest
|
||||
# - distro: oracle7
|
||||
# init: /usr/lib/systemd/systemd
|
||||
# run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
# version: latest
|
||||
|
||||
- distro: ubuntu1604
|
||||
version: latest
|
||||
|
@ -29,24 +29,24 @@ env:
|
|||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: ubuntu1204
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: debian7
|
||||
version: latest
|
||||
init: /sbin/init
|
||||
|
||||
- distro: debian8
|
||||
version: latest
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
init: /sbin/init
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
# - distro: debian9
|
||||
# version: latest
|
||||
# init: /lib/systemd/systemd
|
||||
# run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
- distro: debian9
|
||||
version: latest
|
||||
init: /lib/systemd/systemd
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
- distro: amazon
|
||||
init: /lib/systemd/systemd
|
||||
version: latest
|
||||
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||
|
||||
before_install:
|
||||
# Pull container
|
||||
|
@ -58,10 +58,14 @@ 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.yml'
|
||||
- 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-ssh-hardening/tests/default_custom.yml'
|
||||
- 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-ssh-hardening/tests/default.yml'
|
||||
|
||||
# Verify role
|
||||
- 'inspec exec https://github.com/dev-sec/ssh-baseline/ -t docker://$(cat ${container_id})'
|
||||
# remove the UseLogin-check, see here for reasons: https://github.com/dev-sec/ansible-ssh-hardening/pull/141
|
||||
- 'inspec exec https://github.com/dev-sec/ssh-baseline/ -t docker://$(cat ${container_id}) --controls=sshd-01 sshd-02 sshd-03 sshd-04 sshd-05 sshd-06 sshd-07 sshd-08 sshd-09 sshd-10 sshd-11 sshd-12 sshd-13 sshd-14 sshd-16 sshd-17 sshd-18 sshd-19 sshd-20 sshd-21 sshd-22 sshd-23 sshd-24 sshd-25 sshd-26 sshd-27 sshd-28 sshd-29 sshd-30 sshd-31 sshd-32 sshd-33 sshd-34 sshd-35 sshd-36 sshd-37 sshd-38 sshd-39 sshd-40 sshd-41 sshd-42 sshd-43 sshd-44 sshd-45 sshd-46 sshd-47 sshd-48 --no-distinct-exit'
|
||||
# remove UseRoaming and RhostsRSAAuthentication because these options are deprecated - ssh-14, ssh-15, ssh-21
|
||||
- 'inspec exec https://github.com/dev-sec/ssh-baseline/ -t docker://$(cat ${container_id}) --controls=ssh-01 ssh-02 ssh-03 ssh-04 ssh-05 ssh-06 ssh-07 ssh-08 ssh-09 ssh-10 ssh-11 ssh-12 ssh-13 ssh-16 ssh-17 ssh-18 ssh-19 ssh-20 --no-distinct-exit'
|
||||
|
||||
notifications:
|
||||
webhooks: https://galaxy.ansible.com/api/v1/notifications/
|
||||
|
|
|
@ -1,11 +1,170 @@
|
|||
# Change Log
|
||||
|
||||
## [4.4.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.4.0) (2017-12-29)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.3.1...4.4.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Changes in selinux section to avoid confusion and some inconsistencies [\#127](https://github.com/dev-sec/ansible-ssh-hardening/issues/127)
|
||||
- Issue \#137: Fix sshd\_config's "Match Group sftponly" [\#138](https://github.com/dev-sec/ansible-ssh-hardening/pull/138) ([kekumu](https://github.com/kekumu))
|
||||
- allow configuration of GatewayPorts [\#136](https://github.com/dev-sec/ansible-ssh-hardening/pull/136) ([pwyliu](https://github.com/pwyliu))
|
||||
- Added support for AuthorizedKeysFile config setting [\#132](https://github.com/dev-sec/ansible-ssh-hardening/pull/132) ([hyrsky](https://github.com/hyrsky))
|
||||
- corrected comments explaining the task's behaviour [\#131](https://github.com/dev-sec/ansible-ssh-hardening/pull/131) ([martinbydefault](https://github.com/martinbydefault))
|
||||
- Add Two-Factor Authentication [\#123](https://github.com/dev-sec/ansible-ssh-hardening/pull/123) ([lazzurs](https://github.com/lazzurs))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- ssh\_use\_dns used twice in defaults/main.yml [\#129](https://github.com/dev-sec/ansible-ssh-hardening/issues/129)
|
||||
- line 56: Bad SSH2 mac spec [\#135](https://github.com/dev-sec/ansible-ssh-hardening/issues/135)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- coreos support? [\#142](https://github.com/dev-sec/ansible-ssh-hardening/issues/142)
|
||||
- UseLogin is deprecated on CentOS 7 [\#140](https://github.com/dev-sec/ansible-ssh-hardening/issues/140)
|
||||
- sftp Match Group settings overriding global sshd\_config settings [\#137](https://github.com/dev-sec/ansible-ssh-hardening/issues/137)
|
||||
- get openssh-version fails on FreeBSD \(with ansible 2.4.0.0\) [\#133](https://github.com/dev-sec/ansible-ssh-hardening/issues/133)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Remove deprecated UseLogin option [\#141](https://github.com/dev-sec/ansible-ssh-hardening/pull/141) ([syhe](https://github.com/syhe))
|
||||
- Macs kex ciphers [\#139](https://github.com/dev-sec/ansible-ssh-hardening/pull/139) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- force /bin/sh when getting openssh-version [\#134](https://github.com/dev-sec/ansible-ssh-hardening/pull/134) ([gtz42](https://github.com/gtz42))
|
||||
|
||||
## [4.3.1](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.3.1) (2017-08-14)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.3.0...4.3.1)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Remove duplicate ssh\_use\_dns [\#130](https://github.com/dev-sec/ansible-ssh-hardening/pull/130) ([MagnusEnger](https://github.com/MagnusEnger))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- System completely unresponsive after role execution [\#126](https://github.com/dev-sec/ansible-ssh-hardening/issues/126)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- role creates duplicate parameter/values after run [\#124](https://github.com/dev-sec/ansible-ssh-hardening/issues/124)
|
||||
|
||||
## [4.3.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.3.0) (2017-08-03)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.1.3...4.3.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Fix ansible.cfg settings [\#122](https://github.com/dev-sec/ansible-ssh-hardening/pull/122) ([fazlearefin](https://github.com/fazlearefin))
|
||||
- Finish 94 [\#116](https://github.com/dev-sec/ansible-ssh-hardening/pull/116) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Don't overwrite ssh\_host\_key\_files if set manually [\#125](https://github.com/dev-sec/ansible-ssh-hardening/pull/125) ([oakey-b1](https://github.com/oakey-b1))
|
||||
- Add comment filter to {{ansible\_managed}} string [\#121](https://github.com/dev-sec/ansible-ssh-hardening/pull/121) ([fazlearefin](https://github.com/fazlearefin))
|
||||
|
||||
## [4.1.3](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.1.3) (2017-06-30)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.2.0...4.1.3)
|
||||
|
||||
## [4.2.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.2.0) (2017-06-30)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.1.2...4.2.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Add support to specify a list of revoked public keys [\#120](https://github.com/dev-sec/ansible-ssh-hardening/pull/120) ([bachp](https://github.com/bachp))
|
||||
- use package instead of yum so the operation works on Fedora [\#119](https://github.com/dev-sec/ansible-ssh-hardening/pull/119) ([stenwt](https://github.com/stenwt))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- fails in --check mode [\#111](https://github.com/dev-sec/ansible-ssh-hardening/issues/111)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Do not use shell when not needed + Lint whitespaces [\#118](https://github.com/dev-sec/ansible-ssh-hardening/pull/118) ([krhubert](https://github.com/krhubert))
|
||||
|
||||
## [4.1.2](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.1.2) (2017-05-31)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.1.1...4.1.2)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- added check\_mode: no to "get openssh-version" task, so it won't fail … [\#117](https://github.com/dev-sec/ansible-ssh-hardening/pull/117) ([wschaft](https://github.com/wschaft))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- User login failed after running this module [\#114](https://github.com/dev-sec/ansible-ssh-hardening/issues/114)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Update readme to include baselines [\#110](https://github.com/dev-sec/ansible-ssh-hardening/issues/110)
|
||||
|
||||
## [4.1.1](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.1.1) (2017-05-18)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.1.0...4.1.1)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- fix validation error [\#113](https://github.com/dev-sec/ansible-ssh-hardening/pull/113) ([pwyliu](https://github.com/pwyliu))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- fix validation error [\#113](https://github.com/dev-sec/ansible-ssh-hardening/pull/113) ([pwyliu](https://github.com/pwyliu))
|
||||
|
||||
## [4.1.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.1.0) (2017-05-09)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/4.0.0...4.1.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Provide option to allow password server login [\#106](https://github.com/dev-sec/ansible-ssh-hardening/issues/106)
|
||||
- Deprecation warning always\_run [\#82](https://github.com/dev-sec/ansible-ssh-hardening/issues/82)
|
||||
- Added support for UseDNS config switch [\#109](https://github.com/dev-sec/ansible-ssh-hardening/pull/109) ([ftaeger](https://github.com/ftaeger))
|
||||
- Added support for UseDNS config switch [\#108](https://github.com/dev-sec/ansible-ssh-hardening/pull/108) ([ftaeger](https://github.com/ftaeger))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- `create ssh\_config and set permissions to root/644` step repeated [\#104](https://github.com/dev-sec/ansible-ssh-hardening/issues/104)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Added support for PermitTunnel config switch [\#112](https://github.com/dev-sec/ansible-ssh-hardening/pull/112) ([fti7](https://github.com/fti7))
|
||||
- Adds option to enable password based authentication on the server [\#107](https://github.com/dev-sec/ansible-ssh-hardening/pull/107) ([colin-nolan](https://github.com/colin-nolan))
|
||||
|
||||
## [4.0.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/4.0.0) (2017-04-22)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/3.2.0...4.0.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Avoid small primes for DH and allow rebuild of DH primes [\#89](https://github.com/dev-sec/ansible-ssh-hardening/issues/89)
|
||||
- Accommodate missing plugins in kitchen\_vagrant\_block.rb [\#100](https://github.com/dev-sec/ansible-ssh-hardening/pull/100) ([fullyint](https://github.com/fullyint))
|
||||
- Use different Hostkeys according to installed ssh version [\#99](https://github.com/dev-sec/ansible-ssh-hardening/pull/99) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Remove small dh primes [\#97](https://github.com/dev-sec/ansible-ssh-hardening/pull/97) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Add Ed25519 SSH host key to match commit 28b4df3 in ssh-baseline [\#96](https://github.com/dev-sec/ansible-ssh-hardening/pull/96) ([techraf](https://github.com/techraf))
|
||||
- Add support for FreeBSD OpenSSH server and client [\#95](https://github.com/dev-sec/ansible-ssh-hardening/pull/95) ([jbenden](https://github.com/jbenden))
|
||||
- Replace deprecated always\_run with check\_mode [\#93](https://github.com/dev-sec/ansible-ssh-hardening/pull/93) ([jbenden](https://github.com/jbenden))
|
||||
- Defaults: Remove DSA from SSH host keys to match ssh-baseline profile [\#92](https://github.com/dev-sec/ansible-ssh-hardening/pull/92) ([techraf](https://github.com/techraf))
|
||||
- use new docker images [\#91](https://github.com/dev-sec/ansible-ssh-hardening/pull/91) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- use centos 7 in vagrant, limit ssh conns [\#88](https://github.com/dev-sec/ansible-ssh-hardening/pull/88) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- remove support for ansible 1.9 [\#87](https://github.com/dev-sec/ansible-ssh-hardening/pull/87) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- make ChallengeResponseAuthentication configurable [\#85](https://github.com/dev-sec/ansible-ssh-hardening/pull/85) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- List only one Port in ssh config [\#84](https://github.com/dev-sec/ansible-ssh-hardening/pull/84) ([fullyint](https://github.com/fullyint))
|
||||
- Fix ssh config to handle custom options per Host [\#83](https://github.com/dev-sec/ansible-ssh-hardening/pull/83) ([fullyint](https://github.com/fullyint))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- SELinux-specific task still runs on SELinux-disabled systems [\#74](https://github.com/dev-sec/ansible-ssh-hardening/issues/74)
|
||||
- List only one Port in ssh config [\#84](https://github.com/dev-sec/ansible-ssh-hardening/pull/84) ([fullyint](https://github.com/fullyint))
|
||||
- Fix ssh config to handle custom options per Host [\#83](https://github.com/dev-sec/ansible-ssh-hardening/pull/83) ([fullyint](https://github.com/fullyint))
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Should compression be opt-in? [\#90](https://github.com/dev-sec/ansible-ssh-hardening/issues/90)
|
||||
- The role fails when conditionally included [\#86](https://github.com/dev-sec/ansible-ssh-hardening/issues/86)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- remove duplicate section [\#105](https://github.com/dev-sec/ansible-ssh-hardening/pull/105) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Fix ssh\_server\_ports and ssh\_client\_ports documentation bug [\#80](https://github.com/dev-sec/ansible-ssh-hardening/pull/80) ([kivilahtio](https://github.com/kivilahtio))
|
||||
|
||||
## [3.2.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/3.2.0) (2016-10-24)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/3.1.0...3.2.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- CentOS 7 selinux dependencies [\#76](https://github.com/dev-sec/ansible-ssh-hardening/issues/76)
|
||||
- install selinux dependencies, check for already installed semodule [\#79](https://github.com/dev-sec/ansible-ssh-hardening/pull/79) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Parameterise Banner and DebianBanner as defaults [\#77](https://github.com/dev-sec/ansible-ssh-hardening/pull/77) ([tsenart](https://github.com/tsenart))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
@ -13,16 +172,11 @@
|
|||
- Some tasks are always run even if they are not needed [\#78](https://github.com/dev-sec/ansible-ssh-hardening/issues/78)
|
||||
- Selinux issue [\#75](https://github.com/dev-sec/ansible-ssh-hardening/issues/75)
|
||||
- Running the tests locally [\#61](https://github.com/dev-sec/ansible-ssh-hardening/issues/61)
|
||||
- SELinux-specific task still runs on SELinux-disabled systems [\#74](https://github.com/dev-sec/ansible-ssh-hardening/issues/74)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Applied-Crypto-Hardening project and new cyphers. [\#28](https://github.com/dev-sec/ansible-ssh-hardening/issues/28)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- install selinux dependencies, check for already installed semodule [\#79](https://github.com/dev-sec/ansible-ssh-hardening/pull/79) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
## [3.1.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/3.1.0) (2016-08-03)
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/3.1...3.1.0)
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ All tests will be reviewed internally for their validity and overall project dir
|
|||
|
||||
### Document your code
|
||||
|
||||
As code is more often read than written, please provide documentation in all projects.
|
||||
As code is more often read than written, please provide documentation in all projects.
|
||||
|
||||
Adhere to the respective guidelines for documentation:
|
||||
|
||||
|
|
|
@ -6,46 +6,73 @@
|
|||
|
||||
## Description
|
||||
|
||||
This role provides secure ssh-client and ssh-server configurations.
|
||||
This role provides secure ssh-client and ssh-server configurations. It is intended to be compliant with the [DevSec SSH Baseline](https://github.com/dev-sec/ssh-baseline).
|
||||
|
||||
Warning: This role disables root-login on the target server! Please make sure you have another user with su or sudo permissions that can login into the server.
|
||||
|
||||
## Requirements
|
||||
|
||||
* Ansible > 2.2.1
|
||||
* Ansible > 2.4
|
||||
|
||||
## Role Variables
|
||||
| Name | Default Value | Description |
|
||||
| -------------- | ------------- | -----------------------------------|
|
||||
|`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 |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_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 |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_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 |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_ports` | ['22'] |ports on which ssh-server should listen|
|
||||
|`ssh_client_port` | '22' |port to which ssh-client should connect|
|
||||
|`ssh_listen_to` | ['0.0.0.0'] |one or more ip addresses, to which ssh-server should listen to. Default is all adresseses, but should be configured to specific addresses 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'] |Host keys to look for when starting sshd.|
|
||||
|`ssh_host_key_files` | [] |Host keys for sshd. If empty ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key'] will be used, as far as supported by the installed sshd version|
|
||||
|`ssh_client_alive_interval` | 600 | specifies an interval for sending keepalive messages |
|
||||
|`ssh_client_alive_count` | 3 | defines how often keep-alive messages are sent |
|
||||
|`ssh_permit_tunnel` | false | true if SSH Port Tunneling is required |
|
||||
|`ssh_remote_hosts` | [] | one or more hosts and their custom options for the ssh-client. Default is empty. See examples in `defaults/main.yml`.|
|
||||
|`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_gateway_ports` | `false` | `false` to disable binding forwarded ports to non-loopback addresses. Set to `true` to force binding on wildcard address. Set to `clientspecified` to allow the client to specify which address to bind to.|
|
||||
|`ssh_allow_agent_forwarding` | false | false to disable Agent Forwarding. Set to true to allow Agent Forwarding.|
|
||||
|`ssh_pam_support` | true | true if SSH has PAM support.|
|
||||
|`ssh_use_pam` | false | false to disable pam authentication.|
|
||||
|`ssh_gssapi_support` | true | true if SSH has GSSAPI support.|
|
||||
|`ssh_kerberos_support` | true | true if SSH has Kerberos support.|
|
||||
|`ssh_deny_users` | '' | if specified, login is disallowed for user names that match one of the patterns.|
|
||||
|`ssh_allow_users` | '' | if specified, login is allowed only for user names that match one of the patterns.|
|
||||
|`ssh_deny_groups` | '' | if specified, login is disallowed for users whose primary group or supplementary group list matches one of the patterns.|
|
||||
|`ssh_allow_groups` | '' | if specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns.|
|
||||
|`ssh_authorized_keys_file` | '' | change default file that contains the public keys that can be used for user authentication.|
|
||||
|`ssh_trusted_user_ca_keys_file` | '' | specifies the file containing trusted certificate authorities public keys used to sign user certificates. |
|
||||
|`ssh_trusted_user_ca_keys` | [] | set the trusted certificate authorities public keys used to sign user certificates. Only used if ssh_trusted_user_ca_keys_file is set. |
|
||||
|`ssh_authorized_principals_file` | '' | specifies the file containing principals that are allowed. Only used if ssh_trusted_user_ca_keys_file is set. |
|
||||
|`ssh_authorized_principals` | [] | list of hashes containing file paths and authorized principals, see default_custom.yml for all options. Only used if ssh_authorized_principals_file is set. |
|
||||
|`ssh_print_motd` | false | false to disable printing of the MOTD|
|
||||
|`ssh_print_last_log` | false | false to disable display of last login information|
|
||||
|`sftp_enabled` | false | true to enable sftp configuration|
|
||||
|`sftp_chroot` | true | false to disable chroot for sftp|
|
||||
|`sftp_chroot_dir` | /home/%u | change default sftp chroot location|
|
||||
|`ssh_client_roaming` | false | enable experimental client roaming|
|
||||
|`sshd_moduli_file` | '/etc/ssh/moduli' | path to the SSH moduli file |
|
||||
|`sshd_moduli_minimum` | 2048 | remove Diffie-Hellman parameters smaller than the defined size to mitigate logjam|
|
||||
|`ssh_challengeresponseauthentication` | false | Specifies whether challenge-response authentication is allowed (e.g. via PAM) |
|
||||
|`ssh_client_password_login` | false | `true` to allow password-based authentication with the ssh client |
|
||||
|`ssh_server_password_login` | false | `true` to allow password-based authentication with the ssh server |
|
||||
|`ssh_google_auth` | false | `true` to enable google authenticator based TOTP 2FA |
|
||||
|`ssh_pam_device` | false | `true` to enable public key auth with pam device 2FA |
|
||||
|`ssh_banner` | `false` | `true` to print a banner on login |
|
||||
|`ssh_client_hardening` | `true` | `false` to stop harden the client |
|
||||
|`ssh_client_port` | `'22'` | Specifies the port number to connect on the remote host. |
|
||||
|`ssh_compression` | `false` | Specifies whether compression is enabled after the user has authenticated successfully. |
|
||||
|`ssh_max_auth_retries` | `2` | Specifies the maximum number of authentication attempts permitted per connection. |
|
||||
|`ssh_print_debian_banner` | `false` | `true` to print debian specific banner |
|
||||
|`ssh_server_enabled` | `true` | `false` to disable the opensshd server |
|
||||
|`ssh_server_hardening` | `true` | `false` to stop harden the server |
|
||||
|`ssh_server_match_group` | '' | Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file. |
|
||||
|`ssh_server_match_user` | '' | Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file. |
|
||||
|`ssh_server_permit_environment_vars` | `false` | `true` to specify that ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd |
|
||||
|`ssh_use_dns` | `false` | Specifies whether sshd should look up the remote host name, and to check that the resolved host name for the remote IP address maps back to the very same IP address. |
|
||||
|`ssh_server_revoked_keys` | [] | a list of revoked public keys that the ssh server will always reject, useful to revoke known weak or compromised keys.|
|
||||
|`ssh_max_startups` | '10:30:100' | Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon.|
|
||||
|`ssh_macs` | [] | Change this list to overwrite macs. Defaults found in `defaults/main.yml` |
|
||||
|`ssh_kex` | [] | Change this list to overwrite kexs. Defaults found in `defaults/main.yml` |
|
||||
|`ssh_ciphers` | [] | Change this list to overwrite ciphers. Defaults found in `defaults/main.yml` |
|
||||
|
||||
## Example Playbook
|
||||
|
||||
|
@ -119,11 +146,9 @@ Always look into log files first and if possible look at the negotation between
|
|||
|
||||
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.
|
||||
|
||||
**After using the role Ansibles template/copy/file module does not work anymore!**
|
||||
|
||||
This role deactivates SFTP. Ansible uses by default SFTP to transfer files to the remote hosts. You have to set `scp_if_ssh = True` in your ansible.cfg. This way Ansible uses SCP to copy files.
|
||||
This role by default deactivates SFTP. Ansible uses by default SFTP to transfer files to the remote hosts. You have to set `scp_if_ssh = True` in your ansible.cfg. This way Ansible uses SCP to copy files. Alternatively you can enable SFTP again by setting `sftp_enabled` to `true`.
|
||||
|
||||
**Cannot restart sshd-service due to lack of privileges**
|
||||
|
||||
|
@ -145,7 +170,7 @@ See [contributor guideline](CONTRIBUTING.md).
|
|||
|
||||
## License and Author
|
||||
|
||||
* Author:: Sebastian Gumprich <sebastian.gumprich@38.de>
|
||||
* Author:: Sebastian Gumprich
|
||||
* Author:: Christoph Hartmann <chris@lollyrock.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
# config file for ansible -- http://ansible.com/
|
||||
# ==============================================
|
||||
|
||||
# nearly all parameters can be overridden in ansible-playbook
|
||||
# nearly all parameters can be overridden in ansible-playbook
|
||||
# or with command line flags. ansible will read ANSIBLE_CONFIG,
|
||||
# ansible.cfg in the current working directory, .ansible.cfg in
|
||||
# the home directory or /etc/ansible/ansible.cfg, whichever it
|
||||
# finds first
|
||||
|
||||
[defaults]
|
||||
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d by {uid} on {host}
|
||||
ansible_managed = Ansible managed: {file} modified by {uid} on {host}
|
||||
roles_path = /vagrant
|
||||
|
||||
role_path = /vagrant
|
||||
[ssh_connection]
|
||||
scp_if_ssh = True
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
---
|
||||
- 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
|
||||
roles:
|
||||
- ansible-ssh-hardening
|
||||
vars:
|
||||
network_ipv6_enable: true
|
||||
ssh_allow_root_with_key: true
|
||||
ssh_client_password_login: true
|
||||
ssh_client_cbc_required: true
|
||||
ssh_server_weak_hmac: true
|
||||
ssh_client_weak_kex: true
|
||||
ssh_remote_hosts:
|
||||
- names: ['example.com', 'example2.com']
|
||||
options: ['Port 2222', 'ForwardAgent yes']
|
||||
- names: ['example3.com']
|
||||
options: ['StrictHostKeyChecking no']
|
||||
|
||||
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
|
||||
hosts: localhost
|
||||
roles:
|
||||
- ansible-ssh-hardening
|
|
@ -1,24 +1,22 @@
|
|||
# true if IPv6 is needed
|
||||
network_ipv6_enable: false # sshd + ssh
|
||||
|
||||
# true if sshd should be started and enabled
|
||||
ssh_server_enabled: true # sshd
|
||||
|
||||
# true if DNS resolutions are needed, look up the remote host name, defaults to false from 6.8, see: http://www.openssh.com/txt/release-6.8
|
||||
ssh_use_dns: false # sshd
|
||||
|
||||
# true or value if compression is needed
|
||||
ssh_compression: false # sshd
|
||||
|
||||
# For which components (client and server) to generate the configuration for. Can be useful when running against a client without an SSH server.
|
||||
ssh_client_hardening: true # ssh
|
||||
ssh_server_hardening: true # sshd
|
||||
|
||||
# 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_client_cbc_required: false # ssh
|
||||
ssh_server_cbc_required: false # sshd
|
||||
|
||||
# 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_client_weak_hmac: false # ssh
|
||||
ssh_server_weak_hmac: false # sshd
|
||||
|
||||
# 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_client_weak_kex: false # ssh
|
||||
ssh_server_weak_kex: false # sshd
|
||||
|
||||
# If true, password login is allowed. For sshd, it is always set to no password login.
|
||||
# If true, password login is allowed
|
||||
ssh_client_password_login: false # ssh
|
||||
ssh_server_password_login: false # sshd
|
||||
|
||||
# ports on which ssh-server should listen
|
||||
ssh_server_ports: ['22'] # sshd
|
||||
|
@ -30,14 +28,17 @@ ssh_client_port: '22' # ssh
|
|||
ssh_listen_to: ['0.0.0.0'] # sshd
|
||||
|
||||
# Host keys to look for when starting sshd.
|
||||
ssh_host_key_files: ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key'] # sshd
|
||||
ssh_host_key_files: [] # sshd
|
||||
|
||||
# Specifies the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged.
|
||||
ssh_max_auth_retries: 2
|
||||
|
||||
ssh_client_alive_interval: 600 # sshd
|
||||
ssh_client_alive_interval: 300 # sshd
|
||||
ssh_client_alive_count: 3 # sshd
|
||||
|
||||
# Allow SSH Tunnels
|
||||
ssh_permit_tunnel: false
|
||||
|
||||
# Hosts with custom options. # ssh
|
||||
# Example:
|
||||
# ssh_remote_hosts:
|
||||
|
@ -53,12 +54,31 @@ ssh_allow_root_with_key: false # sshd
|
|||
# false to disable TCP Forwarding. Set to true to allow TCP Forwarding.
|
||||
ssh_allow_tcp_forwarding: false # sshd
|
||||
|
||||
# false to disable binding forwarded ports to non-loopback addresses. Set to true to force binding on wildcard address.
|
||||
# Set to 'clientspecified' to allow the client to specify which address to bind to.
|
||||
ssh_gateway_ports: false # sshd
|
||||
|
||||
# false to disable Agent Forwarding. Set to true to allow Agent Forwarding.
|
||||
ssh_allow_agent_forwarding: false # sshd
|
||||
|
||||
# true if SSH has PAM support
|
||||
ssh_pam_support: true
|
||||
|
||||
# false to disable pam authentication.
|
||||
ssh_use_pam: false # sshd
|
||||
|
||||
# false to disable google 2fa authentication
|
||||
ssh_google_auth: false # sshd
|
||||
|
||||
# false to disable pam device 2FA input
|
||||
ssh_pam_device: false # sshd
|
||||
|
||||
# true if SSH support GSSAPI
|
||||
ssh_gssapi_support: true
|
||||
|
||||
# true if SSH support Kerberos
|
||||
ssh_kerberos_support: true
|
||||
|
||||
# if specified, login is disallowed for user names that match one of the patterns.
|
||||
ssh_deny_users: '' # sshd
|
||||
|
||||
|
@ -71,6 +91,36 @@ ssh_deny_groups: '' # sshd
|
|||
# if specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns.
|
||||
ssh_allow_groups: '' # sshd
|
||||
|
||||
# change default file that contains the public keys that can be used for user authentication.
|
||||
ssh_authorized_keys_file: '' # sshd
|
||||
|
||||
# specifies the file containing trusted certificate authorities public keys used to sign user certificates.
|
||||
ssh_trusted_user_ca_keys_file: '' # sshd
|
||||
|
||||
# set the trusted certificate authorities public keys used to sign user certificates.
|
||||
# Example:
|
||||
# ssh_trusted_user_ca_keys:
|
||||
# - 'ssh-rsa ... comment1'
|
||||
# - 'ssh-rsa ... comment2'
|
||||
ssh_trusted_user_ca_keys: [] # sshd
|
||||
|
||||
# specifies the file containing principals that are allowed. Only used if ssh_trusted_user_ca_keys_file is set.
|
||||
# Example:
|
||||
# ssh_authorized_principals_file: '/etc/ssh/auth_principals/%u'
|
||||
#
|
||||
# %h is replaced by the home directory of the user being authenticated, and %u is
|
||||
# replaced by the username of that user. After expansion, the path is taken to be
|
||||
# an absolute path or one relative to the user's home directory.
|
||||
#
|
||||
ssh_authorized_principals_file: '' # sshd
|
||||
|
||||
# list of hashes containing file paths and authorized principals. Only used if ssh_authorized_principals_file is set.
|
||||
# Example:
|
||||
# ssh_authorized_principals:
|
||||
# - { path: '/etc/ssh/auth_principals/root', principals: [ 'root' ], owner: "{{ ssh_owner }}", group: "{{ ssh_group }}", directoryowner: "{{ ssh_owner }}", directorygroup: "{{ ssh_group}}" }
|
||||
# - { path: '/etc/ssh/auth_principals/myuser', principals: [ 'masteradmin', 'webserver' ] }
|
||||
ssh_authorized_principals: [] # sshd
|
||||
|
||||
# false to disable printing of the MOTD
|
||||
ssh_print_motd: false # sshd
|
||||
|
||||
|
@ -86,16 +136,33 @@ ssh_print_debian_banner: false # sshd (Debian OS family only)
|
|||
# true to enable sftp configuration
|
||||
sftp_enabled: false
|
||||
|
||||
# false to disable sftp chroot
|
||||
sftp_chroot: true
|
||||
|
||||
# change default sftp chroot location
|
||||
sftp_chroot_dir: /home/%u
|
||||
|
||||
# enable experimental client roaming
|
||||
ssh_client_roaming: false
|
||||
|
||||
# list of hashes (containing user and rules) to generate Match User blocks for.
|
||||
ssh_server_match_user: false # sshd
|
||||
|
||||
# list of hashes (containing group and rules) to generate Match Group blocks for.
|
||||
ssh_server_match_group: false # sshd
|
||||
|
||||
ssh_server_permit_environment_vars: false
|
||||
|
||||
# maximum number of concurrent unauthenticated connections to the SSH daemon
|
||||
ssh_max_startups: '10:30:100' # sshd
|
||||
|
||||
ssh_ps53: 'yes'
|
||||
ssh_ps59: 'sandbox'
|
||||
|
||||
ssh_macs: []
|
||||
ssh_ciphers: []
|
||||
ssh_kex: []
|
||||
|
||||
ssh_macs_53_default:
|
||||
- hmac-ripemd160
|
||||
- hmac-sha1
|
||||
|
@ -105,26 +172,25 @@ ssh_macs_59_default:
|
|||
- hmac-sha2-256
|
||||
- hmac-ripemd160
|
||||
|
||||
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_66_weak: "{{ ssh_macs_66_default + ['hmac-sha1'] }}"
|
||||
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_ciphers_53_default:
|
||||
- aes256-ctr
|
||||
- aes192-ctr
|
||||
- aes128-ctr
|
||||
|
||||
ssh_ciphers_53_weak: "{{ ssh_ciphers_53_default + ['aes256-cbc', 'aes192-cbc', 'aes128-cbc'] }}"
|
||||
|
||||
ssh_ciphers_66_default:
|
||||
- chacha20-poly1305@openssh.com
|
||||
- aes256-gcm@openssh.com
|
||||
|
@ -133,23 +199,25 @@ ssh_ciphers_66_default:
|
|||
- aes192-ctr
|
||||
- aes128-ctr
|
||||
|
||||
ssh_ciphers_66_weak: "{{ ssh_ciphers_66_default + ['aes256-cbc', 'aes192-cbc', 'aes128-cbc'] }}"
|
||||
|
||||
ssh_kex_59_default:
|
||||
- diffie-hellman-group-exchange-sha256
|
||||
|
||||
ssh_kex_59_weak: "{{ ssh_kex_59_default + ['diffie-hellman-group14-sha1', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group1-sha1'] }}"
|
||||
|
||||
ssh_kex_66_default:
|
||||
- curve25519-sha256@libssh.org
|
||||
- diffie-hellman-group-exchange-sha256
|
||||
|
||||
ssh_kex_66_weak: "{{ ssh_kex_66_default + ['diffie-hellman-group14-sha1', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group1-sha1'] }}"
|
||||
|
||||
# directory where to store ssh_password policy
|
||||
ssh_custom_selinux_dir: '/etc/selinux/local-policies'
|
||||
|
||||
sshd_moduli_file: '/etc/ssh/moduli'
|
||||
sshd_moduli_minimum: 2048
|
||||
|
||||
# disable ChallengeResponseAuthentication
|
||||
ssh_challengeresponseauthentication: false
|
||||
|
||||
# a list of public keys that are never accepted by the ssh server
|
||||
ssh_server_revoked_keys: []
|
||||
|
||||
# Set to false to turn the role into a no-op. Useful when using
|
||||
# the Ansible role dependency mechanism.
|
||||
ssh_hardening_enabled: true
|
|
@ -1,2 +1,4 @@
|
|||
- name: restart sshd
|
||||
service: name={{ sshd_service_name }} state=restarted
|
||||
when: "(ssh_server_enabled|bool)"
|
||||
become: yes
|
||||
|
|
|
@ -1 +1 @@
|
|||
{install_date: 'Sun Apr 23 07:59:24 2017', version: 4.0.0}
|
||||
{install_date: 'Mon Dec 17 12:48:22 2018', version: 5.0.0}
|
||||
|
|
|
@ -4,7 +4,7 @@ galaxy_info:
|
|||
description: 'This Ansible role provides numerous security-related ssh configurations, providing all-round base protection.'
|
||||
company: Hardening Framework Team
|
||||
license: Apache License 2.0
|
||||
min_ansible_version: '2.2.1'
|
||||
min_ansible_version: '2.4'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
|
@ -19,6 +19,7 @@ galaxy_info:
|
|||
versions:
|
||||
- wheezy
|
||||
- jessie
|
||||
- name: Amazon
|
||||
galaxy_tags:
|
||||
- system
|
||||
- security
|
||||
|
|
36
ansible/roles/dev-sec.ssh-hardening/tasks/2fa.yml
Normal file
36
ansible/roles/dev-sec.ssh-hardening/tasks/2fa.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
# Install the 2FA packages and setup the config in PAM and SSH
|
||||
- name: Install google authenticator PAM module
|
||||
apt:
|
||||
name: 'libpam-google-authenticator'
|
||||
state: present
|
||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
||||
|
||||
- name: Install google authenticator PAM module
|
||||
yum:
|
||||
name: 'google-authenticator'
|
||||
state: present
|
||||
when: ansible_os_family == 'RedHat' or ansible_os_family == 'Oracle Linux'
|
||||
|
||||
- name: Add google auth module to PAM
|
||||
pamd:
|
||||
name: 'sshd'
|
||||
type: 'auth'
|
||||
control: 'required'
|
||||
module_path: 'pam_google_authenticator.so'
|
||||
|
||||
- name: Remove password auth from PAM
|
||||
pamd:
|
||||
name: 'sshd'
|
||||
type: 'auth'
|
||||
control: 'substack'
|
||||
module_path: 'password-auth'
|
||||
state: absent
|
||||
when: ansible_distribution == 'RedHat' or ansible_distribution == 'Oracle Linux' or ansible_distribution == 'Amazon'
|
||||
|
||||
- name: Remove password auth from PAM
|
||||
replace:
|
||||
dest: '/etc/pam.d/sshd'
|
||||
regexp: '^@include common-auth'
|
||||
replace: '#@include common-auth'
|
||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
- name: Set ssh CA pub keys
|
||||
template:
|
||||
src: 'trusted_user_ca_keys.j2'
|
||||
dest: '{{ ssh_trusted_user_ca_keys_file }}'
|
||||
mode: '0644'
|
||||
owner: '{{ ssh_owner }}'
|
||||
group: '{{ ssh_group }}'
|
||||
notify: restart sshd
|
||||
|
||||
- name: Create ssh authorized principals directories
|
||||
file:
|
||||
path: '{{ item.path | dirname }}'
|
||||
mode: '{{ item.directorymode | default(0700) }}'
|
||||
owner: '{{ item.directoryowner | default(ssh_owner) }}'
|
||||
group: '{{ item.directorygroup | default(ssh_group) }}'
|
||||
state: directory
|
||||
with_items: '{{ ssh_authorized_principals }}'
|
||||
|
||||
- name: Set ssh authorized principals
|
||||
template:
|
||||
src: 'authorized_principals.j2'
|
||||
dest: '{{ item.path }}'
|
||||
mode: '{{ item.filemode | default(0600) }}'
|
||||
owner: '{{ item.owner| default(ssh_owner) }}'
|
||||
group: '{{ item.group | default(ssh_group) }}'
|
||||
with_items: '{{ ssh_authorized_principals }}'
|
63
ansible/roles/dev-sec.ssh-hardening/tasks/crypto.yml
Normal file
63
ansible/roles/dev-sec.ssh-hardening/tasks/crypto.yml
Normal file
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
|
||||
- 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 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 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 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 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 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 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 kex according to openssh-version
|
||||
set_fact:
|
||||
ssh_kex: '{{ ssh_kex_59_default }}'
|
||||
when: sshd_version.stdout >= '5.9' and not ssh_kex
|
||||
|
83
ansible/roles/dev-sec.ssh-hardening/tasks/hardening.yml
Normal file
83
ansible/roles/dev-sec.ssh-hardening/tasks/hardening.yml
Normal file
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
- name: Set OS dependent variables
|
||||
include_vars: '{{ item }}'
|
||||
with_first_found:
|
||||
- '{{ ansible_distribution }}_{{ ansible_distribution_major_version }}.yml'
|
||||
- '{{ ansible_distribution }}.yml'
|
||||
- '{{ ansible_os_family }}_{{ ansible_distribution_major_version }}.yml'
|
||||
- '{{ ansible_os_family }}.yml'
|
||||
|
||||
- name: get openssh-version
|
||||
shell: ssh -V 2>&1 | sed -r 's/.*_([0-9]*\.[0-9]).*/\1/g'
|
||||
args:
|
||||
executable: /bin/sh
|
||||
changed_when: false
|
||||
register: sshd_version
|
||||
check_mode: no
|
||||
|
||||
- name: include tasks to create crypo-vars
|
||||
include_tasks: 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 }}'
|
||||
notify: restart sshd
|
||||
when: ssh_server_hardening
|
||||
|
||||
- name: create sshd_config and set permissions to root/600
|
||||
template:
|
||||
src: 'opensshd.conf.j2'
|
||||
dest: '/etc/ssh/sshd_config'
|
||||
mode: '0600'
|
||||
owner: '{{ ssh_owner }}'
|
||||
group: '{{ ssh_group }}'
|
||||
validate: '/usr/sbin/sshd -T -f %s'
|
||||
notify: restart sshd
|
||||
when: ssh_server_hardening
|
||||
|
||||
- name: create ssh_config and set permissions to root/644
|
||||
template:
|
||||
src: 'openssh.conf.j2'
|
||||
dest: '/etc/ssh/ssh_config'
|
||||
mode: '0644'
|
||||
owner: '{{ ssh_owner }}'
|
||||
group: '{{ ssh_group }}'
|
||||
when: ssh_client_hardening
|
||||
|
||||
- name: Check if {{ sshd_moduli_file }} contains weak DH parameters
|
||||
shell: awk '$5 < {{ sshd_moduli_minimum }}' {{ sshd_moduli_file }}
|
||||
register: sshd_register_moduli
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
|
||||
- name: remove all small primes
|
||||
shell: awk '$5 >= {{ sshd_moduli_minimum }}' {{ sshd_moduli_file }} > {{ sshd_moduli_file }}.new ;
|
||||
[ -r {{ sshd_moduli_file }}.new -a -s {{ sshd_moduli_file }}.new ] && mv {{ sshd_moduli_file }}.new {{ sshd_moduli_file }} || true
|
||||
notify: restart sshd
|
||||
when: sshd_register_moduli.stdout
|
||||
|
||||
- name: include tasks to setup ca keys and principals
|
||||
include_tasks: ca_keys_and_principals.yml
|
||||
when: ssh_trusted_user_ca_keys_file != ''
|
||||
|
||||
- name: include tasks to setup 2FA
|
||||
include_tasks: 2fa.yml
|
||||
when:
|
||||
- ssh_use_pam
|
||||
- ssh_challengeresponseauthentication
|
||||
- ssh_google_auth
|
||||
|
||||
- name: test to see if selinux is installed and running
|
||||
command: getenforce
|
||||
register: sestatus
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
|
||||
- name: include selinux specific tasks
|
||||
include_tasks: selinux.yml
|
||||
when: sestatus.rc == 0
|
|
@ -1,105 +1,4 @@
|
|||
---
|
||||
- name: Set OS dependent variables
|
||||
include_vars: "{{ item }}"
|
||||
with_first_found:
|
||||
- "{{ ansible_distribution }}_{{ ansible_distribution_major_version }}.yml"
|
||||
- "{{ ansible_distribution }}.yml"
|
||||
- "{{ ansible_os_family }}_{{ ansible_distribution_major_version }}.yml"
|
||||
- "{{ ansible_os_family }}.yml"
|
||||
|
||||
- name: get openssh-version
|
||||
shell: ssh -V 2>&1 | sed -r 's/.*_([0-9]*\.[0-9]).*/\1/g'
|
||||
changed_when: false
|
||||
register: sshd_version
|
||||
|
||||
- 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'
|
||||
|
||||
- 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'
|
||||
|
||||
- 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'
|
||||
|
||||
- name: create sshd_config and set permissions to root/600
|
||||
template: src='opensshd.conf.j2' dest='/etc/ssh/sshd_config' mode=0600 owner="{{ ssh_owner }}" group="{{ ssh_group }}" validate="/usr/sbin/sshd -T -f %s"
|
||||
notify: restart sshd
|
||||
when: ssh_server_hardening
|
||||
|
||||
- name: create ssh_config and set permissions to root/644
|
||||
template: src='openssh.conf.j2' dest='/etc/ssh/ssh_config' mode=0644 owner="{{ ssh_owner }}" group="{{ ssh_group }}"
|
||||
when: ssh_client_hardening
|
||||
|
||||
- name: Check if /etc/ssh/moduli contains weak DH parameters
|
||||
shell: awk '$5 < {{ sshd_moduli_minimum }}' /etc/ssh/moduli
|
||||
register: sshd_register_moduli
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
|
||||
- name: remove all small primes
|
||||
shell: awk '$5 >= {{ sshd_moduli_minimum }}' /etc/ssh/moduli > /etc/ssh/moduli.new ;
|
||||
[ -r /etc/ssh/moduli.new -a -s /etc/ssh/moduli.new ] && mv /etc/ssh/moduli.new /etc/ssh/moduli || true
|
||||
notify: restart sshd
|
||||
when: sshd_register_moduli.stdout
|
||||
|
||||
- name: test to see if selinux is running
|
||||
command: getenforce
|
||||
register: sestatus
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
|
||||
- block: # only runs when selinux is running
|
||||
- name: install selinux dependencies when selinux is installed on RHEL or Oracle Linux
|
||||
yum: name="{{item}}" state=installed
|
||||
with_items:
|
||||
- policycoreutils-python
|
||||
- checkpolicy
|
||||
when: ansible_os_family == 'RedHat' or ansible_os_family == 'Oracle Linux'
|
||||
|
||||
- name: install selinux dependencies when selinux is installed on Debian or Ubuntu
|
||||
apt: name="{{item}}" state=installed
|
||||
with_items:
|
||||
- policycoreutils
|
||||
- checkpolicy
|
||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
||||
|
||||
- name: check if ssh_password module is already installed
|
||||
shell: "semodule -l| grep ssh_password"
|
||||
register: ssh_password_module
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
|
||||
# The following tasks only get executed when selinux is in state enforcing, UsePam is "no" and the ssh_password module is installed.
|
||||
# See this issue for more info: https://github.com/hardening-io/ansible-ssh-hardening/issues/23
|
||||
- block:
|
||||
- name: Create selinux custom policy drop folder
|
||||
file: path='{{ ssh_custom_selinux_dir }}' state=directory owner=root group=root mode=0750
|
||||
|
||||
- name: Distributing custom selinux policies
|
||||
copy: src='ssh_password' dest='{{ ssh_custom_selinux_dir }}'
|
||||
|
||||
- name: check and compile policy
|
||||
shell: checkmodule -M -m -o {{ ssh_custom_selinux_dir }}/ssh_password.mod {{ ssh_custom_selinux_dir }}/ssh_password
|
||||
|
||||
- name: create selinux policy module package
|
||||
shell: semodule_package -o {{ ssh_custom_selinux_dir }}/ssh_password.pp -m {{ ssh_custom_selinux_dir }}/ssh_password.mod
|
||||
|
||||
- name: install selinux policy
|
||||
shell: semodule -i {{ ssh_custom_selinux_dir }}/ssh_password.pp
|
||||
|
||||
when: not ssh_use_pam and sestatus.stdout != 'Disabled' and ssh_password_module.stdout.find('ssh_password') != 0
|
||||
|
||||
# The following tasks only get executed when selinux is in state enforcing, UsePam is "yes" and the ssh_password module is installed.
|
||||
- name: remove selinux-policy when Pam is used, because Allowing sshd to read the shadow file directly is considered a potential security risk (http://danwalsh.livejournal.com/12333.html)
|
||||
shell: semodule -r ssh_password
|
||||
when: ssh_use_pam and ssh_password_module.stdout.find('ssh_password') == 0
|
||||
|
||||
when: sestatus.rc == 0
|
||||
- include_tasks: hardening.yml
|
||||
when: ssh_hardening_enabled
|
||||
|
|
57
ansible/roles/dev-sec.ssh-hardening/tasks/selinux.yml
Normal file
57
ansible/roles/dev-sec.ssh-hardening/tasks/selinux.yml
Normal file
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
- name: install selinux dependencies when selinux is installed on RHEL or Oracle Linux
|
||||
package:
|
||||
name: '{{ item }}'
|
||||
state: present
|
||||
with_items:
|
||||
- 'policycoreutils-python'
|
||||
- 'checkpolicy'
|
||||
when: ansible_os_family == 'RedHat' or ansible_os_family == 'Oracle Linux'
|
||||
|
||||
- name: install selinux dependencies when selinux is installed on Debian or Ubuntu
|
||||
apt:
|
||||
name: '{{ item }}'
|
||||
state: present
|
||||
with_items:
|
||||
- 'policycoreutils'
|
||||
- 'checkpolicy'
|
||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
||||
|
||||
- name: check if ssh_password module is already installed
|
||||
shell: 'semodule -l | grep ssh_password'
|
||||
register: ssh_password_module
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
|
||||
# The following tasks only get executed when selinux is in state enforcing, UsePam is 'no' and the ssh_password module is installed.
|
||||
# See this issue for more info: https://github.com/hardening-io/ansible-ssh-hardening/issues/23
|
||||
- block:
|
||||
- name: Create selinux custom policy drop folder
|
||||
file:
|
||||
path: '{{ ssh_custom_selinux_dir }}'
|
||||
state: 'directory'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0750'
|
||||
|
||||
- name: Distributing custom selinux policies
|
||||
copy:
|
||||
src: 'ssh_password'
|
||||
dest: '{{ ssh_custom_selinux_dir }}'
|
||||
|
||||
- name: check and compile policy
|
||||
shell: checkmodule -M -m -o {{ ssh_custom_selinux_dir }}/ssh_password.mod {{ ssh_custom_selinux_dir }}/ssh_password
|
||||
|
||||
- name: create selinux policy module package
|
||||
shell: semodule_package -o {{ ssh_custom_selinux_dir }}/ssh_password.pp -m {{ ssh_custom_selinux_dir }}/ssh_password.mod
|
||||
|
||||
- name: install selinux policy
|
||||
shell: semodule -i {{ ssh_custom_selinux_dir }}/ssh_password.pp
|
||||
|
||||
when: not ssh_use_pam and sestatus.stdout != 'Disabled' and ssh_password_module.stdout.find('ssh_password') != 0
|
||||
|
||||
# The following tasks only get executed when selinux is installed, UsePam is 'yes' and the ssh_password module is installed.
|
||||
- name: remove selinux-policy when Pam is used, because Allowing sshd to read the shadow file directly is considered a potential security risk (http://danwalsh.livejournal.com/12333.html)
|
||||
command: semodule -r ssh_password
|
||||
when: ssh_use_pam and ssh_password_module.stdout.find('ssh_password') == 0
|
|
@ -0,0 +1,5 @@
|
|||
# {{ansible_managed|comment}}
|
||||
|
||||
{% for principal in item.principals %}
|
||||
{{ principal }}
|
||||
{% endfor %}
|
|
@ -1,4 +1,4 @@
|
|||
# {{ansible_managed}}
|
||||
# {{ansible_managed|comment}}
|
||||
|
||||
# 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.
|
||||
|
@ -45,44 +45,23 @@ 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
|
||||
|
@ -90,23 +69,10 @@ StrictHostKeyChecking ask
|
|||
# **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
|
||||
|
@ -116,10 +82,11 @@ ForwardX11 no
|
|||
|
||||
# Never use host-based authentication. It can be exploited.
|
||||
HostbasedAuthentication no
|
||||
{% if sshd_version.stdout | float < 7.4 -%}
|
||||
RhostsRSAAuthentication no
|
||||
|
||||
# Enable RSA authentication via identity files.
|
||||
RSAAuthentication yes
|
||||
{% endif %}
|
||||
|
||||
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
|
||||
PasswordAuthentication {{ 'yes' if ssh_client_password_login else 'no' }}
|
||||
|
@ -144,5 +111,7 @@ Compression yes
|
|||
#EscapeChar ~
|
||||
#VisualHostKey yes
|
||||
|
||||
{% if sshd_version.stdout | float <= 7.1 -%}
|
||||
# Disable experimental client roaming. This is known to cause potential issues with secrets being disclosed to malicious servers and defaults to being disabled.
|
||||
UseRoaming {{ 'yes' if ssh_client_roaming else 'no' }}
|
||||
{% endif %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# {{ansible_managed}}
|
||||
# {{ansible_managed|comment}}
|
||||
|
||||
# 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.
|
||||
|
@ -7,7 +7,7 @@
|
|||
# ===================
|
||||
|
||||
# Either disable or only allowssh root login via certificates.
|
||||
PermitRootLogin {{ 'without-password' if ssh_allow_root_with_key else 'no' }}
|
||||
PermitRootLogin {{ 'without-password' if (ssh_allow_root_with_key|bool) else 'no' }}
|
||||
|
||||
# Define which port sshd should listen to. Default to `22`.
|
||||
{% for port in ssh_server_ports -%}
|
||||
|
@ -15,7 +15,7 @@ Port {{port}}
|
|||
{% endfor %}
|
||||
|
||||
# Address family should always be limited to the active network configuration.
|
||||
AddressFamily {{ 'any' if network_ipv6_enable else 'inet' }}
|
||||
AddressFamily {{ 'any' if (network_ipv6_enable|bool) else 'inet' }}
|
||||
|
||||
# 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 -%}
|
||||
|
@ -48,40 +48,17 @@ LogLevel VERBOSE
|
|||
# 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') 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_server_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
|
||||
|
@ -90,34 +67,22 @@ LogLevel VERBOSE
|
|||
# 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') 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_server_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_server_weak_kex -%}
|
||||
KexAlgorithms {{ sshd_kex_59_weak | join(',') }}
|
||||
{% else -%}
|
||||
KexAlgorithms {{ ssh_kex_59_default | join(',') }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{# 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 }}
|
||||
|
||||
# Authentication
|
||||
# --------------
|
||||
|
||||
# Secure Login directives.
|
||||
UseLogin no
|
||||
{% if sshd_version.stdout | float < 7.5 -%}
|
||||
UsePrivilegeSeparation {% if (ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version <= '6') -%}{{ssh_ps53}}{% else %}{{ssh_ps59}}{% endif %}
|
||||
{% endif %}
|
||||
|
||||
PermitUserEnvironment no
|
||||
LoginGraceTime 30s
|
||||
MaxAuthTries {{ssh_max_auth_retries}}
|
||||
MaxSessions 10
|
||||
MaxStartups 10:30:100
|
||||
MaxStartups {{ssh_max_startups}}
|
||||
|
||||
# Enable public key authentication
|
||||
PubkeyAuthentication yes
|
||||
|
@ -128,22 +93,37 @@ IgnoreUserKnownHosts yes
|
|||
HostbasedAuthentication no
|
||||
|
||||
# Enable PAM to enforce system wide rules
|
||||
UsePAM {{ 'yes' if ssh_use_pam else 'no' }}
|
||||
{% if ssh_pam_support -%}
|
||||
UsePAM {{ 'yes' if (ssh_use_pam|bool) else 'no' }}
|
||||
{% endif %}
|
||||
{% if ssh_google_auth %}
|
||||
# Force public key auth then ask for google auth code
|
||||
AuthenticationMethods publickey,keyboard-interactive
|
||||
{% endif %}
|
||||
|
||||
# Force public key auth then ask for pam device input
|
||||
{% if ssh_pam_device %}
|
||||
AuthenticationMethods publickey,keyboard-interactive:pam
|
||||
{% endif %}
|
||||
|
||||
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
|
||||
PasswordAuthentication no
|
||||
PasswordAuthentication {{ 'yes' if (ssh_server_password_login|bool) else 'no' }}
|
||||
PermitEmptyPasswords no
|
||||
ChallengeResponseAuthentication {{ 'yes' if ssh_challengeresponseauthentication else 'no' }}
|
||||
ChallengeResponseAuthentication {{ 'yes' if (ssh_challengeresponseauthentication|bool) else 'no' }}
|
||||
|
||||
{% if ssh_kerberos_support -%}
|
||||
# Only enable Kerberos authentication if it is configured.
|
||||
KerberosAuthentication no
|
||||
KerberosOrLocalPasswd no
|
||||
KerberosTicketCleanup yes
|
||||
#KerberosGetAFSToken no
|
||||
{% endif %}
|
||||
|
||||
{% if ssh_gssapi_support -%}
|
||||
# Only enable GSSAPI authentication if it is configured.
|
||||
GSSAPIAuthentication no
|
||||
GSSAPICleanupCredentials yes
|
||||
{% endif %}
|
||||
|
||||
# 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 -%}
|
||||
|
@ -162,6 +142,17 @@ DenyGroups {{ssh_deny_groups}}
|
|||
AllowGroups {{ssh_allow_groups}}
|
||||
{% endif %}
|
||||
|
||||
{% if ssh_authorized_keys_file %}
|
||||
AuthorizedKeysFile {{ ssh_authorized_keys_file }}
|
||||
{% endif %}
|
||||
|
||||
{% if ssh_trusted_user_ca_keys_file %}
|
||||
TrustedUserCAKeys {{ ssh_trusted_user_ca_keys_file }}
|
||||
{% if ssh_authorized_principals_file %}
|
||||
AuthorizedPrincipalsFile {{ ssh_authorized_principals_file }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
# Network
|
||||
# -------
|
||||
|
||||
|
@ -173,52 +164,104 @@ ClientAliveInterval {{ssh_client_alive_interval}}
|
|||
ClientAliveCountMax {{ssh_client_alive_count}}
|
||||
|
||||
# Disable tunneling
|
||||
PermitTunnel no
|
||||
PermitTunnel {{ 'yes' if (ssh_permit_tunnel|bool) else 'no' }}
|
||||
|
||||
# Disable forwarding tcp connections.
|
||||
# no real advantage without denied shell access
|
||||
AllowTcpForwarding {{ 'yes' if ssh_allow_tcp_forwarding else 'no' }}
|
||||
AllowTcpForwarding {{ 'yes' if (ssh_allow_tcp_forwarding|bool) else 'no' }}
|
||||
|
||||
# Disable agent formwarding, since local agent could be accessed through forwarded connection.
|
||||
# no real advantage without denied shell access
|
||||
AllowAgentForwarding {{ 'yes' if ssh_allow_agent_forwarding else 'no' }}
|
||||
AllowAgentForwarding {{ 'yes' if (ssh_allow_agent_forwarding|bool) else 'no' }}
|
||||
|
||||
{% if ssh_gateway_ports|bool %}
|
||||
# Port forwardings are forced to bind to the wildcard address
|
||||
GatewayPorts yes
|
||||
{% elif ssh_gateway_ports == 'clientspecified' %}
|
||||
# Clients allowed to specify which address to bind port forwardings to
|
||||
GatewayPorts clientspecified
|
||||
{% else %}
|
||||
# Do not allow remote port forwardings to bind to non-loopback addresses.
|
||||
GatewayPorts no
|
||||
{% endif %}
|
||||
|
||||
# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
|
||||
X11Forwarding no
|
||||
X11UseLocalhost yes
|
||||
|
||||
# User environment configuration
|
||||
# ==============================
|
||||
|
||||
{% if ssh_server_permit_environment_vars %}
|
||||
PermitUserEnvironment yes
|
||||
{% for item in ssh_server_permit_environment_vars %}
|
||||
AcceptEnv {{ item }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
PermitUserEnvironment no
|
||||
{% endif %}
|
||||
|
||||
# Misc. configuration
|
||||
# ===================
|
||||
|
||||
PrintMotd {{ 'yes' if ssh_print_motd else 'no' }}
|
||||
Compression {{ 'yes' if (ssh_compression|bool) else 'no' }}
|
||||
|
||||
UseDNS {{ 'yes' if (ssh_use_dns|bool) else 'no' }}
|
||||
|
||||
PrintMotd {{ 'yes' if (ssh_print_motd|bool) else 'no' }}
|
||||
|
||||
{% if ansible_os_family != 'FreeBSD' %}
|
||||
PrintLastLog {{ 'yes' if ssh_print_last_log else 'no' }}
|
||||
PrintLastLog {{ 'yes' if (ssh_print_last_log|bool) else 'no' }}
|
||||
{% endif %}
|
||||
|
||||
Banner {{ '/etc/ssh/banner.txt' if ssh_banner else 'none' }}
|
||||
Banner {{ '/etc/ssh/banner.txt' if (ssh_banner|bool) else 'none' }}
|
||||
|
||||
{% if ansible_os_family == 'Debian' %}
|
||||
DebianBanner {{ 'yes' if ssh_print_debian_banner else 'no' }}
|
||||
DebianBanner {{ 'yes' if (ssh_print_debian_banner|bool) else 'no' }}
|
||||
{% endif %}
|
||||
|
||||
# Reject keys that are explicitly blacklisted
|
||||
RevokedKeys /etc/ssh/revoked_keys
|
||||
|
||||
{% if sftp_enabled %}
|
||||
# SFTP matching configuration
|
||||
# ===========================
|
||||
# Configuration, in case SFTP is used
|
||||
## override default of no subsystems
|
||||
## Subsystem sftp /opt/app/openssh5/libexec/sftp-server
|
||||
# override default of no subsystems
|
||||
# Subsystem sftp /opt/app/openssh5/libexec/sftp-server
|
||||
|
||||
Subsystem sftp internal-sftp -l INFO -f LOCAL6
|
||||
#
|
||||
## These lines must appear at the *end* of sshd_config
|
||||
|
||||
# These lines must appear at the *end* of sshd_config
|
||||
Match Group sftponly
|
||||
ForceCommand internal-sftp -l INFO -f LOCAL6
|
||||
ChrootDirectory {{ sftp_chroot_dir }}
|
||||
AllowTcpForwarding no
|
||||
AllowAgentForwarding no
|
||||
PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
X11Forwarding no
|
||||
ForceCommand internal-sftp -l INFO -f LOCAL6
|
||||
{% if sftp_chroot %}
|
||||
ChrootDirectory {{ sftp_chroot_dir }}
|
||||
{% endif %}
|
||||
AllowTcpForwarding no
|
||||
AllowAgentForwarding no
|
||||
PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
X11Forwarding no
|
||||
{% endif %}
|
||||
|
||||
{% if ssh_server_match_group %}
|
||||
# Group matching configuration
|
||||
# ============================
|
||||
|
||||
{% for item in ssh_server_match_group %}
|
||||
Match Group {{ item.group }}
|
||||
{{ item.rules | indent(4) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if ssh_server_match_user %}
|
||||
# User matching configuration
|
||||
# ===========================
|
||||
|
||||
{% for item in ssh_server_match_user %}
|
||||
Match User {{ item.user }}
|
||||
{{ item.rules | indent(4) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue