Ansible deployment

This commit is contained in:
Oleg Lavrovsky 2017-04-24 14:22:51 +02:00
parent 921522852a
commit 380481706e
137 changed files with 4532 additions and 40 deletions

1
.gitignore vendored
View file

@ -9,6 +9,7 @@
/static/
/media/
/tmp/
/.keys/
/.vagrant/
/Vagrantfile.local
/docs/_build/

View file

@ -66,8 +66,8 @@ Now access the admin panel with the user account you created earlier: http://loc
## Production notes
We suggest using Docker or [Dokku](http://dokku.viewdocs.io/) for automated deployment. There is a Makefile to help set up and manage the instance.
We use Ansible for automated deployment. You need to obtain an SSH and vault keys and place these in a `.keys` folder, then:
- Initial setup: `make setup`
- Startup: `make run-detached`
- Release: `make release`
```
ansible-playbook -s ansible/docker.yaml -i ansible/inventories/production
```

4
ansible.cfg Normal file
View file

@ -0,0 +1,4 @@
[defaults]
retry_files_enabled = False
roles_path = ansible/roles
vault_password_file = .keys/ansible.vault

9
ansible/docker.yaml Normal file
View file

@ -0,0 +1,9 @@
- hosts: webservers
become: yes
become_method: 'sudo'
gather_facts: yes
roles:
- role: docker-ubuntu
docker_users: ansible
- role: docker-compose
docker_compose_version: 1.12.0

10
ansible/harden.yaml Normal file
View file

@ -0,0 +1,10 @@
- hosts: webservers
become: True
gather_facts: True
roles:
- role: dev-sec.os-hardening
- role: dev-sec.ssh-hardening
become: yes
- dev-sec.nginx-hardening

View file

@ -0,0 +1,18 @@
---
django_project_name: publichealth
elasticsearch_heap_size: 1g
memcached_memory_allocation_mb: 256
nginx_worker_processes: 2
nginx_worker_connections: 1024
domain: "{{ vault_domain }}"
django_email_key: "{{ vault_django_email_key }}"
django_email_domain: "{{ vault_django_email_domain }}"
django_email_from: "{{ vault_django_email_from }}"
django_secret_key: "{{ vault_django_secret_key }}"

View file

@ -0,0 +1,18 @@
$ANSIBLE_VAULT;1.1;AES256
62653363616638643933303063396435316366376466643563316461343162633661346638343836
6232346565306638373931396164303438373261396630610a343536386335336634663239626637
36376137393433343636366137333336303764616536643864353630366535653936663531373439
3966363565633630620a373238363535653936383365656366306231666365656265303638393864
33323363373365613134393261393139656261323036656632366562316264346434393366656165
35363861303036316465326134653163303835376333633132633332303438666363386330303463
66376132396666396163306566663534646261653139343432663332323837666165653235633538
34613037306339623032613939663639663161336539333832333438306466653439306535343134
64363833666138626561363263323338376261343333623839366236343464363737616232633566
62633934323463623834653539613039636138666539666665333434663165636639303532333233
30363437633762366230326231653961373462383330336462313935643761316334666232613261
64613538363763666666303832393632373934343162613439616535663666373434333632633664
64623531383239636464393036346565373564356666626632613437303335653465386639623366
61636231383561336238336334303462643137633465303466633764336630636462626535666633
61386263316437346666633164616162636234623530343038343338373439616131333538343835
39386435373035633837383264346266643433366363653566363863393434356337633366363635
64666465613164353238626165623931633534666438386264633431356332616264

View file

@ -0,0 +1,7 @@
[webservers]
172.104.150.7
[all:vars]
ansible_connection=ssh
ansible_ssh_user=ansible
ansible_ssh_private_key_file=.keys/ansible.pem

View file

@ -0,0 +1,13 @@
README.pdf
README.html
shared_test_repo/
test/integration
.kitchen
coverage
Vagrantfile.erb
Gemfile.lock
Berksfile.lock
ansible.cfg
hosts

View file

@ -0,0 +1,65 @@
---
driver:
name: vagrant
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/
playbook: default.yml
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
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: centos-6.4
driver_config:
box: opscode-centos-6.4
box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_centos-6.4_provisionerless.box
- name: centos-6.5
driver_config:
box: opscode-centos-6.5
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
- name: oracle-6.4
driver_config:
box: oracle-6.4
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel64-64.box
- name: oracle-6.5
driver_config:
box: oracle-6.5
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel65-64.box
- name: debian-6
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
- name: debian-8
driver_config:
box: debian-8
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-8.1_chef-provisionerless.box
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/tests-ssh-hardening
suites:
- name: nginx-ansible_1.9
provisioner:
ansible_version: 1.9.4
- name: nginx-ansible_latest

View file

@ -0,0 +1,60 @@
---
driver:
name: docker
use_sudo: false
transport:
max_ssh_sessions: 5
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
platforms:
- name: ubuntu-12.04
driver:
image: ubuntu:12.04
- name: ubuntu-14.04
driver:
image: ubuntu:14.04
- name: ubuntu-16.04
driver:
image: ubuntu:16.04
- name: centos-6.7
driver:
image: centos:6.7
- name: centos-6.8
driver:
image: centos:6.8
- name: centos-7
driver:
image: centos:7
privileged: true
run_command: /usr/sbin/init
- name: debian-7
driver:
image: debian:7
- name: debian-8
driver:
image: debian:8
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/tests-nginx-hardening
suites:
- name: nginx-ansible_1.9
provisioner:
ansible_version: 1.9.4
- name: nginx-ansible_latest

View file

@ -0,0 +1,23 @@
---
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/
language: python
python: "2.7"
env:
- ANSIBLE_VERSION=latest
- ANSIBLE_VERSION=1.9.4
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
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"

View file

@ -0,0 +1,23 @@
# Change Log
## [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)
**Fixed bugs:**
- ssl\_dhparam [\#4](https://github.com/dev-sec/ansible-nginx-hardening/issues/4)
**Closed issues:**
- Make the owner /etc/nginx configurabe [\#3](https://github.com/dev-sec/ansible-nginx-hardening/issues/3)
- Running worker process as non-privileged user \(1 failed\) [\#2](https://github.com/dev-sec/ansible-nginx-hardening/issues/2)
**Merged pull requests:**
- create dhparam file. fix \#4 [\#5](https://github.com/dev-sec/ansible-nginx-hardening/pull/5) ([rndmh3ro](https://github.com/rndmh3ro))
- improve gemfile, update readme for local tests [\#1](https://github.com/dev-sec/ansible-nginx-hardening/pull/1) ([chris-rock](https://github.com/chris-rock))
## [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)*

View file

@ -0,0 +1,85 @@
# Contributor Guideline
This document provides an overview of how you can participate in improving this project or extending it. We are grateful for all your help: bug reports and fixes, code contributions, documentation or ideas. Feel free to join, we appreciate your support!!
## Communication
### GitHub repositories
Much of the issues, goals and ideas are tracked in the respective projects in GitHub. Please use this channel to report bugs and post ideas.
## git and GitHub
In order to contribute code please:
1. Fork the project on GitHub
2. Clone the project
3. Add changes (and tests)
4. Commit and push
5. Create a merge-request
To have your code merged, see the expectations listed below.
You can find a well-written guide [here](https://help.github.com/articles/fork-a-repo).
Please follow common commit best-practices. Be explicit, have a short summary, a well-written description and references. This is especially important for the merge-request.
Some great guidelines can be found [here](https://wiki.openstack.org/wiki/GitCommitMessages) and [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message).
## Expectations
### Don't reinvent the wheel
This hardening project doesn't intend to reinvent the configuration stack for services. Aim to use official configuration projects first and provide hardening as a layer on top. The goal is remove the need for a user to configure all aspects of services and maintain security configuration. This way, the user can still configure a service using the interface provided by the official project.
* For Chef refer to the official [opscode community cookbooks](http://community.opscode.com/cookbooks).
* For Puppet head to the [Puppet Forge](https://forge.puppetlabs.com/) and take a node of the Puppet supported modules.
* For Ansible check the [Ansible Module Index](http://docs.ansible.com/list_of_all_modules.html)
These projects are generally hosted on GitHub as well.
In some cases, we in fact create the full rollout stack, but this is generally the exception ([os-hardening](https://github.com/TelekomLabs/chef-os-hardening), [nginx-hardening](https://github.com/TelekomLabs/chef-nginx-hardening)).
### Be explicit
* Please avoid using nonsensical property and variable names.
* Use self-describing attribute names for user configuration.
* In case of failures, communicate what happened and why a failure occurs to the user. Make it easy to track the code or action that produced the error. Try to catch and handle errors if possible to provide improved failure messages.
### Add tests
The security review of this project is done using integration tests.
Whenever you add a new security configuration, please start by writing a test that checks for this configuration. For example: If you want to set a new attribute in a configuration file, write a test that expects the value to be set first. Then implement your change.
You may add a new feature request by creating a test for whatever value you need.
All tests will be reviewed internally for their validity and overall project direction.
### Document your code
As code is more often read than written, please provide documentation in all projects.
Adhere to the respective guidelines for documentation:
* Chef generally documents code based explicit readme files. For code documentation please use [yard-chef](https://github.com/rightscale/yard-chef)
* [Puppet module documentation](http://docs.puppetlabs.com/puppet/latest/reference/modules_documentation.html)
### Follow coding styles
We generally include test for coding guidelines:
* Chef follows [Foodcritic](http://acrmp.github.io/foodcritic/)
* Puppet is checked with [puppet-lint](http://puppet-lint.com/checks/)
* Ansible is checked by running the playbook with the syntax-check option, e.g. `ansible-playbook foo.yml --syntax-check`
Remember: Code is generally read much more often than written.
### Use Markdown
Wherever possible, please refrain from any other formats and stick to simple markdown.

View file

@ -0,0 +1,41 @@
# encoding: utf-8
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'
gem 'kitchen-vagrant'
gem 'kitchen-inspec'
gem 'kitchen-sharedtests', '~> 0.2.0'
gem 'kitchen-sync'
gem 'kitchen-transport-rsync'
gem 'kitchen-docker'
end
group :openstack do
gem 'kitchen-openstack'
end
group :tools do
gem 'github_changelog_generator', '~> 1'
end

View file

@ -0,0 +1,133 @@
# nginx-hardening (Ansible Role)
[![Build Status](http://img.shields.io/travis/dev-sec/ansible-nginx-hardening.svg)][1]
[![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)][2]
[![Ansible Galaxy](https://img.shields.io/badge/galaxy-nginx--hardening-660198.svg)][3]
## Description
This role provides secure nginx configuration.
It works with the following nginx-roles, including, but not limited to:
* [geerlinggux.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
## Role Variables
| Name | Default Value | Description |
| -------------- | ------------- | -----------------------------------|
| [nginx_client_body_buffer_size][] | `1k` | Sets buffer size for reading client request body. In case the request body is larger than the buffer, the whole body or only its part is written to a temporary file. |
| nginx_remove_default_site | `true` | Disables the default site. Set to false to enable the default site in nginx. |
| [nginx_client_max_body_size][] | `1k` | Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field. If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client. |
| [nginx_keepalive_timeout][] | `5 5` | The first parameter sets a timeout during which a keep-alive client connection will stay open on the server side. The zero value disables keep-alive client connections. The optional second parameter sets a value in the “Keep-Alive: timeout=time” response header field. |
| [nginx_server_tokens][] | `off` | Disables emitting nginx version in error messages and in the "Server" response header field. Set to on to enable the nginx version in error messages and "Server" response header. |
| [nginx_client_header_buffer_size][] | `1k` | Sets buffer size for reading client request header. For most requests, a buffer of 1K bytes is enough. |
| [nginx_large_client_header_buffers][] | `2 1k` | Sets the maximum number and size of buffers used for reading large client request header. |
| [nginx_client_body_timeout][] | `10` | Defines a timeout for reading client request body. |
| [nginx_client_header_timeout][] | `10` | Defines a timeout for reading client request header. |
| [nginx_send_timeout][] | `10` | Sets a timeout for transmitting a response to the client. |
| [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_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. |
## Example Playbook
- hosts: localhost
roles:
- dev-sec.nginx-hardening
## Local Testing
The preferred way of locally testing the role is to use Docker. You will have to install Docker on your system. See [Get started](https://docs.docker.com/) for a Docker package suitable to for your system.
You can also use vagrant and Virtualbox or VMWare to run tests locally. You will have to install Virtualbox and Vagrant on your system. See [Vagrant Downloads](http://downloads.vagrantup.com/) for a vagrant package suitable for your system. For all our tests we use `test-kitchen`. If you are not familiar with `test-kitchen` please have a look at [their guide](http://kitchen.ci/docs/getting-started).
Next install test-kitchen:
```bash
# Install dependencies
gem install bundler
bundle install
```
### Testing with Docker
```
# fast test on one machine
bundle exec kitchen test default-ubuntu-1204
# test on all machines
bundle exec kitchen test
# for development
bundle exec kitchen create default-ubuntu-1204
bundle exec kitchen converge default-ubuntu-1204
```
### Testing with Virtualbox
```
# fast test on one machine
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test nginx-ansible-19-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 nginx-ansible-19-ubuntu-1404
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen converge nginx-ansible-19-ubuntu-1404
```
For more information see [test-kitchen](http://kitchen.ci/docs/getting-started)
## Contributing
See [contributor guideline](CONTRIBUTING.md).
## License and Author
* Author:: Sebastian Gumprich <sebastian.gumprich@38.de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
[1]: http://travis-ci.org/dev-sec/ansible-nginx-hardening
[2]: https://gitter.im/dev-sec/general
[3]: https://galaxy.ansible.com/dev-sec/nginx-hardening/
[nginx_client_body_buffer_size]: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
[nginx_client_max_body_size]: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
[nginx_keepalive_timeout]: http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout
[nginx_server_tokens]: http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
[nginx_more_clear_headers]: http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
[nginx_client_header_buffer_size]: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size
[nginx_large_client_header_buffers]: http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers
[nginx_client_body_timeout]: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout
[nginx_client_header_timeout]: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout
[nginx_send_timeout]: http://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout
[nginx_limit_conn_zone]: http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone
[nginx_limit_conn]: http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn
[nginx_add_header]: http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
[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

View file

@ -0,0 +1,11 @@
#!/usr/bin/env rake
# encoding: utf-8
# Automatically generate a changelog for this project. Only loaded if
# the necessary gem is installed.
begin
require 'github_changelog_generator/task'
GitHubChangelogGenerator::RakeTask.new :changelog
rescue LoadError
puts '>>>>> GitHub Changelog Generator not loaded, omitting tasks'
end

View file

@ -0,0 +1,6 @@
---
- name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings
hosts: localhost
roles:
- geerlingguy.nginx
- ansible-nginx-hardening

View file

@ -0,0 +1,26 @@
---
nginx_client_body_buffer_size: '1k'
nginx_remove_default_site: true
nginx_client_max_body_size: '1k'
nginx_keepalive_timeout: '5 5'
nginx_server_tokens: 'off'
nginx_client_header_buffer_size: "1k"
nginx_large_client_header_buffers: "2 1k"
nginx_client_body_timeout: "10"
nginx_client_header_timeout: "10"
nginx_send_timeout: "10"
nginx_limit_conn_zone: "$binary_remote_addr zone=default:10m"
nginx_limit_conn: "default 5"
nginx_add_header: [
# vvoid clickjacking
"X-Frame-Options SAMEORIGIN",
# disable content-type sniffing
"X-Content-Type-Options nosniff",
# XSS filter
"X-XSS-Protection \"1; mode=block\"" ]
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_ssl_prefer_server_ciphers: "on"
nginx_dh_param: "{{nginx_root_dir}}/dh{{nginx_dh_size}}.pem"
nginx_dh_size: "2048"

View file

@ -0,0 +1,2 @@
- name: reload nginx
service: name={{ nginx_service_name }} state=reloaded

View file

@ -0,0 +1 @@
{install_date: 'Sun Apr 23 07:59:34 2017', version: 1.0.2}

View file

@ -0,0 +1,27 @@
---
galaxy_info:
author: "Sebastian Gumprich"
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'
platforms:
- name: EL
versions:
- 6
- 7
- name: Ubuntu
versions:
- precise
- trusty
- xenial
- name: Debian
versions:
- wheezy
- jessie
galaxy_tags:
- system
- security
- hardening
- nginx
dependencies: []

View file

@ -0,0 +1 @@
- src: geerlingguy.nginx

View file

@ -0,0 +1,4 @@
- hosts: localhost
roles:
- geerlingguy.nginx
- ansible-nginx-hardening

View file

@ -0,0 +1,35 @@
---
- 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
- name: create additional configuration
template: src="hardening.conf.j2" dest="{{nginx_config_conf_dir}}/90.hardening.conf" owner="root" group="root"
notify: reload 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
- 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
- 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
- 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
- name: remove default.conf
file: path="{{nginx_default_conf}}" state=absent
when: nginx_remove_default_site
notify: reload nginx
- name: generate dh group
command: openssl dhparam -out {{nginx_dh_param}} {{nginx_dh_size}} creates={{nginx_dh_param}}
notify: reload nginx

View file

@ -0,0 +1,17 @@
# {{ansible_managed}}
# 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}};
{% for header in nginx_add_header %}
add_header {{header}};
{% endfor %}

View file

@ -0,0 +1,4 @@
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'

View file

@ -0,0 +1,4 @@
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'

View file

@ -0,0 +1,4 @@
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'

View file

@ -0,0 +1,3 @@
.kitchen
hosts
Gemfile.lock

View file

@ -0,0 +1,80 @@
---
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
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-os-hardening/
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
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
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
box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_centos-6.4_provisionerless.box
- name: centos-6.5
driver_config:
box: opscode-centos-6.5
box_url: 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
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel64-64.box
- name: oracle-6.5
driver_config:
box: oracle-6.5
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel65-64.box
- name: oracle-7
driver_config:
box: boxcutter/ol72
- 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
- name: debian-8
driver_config:
box: debian-8
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-8.1_chef-provisionerless.box
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/linux-baseline/
suites:
- name: os

View file

@ -0,0 +1,77 @@
---
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
provisioner:
name: ansible_playbook
hosts: all
require_ansible_repo: false
require_chef_for_busser: false
require_ruby_for_busser: false
ansible_verbose: true
ansible_diff: true
hosts: all
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"
platforms:
- name: centos6-ansible-latest
driver:
image: rndmh3ro/docker-centos6-ansible:latest
platform: centos
- name: centos7-ansible-latest
driver:
image: rndmh3ro/docker-centos7-ansible:latest
platform: centos
- name: oracle6-ansible-latest
driver:
image: rndmh3ro/docker-oracle6-ansible:latest
platform: centos
- name: oracle7-ansible-latest
driver:
image: rndmh3ro/docker-oracle7-ansible:latest
platform: centos
- name: ubuntu1204-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1204-ansible:latest
platform: ubuntu
- name: ubuntu1404-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1404-ansible:latest
platform: ubuntu
- name: ubuntu1604-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1604-ansible:latest
platform: ubuntu
- name: debian7-ansible-latest
driver:
image: rndmh3ro/docker-debian7-ansible:latest
platform: debian
- name: debian8-ansible-latest
driver:
image: rndmh3ro/docker-debian8-ansible:latest
platform: debian
- name: debian9-ansible-latest
driver:
image: rndmh3ro/docker-debian9-ansible:latest
platform: debian
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/tests-os-hardening
suites:
- name: os

View file

@ -0,0 +1,65 @@
---
services: docker
env:
- distro: centos6
version: latest
init: /sbin/init
- distro: centos7
init: /usr/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: ubuntu1604
version: latest
init: /lib/systemd/systemd
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
- distro: ubuntu1404
version: latest
init: /sbin/init
- distro: ubuntu1204
version: latest
init: /sbin/init
- distro: debian7
version: latest
init: /sbin/init
- distro: debian8
version: latest
init: /sbin/init
- distro: debian9
version: latest
init: /lib/systemd/systemd
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
before_install:
# Pull container
- 'docker pull rndmh3ro/docker-${distro}-ansible:${version}'
script:
- container_id=$(mktemp)
# 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"'
# 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'
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/

View file

@ -0,0 +1,150 @@
# Change Log
## [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)
**Fixed bugs:**
- CentOS 7 selinux dependencies [\#102](https://github.com/dev-sec/ansible-os-hardening/issues/102)
- ubuntu xenial warning during activate gpg-check for yum-repos [\#99](https://github.com/dev-sec/ansible-os-hardening/issues/99)
- rhel\_system\_auth.j2 is still using pam\_passwdqc.so for CentOS 7 [\#98](https://github.com/dev-sec/ansible-os-hardening/issues/98)
- Enable pam\_pwquality in rhel-family \> 7 [\#73](https://github.com/dev-sec/ansible-os-hardening/issues/73)
- "irc" user always changed after reboot [\#53](https://github.com/dev-sec/ansible-os-hardening/issues/53)
**Merged pull requests:**
- update template [\#101](https://github.com/dev-sec/ansible-os-hardening/pull/101) ([rndmh3ro](https://github.com/rndmh3ro))
- fix deprecation warning for undefined error. \#99 [\#100](https://github.com/dev-sec/ansible-os-hardening/pull/100) ([rndmh3ro](https://github.com/rndmh3ro))
- add rhel7 pam\_pwquality. fix \#73 [\#94](https://github.com/dev-sec/ansible-os-hardening/pull/94) ([rndmh3ro](https://github.com/rndmh3ro))
## [3.1.0](https://github.com/dev-sec/ansible-os-hardening/tree/3.1.0) (2016-08-03)
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/3.1...3.1.0)
## [3.1](https://github.com/dev-sec/ansible-os-hardening/tree/3.1) (2016-07-27)
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/3.0.0...3.1)
**Implemented enhancements:**
- Supports --check mode [\#93](https://github.com/dev-sec/ansible-os-hardening/pull/93) ([conorsch](https://github.com/conorsch))
- Adds support for CentOS 7 [\#91](https://github.com/dev-sec/ansible-os-hardening/pull/91) ([conorsch](https://github.com/conorsch))
- Docker [\#90](https://github.com/dev-sec/ansible-os-hardening/pull/90) ([rndmh3ro](https://github.com/rndmh3ro))
- debian 8 support [\#88](https://github.com/dev-sec/ansible-os-hardening/pull/88) ([rndmh3ro](https://github.com/rndmh3ro))
- Ufw manage defaults [\#85](https://github.com/dev-sec/ansible-os-hardening/pull/85) ([fitz123](https://github.com/fitz123))
- replace ignore\_errors to failed\_when to supress ugly error warnings [\#81](https://github.com/dev-sec/ansible-os-hardening/pull/81) ([fitz123](https://github.com/fitz123))
- fix bare variables usage for loops [\#79](https://github.com/dev-sec/ansible-os-hardening/pull/79) ([fitz123](https://github.com/fitz123))
**Fixed bugs:**
- Centos 7.1 fails at \[Change various sysctl-settings on rhel-hosts...\] [\#74](https://github.com/dev-sec/ansible-os-hardening/issues/74)
- Hardening fails on Centos 7.1 at task 'minimize access' [\#71](https://github.com/dev-sec/ansible-os-hardening/issues/71)
**Closed issues:**
- Permissions on /etc/shadow can lock out GUI users [\#86](https://github.com/dev-sec/ansible-os-hardening/issues/86)
- network related sysctl rewritten by ufw in ubuntu [\#82](https://github.com/dev-sec/ansible-os-hardening/issues/82)
- ansible \>= 2.0 complains: Using bare variables is deprecated [\#78](https://github.com/dev-sec/ansible-os-hardening/issues/78)
- Norm-Audit-Hardening-Audit [\#76](https://github.com/dev-sec/ansible-os-hardening/issues/76)
**Merged pull requests:**
- Fix a formatting issue in readme. [\#92](https://github.com/dev-sec/ansible-os-hardening/pull/92) ([vivekagr](https://github.com/vivekagr))
- Permits overriding permissions on /etc/shadow [\#89](https://github.com/dev-sec/ansible-os-hardening/pull/89) ([conorsch](https://github.com/conorsch))
## [3.0.0](https://github.com/dev-sec/ansible-os-hardening/tree/3.0.0) (2016-03-13)
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/2.0.0...3.0.0)
**Implemented enhancements:**
- update platforms in meta-file [\#69](https://github.com/dev-sec/ansible-os-hardening/pull/69) ([rndmh3ro](https://github.com/rndmh3ro))
- add webhook for ansible galaxy [\#68](https://github.com/dev-sec/ansible-os-hardening/pull/68) ([rndmh3ro](https://github.com/rndmh3ro))
- Move sysctl vars to defaults [\#67](https://github.com/dev-sec/ansible-os-hardening/pull/67) ([rndmh3ro](https://github.com/rndmh3ro))
- make sys\_uid and sys\_gid configurable [\#62](https://github.com/dev-sec/ansible-os-hardening/pull/62) ([rndmh3ro](https://github.com/rndmh3ro))
- Ansible 2.0 support [\#59](https://github.com/dev-sec/ansible-os-hardening/pull/59) ([rndmh3ro](https://github.com/rndmh3ro))
- use inspec as test framework [\#58](https://github.com/dev-sec/ansible-os-hardening/pull/58) ([chris-rock](https://github.com/chris-rock))
- Packages as attributes [\#57](https://github.com/dev-sec/ansible-os-hardening/pull/57) ([rndmh3ro](https://github.com/rndmh3ro))
- Change categories to tags for upcoming ansible 2.0 [\#56](https://github.com/dev-sec/ansible-os-hardening/pull/56) ([rndmh3ro](https://github.com/rndmh3ro))
- Add SINGLE and PROMPT parameters. [\#55](https://github.com/dev-sec/ansible-os-hardening/pull/55) ([rndmh3ro](https://github.com/rndmh3ro))
- add changelog generator [\#54](https://github.com/dev-sec/ansible-os-hardening/pull/54) ([chris-rock](https://github.com/chris-rock))
**Fixed bugs:**
- Updates "tags" parameters on includes in main.yml [\#66](https://github.com/dev-sec/ansible-os-hardening/pull/66) ([conorsch](https://github.com/conorsch))
- Suid set def var, fix \#64 [\#63](https://github.com/dev-sec/ansible-os-hardening/pull/63) ([rndmh3ro](https://github.com/rndmh3ro))
- ERROR! Include tasks should not specify tags in more than one way [\#60](https://github.com/dev-sec/ansible-os-hardening/pull/60) ([fitz123](https://github.com/fitz123))
**Closed issues:**
- Hardening fails on Centos 7.1 at task 'remove suid/sgid bit from all binaries except in system and user whitelist' [\#72](https://github.com/dev-sec/ansible-os-hardening/issues/72)
- ansible 2.0 | "remove suid/sgid" task fails [\#64](https://github.com/dev-sec/ansible-os-hardening/issues/64)
- Custom sysctl [\#50](https://github.com/dev-sec/ansible-os-hardening/issues/50)
**Merged pull requests:**
- Release 3.0.0 [\#75](https://github.com/dev-sec/ansible-os-hardening/pull/75) ([rndmh3ro](https://github.com/rndmh3ro))
## [2.0.0](https://github.com/dev-sec/ansible-os-hardening/tree/2.0.0) (2015-11-28)
[Full Changelog](https://github.com/dev-sec/ansible-os-hardening/compare/1.0.0...2.0.0)
**Closed issues:**
- Fix directory structure. [\#48](https://github.com/dev-sec/ansible-os-hardening/issues/48)
- pam auth update error [\#47](https://github.com/dev-sec/ansible-os-hardening/issues/47)
**Merged pull requests:**
- Add explicit role-path to kitchen.yml [\#52](https://github.com/dev-sec/ansible-os-hardening/pull/52) ([rndmh3ro](https://github.com/rndmh3ro))
- Fix pam passwdqc template [\#51](https://github.com/dev-sec/ansible-os-hardening/pull/51) ([rndmh3ro](https://github.com/rndmh3ro))
- New dir layout [\#49](https://github.com/dev-sec/ansible-os-hardening/pull/49) ([rndmh3ro](https://github.com/rndmh3ro))
- remove duplicate "update pam" task [\#46](https://github.com/dev-sec/ansible-os-hardening/pull/46) ([fitz123](https://github.com/fitz123))
- Fix stuck in case pam files was updated before by force update [\#45](https://github.com/dev-sec/ansible-os-hardening/pull/45) ([fitz123](https://github.com/fitz123))
- Fix nologin shell path [\#44](https://github.com/dev-sec/ansible-os-hardening/pull/44) ([fitz123](https://github.com/fitz123))
- improved travis-tests to cover more cases [\#42](https://github.com/dev-sec/ansible-os-hardening/pull/42) ([rndmh3ro](https://github.com/rndmh3ro))
## [1.0.0](https://github.com/dev-sec/ansible-os-hardening/tree/1.0.0) (2015-09-01)
**Closed issues:**
- ansible-os-hardening/tasks/minimize\_access.yml [\#38](https://github.com/dev-sec/ansible-os-hardening/issues/38)
- Role configuration. vars/main.yml? [\#34](https://github.com/dev-sec/ansible-os-hardening/issues/34)
- Sysctl reloading [\#18](https://github.com/dev-sec/ansible-os-hardening/issues/18)
- Add conditions for disabling of ip forwarding [\#15](https://github.com/dev-sec/ansible-os-hardening/issues/15)
- Disable System Accounts [\#6](https://github.com/dev-sec/ansible-os-hardening/issues/6)
**Merged pull requests:**
- Update kitchen-ansible, remove separate debian install [\#40](https://github.com/dev-sec/ansible-os-hardening/pull/40) ([rndmh3ro](https://github.com/rndmh3ro))
- Add mode to su-binary task. Fix \#38 [\#39](https://github.com/dev-sec/ansible-os-hardening/pull/39) ([rndmh3ro](https://github.com/rndmh3ro))
- update common kitchen.yml platforms \(ansible\), kitchen\_debian.yml platforms \(ansible\) [\#37](https://github.com/dev-sec/ansible-os-hardening/pull/37) ([chris-rock](https://github.com/chris-rock))
- Change oneliner if-statements to be more readable [\#36](https://github.com/dev-sec/ansible-os-hardening/pull/36) ([rndmh3ro](https://github.com/rndmh3ro))
- Separate system-vars from editable vars. Fix \#34 [\#35](https://github.com/dev-sec/ansible-os-hardening/pull/35) ([rndmh3ro](https://github.com/rndmh3ro))
- Create limits.d-directory if it does not exist. [\#33](https://github.com/dev-sec/ansible-os-hardening/pull/33) ([rndmh3ro](https://github.com/rndmh3ro))
- Add correct CONTRIB-file [\#32](https://github.com/dev-sec/ansible-os-hardening/pull/32) ([rndmh3ro](https://github.com/rndmh3ro))
- Add Ansible Galaxy badge [\#31](https://github.com/dev-sec/ansible-os-hardening/pull/31) ([rndmh3ro](https://github.com/rndmh3ro))
- Update readme, todo, changelog, vars [\#30](https://github.com/dev-sec/ansible-os-hardening/pull/30) ([rndmh3ro](https://github.com/rndmh3ro))
- List-cleanup and follow symlinks added [\#29](https://github.com/dev-sec/ansible-os-hardening/pull/29) ([rndmh3ro](https://github.com/rndmh3ro))
- Add module configuration [\#28](https://github.com/dev-sec/ansible-os-hardening/pull/28) ([rndmh3ro](https://github.com/rndmh3ro))
- Fix two sysctl-settings [\#27](https://github.com/dev-sec/ansible-os-hardening/pull/27) ([rndmh3ro](https://github.com/rndmh3ro))
- Add meta-files for Ansible Galaxy [\#26](https://github.com/dev-sec/ansible-os-hardening/pull/26) ([rndmh3ro](https://github.com/rndmh3ro))
- Disable System Accounts. Fix \#6 [\#25](https://github.com/dev-sec/ansible-os-hardening/pull/25) ([rndmh3ro](https://github.com/rndmh3ro))
- Use changed\_when to avoid changed tasks [\#24](https://github.com/dev-sec/ansible-os-hardening/pull/24) ([rndmh3ro](https://github.com/rndmh3ro))
- Delete authconfig-task on rhel-systems [\#23](https://github.com/dev-sec/ansible-os-hardening/pull/23) ([rndmh3ro](https://github.com/rndmh3ro))
- Add missing rhosts-include task [\#21](https://github.com/dev-sec/ansible-os-hardening/pull/21) ([rndmh3ro](https://github.com/rndmh3ro))
- Change sysctl-task. Fix \#18 [\#20](https://github.com/dev-sec/ansible-os-hardening/pull/20) ([rndmh3ro](https://github.com/rndmh3ro))
- Add travis-support [\#17](https://github.com/dev-sec/ansible-os-hardening/pull/17) ([rndmh3ro](https://github.com/rndmh3ro))
- Add conditions for various tasks. Fix \#15 [\#16](https://github.com/dev-sec/ansible-os-hardening/pull/16) ([rndmh3ro](https://github.com/rndmh3ro))
- fix configuration of playbook path [\#14](https://github.com/dev-sec/ansible-os-hardening/pull/14) ([chris-rock](https://github.com/chris-rock))
- Make tasks clearer [\#13](https://github.com/dev-sec/ansible-os-hardening/pull/13) ([rndmh3ro](https://github.com/rndmh3ro))
- Add remove suid/sgid function [\#12](https://github.com/dev-sec/ansible-os-hardening/pull/12) ([rndmh3ro](https://github.com/rndmh3ro))
- Add task to remove unused repos and pkgs [\#11](https://github.com/dev-sec/ansible-os-hardening/pull/11) ([rndmh3ro](https://github.com/rndmh3ro))
- Edit README to fit to os-hardening [\#10](https://github.com/dev-sec/ansible-os-hardening/pull/10) ([rndmh3ro](https://github.com/rndmh3ro))
- ignore RAs on Ipv6 [\#9](https://github.com/dev-sec/ansible-os-hardening/pull/9) ([rndmh3ro](https://github.com/rndmh3ro))
- Repair debian install script [\#8](https://github.com/dev-sec/ansible-os-hardening/pull/8) ([rndmh3ro](https://github.com/rndmh3ro))
- Separate tasks into multiple smaller files [\#7](https://github.com/dev-sec/ansible-os-hardening/pull/7) ([rndmh3ro](https://github.com/rndmh3ro))
- Enable gpg-check on all yum-repositories [\#5](https://github.com/dev-sec/ansible-os-hardening/pull/5) ([rndmh3ro](https://github.com/rndmh3ro))
- Change playbook-path to accomodate test-repo [\#4](https://github.com/dev-sec/ansible-os-hardening/pull/4) ([rndmh3ro](https://github.com/rndmh3ro))
- treat securetty config as an array [\#3](https://github.com/dev-sec/ansible-os-hardening/pull/3) ([arlimus](https://github.com/arlimus))
- Add Securetty-support [\#2](https://github.com/dev-sec/ansible-os-hardening/pull/2) ([rndmh3ro](https://github.com/rndmh3ro))
- Add profile.conf configuration [\#1](https://github.com/dev-sec/ansible-os-hardening/pull/1) ([rndmh3ro](https://github.com/rndmh3ro))
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*

View file

@ -0,0 +1,85 @@
# Contributor Guideline
This document provides an overview of how you can participate in improving this project or extending it. We are grateful for all your help: bug reports and fixes, code contributions, documentation or ideas. Feel free to join, we appreciate your support!!
## Communication
### GitHub repositories
Much of the issues, goals and ideas are tracked in the respective projects in GitHub. Please use this channel to report bugs and post ideas.
## git and GitHub
In order to contribute code please:
1. Fork the project on GitHub
2. Clone the project
3. Add changes (and tests)
4. Commit and push
5. Create a merge-request
To have your code merged, see the expectations listed below.
You can find a well-written guide [here](https://help.github.com/articles/fork-a-repo).
Please follow common commit best-practices. Be explicit, have a short summary, a well-written description and references. This is especially important for the merge-request.
Some great guidelines can be found [here](https://wiki.openstack.org/wiki/GitCommitMessages) and [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message).
## Expectations
### Don't reinvent the wheel
This hardening project doesn't intend to reinvent the configuration stack for services. Aim to use official configuration projects first and provide hardening as a layer on top. The goal is remove the need for a user to configure all aspects of services and maintain security configuration. This way, the user can still configure a service using the interface provided by the official project.
* For Chef refer to the official [opscode community cookbooks](http://community.opscode.com/cookbooks).
* For Puppet head to the [Puppet Forge](https://forge.puppetlabs.com/) and take a node of the Puppet supported modules.
* For Ansible check the [Ansible Module Index](http://docs.ansible.com/list_of_all_modules.html)
These projects are generally hosted on GitHub as well.
In some cases, we in fact create the full rollout stack, but this is generally the exception ([os-hardening](https://github.com/TelekomLabs/chef-os-hardening), [nginx-hardening](https://github.com/TelekomLabs/chef-nginx-hardening)).
### Be explicit
* Please avoid using nonsensical property and variable names.
* Use self-describing attribute names for user configuration.
* In case of failures, communicate what happened and why a failure occurs to the user. Make it easy to track the code or action that produced the error. Try to catch and handle errors if possible to provide improved failure messages.
### Add tests
The security review of this project is done using integration tests.
Whenever you add a new security configuration, please start by writing a test that checks for this configuration. For example: If you want to set a new attribute in a configuration file, write a test that expects the value to be set first. Then implement your change.
You may add a new feature request by creating a test for whatever value you need.
All tests will be reviewed internally for their validity and overall project direction.
### Document your code
As code is more often read than written, please provide documentation in all projects.
Adhere to the respective guidelines for documentation:
* Chef generally documents code based explicit readme files. For code documentation please use [yard-chef](https://github.com/rightscale/yard-chef)
* [Puppet module documentation](http://docs.puppetlabs.com/puppet/latest/reference/modules_documentation.html)
### Follow coding styles
We generally include test for coding guidelines:
* Chef follows [Foodcritic](http://acrmp.github.io/foodcritic/)
* Puppet is checked with [puppet-lint](http://puppet-lint.com/checks/)
* Ansible is checked by running the playbook with the syntax-check option, e.g. `ansible-playbook foo.yml --syntax-check`
Remember: Code is generally read much more often than written.
### Use Markdown
Wherever possible, please refrain from any other formats and stick to simple markdown.

View file

@ -0,0 +1,18 @@
# encoding: utf-8
source 'https://rubygems.org'
group :integration do
gem 'test-kitchen', '~> 1.0'
gem 'kitchen-ansible'
gem 'kitchen-vagrant'
gem 'kitchen-inspec'
gem 'kitchen-sharedtests', '~> 0.2.0'
gem 'kitchen-sync'
gem 'kitchen-transport-rsync'
gem 'kitchen-docker'
end
group :tools do
gem 'github_changelog_generator', '~> 1'
end

View file

@ -0,0 +1,214 @@
# os-hardening (Ansible Role)
[![Build Status](http://img.shields.io/travis/dev-sec/ansible-os-hardening.svg)][1]
[![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)][2]
[![Ansible Galaxy](https://img.shields.io/badge/galaxy-os--hardening-660198.svg)][3]
## Description
This roles provides numerous security-related configurations, providing all-round base protection.
It configures:
* Configures package management e.g. allows only signed packages
* Remove packages with known issues
* Configures `pam` and `pam_limits` module
* Shadow password suite configuration
* Configures system path permissions
* Disable core dumps via soft limits
* Restrict Root Logins to System Console
* Set SUIDs
* Configures kernel parameters via sysctl
It will not:
* Update system packages
* Install security patches
## Requirements
* Ansible 2.2.1
## Variables
| Name | Default Value | Description |
| -------------- | ------------- | -----------------------------------|
| `os_desktop_enable`| false | true if this is a desktop system, ie Xorg, KDE/GNOME/Unity/etc|
| `os_env_extra_user_paths`| [] | add additional paths to the user's `PATH` variable (default is empty).|
| `os_env_umask`| 027| set default permissions for new files to `750` |
| `os_auth_pw_max_age`| 60 | maximum password age (set to `99999` to effectively disable it) |
| `os_auth_pw_min_age`| 7 | minimum password age (before allowing any other password change)|
| `os_auth_retries`| 5 | the maximum number of authentication attempts, before the account is locked for some time|
| `os_auth_lockout_time`| 600 | time in seconds that needs to pass, if the account was locked due to too many failed authentication attempts|
| `os_auth_timeout`| 60 | authentication timeout in seconds, so login will exit if this time passes|
| `os_auth_allow_homeless`| false | true if to allow users without home to login|
| `os_auth_pam_passwdqc_enable`| true | true if you want to use strong password checking in PAM using passwdqc|
| `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|
| `os_security_suid_sgid_whitelist`| [] | a list of paths which should not have their SUID/SGID bits altered|
| `os_security_suid_sgid_remove_from_unknown`| false | true if you want to remove SUID/SGID bits from any file, that is not explicitly configured in a `blacklist`. This will make every Ansible-run search through the mounted filesystems looking for SUID/SGID bits that are not configured in the default and user blacklist. If it finds an SUID/SGID bit, it will be removed, unless this file is in your `whitelist`.|
| `os_security_packages_clean'`| true | removes packages with known issues. See section packages.|
| `ufw_manage_defaults` | true | true means apply all settings with `ufw_` prefix|
| `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` |
## Packages
We remove the following packages:
* xinetd ([NSA](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf), Chapter 3.2.1)
* inetd ([NSA](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf), Chapter 3.2.1)
* tftp-server ([NSA](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf), Chapter 3.2.5)
* 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)
## Example Playbook
- 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:
```
- 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
```
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.
## Local Testing
The preferred way of locally testing the role is to use Docker. You will have to install Docker on your system. See [Get started](https://docs.docker.com/) for a Docker package suitable to for your system.
You can also use vagrant and Virtualbox or VMWare to run tests locally. You will have to install Virtualbox and Vagrant on your system. See [Vagrant Downloads](http://downloads.vagrantup.com/) for a vagrant package suitable for your system. For all our tests we use `test-kitchen`. If you are not familiar with `test-kitchen` please have a look at [their guide](http://kitchen.ci/docs/getting-started).
Next install test-kitchen:
```bash
# Install dependencies
gem install bundler
bundle install
```
### Testing with Docker
```
# fast test on one machine
bundle exec kitchen test default-ubuntu-1204
# test on all machines
bundle exec kitchen test
# for development
bundle exec kitchen create default-ubuntu-1204
bundle exec kitchen converge default-ubuntu-1204
```
### Testing with Virtualbox
```
# fast test on one machine
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test default-ubuntu-1204
# 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
```
For more information see [test-kitchen](http://kitchen.ci/docs/getting-started)
## Contributors + Kudos
...
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)
Thanks to all of you!
## Contributing
See [contributor guideline](CONTRIBUTING.md).
## License and Author
* Author:: Sebastian Gumprich <sebastian.gumprich@38.de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
[1]: http://travis-ci.org/dev-sec/ansible-os-hardening
[2]: https://gitter.im/dev-sec/general
[3]: https://galaxy.ansible.com/dev-sec/os-hardening

View file

@ -0,0 +1,11 @@
#!/usr/bin/env rake
# encoding: utf-8
# Automatically generate a changelog for this project. Only loaded if
# the necessary gem is installed.
begin
require 'github_changelog_generator/task'
GitHubChangelogGenerator::RakeTask.new :changelog
rescue LoadError
puts '>>>>> GitHub Changelog Generator not loaded, omitting tasks'
end

View file

@ -0,0 +1,4 @@
# TODO
* [Adduser consistency](https://github.com/hardening-io/chef-os-hardening/pull/73)
* [add support for limiting password re-use](https://github.com/hardening-io/puppet-os-hardening/pull/61)

View file

@ -0,0 +1,15 @@
# 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}
# additional paths to search for roles in, colon separated
roles_path = ../

View file

@ -0,0 +1,20 @@
---
- name: wrapper playbook for kitchen testing "ansible-os-hardening" with custom vars for testing
hosts: localhost
roles:
- ansible-os-hardening
vars:
os_security_users_allow: change_user
os_security_kernel_enable_core_dump: false
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']
- name: wrapper playbook for kitchen testing "ansible-os-hardening"
hosts: localhost
roles:
- ansible-os-hardening

View file

@ -0,0 +1,118 @@
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
os_auth_lockout_time: 600 # 10min
os_auth_timeout: 60
os_auth_allow_homeless: false
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_security_kernel_enable_module_loading: true
os_security_kernel_enable_core_dump: false
os_security_suid_sgid_enforce: true
# user-defined blacklist and whitelist
os_security_suid_sgid_blacklist: []
os_security_suid_sgid_whitelist: []
# if this is true, remove any suid/sgid bits from files that were not in the whitelist
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']
# Allow interactive startup (rhel, centos)
os_security_init_prompt: true
# Require root password for single user mode. (rhel, centos)
os_security_init_single: false
# Apply ufw defaults
ufw_manage_defaults: true
# Empty variable disables IPT_SYSCTL in /etc/default/ufw
# by default in Ubuntu it set to: /etc/ufw/sysctl.conf
# CAUTION
# if you enable it - it'll overwrite /etc/sysctl.conf file, managed by hardening framework
ufw_ipt_sysctl: ''
# Default ufw variables
ufw_default_input_policy: 'DROP'
ufw_default_output_policy: 'ACCEPT'
ufw_default_forward_policy: 'DROP'
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.
net.ipv4.ip_forward: 0
# 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
# 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_rhel_config:
# ExecShield protection against buffer overflows
kernel.exec-shield: 1
# Syncookies is used to prevent SYN-flooding attacks.
net.ipv4.tcp_syncookies: 1

View file

@ -0,0 +1,5 @@
# 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!
Vagrant.configure(2) do |config|
end

View file

@ -0,0 +1 @@
{install_date: 'Sun Apr 23 07:59:14 2017', version: 4.0.0}

View file

@ -0,0 +1,26 @@
---
galaxy_info:
author: "Sebastian Gumprich"
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'
platforms:
- name: EL
versions:
- 6
- 7
- name: Ubuntu
versions:
- precise
- trusty
- xenial
- name: Debian
versions:
- wheezy
- jessie
galaxy_tags:
- system
- security
- hardening
dependencies: []

View file

@ -0,0 +1,6 @@
---
- name: remove packages
apt: name='{{item}}' state=removed
with_items:
- "{{os_security_packages_list}}"
when: os_security_packages_clean

View file

@ -0,0 +1,9 @@
---
- 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
- 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

View file

@ -0,0 +1,4 @@
---
- name: create login.defs
template: src='login.defs.j2' dest='/etc/login.defs' owner=root group=root mode=0444

View file

@ -0,0 +1,43 @@
---
- 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

View file

@ -0,0 +1,26 @@
---
# 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:
- '/usr/local/sbin'
- '/usr/local/bin'
- '/usr/sbin'
- '/usr/bin'
- '/sbin'
- '/bin'
- '{{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 | 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 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

View file

@ -0,0 +1,61 @@
---
- name: update pam on Debian systems
command: 'pam-auth-update --package'
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
changed_when: False
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'
- name: remove pam_cracklib, because it does not play nice with passwdqc
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'
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}}'
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'
when: (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') and not os_auth_pam_passwdqc_enable
- name: install tally2
apt: name='libpam-modules' state='installed'
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
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
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
- 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
- name: remove passwdqc
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
- 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

View file

@ -0,0 +1,4 @@
---
- name: create profile.conf
template: src='profile.conf.j2' dest='/etc/profile.d/pinerolo_profile.sh' owner=root group=root mode=0750
when: not os_security_kernel_enable_core_dump

View file

@ -0,0 +1,13 @@
---
- name: Get user accounts | DTAG SEC Req 3.21-4
command: "awk -F: '{print $1}' /etc/passwd"
changed_when: False
check_mode: no
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 hosts.equiv from system | DTAG SEC Req 3.21-4
file: dest='/etc/hosts.equiv' state=absent

View file

@ -0,0 +1,3 @@
---
- name: create securetty
template: src='securetty.j2' dest='/etc/securetty' owner=root group=root mode=0400

View file

@ -0,0 +1,24 @@
---
- name: remove suid/sgid bit from binaries in blacklist
file: path='{{item}}' mode='a-s' state=file follow=yes
failed_when: false
with_items:
- '{{ os_security_suid_sgid_system_blacklist }}'
- '{{ os_security_suid_sgid_blacklist }}'
- name: find binaries with suid/sgid set
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
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) }}'
when: os_security_suid_sgid_remove_from_unknown

View file

@ -0,0 +1,45 @@
---
- name: protect sysctl.conf
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: install initramfs-tools
apt: name='initramfs-tools' state=installed 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
when: ansible_os_family == 'Debian' and os_security_kernel_enable_module_loading
register: initramfs
- name: update-initramfs
command: 'update-initramfs -u'
when: initramfs.changed
- name: Change various sysctl-settings, look at the sysctl-vars file for documentation
sysctl:
name: '{{ item.key }}'
value: '{{ item.value }}'
sysctl_set: yes
state: present
reload: yes
ignoreerrors: yes
with_dict: '{{ sysctl_config }}'
- name: Change various sysctl-settings on rhel-hosts, look at the sysctl-vars file for documentation
sysctl:
name: '{{ item.key }}'
value: '{{ item.value }}'
state: present
reload: yes
ignoreerrors: yes
with_dict: '{{ sysctl_rhel_config }}'
when: ansible_distribution == 'RedHat' or ansible_distribution == 'Fedora' or ansible_distribution == 'CentOS'
- name: Apply ufw defaults
template: src="ufw.j2" dest=/etc/default/ufw
when: ufw_manage_defaults and (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu')
tags: ufw

View file

@ -0,0 +1,35 @@
---
- name: get UID_MIN from login.defs
shell: awk '/^\s*UID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs removes=/etc/login.defs
register: uid_min
check_mode: no
changed_when: False
- name: calculate UID_MAX from UID_MIN by substracting 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'
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'
when: not uid_min
- name: get all system accounts
command: awk -F'':'' '{ if ( $3 <= {{uid_max|quote}} ) print $1}' /etc/passwd removes=/etc/passwd
changed_when: False
check_mode: no
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
- 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) }}'

View file

@ -0,0 +1,36 @@
---
- name: remove unused repositories
file: name='/etc/yum.repos.d/{{item}}.repo' state=absent
with_items:
- 'CentOS-Debuginfo'
- 'CentOS-Media'
- 'CentOS-Vault'
when: os_security_packages_clean
- name: get yum-repository-files
shell: 'find /etc/yum.repos.d/ -type f -name *.repo'
changed_when: False
register: yum_repos
- name: check if rhnplugin.conf exists
stat: path='/etc/yum/pluginconf.d/rhnplugin.conf'
register: rhnplugin_file
# 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:
- '/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'
when: rhnplugin_file.stat.exists
- name: remove packages
yum: name='{{item}}' state=removed
with_items:
- "{{os_security_packages_list}}"
when: os_security_packages_clean

View file

@ -0,0 +1,3 @@
# {{ansible_managed}}
# Prevent core dumps for all users. These are usually only needed by developers and may contain sensitive information.
* hard core 0

View file

@ -0,0 +1,210 @@
# 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
#MAIL_FILE .mail
# Enable logging and display of `/var/log/faillog` login failure info. This option conflicts with the `pam_tally` PAM module.
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
# Enable logging of successful logins
LOG_OK_LOGINS yes
# Enable "syslog" logging of su activity - in addition to sulog file logging.
SYSLOG_SU_ENAB yes
# Enable "syslog" logging of newgrp and sg.
SYSLOG_SG_ENAB yes
# If defined, all su activity is logged to this file.
#SULOG_FILE /var/log/sulog
# If defined, file which maps tty line to `TERM` environment parameter. Each line of the file is in a format something like "vt100 tty01".
#TTYTYPE_FILE /etc/ttytype
# If defined, login failures will be logged here in a utmp format last, when invoked as lastb, will read `/var/log/btmp`, so...
FTMP_FILE /var/log/btmp
# If defined, the command name to display when running "su -". For # example, if this is defined as "su" then a "ps" will display the command is "-su". If not defined, then "ps" would display the name of the shell actually being run, e.g. something like "-sh".
SU_NAME su
# If defined, file which inhibits all the usual chatter during the login sequence. If a full pathname, then hushed mode will be enabled if the user's name or shell are found in the file. If not a full pathname, then hushed mode will be enabled if the file exists in the user's home directory.
#HUSHLOGIN_FILE /etc/hushlogins
HUSHLOGIN_FILE .hushlogin
# *REQUIRED*: The default PATH settings, for superuser and normal users. (they are minimal, add the rest in the shell startup files)
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin{{ os_env_extra_user_paths| join (':') }}
# Terminal permissions
# --------------------
# Login tty will be assigned this group ownership.
# If you have a "write" program which is "setgid" to a special group which owns the terminals, define `TTYGROUP` to the group number and `TTYPERM` to `0620`. Otherwise leave `TTYGROUP` commented out and assign `TTYPERM` to either `622` or `600`.
TTYGROUP tty
# Login tty will be set to this permission.
# In Debian `/usr/bin/bsd-write` or similar programs are setgid tty. However, the default and recommended value for `TTYPERM` is still `0600` to not allow anyone to write to anyone else console or terminal
# Users can still allow other people to write them by issuing the `mesg y` command.
TTYPERM 0600
# Login conf initializations
# --------------------------
# Terminal ERASE character ('\010' = backspace). Only used on System V.
ERASECHAR 0177
# Terminal KILL character ('\025' = CTRL/U). Only used on System V.
KILLCHAR 025
# The default umask value for `pam_umask` and is used by useradd and newusers to set the mode of the new home directories.
# If `USERGROUPS_ENAB` is set to `yes`, that will modify this `UMASK` default value for private user groups, i. e. the uid is the same as gid, and username is the same as the primary group name: for these, the user permissions will be used as group permissions, e. g. `022` will become `002`.
# 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}}
# 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.
USERGROUPS_ENAB yes
# Password aging controls
# -----------------------
# Maximum number of days a password may be used.
PASS_MAX_DAYS {{os_auth_pw_max_age}}
# Minimum number of days allowed between password changes.
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_MAX 60000
# System accounts
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_MAX 60000
# System accounts
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}}
# Max time in seconds for login
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".
{% if os_chfn_restrict %}
CHFN_RESTRICT {{ os_chfn_restrict }}
{% endif %}
# Should login be allowed if we can't cd to the home directory?
DEFAULT_HOME {{ 'yes' if os_auth_allow_homeless else 'no' }}
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#USERDEL_CMD /usr/sbin/userdel_local
# Instead of the real user shell, the program specified by this parameter will be launched, although its visible name (`argv[0]`) will be the shell's. The program may do whatever it wants (logging, additional authentification, banner, ...) before running the actual shell.
#FAKE_SHELL /bin/fakeshell
# If defined, either full pathname of a file containing device names or a ":" delimited list of device names. Root logins will be allowed only upon these devices.
# This variable is used by login and su.
#CONSOLE /etc/consoles
#CONSOLE console:tty01:tty02:tty03:tty04
# List of groups to add to the user's supplementary group set when logging in on the console (as determined by the `CONSOLE` setting). Default is none.
# Use with caution - it is possible for users to gain permanent access to these groups, even when not logged in on the console. How to do it is left as an exercise for the reader...
# This variable is used by login and su.
#CONSOLE_GROUPS floppy:audio:cdrom
# If set to `MD5`, MD5-based algorithm will be used for encrypting password
# If set to `SHA256`, SHA256-based algorithm will be used for encrypting password
# If set to `SHA512`, SHA512-based algorithm will be used for encrypting password
# If set to `DES`, DES-based algorithm will be used for encrypting password (default)
# Overrides the MD5_CRYPT_ENAB option
#
# Note: It is recommended to use a value consistent with
# the PAM modules configuration.
MD5_CRYPT_ENAB no
ENCRYPT_METHOD SHA512
# Only used if `ENCRYPT_METHOD` is set to `SHA256` or `SHA512`: Define the number of SHA rounds.
# With a lot of rounds, it is more difficult to brute forcing the password. But note also that it more CPU resources will be needed to authenticate users.
# If not specified, the libc will choose the default number of rounds (5000). The values must be inside the 1000-999999999 range. If only one of the MIN or MAX values is set, then this value will be used.
# If MIN > MAX, the highest value will be used.
#SHA_CRYPT_MIN_ROUNDS 5000
#SHA_CRYPT_MAX_ROUNDS 5000
# Obsoleted by PAM
# ================
# These options are now handled by PAM. Please edit the appropriate file in `/etc/pam.d/` to enable the equivelants of them.
#MOTD_FILE
#DIALUPS_CHECK_ENAB
#LASTLOG_ENAB
#MAIL_CHECK_ENAB
#OBSCURE_CHECKS_ENAB
#PORTTIME_CHECKS_ENAB
#SU_WHEEL_ONLY
#CRACKLIB_DICTPATH
#PASS_CHANGE_TRIES
#PASS_ALWAYS_WARN
#ENVIRON_FILE
#NOLOGINS_FILE
#ISSUE_FILE
#PASS_MIN_LEN
#PASS_MAX_LEN
#ULIMIT
#ENV_HZ
#CHFN_AUTH
#CHSH_AUTH
#FAIL_DELAY
# Obsoleted
# =========
# These options are no more handled by shadow.
# Shadow utilities will display a warning if they still appear.
#CLOSE_SESSIONS
#LOGIN_STRING
#NO_PASSWORD_CONSOLE
#QMAIL_DIR
# If set to `yes`, new passwords will be encrypted using the MD5-based algorithm compatible with the one used by recent releases of FreeBSD. It supports passwords of unlimited length and longer salt strings.
# Set to `no` if you need to copy encrypted passwords to other systems which don't understand the new algorithm. Default is `no`.
# This variable is deprecated. You should use ENCRYPT_METHOD.
#
#MD5_CRYPT_ENAB no

View file

@ -0,0 +1,111 @@
# {{ ansible_managed }}
# 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/`
# We will sort by folder.
# Arch
# ----
#
# Modules for certains builds, contains support modules and some CPU-specific optimizations.
{% if ansible_architecture == 'x86_64' %}
# Optimize for x86_64 cryptographic features
twofish-x86_64-3way
twofish-x86_64
aes-x86_64
salsa20-x86_64
blowfish-x86_64
{% endif %}
{% if 'amd' in ansible_processor %}
# AMD-specific optimizations
kvm-amd
{% else %}
# Intel-specific optimizations
ghash-clmulni-intel
aesni-intel
kvm-intel
{% endif %}
kvm
# Crypto
# ------
# Some core modules which comprise strong cryptography.
blowfish_common
blowfish_generic
ctr
cts
lrw
lzo
rmd160
rmd256
rmd320
serpent
sha512_generic
twofish_common
twofish_generic
xts
zlib
# Drivers
# -------
# Basics
lp
rtc
loop
# Filesystems
ext2
btrfs
{% if os_desktop_enable %}
# Desktop
psmouse
snd
snd_ac97_codec
snd_intel8x0
snd_page_alloc
snd_pcm
snd_timer
soundcore
usbhid
{% endif %}
# Lib
# ---
xz
# Net
# ---
# All packets needed for netfilter rules (ie iptables, ebtables).
ip_tables
x_tables
iptable_filter
iptable_nat
# Targets
ipt_LOG
ipt_REJECT
# Modules
xt_connlimit
xt_tcpudp
xt_recent
xt_limit
xt_conntrack
nf_conntrack
nf_conntrack_ipv4
nf_defrag_ipv4
xt_state
nf_nat
# Addons
xt_pknock

View file

@ -0,0 +1,7 @@
Name: passwdqc password strength enforcement
Default: yes
Priority: 1024
Conflicts: cracklib
Password-Type: Primary
Password:
requisite pam_passwdqc.so {{os_auth_pam_passwdqc_options}}

View file

@ -0,0 +1,10 @@
Name: tally2 lockout after failed attempts enforcement
Default: yes
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}}
Account-Type: Primary
Account-Initial:
required pam_tally2.so

View file

@ -0,0 +1,4 @@
# {{ ansible_managed }}
# 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

View file

@ -0,0 +1,90 @@
# See libuser.conf(5) for more information.
# {{ ansible_managed }}
# Do not modify the default module list if you care about unattended calls
# to programs (i.e., scripts) working!
[import]
# Data from these files is used when libuser.conf does not define a value.
# The mapping is documented in the man page.
login_defs = /etc/login.defs
default_useradd = /etc/default/useradd
[defaults]
# The default (/usr/lib*/libuser) is usually correct
# moduledir = /your/custom/directory
# The following variables are usually imported:
# skeleton = /etc/skel
# mailspooldir = /var/mail
# NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512
crypt_style = sha512
modules = files shadow
create_modules = files shadow
# modules = files shadow ldap
# create_modules = ldap
[userdefaults]
LU_USERNAME = %n
# LU_UIDNUMBER = 500
LU_GIDNUMBER = %u
# LU_USERPASSWORD = !!
# LU_GECOS = %n
# LU_HOMEDIRECTORY = /home/%n
# LU_LOGINSHELL = /bin/bash
# LU_SHADOWNAME = %n
# LU_SHADOWPASSWORD = !!
# LU_SHADOWLASTCHANGE = %d
# LU_SHADOWMIN = 0
# LU_SHADOWMAX = 99999
# LU_SHADOWWARNING = 7
# LU_SHADOWINACTIVE = -1
# LU_SHADOWEXPIRE = -1
# LU_SHADOWFLAG = -1
[groupdefaults]
LU_GROUPNAME = %n
# LU_GIDNUMBER = 500
# LU_GROUPPASSWORD = !!
# LU_MEMBERUID =
# LU_ADMINISTRATORUID =
[files]
# This is useful for the case where some master files are used to
# populate a different NSS mechanism which this workstation uses.
# directory = /etc
[shadow]
# This is useful for the case where some master files are used to
# populate a different NSS mechanism which this workstation uses.
# directory = /etc
[ldap]
# Setting these is always necessary.
# server = ldap
# basedn = dc=example,dc=com
# Setting these is rarely necessary, since it's usually correct.
# userBranch = ou=People
# groupBranch = ou=Group
# Set only if your administrative user uses simple bind operations to
# connect to the server.
# binddn = cn=Manager,dc=example,dc=com
# Set this only if the default user (as determined by SASL) is incorrect
# for SASL bind operations. Usually, it's correct, so you'll rarely need
# to set these.
# user = Manager
# authuser = Manager
[sasl]
# Set these only if your sasldb is only used by a particular application, and
# in a particular domain. The default (all applications, all domains) is
# probably correct for most installations.
# appname = imap
# domain = EXAMPLE.COM

View file

@ -0,0 +1,31 @@
# {{ ansible_managed }}
# color => new RH6.0 bootup
# verbose => old-style bootup
# anything else => new style bootup without ANSI colors or positioning
BOOTUP=color
# column to start "[ OK ]" label in
RES_COL=60
# terminal sequence to move to that column. You could change this
# to something like "tput hpa ${RES_COL}" if your terminal supports it
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
# terminal sequence to set color to a 'success' color (currently: green)
SETCOLOR_SUCCESS="echo -en \\033[0;32m"
# terminal sequence to set color to a 'failure' color (currently: red)
SETCOLOR_FAILURE="echo -en \\033[0;31m"
# terminal sequence to set color to a 'warning' color (currently: yellow)
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' }}
# Set to 'yes' to allow probing for devices with swap signatures
AUTOSWAP=no
# What ttys should gettys be started on?
ACTIVE_CONSOLES=/dev/tty[1-6]
# Set to '/sbin/sulogin' to prompt for password on single-user mode
# Set to '/sbin/sushell' otherwise
SINGLE={{ '/sbin/sulogin' if os_security_init_single else '/sbin/sushell' }}
# NSA 2.2.4.1 Set Daemon umask
umask 027

View file

@ -0,0 +1,40 @@
# {{ ansible_managed }}
#---
#%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}}
{% endif %}
auth required pam_env.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth required pam_deny.so
{% if os_auth_retries > 0 %}
account required pam_tally2.so
{% endif %}
account required pam_unix.so
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}}
{%- else %}
password requisite pam_passwdqc.so {{os_auth_pam_passwdqc_options}}
{%- endif %}
{% else %}
password requisite pam_cracklib.so try_first_pass retry=3 type=
{% endif %}
# NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512
# NSA 2.3.3.6 Limit Password Reuse
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so

View file

@ -0,0 +1,6 @@
# {{ ansible_managed }}
# A list of TTYs, from which root can log in
# see `man securetty` for reference
{{ "\n".join(os_auth_root_ttys) }}

View file

@ -0,0 +1,44 @@
# /etc/default/ufw
#
# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
IPV6={{ 'no' if sysctl_config['net.ipv6.conf.all.disable_ipv6'] is defined and sysctl_config['net.ipv6.conf.all.disable_ipv6'] == 1 else 'yes' }}
# Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_INPUT_POLICY="{{ ufw_default_input_policy }}"
# Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_OUTPUT_POLICY="{{ ufw_default_output_policy }}"
# Set the default forward policy to ACCEPT, DROP or REJECT. Please note that
# if you change this you will most likely want to adjust your rules
DEFAULT_FORWARD_POLICY="{{ ufw_default_forward_policy }}"
# Set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please
# note that setting this to ACCEPT may be a security risk. See 'man ufw' for
# details
DEFAULT_APPLICATION_POLICY="{{ ufw_default_application_policy }}"
# By default, ufw only touches its own chains. Set this to 'yes' to have ufw
# manage the built-in chains too. Warning: setting this to 'yes' will break
# non-ufw managed firewall rules
MANAGE_BUILTINS="{{ ufw_manage_builtins }}"
#
# IPT backend
#
# only enable if using iptables backend and want to overwrite /etc/sysctl.conf
{% if ufw_ipt_sysctl == '' %}#{% endif %}IPT_SYSCTL={{ ufw_ipt_sysctl }}
# Extra connection tracking modules to load. Complete list can be found in
# net/netfilter/Kconfig of your kernel source. Some common modules:
# nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support
# nf_conntrack_netbios_ns: NetBIOS (samba) client support
# nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT
# nf_conntrack_ftp, nf_nat_ftp: active FTP support
# nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side)
IPT_MODULES="{{ ufw_ipt_modules }}"

View file

@ -0,0 +1,14 @@
os_packages_pam_ccreds: 'libpam-ccreds'
os_packages_pam_passwdqc: 'libpam-passwdqc'
os_packages_pam_cracklib: 'libpam-cracklib'
passwdqc_path: '/usr/share/pam-configs/passwdqc'
tally2_path: '/usr/share/pam-configs/tally2'
os_nologin_shell_path: '/usr/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.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: shadow
mode: "0640"

View file

@ -0,0 +1,12 @@
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.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: root
mode: "0600"

View file

@ -0,0 +1,12 @@
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.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: root
mode: "0600"

View file

@ -0,0 +1,111 @@
# SYSTEM CONFIGURATION
# ====================
# These are not meant to be modified by the user
# suid and sgid blacklists and whitelists
# ---------------------------------------
# don't change values in the system_blacklist/whitelist
# 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:
# blacklist as provided by NSA
- '/usr/bin/rcp'
- '/usr/bin/rlogin'
- '/usr/bin/rsh'
# sshd must not use host-based authentication (see ssh cookbook)
- '/usr/libexec/openssh/ssh-keysign'
- '/usr/lib/openssh/ssh-keysign'
# misc others
- '/sbin/netreport' # not normally required for user
- '/usr/sbin/usernetctl' # modify interfaces via functional accounts
# connecting to ...
- '/usr/sbin/userisdnctl' # no isdn...
- '/usr/sbin/pppd' # no ppp / dsl ...
# lockfile
- '/usr/bin/lockfile'
- '/usr/bin/mail-lock'
- '/usr/bin/mail-unlock'
- '/usr/bin/mail-touchlock'
- '/usr/bin/dotlockfile'
# need more investigation blacklist for now
- '/usr/bin/arping'
- '/usr/sbin/uuidd'
- '/usr/bin/mtr' # investigate current state...
- '/usr/lib/evolution/camel-lock-helper-1.2' # investigate current state...
- '/usr/lib/pt_chown' # pseudo-tty needed?
- '/usr/lib/eject/dmcrypt-get-device'
- '/usr/lib/mc/cons.saver' # midnight commander screensaver
# list of suid/sgid entries that can remain untouched
os_security_suid_sgid_system_whitelist:
# whitelist as provided by NSA
- '/bin/mount'
- '/bin/ping'
- '/bin/su'
- '/bin/umount'
- '/sbin/pam_timestamp_check'
- '/sbin/unix_chkpwd'
- '/usr/bin/at'
- '/usr/bin/gpasswd'
- '/usr/bin/locate'
- '/usr/bin/newgrp'
- '/usr/bin/passwd'
- '/usr/bin/ssh-agent'
- '/usr/libexec/utempter/utempter'
- '/usr/sbin/lockdev'
- '/usr/sbin/sendmail.sendmail'
- '/usr/bin/expiry'
# whitelist ipv6
- '/bin/ping6'
- '/usr/bin/traceroute6.iputils'
# whitelist nfs
- '/sbin/mount.nfs'
- '/sbin/umount.nfs'
# whitelist nfs4
- '/sbin/mount.nfs4'
- '/sbin/umount.nfs4'
# whitelist cron
- '/usr/bin/crontab'
# whitelist consolemssaging
- '/usr/bin/wall'
- '/usr/bin/write'
# whitelist: only SGID with utmp group for multi-session access
# impact is limited; installation/usage has some remaining risk
- '/usr/bin/screen'
# whitelist locate
- '/usr/bin/mlocate'
# whitelist usermanagement
- '/usr/bin/chage'
- '/usr/bin/chfn'
- '/usr/bin/chsh'
# whitelist fuse
- '/bin/fusermount'
# whitelist pkexec
- '/usr/bin/pkexec'
# whitelist sudo
- '/usr/bin/sudo'
- '/usr/bin/sudoedit'
# whitelist postfix
- '/usr/sbin/postdrop'
- '/usr/sbin/postqueue'
# whitelist apache
- '/usr/sbin/suexec'
# whitelist squid
- '/usr/lib/squid/ncsa_auth'
- '/usr/lib/squid/pam_auth'
# whitelist kerberos
- '/usr/kerberos/bin/ksu'
# whitelist pam_caching
- '/usr/sbin/ccreds_validate'
# whitelist Xorg
- '/usr/bin/Xorg' # xorg
- '/usr/bin/X' # xorg
- '/usr/lib/dbus-1.0/dbus-daemon-launch-helper' # freedesktop ipc
- '/usr/lib/vte/gnome-pty-helper' # gnome
- '/usr/lib/libvte9/gnome-pty-helper' # gnome
- '/usr/lib/libvte-2.90-9/gnome-pty-helper' # gnome
# system accounts that do not get their login disabled and pasword changed
os_always_ignore_users: ['root','sync','shutdown','halt']

View file

@ -0,0 +1,3 @@
.kitchen
hosts
Gemfile.lock

View file

@ -0,0 +1,81 @@
---
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
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/
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
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
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
- name: centos-7.2
driver_config:
box: opscode-centos-7.2
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.2_chef-provisionerless.box
- name: centos-6.5
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
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel64-64.box
- name: oracle-6.5
driver_config:
box: oracle-6.5
box_url: https://storage.us2.oraclecloud.com/v1/istoilis-istoilis/vagrant/oel65-64.box
- name: oracle-7
driver_config:
box: boxcutter/ol72
- 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
- name: debian-8
driver_config:
box: debian-8
box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-8.1_chef-provisionerless.box
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/ssh-baseline/
suites:
- name: ssh

View file

@ -0,0 +1,81 @@
---
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
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
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
ansible_extra_flags:
- "--skip-tags=sysctl"
platforms:
- name: centos6-ansible-latest
driver:
image: rndmh3ro/docker-centos6-ansible:latest
platform: centos
- name: centos7-ansible-latest
driver:
image: rndmh3ro/docker-centos7-ansible:latest
platform: centos
- name: oracle6-ansible-latest
driver:
image: rndmh3ro/docker-oracle6-ansible:latest
platform: centos
- name: oracle7-ansible-latest
driver:
image: rndmh3ro/docker-oracle7-ansible:latest
platform: centos
- name: ubuntu1204-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1204-ansible:latest
platform: ubuntu
- name: ubuntu1404-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1404-ansible:latest
platform: ubuntu
- name: ubuntu1604-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1604-ansible:latest
platform: ubuntu
- name: debian7-ansible-latest
driver:
image: rndmh3ro/docker-debian7-ansible:latest
platform: debian
- name: debian8-ansible-latest
driver:
image: rndmh3ro/docker-debian8-ansible:latest
platform: debian
#- name: debian9-ansible-latest
# driver:
# image: rndmh3ro/docker-debian9-ansible:latest
# platform: debian
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/ssh-baseline
suites:
- name: ssh

View file

@ -0,0 +1,67 @@
---
services: docker
env:
- distro: centos6
version: latest
init: /sbin/init
- distro: centos7
init: /usr/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: ubuntu1604
version: latest
init: /lib/systemd/systemd
run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
- distro: ubuntu1404
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
# - distro: debian9
# version: latest
# init: /lib/systemd/systemd
# run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro"
before_install:
# Pull container
- 'docker pull rndmh3ro/docker-${distro}-ansible:${version}'
script:
- container_id=$(mktemp)
# Run container in detached state.
- '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'
# Verify role
- 'inspec exec https://github.com/dev-sec/ssh-baseline/ -t docker://$(cat ${container_id})'
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/

View file

@ -0,0 +1,174 @@
# Change Log
## [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)
- Parameterise Banner and DebianBanner as defaults [\#77](https://github.com/dev-sec/ansible-ssh-hardening/pull/77) ([tsenart](https://github.com/tsenart))
**Fixed bugs:**
- 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)
**Implemented enhancements:**
- use new ciphers, kex, macs and privilege separation for redhat family 7 or later [\#72](https://github.com/dev-sec/ansible-ssh-hardening/issues/72)
## [3.1](https://github.com/dev-sec/ansible-ssh-hardening/tree/3.1) (2016-08-03)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/3.0.0...3.1)
**Implemented enhancements:**
- Add Xenial / Ubuntu 16.04 LTS to meta/main.yml [\#63](https://github.com/dev-sec/ansible-ssh-hardening/issues/63)
- Use new ciphers, kex, macs and priv separation sandbox for redhat family 7 [\#73](https://github.com/dev-sec/ansible-ssh-hardening/pull/73) ([atomic111](https://github.com/atomic111))
- add docker support [\#71](https://github.com/dev-sec/ansible-ssh-hardening/pull/71) ([rndmh3ro](https://github.com/rndmh3ro))
- add always\_run: true to task. fix \#64 [\#69](https://github.com/dev-sec/ansible-ssh-hardening/pull/69) ([rndmh3ro](https://github.com/rndmh3ro))
- Debian8 [\#68](https://github.com/dev-sec/ansible-ssh-hardening/pull/68) ([rndmh3ro](https://github.com/rndmh3ro))
- Fixed KexAlgorithms Conditional Statement [\#66](https://github.com/dev-sec/ansible-ssh-hardening/pull/66) ([cjsheets](https://github.com/cjsheets))
- Moves vars to defaults [\#60](https://github.com/dev-sec/ansible-ssh-hardening/pull/60) ([conorsch](https://github.com/conorsch))
**Fixed bugs:**
- semodule ssh\_password error on AWS Centos 7 [\#64](https://github.com/dev-sec/ansible-ssh-hardening/issues/64)
**Closed issues:**
- `ssh\_server\_ports` a bit misleading in the vars section? [\#62](https://github.com/dev-sec/ansible-ssh-hardening/issues/62)
- sftp\_enabled: false will break Ansible's template module [\#55](https://github.com/dev-sec/ansible-ssh-hardening/issues/55)
- Move cipher/kex/mac vars to defaults [\#53](https://github.com/dev-sec/ansible-ssh-hardening/issues/53)
**Merged pull requests:**
- Add SCP/SFTP to FAQ [\#58](https://github.com/dev-sec/ansible-ssh-hardening/pull/58) ([rndmh3ro](https://github.com/rndmh3ro))
## [3.0.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/3.0.0) (2016-03-13)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/2.0.0...3.0.0)
**Implemented enhancements:**
- Added sftp\_enabled, sftp\_chroot\_dir, and ssh\_client\_roaming from the … [\#57](https://github.com/dev-sec/ansible-ssh-hardening/pull/57) ([shirokatze](https://github.com/shirokatze))
- add test support for ansible 1.9 and 2.0 [\#56](https://github.com/dev-sec/ansible-ssh-hardening/pull/56) ([rndmh3ro](https://github.com/rndmh3ro))
- update platforms in meta-file [\#52](https://github.com/dev-sec/ansible-ssh-hardening/pull/52) ([rndmh3ro](https://github.com/rndmh3ro))
- add webhook for ansible galaxy [\#51](https://github.com/dev-sec/ansible-ssh-hardening/pull/51) ([rndmh3ro](https://github.com/rndmh3ro))
- Disable experimental client roaming. [\#49](https://github.com/dev-sec/ansible-ssh-hardening/pull/49) ([rndmh3ro](https://github.com/rndmh3ro))
- use inspec as test framework [\#48](https://github.com/dev-sec/ansible-ssh-hardening/pull/48) ([chris-rock](https://github.com/chris-rock))
- Change categories to tags for upcoming ansible 2.0 [\#47](https://github.com/dev-sec/ansible-ssh-hardening/pull/47) ([rndmh3ro](https://github.com/rndmh3ro))
- add changelog generator [\#46](https://github.com/dev-sec/ansible-ssh-hardening/pull/46) ([chris-rock](https://github.com/chris-rock))
**Closed issues:**
- Install from ansible galaxy missing files \(tasks\) [\#50](https://github.com/dev-sec/ansible-ssh-hardening/issues/50)
- should generate new ssh host key files [\#45](https://github.com/dev-sec/ansible-ssh-hardening/issues/45)
**Merged pull requests:**
- New release 3.0.0 [\#59](https://github.com/dev-sec/ansible-ssh-hardening/pull/59) ([rndmh3ro](https://github.com/rndmh3ro))
## [2.0.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/2.0.0) (2015-11-28)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/1.2.1...2.0.0)
**Closed issues:**
- Fix directory structure. [\#43](https://github.com/dev-sec/ansible-ssh-hardening/issues/43)
**Merged pull requests:**
- New dir layout. Fix \#43 [\#44](https://github.com/dev-sec/ansible-ssh-hardening/pull/44) ([rndmh3ro](https://github.com/rndmh3ro))
- Add var to travis job [\#42](https://github.com/dev-sec/ansible-ssh-hardening/pull/42) ([rndmh3ro](https://github.com/rndmh3ro))
- sftp\_enable option [\#41](https://github.com/dev-sec/ansible-ssh-hardening/pull/41) ([fitz123](https://github.com/fitz123))
## [1.2.1](https://github.com/dev-sec/ansible-ssh-hardening/tree/1.2.1) (2015-10-16)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/1.2...1.2.1)
**Merged pull requests:**
- Allow whitelisted groups on ssh [\#40](https://github.com/dev-sec/ansible-ssh-hardening/pull/40) ([fheinle](https://github.com/fheinle))
## [1.2](https://github.com/dev-sec/ansible-ssh-hardening/tree/1.2) (2015-09-28)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/1.2.0...1.2)
## [1.2.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/1.2.0) (2015-09-28)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/1.1...1.2.0)
**Merged pull requests:**
- bugfix. Now option true for PrintLastLog is available again [\#39](https://github.com/dev-sec/ansible-ssh-hardening/pull/39) ([fitz123](https://github.com/fitz123))
- Add more travis-tests [\#38](https://github.com/dev-sec/ansible-ssh-hardening/pull/38) ([rndmh3ro](https://github.com/rndmh3ro))
- Support for selinux and pam. fix \#23 [\#35](https://github.com/dev-sec/ansible-ssh-hardening/pull/35) ([rndmh3ro](https://github.com/rndmh3ro))
## [1.1](https://github.com/dev-sec/ansible-ssh-hardening/tree/1.1) (2015-09-01)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/1.1.0...1.1)
## [1.1.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/1.1.0) (2015-09-01)
[Full Changelog](https://github.com/dev-sec/ansible-ssh-hardening/compare/1.0.0...1.1.0)
**Closed issues:**
- ssh\_ports - individual client/server config [\#33](https://github.com/dev-sec/ansible-ssh-hardening/issues/33)
- UsePAM should probably default to yes on Red Hat Linux 7 [\#23](https://github.com/dev-sec/ansible-ssh-hardening/issues/23)
**Merged pull requests:**
- Change variable for hmac from server to client [\#37](https://github.com/dev-sec/ansible-ssh-hardening/pull/37) ([rndmh3ro](https://github.com/rndmh3ro))
- Update kitchen-ansible, remove separate debian install [\#36](https://github.com/dev-sec/ansible-ssh-hardening/pull/36) ([rndmh3ro](https://github.com/rndmh3ro))
- Separate ssh client and server ports. Fix \#33 [\#34](https://github.com/dev-sec/ansible-ssh-hardening/pull/34) ([rndmh3ro](https://github.com/rndmh3ro))
- update common kitchen.yml platforms \(ansible\), kitchen\_debian.yml platforms \(ansible\) [\#32](https://github.com/dev-sec/ansible-ssh-hardening/pull/32) ([chris-rock](https://github.com/chris-rock))
- Make MaxAuthTries configurable [\#31](https://github.com/dev-sec/ansible-ssh-hardening/pull/31) ([rndmh3ro](https://github.com/rndmh3ro))
- Change oneliner if-statements to be more readable [\#30](https://github.com/dev-sec/ansible-ssh-hardening/pull/30) ([rndmh3ro](https://github.com/rndmh3ro))
- Make ssh client password login configurable. [\#29](https://github.com/dev-sec/ansible-ssh-hardening/pull/29) ([ypid](https://github.com/ypid))
- Fix join-filter, jinja-cases, intendation [\#27](https://github.com/dev-sec/ansible-ssh-hardening/pull/27) ([rndmh3ro](https://github.com/rndmh3ro))
- Short role review. Fixed role when ssh\_client\_weak\_kex == true. [\#26](https://github.com/dev-sec/ansible-ssh-hardening/pull/26) ([ypid](https://github.com/ypid))
- Make it configurable to only harden ssh client/server or both \(default\). [\#25](https://github.com/dev-sec/ansible-ssh-hardening/pull/25) ([ypid](https://github.com/ypid))
- Separate system-vars from editable vars [\#24](https://github.com/dev-sec/ansible-ssh-hardening/pull/24) ([rndmh3ro](https://github.com/rndmh3ro))
- Add correct CONTRIB-file [\#22](https://github.com/dev-sec/ansible-ssh-hardening/pull/22) ([rndmh3ro](https://github.com/rndmh3ro))
- Add Ansible Galaxy badge [\#21](https://github.com/dev-sec/ansible-ssh-hardening/pull/21) ([rndmh3ro](https://github.com/rndmh3ro))
- fix configuration of playbook path [\#20](https://github.com/dev-sec/ansible-ssh-hardening/pull/20) ([chris-rock](https://github.com/chris-rock))
- Debian install script [\#19](https://github.com/dev-sec/ansible-ssh-hardening/pull/19) ([rndmh3ro](https://github.com/rndmh3ro))
## [1.0.0](https://github.com/dev-sec/ansible-ssh-hardening/tree/1.0.0) (2015-04-30)
**Implemented enhancements:**
- Update variable-documentation [\#12](https://github.com/dev-sec/ansible-ssh-hardening/pull/12) ([rndmh3ro](https://github.com/rndmh3ro))
**Closed issues:**
- add travis test for ubuntu 12.04 [\#7](https://github.com/dev-sec/ansible-ssh-hardening/issues/7)
- Use handler for sshd restart [\#6](https://github.com/dev-sec/ansible-ssh-hardening/issues/6)
- Running test-kitchen fails [\#2](https://github.com/dev-sec/ansible-ssh-hardening/issues/2)
**Merged pull requests:**
- add self as author [\#18](https://github.com/dev-sec/ansible-ssh-hardening/pull/18) ([chris-rock](https://github.com/chris-rock))
- add badges [\#17](https://github.com/dev-sec/ansible-ssh-hardening/pull/17) ([chris-rock](https://github.com/chris-rock))
- fix meta.yml [\#16](https://github.com/dev-sec/ansible-ssh-hardening/pull/16) ([chris-rock](https://github.com/chris-rock))
- add more information to changelog [\#15](https://github.com/dev-sec/ansible-ssh-hardening/pull/15) ([chris-rock](https://github.com/chris-rock))
- Add meta-information for Ansible Galaxy [\#14](https://github.com/dev-sec/ansible-ssh-hardening/pull/14) ([rndmh3ro](https://github.com/rndmh3ro))
- Update CHANGELOG.md [\#13](https://github.com/dev-sec/ansible-ssh-hardening/pull/13) ([rndmh3ro](https://github.com/rndmh3ro))
- Add handler to restart ssh only if necessary. Fix \#6 [\#11](https://github.com/dev-sec/ansible-ssh-hardening/pull/11) ([rndmh3ro](https://github.com/rndmh3ro))
- add more descriptions [\#10](https://github.com/dev-sec/ansible-ssh-hardening/pull/10) ([chris-rock](https://github.com/chris-rock))
- add travis config for ansible [\#9](https://github.com/dev-sec/ansible-ssh-hardening/pull/9) ([chris-rock](https://github.com/chris-rock))
- update .kitchen.yml to find playbook role in tests [\#8](https://github.com/dev-sec/ansible-ssh-hardening/pull/8) ([chris-rock](https://github.com/chris-rock))
- Oracle support [\#5](https://github.com/dev-sec/ansible-ssh-hardening/pull/5) ([rndmh3ro](https://github.com/rndmh3ro))
- Remove custom Vagrantfile-reference. Fix \#2 [\#4](https://github.com/dev-sec/ansible-ssh-hardening/pull/4) ([rndmh3ro](https://github.com/rndmh3ro))
- Remove custom Vagrantfile-reference. Fix \#2 [\#3](https://github.com/dev-sec/ansible-ssh-hardening/pull/3) ([rndmh3ro](https://github.com/rndmh3ro))
- Fix missing gem [\#1](https://github.com/dev-sec/ansible-ssh-hardening/pull/1) ([chris-rock](https://github.com/chris-rock))
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*

View file

@ -0,0 +1,85 @@
# Contributor Guideline
This document provides an overview of how you can participate in improving this project or extending it. We are grateful for all your help: bug reports and fixes, code contributions, documentation or ideas. Feel free to join, we appreciate your support!!
## Communication
### GitHub repositories
Much of the issues, goals and ideas are tracked in the respective projects in GitHub. Please use this channel to report bugs and post ideas.
## git and GitHub
In order to contribute code please:
1. Fork the project on GitHub
2. Clone the project
3. Add changes (and tests)
4. Commit and push
5. Create a merge-request
To have your code merged, see the expectations listed below.
You can find a well-written guide [here](https://help.github.com/articles/fork-a-repo).
Please follow common commit best-practices. Be explicit, have a short summary, a well-written description and references. This is especially important for the merge-request.
Some great guidelines can be found [here](https://wiki.openstack.org/wiki/GitCommitMessages) and [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message).
## Expectations
### Don't reinvent the wheel
This hardening project doesn't intend to reinvent the configuration stack for services. Aim to use official configuration projects first and provide hardening as a layer on top. The goal is remove the need for a user to configure all aspects of services and maintain security configuration. This way, the user can still configure a service using the interface provided by the official project.
* For Chef refer to the official [opscode community cookbooks](http://community.opscode.com/cookbooks).
* For Puppet head to the [Puppet Forge](https://forge.puppetlabs.com/) and take a node of the Puppet supported modules.
* For Ansible check the [Ansible Module Index](http://docs.ansible.com/list_of_all_modules.html)
These projects are generally hosted on GitHub as well.
In some cases, we in fact create the full rollout stack, but this is generally the exception ([os-hardening](https://github.com/TelekomLabs/chef-os-hardening), [nginx-hardening](https://github.com/TelekomLabs/chef-nginx-hardening)).
### Be explicit
* Please avoid using nonsensical property and variable names.
* Use self-describing attribute names for user configuration.
* In case of failures, communicate what happened and why a failure occurs to the user. Make it easy to track the code or action that produced the error. Try to catch and handle errors if possible to provide improved failure messages.
### Add tests
The security review of this project is done using integration tests.
Whenever you add a new security configuration, please start by writing a test that checks for this configuration. For example: If you want to set a new attribute in a configuration file, write a test that expects the value to be set first. Then implement your change.
You may add a new feature request by creating a test for whatever value you need.
All tests will be reviewed internally for their validity and overall project direction.
### Document your code
As code is more often read than written, please provide documentation in all projects.
Adhere to the respective guidelines for documentation:
* Chef generally documents code based explicit readme files. For code documentation please use [yard-chef](https://github.com/rightscale/yard-chef)
* [Puppet module documentation](http://docs.puppetlabs.com/puppet/latest/reference/modules_documentation.html)
### Follow coding styles
We generally include test for coding guidelines:
* Chef follows [Foodcritic](http://acrmp.github.io/foodcritic/)
* Puppet is checked with [puppet-lint](http://puppet-lint.com/checks/)
* Ansible is checked by running the playbook with the syntax-check option, e.g. `ansible-playbook foo.yml --syntax-check`
Remember: Code is generally read much more often than written.
### Use Markdown
Wherever possible, please refrain from any other formats and stick to simple markdown.

View file

@ -0,0 +1,18 @@
# encoding: utf-8
source 'https://rubygems.org'
group :integration do
gem 'test-kitchen', '~> 1.0'
gem 'kitchen-ansible'
gem 'kitchen-vagrant'
gem 'kitchen-inspec'
gem 'kitchen-sharedtests', '~> 0.2.0'
gem 'kitchen-sync'
gem 'kitchen-transport-rsync'
gem 'kitchen-docker'
end
group :tools do
gem 'github_changelog_generator', '~> 1'
end

View file

@ -0,0 +1,165 @@
# ssh-hardening (Ansible Role)
[![Build Status](http://img.shields.io/travis/dev-sec/ansible-ssh-hardening.svg)][1]
[![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)][2]
[![Ansible Galaxy](https://img.shields.io/badge/galaxy-ssh--hardening-660198.svg)][3]
## Description
This role provides secure ssh-client and ssh-server configurations.
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
## 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_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_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_allow_agent_forwarding` | false | false to disable Agent Forwarding. Set to true to allow Agent Forwarding.|
|`ssh_use_pam` | false | false to disable pam authentication.|
|`ssh_deny_users` | '' | 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_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_dir` | /home/%u | change default sftp chroot location|
|`ssh_client_roaming` | false | enable experimental client roaming|
|`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) |
## Example Playbook
- hosts: localhost
roles:
- dev-sec.ssh-hardening
## Local Testing
The preferred way of locally testing the role is to use Docker. You will have to install Docker on your system. See [Get started](https://docs.docker.com/) for a Docker package suitable to for your system.
You can also use vagrant and Virtualbox or VMWare to run tests locally. You will have to install Virtualbox and Vagrant on your system. See [Vagrant Downloads](http://downloads.vagrantup.com/) for a vagrant package suitable for your system. For all our tests we use `test-kitchen`. If you are not familiar with `test-kitchen` please have a look at [their guide](http://kitchen.ci/docs/getting-started).
Next install test-kitchen:
```bash
# Install dependencies
gem install bundler
bundle install
```
### Testing with Docker
```
# fast test on one machine
bundle exec kitchen test default-ubuntu-1204
# test on all machines
bundle exec kitchen test
# for development
bundle exec kitchen create default-ubuntu-1204
bundle exec kitchen converge default-ubuntu-1204
```
### Testing with Virtualbox
```
# fast test on one machine
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test default-ubuntu-1204
# 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
```
For more information see [test-kitchen](http://kitchen.ci/docs/getting-started)
## FAQ / Pitfalls
**I can't log into my account. I have registered the client key, but it still doesn't let me it.**
If you have exhausted all typical issues (firewall, network, key missing, wrong key, account disabled etc.), it may be that your account is locked. The quickest way to find out is to look at the password hash for your user:
sudo grep myuser /etc/shadow
If the hash includes an `!`, your account is locked:
myuser:!:16280:7:60:7:::
The proper way to solve this is to unlock the account (`passwd -u myuser`). If the user doesn't have a password, you should can unlock it via:
usermod -p "*" myuser
Alternatively, if you intend to use PAM, you enabled it via `ssh_use_pam: true`. PAM will allow locked users to get in with keys.
**Why doesn't my application connect via SSH anymore?**
Always look into log files first and if possible look at the negotation between client and server that is completed when connecting.
We have seen some issues in applications (based on python and ruby) that are due to their use of an outdated crypto set. This collides with this hardening module, which reduced the list of ciphers, message authentication codes (MACs) and key exchange (KEX) algorithms to a more secure selection.
If you find this isn't enough, feel free to activate the attributes `cbc_requires` for ciphers, `weak_hmac` for MACs and `weak_kex`for KEX in the variables `ssh_client` or `ssh_server` based on where you want to support them.
**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.
**Cannot restart sshd-service due to lack of privileges**
If you get the following error when running handler "restart sshd"
```
Unable to restart service ssh: Failed to restart ssh.service: Access denied
```
or
```
failure 1 running systemctl show for 'ssh': Failed to connect to bus: No such file or directory
```
either run the playbook as `root` (without `become: yes` at the playbook level), or add `become: yes` to the handler.
This is a bug with Ansible: see [here](https://github.com/dev-sec/ansible-ssh-hardening/pull/81) and [here](https://github.com/ansible/ansible/issues/17490) for more information.
## Contributing
See [contributor guideline](CONTRIBUTING.md).
## License and Author
* Author:: Sebastian Gumprich <sebastian.gumprich@38.de>
* Author:: Christoph Hartmann <chris@lollyrock.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
[1]: http://travis-ci.org/dev-sec/ansible-ssh-hardening
[2]: https://gitter.im/dev-sec/general
[3]: https://galaxy.ansible.com/dev-sec/ssh-hardening/

View file

@ -0,0 +1,25 @@
#!/usr/bin/env rake
# encoding: utf-8
require 'foodcritic'
require 'rspec/core/rake_task'
# Rubocop before rspec so we don't lint vendored cookbooks
desc 'Run all tests except Kitchen (default task)'
task default: [:integration]
# Automatically generate a changelog for this project. Only loaded if
# the necessary gem is installed.
begin
require 'github_changelog_generator/task'
GitHubChangelogGenerator::RakeTask.new :changelog
rescue LoadError
puts '>>>>> GitHub Changelog Generator not loaded, omitting tasks'
end
desc 'Run integration tests'
task :integration do
concurrency = ENV['CONCURRENCY'] || 1
os = ENV['OS'] || ''
sh('sh', '-c', "bundle exec kitchen test -c #{concurrency} #{os}")
end

View 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

View file

@ -0,0 +1,34 @@
---
- 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

View file

@ -0,0 +1,155 @@
# true if IPv6 is needed
network_ipv6_enable: false # sshd + ssh
# 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.
ssh_client_password_login: false # ssh
# ports on which ssh-server should listen
ssh_server_ports: ['22'] # sshd
# port to which ssh-client should connect
ssh_client_port: '22' # ssh
# one or more ip addresses, to which ssh-server should listen to. Default is empty, but should be configured for security reasons!
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
# 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_count: 3 # sshd
# Hosts with custom options. # ssh
# Example:
# ssh_remote_hosts:
# - names: ['example.com', 'example2.com']
# options: ['Port 2222', 'ForwardAgent yes']
# - names: ['example3.com']
# options: ['StrictHostKeyChecking no']
ssh_remote_hosts: []
# false to disable root login altogether. Set to true to allow root to login via key-based mechanism.
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 Agent Forwarding. Set to true to allow Agent Forwarding.
ssh_allow_agent_forwarding: false # sshd
# false to disable pam authentication.
ssh_use_pam: false # sshd
# if specified, login is disallowed for user names that match one of the patterns.
ssh_deny_users: '' # sshd
# if specified, login is allowed only for user names that match one of the patterns.
ssh_allow_users: '' # sshd
# if specified, login is disallowed for users whose primary group or supplementary group list matches one of the patterns.
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
# false to disable printing of the MOTD
ssh_print_motd: false # sshd
# false to disable display of last login information
ssh_print_last_log: false # sshd
# false to disable serving /etc/ssh/banner.txt before authentication is allowed
ssh_banner: false # sshd
# false to disable distribution version leakage during initial protocol handshake
ssh_print_debian_banner: false # sshd (Debian OS family only)
# true to enable sftp configuration
sftp_enabled: false
# change default sftp chroot location
sftp_chroot_dir: /home/%u
# enable experimental client roaming
ssh_client_roaming: false
ssh_ps53: 'yes'
ssh_ps59: 'sandbox'
ssh_macs_53_default:
- hmac-ripemd160
- hmac-sha1
ssh_macs_59_default:
- hmac-sha2-512
- 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_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
- aes128-gcm@openssh.com
- aes256-ctr
- 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_minimum: 2048
# disable ChallengeResponseAuthentication
ssh_challengeresponseauthentication: false

View file

@ -0,0 +1,10 @@
module ssh_password 1.0;
require {
type sshd_t;
type shadow_t;
class file { read open };
}
#============= sshd_t ==============
allow sshd_t shadow_t:file { read open };

View file

@ -0,0 +1,2 @@
- name: restart sshd
service: name={{ sshd_service_name }} state=restarted

View file

@ -0,0 +1,19 @@
# 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'].nil? || 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|
if Vagrant.has_plugin?("vagrant-proxyconf")
config.proxy.http = "#{ENV['http_proxy']}"
config.proxy.https = "#{ENV['https_proxy']}"
config.proxy.no_proxy = "localhost,127.0.0.1"
end
# 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
if Vagrant.has_plugin?("vagrant-vbguest")
config.vbguest.auto_update = false
end
end

View file

@ -0,0 +1 @@
{install_date: 'Sun Apr 23 07:59:24 2017', version: 4.0.0}

View file

@ -0,0 +1,26 @@
---
galaxy_info:
author: "Sebastian Gumprich"
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'
platforms:
- name: EL
versions:
- 6
- 7
- name: Ubuntu
versions:
- precise
- trusty
- xenial
- name: Debian
versions:
- wheezy
- jessie
galaxy_tags:
- system
- security
- hardening
dependencies: []

View file

@ -0,0 +1,105 @@
---
- 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

View file

@ -0,0 +1,148 @@
# {{ansible_managed}}
# This is the ssh client system-wide configuration file.
# See ssh_config(5) for more information on any settings used. Comments will be added only to clarify why a configuration was chosen.
#
# Basic configuration
# ===================
# Address family should always be limited to the active network configuration.
AddressFamily {{ 'any' if network_ipv6_enable else 'inet' }}
{% for host in ssh_remote_hosts -%}
{% if loop.first %}
# Host-specific configuration
{% endif %}
Host {{ host.names | join(' ') }}
{{ host.options | join("\n") | indent(2) }}
{% endfor -%}
# Global defaults for all Hosts
Host *
# The port at the destination should be defined
Port {{ ssh_client_port }}
# Identity file configuration. You may restrict available identity files. Otherwise ssh will search for a pattern and use any that matches.
#IdentityFile ~/.ssh/identity
#IdentityFile ~/.ssh/id_rsa
#IdentityFile ~/.ssh/id_dsa
# Security configuration
# ======================
# Set the protocol version to 2 for security reasons. Disables legacy support.
Protocol 2
# Make sure passphrase querying is enabled
BatchMode no
# Prevent IP spoofing by checking to host IP against the `known_hosts` file.
CheckHostIP yes
# Always ask before adding keys to the `known_hosts` file. Do not set to `yes`.
StrictHostKeyChecking ask
# **Ciphers** -- If your clients don't support CTR (eg older versions), cbc will be added
# CBC: is true if you want to connect with OpenSSL-base libraries
# eg ruby Net::SSH::Transport::CipherFactory requires cbc-versions of the given openssh ciphers to work
# -- see: (http://net-ssh.github.com/net-ssh/classes/Net/SSH/Transport/CipherFactory.html)
#
{% if ssh_client_cbc_required -%}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') 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 %}
# **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 %}
# Alternative setting, if OpenSSH version is below v5.9
#MACs hmac-ripemd160
# **Key Exchange Algorithms** -- Make sure not to use SHA1 for kex, unless it is really necessary
# Weak kex is sometimes required if older package versions are used
# eg ruby's Net::SSH at around 2.2.* doesn't support sha2 for kex, so this will have to be set true in this case.
#
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') or (ansible_distribution == 'Debian' and ansible_distribution_version >= '8') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version >= '7') or (ansible_distribution == 'FreeBSD' and ansible_distribution_version >= '11') -%}
{% if ssh_client_weak_kex -%}
KexAlgorithms {{ ssh_kex_66_weak | join(',') }}
{% else -%}
KexAlgorithms {{ ssh_kex_66_default | join(',') }}
{% endif %}
{% else -%}
{% if ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version <= '6' -%}
#KexAlgorithms
{% elif ssh_client_weak_kex -%}
KexAlgorithms {{ ssh_kex_59_weak | join(',') }}
{% else -%}
KexAlgorithms {{ ssh_kex_59_default | join(',') }}
{% endif %}
{% endif %}
# Disable agent forwarding, since local agent could be accessed through forwarded connection.
ForwardAgent no
# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
ForwardX11 no
# Never use host-based authentication. It can be exploited.
HostbasedAuthentication no
RhostsRSAAuthentication no
# Enable RSA authentication via identity files.
RSAAuthentication yes
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
PasswordAuthentication {{ 'yes' if ssh_client_password_login else 'no' }}
# Only use GSSAPIAuthentication if implemented on the network.
GSSAPIAuthentication no
GSSAPIDelegateCredentials no
# Disable tunneling
Tunnel no
# Disable local command execution.
PermitLocalCommand no
# Misc. configuration
# ===================
# Enable compression. More pressure on the CPU, less on the network.
Compression yes
#EscapeChar ~
#VisualHostKey yes
# 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' }}

View file

@ -0,0 +1,224 @@
# {{ansible_managed}}
# This is the ssh client system-wide configuration file.
# See sshd_config(5) for more information on any settings used. Comments will be added only to clarify why a configuration was chosen.
# Basic configuration
# ===================
# Either disable or only allowssh root login via certificates.
PermitRootLogin {{ 'without-password' if ssh_allow_root_with_key else 'no' }}
# Define which port sshd should listen to. Default to `22`.
{% for port in ssh_server_ports -%}
Port {{port}}
{% endfor %}
# Address family should always be limited to the active network configuration.
AddressFamily {{ 'any' if network_ipv6_enable 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 -%}
ListenAddress {{address}}
{% endfor %}
# List HostKeys here.
{% for key in ssh_host_key_files -%}
HostKey {{key}} # Req 20
{% endfor %}
# Security configuration
# ======================
# Set the protocol version to 2 for security reasons. Disables legacy support.
Protocol 2
# Make sure sshd checks file modes and ownership before accepting logins. This prevents accidental misconfiguration.
StrictModes yes
# Logging, obsoletes QuietMode and FascistLogging
SyslogFacility AUTH
LogLevel VERBOSE
# Cryptography
# ------------
# **Ciphers** -- If your clients don't support CTR (eg older versions), cbc will be added
# CBC: is true if you want to connect with OpenSSL-base libraries
# eg ruby Net::SSH::Transport::CipherFactory requires cbc-versions of the given openssh ciphers to work
# -- see: (http://net-ssh.github.com/net-ssh/classes/Net/SSH/Transport/CipherFactory.html)
#
{% if ssh_server_cbc_required -%}
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') 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 %}
# **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 %}
# Alternative setting, if OpenSSH version is below v5.9
#MACs hmac-ripemd160
# **Key Exchange Algorithms** -- Make sure not to use SHA1 for kex, unless it is really necessary
# Weak kex is sometimes required if older package versions are used
# eg ruby's Net::SSH at around 2.2.* doesn't support sha2 for kex, so this will have to be set true in this case.
# based on: https://bettercrypto.org/static/applied-crypto-hardening.pdf
{% if (ansible_distribution == 'Ubuntu' and ansible_distribution_version >= '14.04') 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 %}
# Authentication
# --------------
# Secure Login directives.
UseLogin no
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 %}
PermitUserEnvironment no
LoginGraceTime 30s
MaxAuthTries {{ssh_max_auth_retries}}
MaxSessions 10
MaxStartups 10:30:100
# Enable public key authentication
PubkeyAuthentication yes
# Never use host-based authentication. It can be exploited.
IgnoreRhosts yes
IgnoreUserKnownHosts yes
HostbasedAuthentication no
# Enable PAM to enforce system wide rules
UsePAM {{ 'yes' if ssh_use_pam else 'no' }}
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication {{ 'yes' if ssh_challengeresponseauthentication else 'no' }}
# Only enable Kerberos authentication if it is configured.
KerberosAuthentication no
KerberosOrLocalPasswd no
KerberosTicketCleanup yes
#KerberosGetAFSToken no
# Only enable GSSAPI authentication if it is configured.
GSSAPIAuthentication no
GSSAPICleanupCredentials yes
# In case you don't use PAM (`UsePAM no`), you can alternatively restrict users and groups here. For key-based authentication this is not necessary, since all keys must be explicitely enabled.
{% if ssh_deny_users -%}
DenyUsers {{ssh_deny_users}}
{% endif %}
{% if ssh_allow_users -%}
AllowUsers {{ssh_allow_users}}
{% endif %}
{% if ssh_deny_groups -%}
DenyGroups {{ssh_deny_groups}}
{% endif %}
{% if ssh_allow_groups -%}
AllowGroups {{ssh_allow_groups}}
{% endif %}
# Network
# -------
# Disable TCP keep alive since it is spoofable. Use ClientAlive messages instead, they use the encrypted channel
TCPKeepAlive no
# Manage `ClientAlive..` signals via interval and maximum count. This will periodically check up to a `..CountMax` number of times within `..Interval` timeframe, and abort the connection once these fail.
ClientAliveInterval {{ssh_client_alive_interval}}
ClientAliveCountMax {{ssh_client_alive_count}}
# Disable tunneling
PermitTunnel no
# Disable forwarding tcp connections.
# no real advantage without denied shell access
AllowTcpForwarding {{ 'yes' if ssh_allow_tcp_forwarding 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' }}
# Do not allow remote port forwardings to bind to non-loopback addresses.
GatewayPorts no
# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
X11Forwarding no
X11UseLocalhost yes
# Misc. configuration
# ===================
PrintMotd {{ 'yes' if ssh_print_motd else 'no' }}
{% if ansible_os_family != 'FreeBSD' %}
PrintLastLog {{ 'yes' if ssh_print_last_log else 'no' }}
{% endif %}
Banner {{ '/etc/ssh/banner.txt' if ssh_banner else 'none' }}
{% if ansible_os_family == 'Debian' %}
DebianBanner {{ 'yes' if ssh_print_debian_banner else 'no' }}
{% endif %}
{% if sftp_enabled %}
# Configuration, in case SFTP is used
## 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
Match Group sftponly
ForceCommand internal-sftp -l INFO -f LOCAL6
ChrootDirectory {{ sftp_chroot_dir }}
AllowTcpForwarding no
AllowAgentForwarding no
PasswordAuthentication no
PermitRootLogin no
X11Forwarding no
{% endif %}

View file

@ -0,0 +1,3 @@
sshd_service_name: ssh
ssh_owner: root
ssh_group: root

View file

@ -0,0 +1,3 @@
sshd_service_name: sshd
ssh_owner: root
ssh_group: wheel

View file

@ -0,0 +1,3 @@
sshd_service_name: sshd
ssh_owner: root
ssh_group: root

View file

@ -0,0 +1,3 @@
sshd_service_name: sshd
ssh_owner: root
ssh_group: root

View file

@ -0,0 +1,5 @@
*.retry
.vagrant
tests/_roles
!tests/_roles/.gitkeep
.DS_Store

Some files were not shown because too many files have changed in this diff Show more