Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e24797d2f | ||
|
|
8c89d78f44 | ||
|
|
d6a99c995e | ||
|
|
5ed100b7ea | ||
|
|
c6febf3249 | ||
|
|
7d68c6036c | ||
|
|
d4a4faa16d | ||
|
|
e1f0efb220 | ||
|
|
73cdd973d7 | ||
|
|
5e7a0a60f1 | ||
|
|
c3b954a2ab | ||
|
|
add303f2be | ||
|
|
03a0f26917 | ||
|
|
fdadb78080 | ||
|
|
2fb54bd224 | ||
|
|
29ee683069 | ||
|
|
d758fa5184 | ||
|
|
2882a15ee1 | ||
|
|
458dfa2b6a | ||
|
|
812c6c5974 | ||
|
|
ae68f73965 | ||
|
|
d1d12ca6d7 | ||
|
|
7af432e1cf | ||
|
|
2dac5e3289 | ||
|
|
c90bbd2c23 | ||
|
|
aec1f5dcb7 | ||
|
|
d1143a06b1 | ||
|
|
dfa89f7b47 | ||
|
|
0f424469be | ||
|
|
240d8acc0c | ||
|
|
5eae12005a | ||
|
|
84d7bb5f5f | ||
|
|
a45eee2204 | ||
|
|
d693a8e200 | ||
|
|
0ac56e4c00 | ||
|
|
05bc809ba3 | ||
|
|
5be13e878f | ||
|
|
659e5ada6a | ||
|
|
0010715039 | ||
|
|
a23eb05001 | ||
|
|
69193fe249 | ||
|
|
369c2986c6 | ||
|
|
02c689eaa0 | ||
|
|
bf82736787 | ||
|
|
c86bdcb4c7 | ||
|
|
b5ca78a9cd | ||
|
|
36bc71fe51 | ||
|
|
876cdab430 | ||
|
|
6c805f6ca9 | ||
|
|
8cb6732882 | ||
|
|
390f7ad6cc | ||
|
|
eca93cc80b | ||
|
|
9614273653 | ||
|
|
a64838272c | ||
|
|
2076990d5d | ||
|
|
3da5b759a2 | ||
|
|
8706246309 | ||
|
|
cd4925d411 | ||
|
|
d1b8e7d7a3 | ||
|
|
19d5a17a99 | ||
|
|
5cc8b2f42a | ||
|
|
976f83e88b | ||
|
|
6c870aae27 | ||
|
|
74c729404b | ||
|
|
b2dd73d27e | ||
|
|
ec9d7d2cb8 | ||
|
|
97c55d6e55 | ||
|
|
5f97dffddf | ||
|
|
eeedaeaffb | ||
|
|
0b945536e2 | ||
|
|
103135ce9a | ||
|
|
4158e0bfb4 | ||
|
|
fed8bdabd7 | ||
|
|
f9bbdb20fe | ||
|
|
4bad4779cd | ||
|
|
75fc31b80c | ||
|
|
10841ced62 | ||
|
|
335df545fb | ||
|
|
6d2c92d4ab | ||
|
|
3334000b97 | ||
|
|
26d84b5f84 | ||
|
|
9b6f313065 | ||
|
|
23071a183c | ||
|
|
66009496e2 | ||
|
|
bbf992d9fc | ||
|
|
91a0d62305 | ||
|
|
60d24db460 | ||
|
|
90e0ce7c6b | ||
|
|
8e4c22d8d9 | ||
|
|
dba53718cf | ||
|
|
4a5fa70507 | ||
|
|
75683161a5 | ||
|
|
2a4b98ab4a | ||
|
|
5d55d29fe2 | ||
|
|
64713ce75d | ||
|
|
ec36bf5b9c | ||
|
|
08aad6e80f | ||
|
|
28c6bf5c66 | ||
|
|
26c73ed1c9 | ||
|
|
54c8e6aedb | ||
|
|
b9e33091e2 | ||
|
|
7f1765c608 | ||
|
|
30f0839513 | ||
|
|
532917d956 | ||
|
|
04654d0490 | ||
|
|
aa166f43fc | ||
|
|
19482c319c | ||
|
|
fc7fb4fc8a | ||
|
|
8baab7516e | ||
|
|
7282187a90 | ||
|
|
157f4fca70 | ||
|
|
70cd7bbf1e | ||
|
|
6be31fbc3b | ||
|
|
756839f8f0 | ||
|
|
c55c1f21ed | ||
|
|
8d3e452ce3 | ||
|
|
d8ea484f92 | ||
|
|
94b9bfc3cd | ||
|
|
3ad4fbab0e | ||
|
|
ebbf6855e8 | ||
|
|
b210df1233 | ||
|
|
a55a4d2024 |
No files matched your search
@@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pip" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
@@ -24,7 +24,6 @@ jobs:
|
||||
molecule_distro:
|
||||
- centos7
|
||||
- centos8
|
||||
- ubuntu1604
|
||||
- ubuntu1804
|
||||
- ubuntu2004
|
||||
- debian9
|
||||
|
||||
@@ -24,7 +24,6 @@ jobs:
|
||||
molecule_distro:
|
||||
- centos7
|
||||
- centos8
|
||||
- ubuntu1604
|
||||
- ubuntu1804
|
||||
- ubuntu2004
|
||||
- debian9
|
||||
|
||||
@@ -24,7 +24,6 @@ jobs:
|
||||
molecule_distro:
|
||||
- centos7
|
||||
- centos8
|
||||
- ubuntu1604
|
||||
- ubuntu1804
|
||||
- ubuntu2004
|
||||
- debian9
|
||||
|
||||
@@ -53,19 +53,11 @@ jobs:
|
||||
# changelog gets updated but action works on old commit id
|
||||
- uses: actions/[email protected]
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: master
|
||||
|
||||
- name: Generate changelog for the release
|
||||
uses: charmixer/auto-changelog-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
since_tag: ${{ steps.previoustag.outputs.tag }}
|
||||
future_release: ${{ steps.version.outputs.next-version }}
|
||||
output: CHANGELOGRELEASE.md
|
||||
# this excludes all versions prior to the collection-release
|
||||
# since they break the changelog generation with the error:
|
||||
# "No common ancestor between ... and $version"
|
||||
exclude_tags_regex: '[0-6]\.\d\.\d'
|
||||
run: |
|
||||
sed '/## \[${{ steps.previoustag.outputs.tag }}\]/Q' CHANGELOG.md > CHANGELOGRELEASE.md
|
||||
|
||||
- name: Read CHANGELOG.md
|
||||
id: package
|
||||
|
||||
@@ -25,7 +25,6 @@ jobs:
|
||||
- centos7
|
||||
- centos8
|
||||
- fedora
|
||||
- ubuntu1604
|
||||
- ubuntu1804
|
||||
- ubuntu2004
|
||||
- debian9
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
CHANGELOG.md
|
||||
@@ -1,5 +1,79 @@
|
||||
# Changelog
|
||||
|
||||
## [7.5.0](https://github.com/dev-sec/ansible-collection-hardening/tree/7.5.0) (2021-04-01)
|
||||
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-collection-hardening/compare/7.4.0...7.5.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Not accepting source routing for IPv6. This was already done for IPv4. [\#424](https://github.com/dev-sec/ansible-collection-hardening/pull/424) ([joubbi](https://github.com/joubbi))
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Harden user home directories [\#276](https://github.com/dev-sec/ansible-collection-hardening/issues/276)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- remove secure-auth param if mysql \>= 8.0.3 [\#438](https://github.com/dev-sec/ansible-collection-hardening/pull/438) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Improved comments. [\#436](https://github.com/dev-sec/ansible-collection-hardening/pull/436) ([joubbi](https://github.com/joubbi))
|
||||
- os\_auth\_pam\_pwquality\_options: Changed type to authtok\_type [\#432](https://github.com/dev-sec/ansible-collection-hardening/pull/432) ([joubbi](https://github.com/joubbi))
|
||||
- add restart-auditd handler after configuration change [\#427](https://github.com/dev-sec/ansible-collection-hardening/pull/427) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Uppercased first letter of task names. [\#422](https://github.com/dev-sec/ansible-collection-hardening/pull/422) ([joubbi](https://github.com/joubbi))
|
||||
|
||||
## [7.4.0](https://github.com/dev-sec/ansible-collection-hardening/tree/7.4.0) (2021-03-23)
|
||||
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-collection-hardening/compare/7.3.0...7.4.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Harden user home dirs [\#428](https://github.com/dev-sec/ansible-collection-hardening/pull/428) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Errors in packer build for vagrant builder [\#244](https://github.com/dev-sec/ansible-collection-hardening/issues/244)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Use pam\_pwhistory.so instead of pam\_unix.so for remembering old passwords [\#431](https://github.com/dev-sec/ansible-collection-hardening/pull/431) ([joubbi](https://github.com/joubbi))
|
||||
- Remove comments from PAM config file, but keep it in the template [\#430](https://github.com/dev-sec/ansible-collection-hardening/pull/430) ([joubbi](https://github.com/joubbi))
|
||||
- add support for using a proxy to test with molecule [\#429](https://github.com/dev-sec/ansible-collection-hardening/pull/429) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- Improve Documentation for sysctl defaults [\#418](https://github.com/dev-sec/ansible-collection-hardening/pull/418) ([joubbi](https://github.com/joubbi))
|
||||
|
||||
## [7.3.0](https://github.com/dev-sec/ansible-collection-hardening/tree/7.3.0) (2021-03-16)
|
||||
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-collection-hardening/compare/7.2.0...7.3.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- pam\_tally2 is deprecated in RHEL8 and pam\_faillock should be used in EL7 and EL8 instead. [\#377](https://github.com/dev-sec/ansible-collection-hardening/issues/377)
|
||||
- Replace pam\_tally2 with pam\_faillock in Redhat [\#273](https://github.com/dev-sec/ansible-collection-hardening/issues/273)
|
||||
- Extend GSSAPI configuration support to ssh\_config [\#403](https://github.com/dev-sec/ansible-collection-hardening/pull/403) ([wzzrd](https://github.com/wzzrd))
|
||||
- add restart handler variable for mysql role [\#399](https://github.com/dev-sec/ansible-collection-hardening/pull/399) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- restructure PAM handling and update for currently supported Linux distributions [\#392](https://github.com/dev-sec/ansible-collection-hardening/pull/392) ([schurzi](https://github.com/schurzi))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Not able to use `sudo` command for user authenticated via ActiveDirectory [\#278](https://github.com/dev-sec/ansible-collection-hardening/issues/278)
|
||||
- You shouldn't touch /etc/pam.d/system-auth-ac in RedHat/CentOS [\#252](https://github.com/dev-sec/ansible-collection-hardening/issues/252)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Netdata monitoring of docker in docker no longer possible [\#412](https://github.com/dev-sec/ansible-collection-hardening/issues/412)
|
||||
- Unable to connect with SSH \(Permission denied \(publickey\)\) [\#411](https://github.com/dev-sec/ansible-collection-hardening/issues/411)
|
||||
- TASK \[os\_hardening : configure auditd | package-08\] [\#410](https://github.com/dev-sec/ansible-collection-hardening/issues/410)
|
||||
- Collection throws undefined ansible\_role\_name error in auditd task [\#409](https://github.com/dev-sec/ansible-collection-hardening/issues/409)
|
||||
- Ensure permissions on /etc/crontab are configured [\#375](https://github.com/dev-sec/ansible-collection-hardening/issues/375)
|
||||
- Documentation should be updated [\#361](https://github.com/dev-sec/ansible-collection-hardening/issues/361)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Improve Release Action [\#421](https://github.com/dev-sec/ansible-collection-hardening/pull/421) ([schurzi](https://github.com/schurzi))
|
||||
- remove FQCN from roles in examples [\#420](https://github.com/dev-sec/ansible-collection-hardening/pull/420) ([schurzi](https://github.com/schurzi))
|
||||
- Ensure permissions on /etc/crontab are configured [\#405](https://github.com/dev-sec/ansible-collection-hardening/pull/405) ([joubbi](https://github.com/joubbi))
|
||||
- remove FQCN from roles in examples [\#404](https://github.com/dev-sec/ansible-collection-hardening/pull/404) ([schurzi](https://github.com/schurzi))
|
||||
- do not install mysql python package on target host [\#401](https://github.com/dev-sec/ansible-collection-hardening/pull/401) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
- make wrong password fail task [\#400](https://github.com/dev-sec/ansible-collection-hardening/pull/400) ([rndmh3ro](https://github.com/rndmh3ro))
|
||||
|
||||
## [7.2.0](https://github.com/dev-sec/ansible-collection-hardening/tree/7.2.0) (2021-02-10)
|
||||
|
||||
[Full Changelog](https://github.com/dev-sec/ansible-collection-hardening/compare/7.1.1...7.2.0)
|
||||
@@ -16,12 +90,14 @@
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Updating version in galaxy.yml should be part of the release process [\#396](https://github.com/dev-sec/ansible-collection-hardening/issues/396)
|
||||
- ssh\_hardening fail on keypair generation [\#388](https://github.com/dev-sec/ansible-collection-hardening/issues/388)
|
||||
- The system must display the date and time of the last successful account logon upon an SSH logon. [\#362](https://github.com/dev-sec/ansible-collection-hardening/issues/362)
|
||||
- Error in "root password is present" step [\#326](https://github.com/dev-sec/ansible-collection-hardening/issues/326)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- update ansible-lint to version 5 [\#397](https://github.com/dev-sec/ansible-collection-hardening/pull/397) ([schurzi](https://github.com/schurzi))
|
||||
- fix minimum required ansible version in docs [\#390](https://github.com/dev-sec/ansible-collection-hardening/pull/390) ([schurzi](https://github.com/schurzi))
|
||||
|
||||
## [7.1.1](https://github.com/dev-sec/ansible-collection-hardening/tree/7.1.1) (2021-02-05)
|
||||
|
||||
@@ -50,6 +50,12 @@ In progress, not working:
|
||||
- [apache_hardening](roles/apache_hardening/)
|
||||
- [windows_hardening](roles/windows_hardening/)
|
||||
|
||||
## Installation
|
||||
|
||||
Install the collection via ansible-galaxy:
|
||||
|
||||
`ansible-galaxy collection install devsec.hardening`
|
||||
|
||||
## Using this collection
|
||||
|
||||
Please refer to the examples in the readmes of the role.
|
||||
|
||||
+7
-43
@@ -1,36 +1,13 @@
|
||||
# The namespace of the collection. This can be a company/brand/organization or product namespace under which all
|
||||
# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with
|
||||
# underscores or numbers and cannot contain consecutive underscores
|
||||
namespace: devsec
|
||||
|
||||
# The name of the collection. Has the same character restrictions as 'namespace'
|
||||
name: hardening
|
||||
|
||||
# The version of the collection. Must be compatible with semantic versioning
|
||||
version: 7.1.1
|
||||
|
||||
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
|
||||
version: 7.4.0
|
||||
readme: README.md
|
||||
|
||||
# A list of the collection's content authors. Can be just the name or in the format 'Full Name <email> (url)
|
||||
# @nicks:irc/im.site#channel'
|
||||
authors:
|
||||
- dev-sec <[email protected]>
|
||||
|
||||
# A short summary description of the collection
|
||||
description: This collection provides battle tested hardening for Linux, SSH, nginx, MySQL
|
||||
|
||||
# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only
|
||||
# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file'
|
||||
- dev-sec <[email protected]>
|
||||
description: 'This collection provides battle tested hardening for Linux, SSH, nginx, MySQL'
|
||||
license:
|
||||
- GPL-2.0-or-later
|
||||
|
||||
# The path to the license file for the collection. This path is relative to the root of the collection. This key is
|
||||
# mutually exclusive with 'license'
|
||||
- GPL-2.0-or-later
|
||||
license_file: ''
|
||||
|
||||
# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character
|
||||
# requirements as 'namespace' and 'name'
|
||||
tags:
|
||||
- devsec
|
||||
- hardening
|
||||
@@ -40,24 +17,11 @@ tags:
|
||||
- nginx
|
||||
- mysql
|
||||
- openssh
|
||||
|
||||
# Collections that this collection requires to be installed for it to be usable. The key of the dict is the
|
||||
# collection label 'namespace.name'. The value is a version range
|
||||
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
|
||||
# range specifiers can be set and are separated by ','
|
||||
dependencies:
|
||||
community.crypto: '>=1.0.0'
|
||||
|
||||
# The URL of the originating SCM repository
|
||||
repository: https://github.com/dev-sec/ansible-os-hardening
|
||||
|
||||
# The URL to the homepage of the collection/project
|
||||
homepage: https://dev-sec.io/
|
||||
|
||||
# The URL to the collection issue tracker
|
||||
issues: https://github.com/dev-sec/ansible-os-hardening/issues
|
||||
|
||||
# ignore files not needed for release
|
||||
repository: 'https://github.com/dev-sec/ansible-os-hardening'
|
||||
homepage: 'https://dev-sec.io/'
|
||||
issues: 'https://github.com/dev-sec/ansible-os-hardening/issues'
|
||||
build_ignore:
|
||||
- codecov.yml
|
||||
- .github
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: wrapper playbook for kitchen testing "ansible-mysql-hardening"
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
tasks:
|
||||
- name: Determine required MySQL Python libraries (Ubuntu Focal Fossa ++)
|
||||
set_fact:
|
||||
@@ -18,9 +22,6 @@
|
||||
- mysql_python_package_debian is not defined
|
||||
- ansible_distribution != "Ubuntu"
|
||||
- ansible_distribution_major_version|int < 20
|
||||
- include_role:
|
||||
name: dev-sec.mysql
|
||||
|
||||
- include_role:
|
||||
name: mysql_hardening
|
||||
vars:
|
||||
|
||||
@@ -3,6 +3,7 @@ dependency:
|
||||
name: galaxy
|
||||
options:
|
||||
role-file: molecule/mysql_hardening/requirements.yml
|
||||
requirements-file: molecule/mysql_hardening/requirements.yml
|
||||
driver:
|
||||
name: docker
|
||||
lint: |
|
||||
@@ -20,6 +21,11 @@ platforms:
|
||||
container: docker
|
||||
security_opts:
|
||||
- apparmor=unconfined
|
||||
env:
|
||||
http_proxy: "${http_proxy}"
|
||||
https_proxy: "${https_proxy}"
|
||||
no_proxy: "${no_proxy}"
|
||||
container: docker
|
||||
provisioner:
|
||||
name: ansible
|
||||
config_options:
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
- name: wrapper playbook for kitchen testing "ansible-mysql-hardening"
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
tasks:
|
||||
- name: Run the equivalent of "apt-get update && apt-get upgrade"
|
||||
apt:
|
||||
@@ -21,3 +25,34 @@
|
||||
file:
|
||||
path: "/etc/mysql/conf.d"
|
||||
state: directory
|
||||
|
||||
- name: Determine required MySQL Python libraries (Ubuntu Focal Fossa ++)
|
||||
set_fact:
|
||||
mysql_python_package_debian: "python3-pymysql"
|
||||
when:
|
||||
- mysql_python_package_debian is not defined
|
||||
- ansible_distribution == "Ubuntu"
|
||||
- ansible_distribution_major_version|int > 19
|
||||
|
||||
- name: Determine required MySQL Python libraries.
|
||||
set_fact:
|
||||
mysql_python_package_debian: "{% if 'python3' in ansible_python_interpreter|default('') %}python3-mysqldb{% else %}python-mysqldb{% endif %}"
|
||||
when:
|
||||
- mysql_python_package_debian is not defined
|
||||
- ansible_distribution != "Ubuntu"
|
||||
- ansible_distribution_major_version|int < 20
|
||||
|
||||
- include_role:
|
||||
name: dev-sec.mysql
|
||||
|
||||
- name: create a user with an empty password
|
||||
community.mysql.mysql_query:
|
||||
query:
|
||||
- "CREATE USER foo@bar;"
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
vars:
|
||||
overwrite_global_mycnf: false
|
||||
mysql_root_password: iloverandompasswordsbutthiswilldo
|
||||
mysql_user_password: iloverandompasswordsbutthiswilldo
|
||||
mysql_config_file: /etc/mysql/mariadb.cnf
|
||||
mysql_root_password_update: true
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: Verify
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
roles:
|
||||
- geerlingguy.git
|
||||
tasks:
|
||||
@@ -40,7 +44,7 @@
|
||||
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
|
||||
|
||||
- name: Execute cinc-auditor tests
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/mysql-baseline.git"
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit supermarket://dev-sec/mysql-baseline"
|
||||
register: test_results
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings
|
||||
become: true
|
||||
hosts: all
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
vars:
|
||||
- nginx_ppa_use: true
|
||||
- nginx_ppa_version: stable
|
||||
|
||||
@@ -21,7 +21,10 @@ platforms:
|
||||
capabilities:
|
||||
- SYS_ADMIN
|
||||
tty: true
|
||||
environment:
|
||||
env:
|
||||
http_proxy: "${http_proxy}"
|
||||
https_proxy: "${https_proxy}"
|
||||
no_proxy: "${no_proxy}"
|
||||
container: docker
|
||||
provisioner:
|
||||
name: ansible
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: prepare playbook for kitchen testing "ansible-nginx-hardening" with custom settings
|
||||
become: true
|
||||
hosts: all
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
tasks:
|
||||
- name: install required tools on SuSE
|
||||
zypper:
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: Verify
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
roles:
|
||||
- geerlingguy.git
|
||||
tasks:
|
||||
@@ -43,7 +47,7 @@
|
||||
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
|
||||
|
||||
- name: Execute cinc-auditor tests
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/nginx-baseline.git"
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit supermarket://dev-sec/nginx-baseline"
|
||||
register: test_results
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: wrapper playbook for kitchen testing "ansible-os-hardening" with custom vars for testing
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
collections:
|
||||
- devsec.hardening
|
||||
tasks:
|
||||
@@ -15,6 +19,7 @@
|
||||
os_security_kernel_enable_core_dump: true
|
||||
os_security_suid_sgid_remove_from_unknown: true
|
||||
os_auth_pam_passwdqc_enable: false
|
||||
os_auth_lockout_time: 15
|
||||
os_desktop_enable: true
|
||||
os_env_extra_user_paths: ['/home']
|
||||
os_auth_allow_homeless: true
|
||||
|
||||
@@ -21,7 +21,10 @@ platforms:
|
||||
capabilities:
|
||||
- SYS_ADMIN
|
||||
tty: true
|
||||
environment:
|
||||
env:
|
||||
http_proxy: "${http_proxy}"
|
||||
https_proxy: "${https_proxy}"
|
||||
no_proxy: "${no_proxy}"
|
||||
container: docker
|
||||
provisioner:
|
||||
name: ansible
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
become: true
|
||||
collections:
|
||||
- devsec.hardening
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
tasks:
|
||||
- name: set ansible_python_interpreter to "/usr/bin/python3" on fedora
|
||||
set_fact:
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: Verify
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
roles:
|
||||
- geerlingguy.git
|
||||
tasks:
|
||||
@@ -33,6 +37,10 @@
|
||||
name: procps
|
||||
when: ansible_facts.os_family == 'Debian'
|
||||
|
||||
- name: include PAM tests
|
||||
include: verify_pam.yml
|
||||
when: ansible_facts.distribution in ['Debian', 'Ubuntu'] or ansible_facts.os_family == 'RedHat'
|
||||
|
||||
- name: download cinc-auditor
|
||||
get_url:
|
||||
url: https://omnitruck.cinc.sh/install.sh
|
||||
@@ -43,7 +51,7 @@
|
||||
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
|
||||
|
||||
- name: Execute cinc-auditor tests
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/linux-baseline.git"
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit supermarket://dev-sec/linux-baseline"
|
||||
register: test_results
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
- name: download pam-tester
|
||||
get_url:
|
||||
url: https://github.com/schurzi/pam-tester/releases/download/latest/pam-tester
|
||||
dest: /bin/pam-tester
|
||||
mode: 0555
|
||||
|
||||
- name: set password for test
|
||||
set_fact:
|
||||
test_pw: "myTest!pw"
|
||||
|
||||
- name: set locale for test
|
||||
set_fact:
|
||||
locale: "en_US.UTF-8"
|
||||
when:
|
||||
- ansible_facts.os_family == 'RedHat'
|
||||
- ansible_facts.distribution_major_version < '8'
|
||||
|
||||
- name: create testuser
|
||||
user:
|
||||
name: testuser
|
||||
password: "{{ test_pw | password_hash('sha512') }}"
|
||||
|
||||
- name: check successfull login with correct password
|
||||
shell:
|
||||
cmd: "pam-tester --user testuser --password {{ test_pw }}"
|
||||
environment:
|
||||
TMPDIR: /var/tmp
|
||||
LC_ALL: "{{ locale | default('C.UTF-8') }}"
|
||||
LANG: "{{ locale | default('C.UTF-8') }}"
|
||||
|
||||
- name: check unsuccessfull login with incorrect password
|
||||
shell:
|
||||
cmd: "pam-tester --user testuser --password {{ test_pw }}fail --expectfail"
|
||||
environment:
|
||||
TMPDIR: /var/tmp
|
||||
LC_ALL: "{{ locale | default('C.UTF-8') }}"
|
||||
LANG: "{{ locale | default('C.UTF-8') }}"
|
||||
with_sequence: count=6
|
||||
|
||||
- name: check unsuccessfull login, with correct password (lockout)
|
||||
shell:
|
||||
cmd: "pam-tester --user testuser --password {{ test_pw }} --expectfail"
|
||||
environment:
|
||||
TMPDIR: /var/tmp
|
||||
LC_ALL: "{{ locale | default('C.UTF-8') }}"
|
||||
LANG: "{{ locale | default('C.UTF-8') }}"
|
||||
|
||||
- name: wait for account to unlock
|
||||
pause:
|
||||
seconds: 20
|
||||
|
||||
- name: check successfull login
|
||||
shell:
|
||||
cmd: "pam-tester --user testuser --password {{ test_pw }}"
|
||||
environment:
|
||||
TMPDIR: /var/tmp
|
||||
LC_ALL: "{{ locale | default('C.UTF-8') }}"
|
||||
LANG: "{{ locale | default('C.UTF-8') }}"
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
collections:
|
||||
- devsec.hardening
|
||||
tasks:
|
||||
|
||||
@@ -21,7 +21,10 @@ platforms:
|
||||
capabilities:
|
||||
- SYS_ADMIN
|
||||
tty: true
|
||||
environment:
|
||||
env:
|
||||
http_proxy: "${http_proxy}"
|
||||
https_proxy: "${https_proxy}"
|
||||
no_proxy: "${no_proxy}"
|
||||
container: docker
|
||||
provisioner:
|
||||
name: ansible
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
tasks:
|
||||
- name: use python3
|
||||
set_fact:
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
- name: Verify
|
||||
hosts: all
|
||||
become: true
|
||||
environment:
|
||||
http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}"
|
||||
https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}"
|
||||
no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}"
|
||||
roles:
|
||||
- geerlingguy.git
|
||||
tasks:
|
||||
@@ -38,7 +42,7 @@
|
||||
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
|
||||
|
||||
- name: Execute cinc-auditor tests
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/ssh-baseline.git"
|
||||
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit supermarket://dev-sec/nginx-baseline"
|
||||
register: test_results
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
@@ -4,3 +4,4 @@ ansible
|
||||
ansible-lint
|
||||
docker
|
||||
flake8
|
||||
jmespath
|
||||
@@ -9,7 +9,7 @@ This role provides security configurations for MySQL and its derivates. It is in
|
||||
It configures:
|
||||
|
||||
- Permissions for the various configuration files and folders
|
||||
- Removes anonymous users, root-users without a password and test databases
|
||||
- Removes anonymous users, users without a password or authentication_string and test databases
|
||||
- various hardening options inside MySQL
|
||||
|
||||
## Requirements
|
||||
@@ -24,7 +24,7 @@ It configures:
|
||||
collections:
|
||||
- devsec.hardening
|
||||
roles:
|
||||
- devsec.hardening.mysql_hardening
|
||||
- mysql_hardening
|
||||
```
|
||||
|
||||
This role expects an existing installation of MySQL or MariaDB. Please ensure that the following variables are set accordingly:
|
||||
@@ -75,5 +75,8 @@ This role expects an existing installation of MySQL or MariaDB. Please ensure th
|
||||
- `mysql_remove_test_database`
|
||||
- Default: true
|
||||
- Description: remove test database
|
||||
- `mysql_hardening_restart_mysql`
|
||||
- Default: true
|
||||
- Description: Restart mysql after running this role
|
||||
|
||||
Further information is available at [Deutsche Telekom (German)](http://www.telekom.com/static/-/155996/7/technische-sicherheitsanforderungen-si) and [Symantec](http://www.symantec.com/connect/articles/securing-mysql-step-step)
|
||||
@@ -4,6 +4,8 @@ mysql_hardening_enabled: true
|
||||
|
||||
mysql_daemon_enabled: true
|
||||
|
||||
mysql_hardening_restart_mysql: true
|
||||
|
||||
# general configuration
|
||||
mysql_datadir: '/var/lib/mysql'
|
||||
mysql_hardening_mysql_hardening_conf_file: '{{mysql_hardening_mysql_confd_dir}}/hardening.cnf'
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
---
|
||||
|
||||
- name: restart mysql
|
||||
service: name='{{ mysql_daemon }}' state=restarted
|
||||
- name: Restart mysql
|
||||
service:
|
||||
name: '{{ mysql_daemon }}'
|
||||
state: restarted
|
||||
when: mysql_hardening_restart_mysql | bool
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: protect my.cnf
|
||||
- name: Protect my.cnf
|
||||
file:
|
||||
path: '{{ mysql_hardening_mysql_conf_file }}'
|
||||
mode: '0640'
|
||||
@@ -8,7 +8,7 @@
|
||||
follow: true
|
||||
state: file
|
||||
|
||||
- name: ensure permissions on mysql-datadir are correct
|
||||
- name: Ensure permissions on mysql-datadir are correct
|
||||
file:
|
||||
path: '{{ mysql_datadir }}'
|
||||
state: directory
|
||||
@@ -16,7 +16,7 @@
|
||||
group: '{{ mysql_hardening_user }}'
|
||||
mode: '0750'
|
||||
|
||||
- name: ensure permissions on mysql-logfile are correct
|
||||
- name: Ensure permissions on mysql-logfile are correct
|
||||
file:
|
||||
path: '{{ mysql_hardening_log_file }}'
|
||||
state: file
|
||||
@@ -24,7 +24,7 @@
|
||||
group: '{{ mysql_hardening_group }}'
|
||||
mode: '0640'
|
||||
|
||||
- name: check mysql configuration-directory exists and has right permissions
|
||||
- name: Check mysql configuration-directory exists and has right permissions
|
||||
file:
|
||||
path: '{{ mysql_hardening_mysql_confd_dir }}'
|
||||
state: directory
|
||||
@@ -32,25 +32,25 @@
|
||||
group: '{{ mysql_hardening_group }}'
|
||||
mode: '0750'
|
||||
|
||||
- name: check include-dir directive is present in my.cnf
|
||||
- name: Check include-dir directive is present in my.cnf
|
||||
lineinfile:
|
||||
dest: '{{ mysql_hardening_mysql_conf_file }}'
|
||||
line: '!includedir {{ mysql_hardening_mysql_confd_dir }}'
|
||||
insertafter: 'EOF'
|
||||
state: present
|
||||
backup: true
|
||||
notify: restart mysql
|
||||
notify: Restart mysql
|
||||
|
||||
- name: apply hardening configuration
|
||||
- name: Apply hardening configuration
|
||||
template:
|
||||
src: 'hardening.cnf.j2'
|
||||
dest: '{{ mysql_hardening_mysql_hardening_conf_file }}'
|
||||
owner: '{{ mysql_cnf_owner }}'
|
||||
group: '{{ mysql_cnf_group }}'
|
||||
mode: '0640'
|
||||
notify: restart mysql
|
||||
notify: Restart mysql
|
||||
|
||||
- name: enable mysql
|
||||
- name: Enable mysql
|
||||
service:
|
||||
name: '{{ mysql_daemon }}'
|
||||
enabled: '{{ mysql_daemon_enabled }}'
|
||||
@@ -21,6 +21,29 @@
|
||||
when: "not lookup('varnames', '^' + item.key + '$')"
|
||||
with_dict: '{{ os_vars }}'
|
||||
|
||||
- name: Gather package facts to check for mysql/mariadb version
|
||||
ansible.builtin.package_facts:
|
||||
manager: auto
|
||||
|
||||
- name: Check if MySQL or MariaDB is used
|
||||
set_fact:
|
||||
mysql_distribution: "{{ ansible_facts.packages['mysql-server'] is defined | ternary('mysql', 'mariadb') }}"
|
||||
|
||||
- name: Check which MySQL/MariaDB version is used
|
||||
community.mysql.mysql_info:
|
||||
filter: version
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
register: mysql_version
|
||||
|
||||
# see https://stackoverflow.com/a/59451077/2953919 for the
|
||||
# dict2items and vice versa magic
|
||||
- name: Drop the secure-auth parameter on MySQL >=8.0.3 (not mariadb)
|
||||
set_fact:
|
||||
mysql_hardening_options: "{{ mysql_hardening_options| dict2items | rejectattr('key', 'search', 'secure-auth') | list | items2dict }}"
|
||||
when:
|
||||
- mysql_version.version.full is version('8.0.3', '>=')
|
||||
- mysql_distribution == "mysql"
|
||||
|
||||
- include: configure.yml
|
||||
when: mysql_hardening_enabled | bool
|
||||
tags:
|
||||
|
||||
@@ -1,46 +1,102 @@
|
||||
---
|
||||
- name: Install mysqld python libary for Ansible
|
||||
package:
|
||||
name: '{{ mysql_python_package }}'
|
||||
state: present
|
||||
|
||||
- debug:
|
||||
msg: 'WARNING - you have to change default mysql_root_password'
|
||||
- name: Fail the role if the mysql root password was not set
|
||||
fail:
|
||||
msg: 'ERROR - you have to change default mysql_root_password'
|
||||
when: mysql_root_password == '-----====>SetR00tPa$$wordH3r3!!!<====-----'
|
||||
|
||||
- name: root password is present
|
||||
mysql_user:
|
||||
- name: ensure that the root password is present
|
||||
community.mysql.mysql_user:
|
||||
name: 'root'
|
||||
host_all: true
|
||||
password: '{{ mysql_root_password | mandatory }}'
|
||||
state: present
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
|
||||
- name: install .my.cnf with credentials
|
||||
- name: Install .my.cnf with credentials
|
||||
template:
|
||||
src: 'my.cnf.j2'
|
||||
dest: '{{ mysql_user_home }}/.my.cnf'
|
||||
mode: '0400'
|
||||
tags: my_cnf
|
||||
|
||||
- name: test database is absent
|
||||
mysql_db:
|
||||
- name: ensure that the test database is absent
|
||||
community.mysql.mysql_db:
|
||||
name: test
|
||||
state: absent
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
when: mysql_remove_test_database
|
||||
|
||||
- name: anonymous users are absent
|
||||
mysql_user:
|
||||
- name: ensure that anonymous users are absent
|
||||
community.mysql.mysql_user:
|
||||
name: ''
|
||||
state: absent
|
||||
host_all: true
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
when: mysql_remove_anonymous_users
|
||||
|
||||
- name: remove remote root
|
||||
- name: ensure that root can only login from localhost
|
||||
community.mysql.mysql_query:
|
||||
query:
|
||||
- DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')
|
||||
- DELETE
|
||||
FROM mysql.user
|
||||
WHERE USER='root'
|
||||
AND HOST NOT IN ('localhost',
|
||||
'127.0.0.1',
|
||||
'::1')
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
when: mysql_remove_remote_root
|
||||
|
||||
- name: get all users that have no password or authentication_string on MySQL version >= 5.7.6
|
||||
community.mysql.mysql_query:
|
||||
query:
|
||||
- SELECT GROUP_CONCAT(USER, '@', HOST SEPARATOR ', ') AS users
|
||||
FROM mysql.user
|
||||
WHERE (length(authentication_string)=0
|
||||
OR authentication_string="")
|
||||
AND USER NOT IN ('mysql.sys',
|
||||
'mysqlxsys',
|
||||
'mariadb.sys');
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
register: mysql_users_wo_passwords_or_auth_string
|
||||
when:
|
||||
- mysql_version.version.full is version('5.7.6', '>=')
|
||||
|
||||
- name: get all users that have no password on MySQL version < 5.7.6
|
||||
community.mysql.mysql_query:
|
||||
query:
|
||||
- SELECT GROUP_CONCAT(USER, '@', HOST SEPARATOR ', ') AS users
|
||||
FROM mysql.user
|
||||
WHERE (length(password)=0
|
||||
OR password="")
|
||||
AND (length(authentication_string)=0
|
||||
OR authentication_string="")
|
||||
AND USER NOT IN ('mysql.sys',
|
||||
'mysqlxsys',
|
||||
'mariadb.sys');
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
register: mysql_users_wo_passwords
|
||||
when:
|
||||
- mysql_version.version.full is version('5.7.6', '<')
|
||||
|
||||
- name: create a fact for users without password or authentication_string
|
||||
set_fact:
|
||||
users_wo_auth: "{{ mysql_users_wo_passwords_or_auth_string.query_result.0.0 | community.general.json_query('users') }}"
|
||||
when:
|
||||
- mysql_users_wo_passwords_or_auth_string.query_result is defined
|
||||
- mysql_users_wo_passwords_or_auth_string.query_result != "" # noqa empty-string-compare
|
||||
|
||||
- name: create a fact for users without password
|
||||
set_fact:
|
||||
users_wo_auth: "{{ mysql_users_wo_passwords.query_result.0.0 | community.general.json_query('users') }}"
|
||||
when:
|
||||
- mysql_users_wo_passwords.query_result is defined
|
||||
- mysql_users_wo_passwords.query_result != "" # noqa empty-string-compare
|
||||
|
||||
- name: ensure that there are no users without password or authentication_string
|
||||
community.mysql.mysql_query:
|
||||
query:
|
||||
- "DROP USER {{ users_wo_auth }}"
|
||||
login_unix_socket: "{{ login_unix_socket | default(omit) }}"
|
||||
when:
|
||||
- users_wo_auth is defined
|
||||
- users_wo_auth != "" # noqa empty-string-compare
|
||||
@@ -10,5 +10,3 @@ mysql_hardening_group: 'adm'
|
||||
|
||||
mysql_cnf_owner: 'root' # owner of /etc/mysql/*.cnf files
|
||||
mysql_cnf_group: 'mysql' # owner of /etc/mysql/*.cnf files
|
||||
|
||||
mysql_python_package: "python3-pymysql"
|
||||
@@ -5,8 +5,6 @@ mysql_hardening_mysql_confd_dir: '/etc/my.cnf.d'
|
||||
|
||||
mysql_hardening_log_file: '/var/log/mariadb/mariadb.log'
|
||||
|
||||
mysql_python_package: 'MySQL-python'
|
||||
|
||||
mysql_cnf_owner: 'root' # owner of /etc/mysql/*.cnf files
|
||||
mysql_cnf_group: 'mysql' # owner of /etc/mysql/*.cnf files
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ mysql_hardening_mysql_conf_file: '/etc/my.cnf'
|
||||
mysql_hardening_mysql_confd_dir: '/etc/my.cnf.d'
|
||||
mysql_hardening_log_file: '/var/log/mariadb/mariadb.log'
|
||||
|
||||
mysql_python_package: 'python3-mysqlclient'
|
||||
|
||||
mysql_cnf_owner: 'root' # owner of /etc/mysql/*.cnf files
|
||||
mysql_cnf_group: 'mysql' # owner of /etc/mysql/*.cnf files
|
||||
|
||||
|
||||
@@ -10,5 +10,3 @@ mysql_cnf_owner: 'root' # owner of /etc/mysql/*.cnf files
|
||||
mysql_cnf_group: 'mysql' # owner of /etc/mysql/*.cnf files
|
||||
|
||||
mysql_hardening_group: 'adm'
|
||||
|
||||
mysql_python_package: "python-mysqldb"
|
||||
@@ -10,5 +10,3 @@ mysql_cnf_owner: 'root' # owner of /etc/mysql/*.cnf files
|
||||
mysql_cnf_group: 'mysql' # owner of /etc/mysql/*.cnf files
|
||||
|
||||
mysql_hardening_group: 'adm'
|
||||
|
||||
mysql_python_package: "python-mysqldb"
|
||||
@@ -10,5 +10,3 @@ mysql_cnf_owner: 'root' # owner of /etc/mysql/*.cnf files
|
||||
mysql_cnf_group: 'mysql' # owner of /etc/mysql/*.cnf files
|
||||
|
||||
mysql_hardening_group: 'adm'
|
||||
|
||||
mysql_python_package: "python3-mysqldb"
|
||||
@@ -83,7 +83,7 @@ It works with the following nginx-roles, including, but not limited to:
|
||||
collections:
|
||||
- devsec.hardening
|
||||
roles:
|
||||
- devsec.hardening.nginx_hardening
|
||||
- nginx_hardening
|
||||
```
|
||||
|
||||
[nginx_client_body_buffer_size]: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: restart nginx
|
||||
- name: Restart nginx
|
||||
service:
|
||||
name: "nginx"
|
||||
state: restarted
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
- name: create additional configuration
|
||||
- name: Create additional configuration
|
||||
template:
|
||||
src: "hardening.conf.j2"
|
||||
dest: "/etc/nginx/conf.d/90.hardening.conf"
|
||||
mode: '0600'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
|
||||
- name: change configuration in main nginx.conf
|
||||
- name: Change configuration in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*server_tokens'
|
||||
@@ -17,9 +17,9 @@
|
||||
mode: '0640'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
|
||||
- name: change ssl_protocols in main nginx.conf
|
||||
- name: Change ssl_protocols in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*ssl_protocols'
|
||||
@@ -28,9 +28,9 @@
|
||||
mode: '0640'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
|
||||
- name: change ssl_prefer_server_ciphers in main nginx.conf
|
||||
- name: Change ssl_prefer_server_ciphers in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*ssl_prefer_server_ciphers'
|
||||
@@ -39,9 +39,9 @@
|
||||
mode: '0640'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
|
||||
- name: change client_max_body_size in main nginx.conf
|
||||
- name: Change client_max_body_size in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*client_max_body_size'
|
||||
@@ -50,9 +50,9 @@
|
||||
mode: '0640'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
|
||||
- name: change client_body_buffer_size in main nginx.conf
|
||||
- name: Change client_body_buffer_size in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*client_body_buffer_size'
|
||||
@@ -61,9 +61,9 @@
|
||||
mode: '0640'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
|
||||
- name: change keepalive_timeout in main nginx.conf
|
||||
- name: Change keepalive_timeout in main nginx.conf
|
||||
lineinfile:
|
||||
dest: "/etc/nginx/nginx.conf"
|
||||
regexp: '^\s*keepalive_timeout'
|
||||
@@ -72,23 +72,23 @@
|
||||
mode: '0640'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
|
||||
- name: remove default.conf
|
||||
- name: Remove default.conf
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
when: nginx_remove_default_site
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
loop:
|
||||
- "/etc/nginx/conf.d/default.conf"
|
||||
- "/etc/nginx/sites-enabled/default"
|
||||
|
||||
- name: generate dh group
|
||||
- name: Generate dh group
|
||||
openssl_dhparam:
|
||||
path: "/etc/nginx/dh{{ nginx_dh_size }}.pem"
|
||||
size: "{{ nginx_dh_size }}"
|
||||
mode: '0640'
|
||||
owner: "root"
|
||||
group: "root"
|
||||
notify: restart nginx
|
||||
notify: Restart nginx
|
||||
@@ -124,6 +124,9 @@ We know that this is the case on Raspberry Pi.
|
||||
- `os_auth_pam_passwdqc_options`
|
||||
- Default: `min=disabled,disabled,16,12,8`
|
||||
- Description: set to any option line (as a string) that you want to pass to passwdqc.
|
||||
- `os_auth_pam_sssd_enable`
|
||||
- Default: `false` (on RHEL8/CentOS8/Fedora `true`)
|
||||
- Description: activate PAM auth support for sssd
|
||||
- `os_security_users_allow`
|
||||
- Default: `[]`
|
||||
- Description: list of things, that a user is allowed to do. May contain `change_user`.
|
||||
@@ -184,6 +187,9 @@ We know that this is the case on Raspberry Pi.
|
||||
- `proc_mnt_options`
|
||||
- Default: `rw,nosuid,nodev,noexec,relatime,hidepid={{ hidepid_option }}`
|
||||
- Description: Mount proc with hardenized options, including `hidepid` with variable value.
|
||||
- `os_ignore_home_folder_users`
|
||||
- Default: `lost+found`
|
||||
- Description: specify user home folders in `/home` that shouldn't be chmodded to 700
|
||||
|
||||
## Packages
|
||||
|
||||
@@ -219,7 +225,7 @@ To prevent some of the filesystems from being disabled, add them to the `os_file
|
||||
collections:
|
||||
- devsec.hardening
|
||||
roles:
|
||||
- devsec.hardening.os_hardening
|
||||
- os_hardening
|
||||
```
|
||||
|
||||
## Changing sysctl variables
|
||||
@@ -232,7 +238,7 @@ So for example if you want to change the IPv4 traffic forwarding variable to `1`
|
||||
collections:
|
||||
- devsec.hardening
|
||||
roles:
|
||||
- devsec.hardening.os_hardening
|
||||
- os_hardening
|
||||
vars:
|
||||
sysctl_overwrite:
|
||||
# Enable IPv4 traffic forwarding.
|
||||
@@ -249,6 +255,13 @@ For more information, please see this [upstream documentation](https://www.kerne
|
||||
|
||||
## More information
|
||||
|
||||
We use specific PAM configuration for every linux distribution. This is a very diverse area, since every vendor seems to push their own system for managing PAM. We used following guides and sources for our configuration.
|
||||
|
||||
- on Debian/Ubuntu we use [pam-config-framework](https://wiki.ubuntu.com/PAMConfigFrameworkSpec)
|
||||
- RHEL8 and compatible use information from [authselect](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-user-authentication-using-authselect_configuring-authentication-and-authorization-in-rhel), but our setup disables the configuration from authselect
|
||||
- RHEL 6/7 and compatible use [authconfig](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/authconfig-install), but our setup disables the configuration from authconfig
|
||||
- for RHEL 6/7 we also use information from [Desktop Security](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/chap-hardening_your_system_with_tools_and_services#sec-Desktop_Security)
|
||||
|
||||
This role is mostly based on guides by:
|
||||
|
||||
- [Arch Linux wiki, Sysctl hardening](https://wiki.archlinux.org/index.php/Sysctl)
|
||||
|
||||
@@ -2,31 +2,37 @@
|
||||
os_desktop_enable: false
|
||||
os_env_extra_user_paths: []
|
||||
os_auth_pw_max_age: 60
|
||||
os_auth_pw_min_age: 7 # discourage password cycling
|
||||
os_auth_pw_min_age: 7 # Discourage password cycling
|
||||
os_auth_retries: 5
|
||||
os_auth_lockout_time: 600 # 10min
|
||||
os_auth_lockout_time: 600 # Seconds (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_pam_passwdqc_options: 'min=disabled,disabled,16,12,8' # Used in RHEL6
|
||||
os_auth_pam_pwquality_options: 'try_first_pass retry=3 authtok_type=' # Used in RHEL7 and RHEL8
|
||||
os_auth_root_ttys: [console, tty1, tty2, tty3, tty4, tty5, tty6]
|
||||
|
||||
os_chfn_restrict: ''
|
||||
# may contain: change_user
|
||||
|
||||
# Set to false to disable chmod /home folders to 700
|
||||
os_chmod_home_folders: true
|
||||
|
||||
# May contain: change_user
|
||||
os_security_users_allow: []
|
||||
# specify system accounts those login should not be disabled and password not changed
|
||||
# Specify user home folders in /home that shouldn't be chmodded to 700
|
||||
os_ignore_home_folder_users: ['lost+found']
|
||||
# Specify system accounts whose login should not be disabled and password not changed
|
||||
os_ignore_users: ['vagrant', 'kitchen']
|
||||
os_security_kernel_enable_module_loading: true
|
||||
os_security_kernel_enable_core_dump: false
|
||||
os_security_suid_sgid_enforce: true
|
||||
# user-defined blacklist and whitelist
|
||||
# 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
|
||||
# If this is true, remove any suid/sgid bits from files that are not in the whitelist
|
||||
os_security_suid_sgid_remove_from_unknown: false
|
||||
|
||||
# remove packages with known issues
|
||||
# Remove packages with known security issues
|
||||
os_security_packages_clean: true
|
||||
os_security_packages_list: ['xinetd', 'inetd', 'ypserv', 'telnet-server', 'rsh-server', 'prelink']
|
||||
|
||||
@@ -39,9 +45,9 @@ os_security_init_single: false
|
||||
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
|
||||
# By default in Ubuntu it is set to: /etc/ufw/sysctl.conf
|
||||
# CAUTION!
|
||||
# If you enable it - it overwrites /etc/sysctl.conf file, managed by hardening framework
|
||||
ufw_ipt_sysctl: ''
|
||||
|
||||
# Default ufw variables
|
||||
@@ -137,10 +143,17 @@ sysctl_config:
|
||||
# kernel.yama.ptrace_scope = 1
|
||||
kernel.yama.ptrace_scope: 1
|
||||
|
||||
# Disable IPv4 traffic forwarding. | sysctl-01
|
||||
# Disable traffic forwarding.
|
||||
# Setting the flag to 0 ensures that a system with multiple interfaces (for example, a hard
|
||||
# proxy), will never be able to forward packets, and therefore, never serve as a router.
|
||||
# | sysctl-01 | sysctl-19
|
||||
net.ipv4.ip_forward: 0
|
||||
net.ipv6.conf.all.forwarding: 0
|
||||
|
||||
# Enable RFC-recommended source validation feature. | sysctl-02
|
||||
# Enable RFC-recommended source validation feature.
|
||||
# If the return packet does not go out the same interface that the corresponding
|
||||
# source packet came from, the packet is dropped (and logged if log_martians is set).
|
||||
# | sysctl-02
|
||||
net.ipv4.conf.all.rp_filter: 1
|
||||
net.ipv4.conf.default.rp_filter: 1
|
||||
|
||||
@@ -148,7 +161,9 @@ sysctl_config:
|
||||
# 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. | sysctl-03
|
||||
# Some routers (and some attackers) will send responses that violate RFC-1122 and attempt
|
||||
# to fill up a log file system with many useless error messages.
|
||||
# | sysctl-03
|
||||
net.ipv4.icmp_ignore_bogus_error_responses: 1
|
||||
|
||||
# Limit the amount of traffic the system uses for ICMP. | sysctl-05
|
||||
@@ -158,7 +173,7 @@ sysctl_config:
|
||||
# source quench, ime exceed, param problem, timestamp reply, information reply | sysctl-06
|
||||
net.ipv4.icmp_ratemask: 88089
|
||||
|
||||
# Protect against wrapping sequence numbers at gigabit speeds | sysctl-07
|
||||
# Disable TCP timestamps in order to not reveal system uptime. | sysctl-07
|
||||
net.ipv4.tcp_timestamps: 0
|
||||
|
||||
# Define restriction level for announcing the local source IP | sysctl-08
|
||||
@@ -187,17 +202,33 @@ sysctl_config:
|
||||
# so disable it if not needed. | sysctl-13
|
||||
net.ipv4.conf.all.accept_source_route: 0
|
||||
net.ipv4.conf.default.accept_source_route: 0
|
||||
net.ipv6.conf.all.accept_source_route: 0
|
||||
net.ipv6.conf.default.accept_source_route: 0
|
||||
|
||||
# For non-routers: don't send redirects, these settings are 0 | sysctl-16
|
||||
# For non-routers: don't send redirects.
|
||||
# An attacker could use a compromised host to send invalid ICMP redirects to other
|
||||
# router devices in an attempt to corrupt routing and have users access a system
|
||||
# set up by the attacker as opposed to a valid system.
|
||||
# | sysctl-16
|
||||
net.ipv4.conf.all.send_redirects: 0
|
||||
net.ipv4.conf.default.send_redirects: 0
|
||||
|
||||
# log martian packets | sysctl-17
|
||||
# Log martian packets
|
||||
# This feature logs packets with un-routable source addresses to the kernel log.
|
||||
# Enabling this feature and logging these packets allows an administrator to investigate
|
||||
# the possibility that an attacker is sending spoofed packets to their system.
|
||||
# | sysctl-17
|
||||
net.ipv4.conf.all.log_martians: 1
|
||||
net.ipv4.conf.default.log_martians: 1
|
||||
|
||||
# Accepting redirects can lead to malicious networking behavior, so disable
|
||||
# it if not needed. | sysctl-13 | sysctl-14 | sysctl-15 | sysctl-20
|
||||
# it if not needed.
|
||||
# Attackers could use bogus ICMP redirect messages to maliciously alter the system
|
||||
# routing tables and get them to send packets to incorrect networks and allow
|
||||
# your system packets to be captured.
|
||||
# Setting net.ipv4.conf.all.secure_redirects to 0 protects the system from
|
||||
# routing table updates by possibly compromised known gateways.
|
||||
# | sysctl-13 | sysctl-14 | sysctl-15 | sysctl-20
|
||||
net.ipv4.conf.default.accept_redirects: 0
|
||||
net.ipv4.conf.all.accept_redirects: 0
|
||||
net.ipv4.conf.all.secure_redirects: 0
|
||||
@@ -208,10 +239,7 @@ sysctl_config:
|
||||
# Disable IPv6 | sysctl-18
|
||||
net.ipv6.conf.all.disable_ipv6: 1
|
||||
|
||||
# Disable IPv6 traffic forwarding. | sysctl-19
|
||||
net.ipv6.conf.all.forwarding: 0
|
||||
|
||||
# ignore RAs on Ipv6. | sysctl-25
|
||||
# Ignore RAs on Ipv6. | sysctl-25
|
||||
net.ipv6.conf.all.accept_ra: 0
|
||||
net.ipv6.conf.default.accept_ra: 0
|
||||
|
||||
@@ -256,7 +284,7 @@ sysctl_config:
|
||||
# at task 'create a combined sysctl-dict if overwrites are defined'
|
||||
sysctl_overwrite:
|
||||
|
||||
# disable unused filesystems
|
||||
# Disable unused filesystems
|
||||
os_unused_filesystems:
|
||||
- "cramfs"
|
||||
- "freevxfs"
|
||||
@@ -273,7 +301,7 @@ os_unused_filesystems:
|
||||
- "sctp" # CIS 3.5.2
|
||||
- "tipc" # CIS 3.5.4
|
||||
|
||||
# whitelist for used filesystems
|
||||
# Whitelist for used filesystems
|
||||
os_filesystem_whitelist: []
|
||||
|
||||
# Set to false to turn the role into a no-op. Useful when using
|
||||
@@ -285,9 +313,10 @@ os_auditd_enabled: true
|
||||
os_auditd_max_log_file: 6
|
||||
os_auditd_max_log_file_action: keep_logs
|
||||
|
||||
# Set the SELinux state, can be either disabled, permissive, or enforcing.
|
||||
# Set the SELinux state, which can be either disabled, permissive, or enforcing.
|
||||
os_selinux_state: enforcing
|
||||
# Set the SELinux polixy.
|
||||
os_selinux_policy: targeted
|
||||
|
||||
# Mount options for proc in /etc/fstab.
|
||||
proc_mnt_options: 'rw,nosuid,nodev,noexec,relatime,hidepid={{ hidepid_option }}'
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
- name: update-initramfs
|
||||
- name: Update-initramfs
|
||||
command: 'update-initramfs -u'
|
||||
|
||||
- name: restart-auditd
|
||||
command:
|
||||
cmd: 'service auditd restart' # rhel: see: https://access.redhat.com/solutions/2664811
|
||||
warn: false # sadly 'service' module fails in that case also by using 'use: service'
|
||||
when: molecule_yml is not defined # restarting auditd in a container does not work
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: remove deprecated or insecure packages | package-01 - package-09
|
||||
- name: Remove deprecated or insecure packages | package-01 - package-09
|
||||
apt:
|
||||
name: '{{ os_security_packages_list }}'
|
||||
state: 'absent'
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
---
|
||||
- name: install auditd package | package-08
|
||||
- name: Install auditd package | package-08
|
||||
package:
|
||||
name: '{{ auditd_package }}'
|
||||
state: 'present'
|
||||
tags: auditd
|
||||
|
||||
- name: configure auditd | package-08
|
||||
- name: Configure auditd | package-08
|
||||
template:
|
||||
src: 'etc/audit/auditd.conf.j2'
|
||||
dest: '/etc/audit/auditd.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0640'
|
||||
notify: 'restart-auditd'
|
||||
tags: auditd
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# Granting write access to this directory for non-privileged users could provide
|
||||
# them the means for gaining unauthorized elevated privileges.
|
||||
# Granting read access to this directory could give an unprivileged user insight
|
||||
# in how to gain elevated privileges or circumvent auditing controls.
|
||||
# CIS 5.1.2 - CIS 5.1.7
|
||||
#
|
||||
- name: Find cron files and directories
|
||||
find:
|
||||
paths:
|
||||
- /etc
|
||||
patterns:
|
||||
- cron.hourly
|
||||
- cron.daily
|
||||
- cron.weekly
|
||||
- cron.monthly
|
||||
- cron.d
|
||||
- crontab
|
||||
file_type: any
|
||||
register: cron_directories
|
||||
|
||||
- name: Ensure permissions on cron files and directories are configured
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: og-rwx
|
||||
with_items: "{{ cron_directories.files }}"
|
||||
@@ -25,6 +25,9 @@
|
||||
tags: auditd
|
||||
when: os_auditd_enabled | bool
|
||||
|
||||
- import_tasks: cron.yml
|
||||
tags: cron
|
||||
|
||||
- import_tasks: limits.yml
|
||||
tags: limits
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- block:
|
||||
- name: create limits.d-directory if it does not exist | sysctl-31a, sysctl-31b
|
||||
- name: Create limits.d-directory if it does not exist | sysctl-31a, sysctl-31b
|
||||
file:
|
||||
path: '/etc/security/limits.d'
|
||||
owner: 'root'
|
||||
@@ -8,7 +8,7 @@
|
||||
mode: '0755'
|
||||
state: 'directory'
|
||||
|
||||
- name: create additional limits config file -> 10.hardcore.conf | sysctl-31a, sysctl-31b
|
||||
- name: Create additional limits config file -> 10.hardcore.conf | sysctl-31a, sysctl-31b
|
||||
pam_limits:
|
||||
dest: '/etc/security/limits.d/10.hardcore.conf'
|
||||
domain: '*'
|
||||
@@ -17,7 +17,7 @@
|
||||
value: '0'
|
||||
comment: Prevent core dumps for all users. These are usually not needed and may contain sensitive information
|
||||
|
||||
- name: set 10.hardcore.conf perms to 0400 and root ownership
|
||||
- name: Set 10.hardcore.conf perms to 0400 and root ownership
|
||||
file:
|
||||
path: /etc/security/limits.d/10.hardcore.conf
|
||||
owner: 'root'
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
when: not os_security_kernel_enable_core_dump | bool
|
||||
|
||||
- name: remove 10.hardcore.conf config file
|
||||
- name: Remove 10.hardcore.conf config file
|
||||
file:
|
||||
path: /etc/security/limits.d/10.hardcore.conf
|
||||
state: absent
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: create login.defs | os-05, os-05b
|
||||
- name: Create login.defs | os-05, os-05b
|
||||
template:
|
||||
src: 'etc/login.defs.j2'
|
||||
dest: '/etc/login.defs'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# still getting found and the permissions minimized in the next task.
|
||||
# This is also the reason why there's ignore_errors: true on the task.
|
||||
# also see: https://github.com/dev-sec/ansible-os-hardening/issues/219
|
||||
- name: find files with write-permissions for group
|
||||
- name: Find files with write-permissions for group
|
||||
shell: "find -L {{ item }} -perm /go+w -type f" # noqa command-instead-of-shell
|
||||
with_flattened:
|
||||
- '/usr/local/sbin'
|
||||
@@ -18,7 +18,7 @@
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: minimize access on found files
|
||||
- name: Minimize access on found files
|
||||
file:
|
||||
path: '{{ item.1 }}'
|
||||
mode: 'go-w'
|
||||
@@ -27,21 +27,21 @@
|
||||
- "{{ minimize_access_directories.results }}"
|
||||
- stdout_lines
|
||||
|
||||
- name: change shadow ownership to root and mode to 0600 | os-02
|
||||
- name: Change shadow ownership to root and mode to 0600 | os-02
|
||||
file:
|
||||
dest: '/etc/shadow'
|
||||
owner: '{{ os_shadow_perms.owner }}'
|
||||
group: '{{ os_shadow_perms.group }}'
|
||||
mode: '{{ os_shadow_perms.mode }}'
|
||||
|
||||
- name: change passwd ownership to root and mode to 0644 | os-03
|
||||
- name: Change passwd ownership to root and mode to 0644 | os-03
|
||||
file:
|
||||
dest: '/etc/passwd'
|
||||
owner: '{{ os_passwd_perms.owner }}'
|
||||
group: '{{ os_passwd_perms.group }}'
|
||||
mode: '{{ os_passwd_perms.mode }}'
|
||||
|
||||
- name: change su-binary to only be accessible to user and group root
|
||||
- name: Change su-binary to only be accessible to user and group root
|
||||
file:
|
||||
dest: '/bin/su'
|
||||
owner: 'root'
|
||||
@@ -49,7 +49,7 @@
|
||||
mode: '0750'
|
||||
when: '"change_user" not in os_security_users_allow'
|
||||
|
||||
- name: set option hidepid for proc filesystem
|
||||
- name: Set option hidepid for proc filesystem
|
||||
mount:
|
||||
path: /proc
|
||||
src: proc
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
---
|
||||
- name: install modprobe to disable filesystems | os-10
|
||||
- name: Install modprobe to disable filesystems | os-10
|
||||
package:
|
||||
name: '{{ modprobe_package }}'
|
||||
state: 'present'
|
||||
|
||||
- name: check if efi is installed
|
||||
- name: Check if efi is installed
|
||||
stat:
|
||||
path: "/sys/firmware/efi"
|
||||
register: efi_installed
|
||||
|
||||
- name: remove vfat from fs-list if efi is used
|
||||
- name: Remove vfat from fs-list if efi is used
|
||||
set_fact:
|
||||
os_unused_filesystems: "{{ os_unused_filesystems | difference('vfat') }}"
|
||||
when:
|
||||
- efi_installed.stat.isdir is defined
|
||||
- efi_installed.stat.isdir
|
||||
|
||||
- name: remove used filesystems from fs-list
|
||||
- name: Remove used filesystems from fs-list
|
||||
set_fact:
|
||||
os_unused_filesystems: "{{ os_unused_filesystems | difference(ansible_mounts | map(attribute='fstype') | list) }}"
|
||||
# we cannot do this on el6 and below, because these systems don't support the map function
|
||||
when: not ((ansible_facts.os_family in ['Oracle Linux', 'RedHat']) and ansible_facts.distribution_major_version < '7')
|
||||
|
||||
- name: disable unused filesystems | os-10
|
||||
- name: Disable unused filesystems | os-10
|
||||
template:
|
||||
src: 'etc/modprobe.d/modprobe.j2'
|
||||
dest: '/etc/modprobe.d/dev-sec.conf'
|
||||
|
||||
@@ -1,125 +1,4 @@
|
||||
---
|
||||
- name: update pam on Debian systems
|
||||
command: 'pam-auth-update --package'
|
||||
when: ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
changed_when: false
|
||||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
# the reason for this is so a user cannot connect to a server,
|
||||
# that isn't connected to an LDAP server anymore.
|
||||
# normally caching credentials shouldn't be necessary for most machines.
|
||||
# removing it provides some more security while not removing usability.
|
||||
- name: remove pam ccreds to disable password caching
|
||||
package:
|
||||
name: '{{ os_packages_pam_ccreds }}'
|
||||
state: 'absent'
|
||||
when:
|
||||
- ansible_facts.os_family != 'Archlinux'
|
||||
|
||||
- name: remove pam_cracklib, because it does not play nice with passwdqc
|
||||
apt:
|
||||
name: '{{ os_packages_pam_cracklib }}'
|
||||
state: 'absent'
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
- os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: install the package for strong password checking
|
||||
apt:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'present'
|
||||
update_cache: 'yes'
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
- os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: configure passwdqc
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_passwdqd.j2'
|
||||
dest: '{{ passwdqc_path }}'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
- os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: remove passwdqc
|
||||
apt:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'absent'
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
- not os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: install tally2
|
||||
apt:
|
||||
name: 'libpam-modules'
|
||||
state: 'present'
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
- not os_auth_pam_passwdqc_enable
|
||||
- os_auth_retries > 0
|
||||
|
||||
- name: configure tally2
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_tally2.j2'
|
||||
dest: '{{ tally2_path }}'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
- not os_auth_pam_passwdqc_enable
|
||||
- os_auth_retries > 0
|
||||
|
||||
- name: delete tally2 when retries is 0
|
||||
file:
|
||||
path: '{{ tally2_path }}'
|
||||
state: 'absent'
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
- not os_auth_pam_passwdqc_enable
|
||||
- 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_facts.os_family == 'RedHat'
|
||||
- ansible_facts.distribution_major_version|int is version('7', '<')
|
||||
- ansible_facts.distribution != 'Amazon'
|
||||
- os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: install the package for strong password checking
|
||||
yum:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'present'
|
||||
when:
|
||||
- ansible_facts.os_family == 'RedHat'
|
||||
- ansible_facts.distribution_major_version|int is version('7', '<')
|
||||
- ansible_facts.distribution != 'Amazon'
|
||||
- os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: remove passwdqc
|
||||
yum:
|
||||
name: '{{ os_packages_pam_passwdqc }}'
|
||||
state: 'absent'
|
||||
when:
|
||||
- ansible_facts.os_family == 'RedHat'
|
||||
- not os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: configure passwdqc and tally via central system-auth confic
|
||||
template:
|
||||
src: 'etc/pam.d/rhel_system_auth.j2'
|
||||
dest: '/etc/pam.d/system-auth-ac'
|
||||
mode: '0640'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when: ansible_facts.os_family == 'RedHat'
|
||||
|
||||
- name: Gather package facts
|
||||
package_facts:
|
||||
manager: auto
|
||||
@@ -127,6 +6,25 @@
|
||||
- ansible_facts.os_family != 'Suse'
|
||||
- ansible_facts.os_family != 'Archlinux'
|
||||
|
||||
# the reason for this is so a user cannot connect to a server,
|
||||
# that isn't connected to an LDAP server anymore.
|
||||
# normally caching credentials shouldn't be necessary for most machines.
|
||||
# removing it provides some more security while not removing usability.
|
||||
- name: Remove pam ccreds to disable password caching
|
||||
package:
|
||||
name: '{{ os_packages_pam_ccreds }}'
|
||||
state: 'absent'
|
||||
when:
|
||||
- ansible_facts.os_family != 'Archlinux'
|
||||
|
||||
- import_tasks: pam_debian.yml
|
||||
when:
|
||||
- ansible_facts.distribution in ['Debian', 'Ubuntu']
|
||||
|
||||
- import_tasks: pam_rhel.yml
|
||||
when:
|
||||
- ansible_facts.os_family == 'RedHat'
|
||||
|
||||
- name: NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512
|
||||
template:
|
||||
src: 'etc/libuser.conf.j2'
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
- name: Install the package for strong password checking
|
||||
apt:
|
||||
name: 'libpam-passwdqc'
|
||||
state: 'present'
|
||||
update_cache: 'yes'
|
||||
when:
|
||||
- os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: Configure passwdqc
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_passwdqc.j2'
|
||||
dest: '{{ passwdqc_path }}'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when:
|
||||
- os_auth_pam_passwdqc_enable
|
||||
|
||||
- name: Install tally2
|
||||
apt:
|
||||
name: 'libpam-modules'
|
||||
state: 'present'
|
||||
when:
|
||||
- os_auth_retries > 0
|
||||
|
||||
- name: Manage tally on Debian stable
|
||||
block:
|
||||
- name: Configure tally2
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_tally2.j2'
|
||||
dest: '{{ tally2_path }}'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when:
|
||||
- os_auth_retries > 0
|
||||
|
||||
- name: Delete tally2 when retries is 0
|
||||
file:
|
||||
path: '{{ tally2_path }}'
|
||||
state: 'absent'
|
||||
when:
|
||||
- os_auth_retries == 0
|
||||
when:
|
||||
- "'libpam-modules' in ansible_facts.packages"
|
||||
- "ansible_facts.packages['libpam-modules'][0].version is version('1.4.0', '<')"
|
||||
|
||||
- name: Manage tally/faillock on Debian unstable
|
||||
block:
|
||||
- name: Delete tally2
|
||||
file:
|
||||
path: '{{ tally2_path }}'
|
||||
state: 'absent'
|
||||
|
||||
- name: create tally directory
|
||||
file:
|
||||
path: '/var/run/faillock'
|
||||
state: 'directory'
|
||||
mode: '0755'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
|
||||
- name: Configure faillock
|
||||
template:
|
||||
src: 'etc/security/faillock.conf.j2'
|
||||
dest: '/etc/security/faillock.conf'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
|
||||
- name: Configure faillock pam
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_faillock.j2'
|
||||
dest: '/usr/share/pam-configs/faillock'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when:
|
||||
- os_auth_retries > 0
|
||||
|
||||
- name: Configure faillock pam authfail
|
||||
template:
|
||||
src: 'usr/share/pam-configs/pam_faillock_authfail.j2'
|
||||
dest: '/usr/share/pam-configs/faillock_authfail'
|
||||
mode: '0644'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
when:
|
||||
- os_auth_retries > 0
|
||||
|
||||
- name: Delete faillock when retries is 0
|
||||
file:
|
||||
path: '/usr/share/pam-configs/faillock'
|
||||
state: 'absent'
|
||||
when:
|
||||
- os_auth_retries == 0
|
||||
|
||||
- name: Delete faillock authfail when retries is 0
|
||||
file:
|
||||
path: '/usr/share/pam-configs/faillock_authfail'
|
||||
state: 'absent'
|
||||
when:
|
||||
- os_auth_retries == 0
|
||||
when:
|
||||
- "'libpam-modules' in ansible_facts.packages"
|
||||
- "ansible_facts.packages['libpam-modules'][0].version is version('1.4.0', '>=')"
|
||||
|
||||
- name: Update pam on Debian systems
|
||||
command: 'pam-auth-update --package'
|
||||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
changed_when: false
|
||||
|
||||
- name: Remove passwdqc
|
||||
apt:
|
||||
name: 'libpam-passwdqc'
|
||||
state: 'absent'
|
||||
when:
|
||||
- not os_auth_pam_passwdqc_enable
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
- name: Install sssd-clients
|
||||
yum:
|
||||
name: sssd-client
|
||||
state: 'present'
|
||||
when:
|
||||
- os_auth_pam_sssd_enable | bool
|
||||
|
||||
- name: Configure passwdqc and faillock via central system-auth config
|
||||
template:
|
||||
src: 'etc/pam.d/rhel_auth.j2'
|
||||
dest: '/etc/pam.d/system-auth-local'
|
||||
mode: '0640'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
|
||||
- name: Enable our config for system-auth
|
||||
file:
|
||||
src: /etc/pam.d/system-auth-local
|
||||
dest: /etc/pam.d/system-auth
|
||||
mode: '0640'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
state: link
|
||||
force: true
|
||||
|
||||
- name: Configure passwdqc and faillock via central password-auth config
|
||||
template:
|
||||
src: 'etc/pam.d/rhel_auth.j2'
|
||||
dest: '/etc/pam.d/password-auth-local'
|
||||
mode: '0640'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
|
||||
- name: Enable our config for password-auth
|
||||
file:
|
||||
src: /etc/pam.d/password-auth-local
|
||||
dest: /etc/pam.d/password-auth
|
||||
mode: '0640'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
state: link
|
||||
force: true
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: add pinerolo_profile.sh to profile.d
|
||||
- name: Add pinerolo_profile.sh to profile.d
|
||||
template:
|
||||
src: 'etc/profile.d/profile.conf.j2'
|
||||
dest: '/etc/profile.d/pinerolo_profile.sh'
|
||||
@@ -8,7 +8,7 @@
|
||||
mode: '0750'
|
||||
when: not os_security_kernel_enable_core_dump | bool
|
||||
|
||||
- name: remove pinerolo_profile.sh from profile.d
|
||||
- name: Remove pinerolo_profile.sh from profile.d
|
||||
file:
|
||||
path: /etc/profile.d/pinerolo_profile.sh
|
||||
state: absent
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
check_mode: false
|
||||
register: users_accounts
|
||||
|
||||
- name: delete rhosts-files from system | os-09
|
||||
- name: Delete rhosts-files from system | os-09
|
||||
file:
|
||||
dest: '~{{ item }}/.rhosts'
|
||||
state: 'absent'
|
||||
with_flattened: '{{ users_accounts.stdout_lines | default([]) }}'
|
||||
|
||||
- name: delete hosts.equiv from system | os-01
|
||||
- name: Delete hosts.equiv from system | os-01
|
||||
file:
|
||||
dest: '/etc/hosts.equiv'
|
||||
state: 'absent'
|
||||
|
||||
- name: delete .netrc-files from system | os-09
|
||||
- name: Delete .netrc-files from system | os-09
|
||||
file:
|
||||
dest: '~{{ item }}/.netrc'
|
||||
state: 'absent'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: create securetty
|
||||
- name: Create securetty
|
||||
template:
|
||||
src: 'etc/securetty.j2'
|
||||
dest: '/etc/securetty'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: configure selinux | selinux-01
|
||||
- name: Configure selinux | selinux-01
|
||||
selinux:
|
||||
policy: "{{ os_selinux_policy }}"
|
||||
state: "{{ os_selinux_state }}"
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: remove suid/sgid bit from binaries in blacklist | os-06
|
||||
- name: Remove suid/sgid bit from binaries in blacklist | os-06
|
||||
file:
|
||||
path: '{{ item }}'
|
||||
mode: 'a-s'
|
||||
@@ -10,18 +10,18 @@
|
||||
- '{{ os_security_suid_sgid_system_blacklist }}'
|
||||
- '{{ os_security_suid_sgid_blacklist }}'
|
||||
|
||||
- name: find binaries with suid/sgid set | os-06
|
||||
- name: Find binaries with suid/sgid set | os-06
|
||||
shell: find / -xdev \( -perm -4000 -o -perm -2000 \) -type f ! -path '/proc/*' -print 2>/dev/null
|
||||
register: sbit_binaries
|
||||
when: os_security_suid_sgid_remove_from_unknown | bool
|
||||
changed_when: false
|
||||
|
||||
- name: gather files from which to remove suids/sgids and remove system white-listed files | os-06
|
||||
- name: Gather files from which to remove suids/sgids and remove system white-listed files | os-06
|
||||
set_fact:
|
||||
suid: '{{ sbit_binaries.stdout_lines | difference(os_security_suid_sgid_system_whitelist) }}'
|
||||
when: os_security_suid_sgid_remove_from_unknown | bool
|
||||
|
||||
- name: remove suid/sgid bit from all binaries except in system and user whitelist | os-06
|
||||
- name: Remove suid/sgid bit from all binaries except in system and user whitelist | os-06
|
||||
file:
|
||||
path: '{{ item }}'
|
||||
mode: 'a-s'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: protect sysctl.conf
|
||||
- name: Protect sysctl.conf
|
||||
file:
|
||||
path: '/etc/sysctl.conf'
|
||||
owner: 'root'
|
||||
@@ -9,7 +9,7 @@
|
||||
modification_time: preserve
|
||||
access_time: preserve
|
||||
|
||||
- name: set Daemon umask, do config for rhel-family | NSA 2.2.4.1
|
||||
- name: Set Daemon umask, do config for rhel-family | NSA 2.2.4.1
|
||||
template:
|
||||
src: 'etc/sysconfig/rhel_sysconfig_init.j2'
|
||||
dest: '/etc/sysconfig/init'
|
||||
@@ -18,7 +18,7 @@
|
||||
mode: '0544'
|
||||
when: ansible_facts.distribution in ['Amazon', 'CentOS', 'Fedora', 'RedHat']
|
||||
|
||||
- name: install initramfs-tools
|
||||
- name: Install initramfs-tools
|
||||
apt:
|
||||
name: 'initramfs-tools'
|
||||
state: 'present'
|
||||
@@ -27,7 +27,7 @@
|
||||
- ansible_facts.os_family == 'Debian'
|
||||
- os_security_kernel_enable_module_loading
|
||||
|
||||
- name: rebuild initramfs with starting pack of modules, if module loading at runtime is disabled
|
||||
- name: Rebuild initramfs with starting pack of modules, if module loading at runtime is disabled
|
||||
template:
|
||||
src: 'etc/initramfs-tools/modules.j2'
|
||||
dest: '/etc/initramfs-tools/modules'
|
||||
@@ -35,15 +35,15 @@
|
||||
group: 'root'
|
||||
mode: '0440'
|
||||
notify:
|
||||
- update-initramfs
|
||||
- Update-initramfs
|
||||
when:
|
||||
- ansible_facts.os_family == 'Debian'
|
||||
- os_security_kernel_enable_module_loading
|
||||
register: initramfs
|
||||
|
||||
- name: change sysctls
|
||||
- name: Change sysctls
|
||||
block:
|
||||
- name: create a combined sysctl-dict if overwrites are defined
|
||||
- name: Create a combined sysctl-dict if overwrites are defined
|
||||
set_fact:
|
||||
sysctl_config: '{{ sysctl_config | combine(sysctl_overwrite) }}'
|
||||
when: sysctl_overwrite | default()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: get UID_MIN from login.defs
|
||||
- name: Get UID_MIN from login.defs
|
||||
shell: awk '/^\s*UID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs
|
||||
args:
|
||||
removes: /etc/login.defs
|
||||
@@ -7,24 +7,24 @@
|
||||
check_mode: false
|
||||
changed_when: false
|
||||
|
||||
- name: calculate UID_MAX from UID_MIN by substracting 1
|
||||
- name: Calculate UID_MAX from UID_MIN by substracting 1
|
||||
set_fact:
|
||||
uid_max: '{{ uid_min.stdout | int - 1 }}'
|
||||
when: uid_min.stdout|int > 0
|
||||
|
||||
- name: set UID_MAX on Debian-systems if no login.defs exist
|
||||
- name: Set UID_MAX on Debian-systems if no login.defs exist
|
||||
set_fact:
|
||||
uid_max: '999'
|
||||
when:
|
||||
- ansible_facts.os_family == 'Debian'
|
||||
- uid_max is not defined
|
||||
|
||||
- name: set UID_MAX on other systems if no login.defs exist
|
||||
- name: Set UID_MAX on other systems if no login.defs exist
|
||||
set_fact:
|
||||
uid_max: '499'
|
||||
when: uid_max is not defined
|
||||
|
||||
- name: get all system accounts
|
||||
- name: Get all system accounts
|
||||
command: awk -F'':'' '{ if ( $3 <= {{ uid_max|quote }} ) print $1}' /etc/passwd
|
||||
args:
|
||||
removes: /etc/passwd
|
||||
@@ -32,12 +32,12 @@
|
||||
check_mode: false
|
||||
register: sys_accs
|
||||
|
||||
- name: remove always ignored system accounts from list
|
||||
- name: Remove always ignored system accounts from list
|
||||
set_fact:
|
||||
sys_accs_cond: '{{ sys_accs.stdout_lines | difference(os_always_ignore_users) }}'
|
||||
check_mode: false
|
||||
|
||||
- name: change system accounts not on the user provided ignore-list
|
||||
- name: Change system accounts not on the user provided ignore-list
|
||||
user:
|
||||
name: '{{ item }}'
|
||||
shell: '{{ os_nologin_shell_path }}'
|
||||
@@ -45,3 +45,20 @@
|
||||
createhome: false
|
||||
with_flattened:
|
||||
- '{{ sys_accs_cond | default([]) | difference(os_ignore_users) | list }}'
|
||||
|
||||
- name: get all home directories in /home, but skip ignored users
|
||||
find:
|
||||
paths: /home/
|
||||
recurse: false
|
||||
file_type: directory
|
||||
excludes: "{{ os_ignore_home_folder_users | join(',') }}"
|
||||
register: home_directories
|
||||
when: os_chmod_home_folders | bool
|
||||
|
||||
- name: set ownership of /home directories to 0700
|
||||
file:
|
||||
mode: 0700
|
||||
path: "{{ item.path }}"
|
||||
state: directory
|
||||
loop: "{{ home_directories.files }}"
|
||||
when: os_chmod_home_folders | bool
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: remove unused repositories
|
||||
- name: Remove unused repositories
|
||||
file:
|
||||
name: '/etc/yum.repos.d/{{ item }}.repo'
|
||||
state: 'absent'
|
||||
@@ -9,7 +9,7 @@
|
||||
- 'CentOS-Vault'
|
||||
when: os_security_packages_clean | bool
|
||||
|
||||
- name: get yum-repository-files
|
||||
- name: Get yum-repository-files
|
||||
find:
|
||||
paths: '/etc/yum.repos.d'
|
||||
patterns: '*.repo'
|
||||
@@ -18,7 +18,7 @@
|
||||
# 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-repository-files
|
||||
- name: Activate gpg-check for yum-repository-files
|
||||
replace:
|
||||
path: '{{ item.path }}'
|
||||
regexp: '^\s*gpgcheck.*'
|
||||
@@ -30,7 +30,7 @@
|
||||
# failed_when is needed because by default replace module will fail if the file doesn't exists.
|
||||
# status.rc is only defined if an error accrued and only error code (rc) 257 will be ignored.
|
||||
# All other errors will still be raised.
|
||||
- name: activate gpg-check for config files
|
||||
- name: Activate gpg-check for config files
|
||||
replace:
|
||||
path: '{{ item }}'
|
||||
regexp: '^\s*gpgcheck\W.*'
|
||||
@@ -43,7 +43,7 @@
|
||||
- '/etc/dnf/dnf.conf'
|
||||
- '/etc/yum/pluginconf.d/rhnplugin.conf'
|
||||
|
||||
- name: remove deprecated or insecure packages | package-01 - package-09
|
||||
- name: Remove deprecated or insecure packages | package-01 - package-09
|
||||
yum:
|
||||
name: '{{ os_security_packages_list }}'
|
||||
state: 'absent'
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{{ ansible_managed | comment }}
|
||||
# Generated by Ansible role {{ ansible_role_name }}
|
||||
|
||||
#%PAM-1.0
|
||||
auth required pam_env.so
|
||||
auth required pam_faildelay.so delay=2000000
|
||||
{% if os_auth_retries > 0 %}
|
||||
auth required pam_faillock.so preauth silent audit even_deny_root deny={{ os_auth_retries }} unlock_time={{ os_auth_lockout_time }}
|
||||
{% endif %}
|
||||
{% if (os_auth_pam_sssd_enable | bool) %}
|
||||
auth [default=1 ignore=ignore success=ok] pam_succeed_if.so uid >= 1000 quiet
|
||||
auth [default=1 ignore=ignore success=ok] pam_localuser.so
|
||||
{% endif %}
|
||||
auth sufficient pam_unix.so nullok try_first_pass
|
||||
{% if (os_auth_pam_sssd_enable | bool) %}
|
||||
auth [default=1 ignore=ignore success=ok] pam_succeed_if.so uid >= 1000 quiet
|
||||
auth sufficient pam_sss.so forward_pass
|
||||
{% endif %}
|
||||
{% if os_auth_retries > 0 %}
|
||||
auth required pam_faillock.so authfail audit even_deny_root deny={{ os_auth_retries }} unlock_time={{ os_auth_lockout_time }}
|
||||
{% endif %}
|
||||
auth required pam_deny.so
|
||||
|
||||
{% if os_auth_retries > 0 %}
|
||||
account required pam_faillock.so
|
||||
{% endif %}
|
||||
account required pam_unix.so
|
||||
account sufficient pam_localuser.so
|
||||
account sufficient pam_succeed_if.so uid < 1000 quiet
|
||||
{% if (os_auth_pam_sssd_enable | bool) %}
|
||||
account [default=bad success=ok user_unknown=ignore] pam_sss.so
|
||||
{% endif %}
|
||||
account required pam_permit.so
|
||||
|
||||
{% if (os_auth_pam_passwdqc_enable | bool) %}
|
||||
password requisite pam_pwquality.so {{ os_auth_pam_pwquality_options }}
|
||||
{% endif %}
|
||||
{# NSA 2.3.3.6 Limit Password Reuse #}
|
||||
password requisite pam_pwhistory.so remember=5 use_authtok
|
||||
{# NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512 #}
|
||||
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
|
||||
{% if (os_auth_pam_sssd_enable | bool) %}
|
||||
password sufficient pam_sss.so use_authtok
|
||||
{% endif %}
|
||||
password required pam_deny.so
|
||||
|
||||
session optional pam_keyinit.so revoke
|
||||
session required pam_limits.so
|
||||
-session optional pam_systemd.so
|
||||
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
|
||||
session required pam_unix.so
|
||||
{% if (os_auth_pam_sssd_enable | bool) %}
|
||||
session optional pam_sss.so
|
||||
{% endif %}
|
||||
@@ -1,40 +0,0 @@
|
||||
{{ ansible_managed | comment }}
|
||||
# Generated by Ansible role {{ ansible_role_name }}
|
||||
|
||||
#%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|bool) %}
|
||||
{%- if ((ansible_facts.os_family == 'RedHat' and ansible_facts.distribution_version|int is version('7', '>=')) or ansible_facts.distribution == 'Amazon') %}
|
||||
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
|
||||
@@ -0,0 +1,65 @@
|
||||
{{ ansible_managed | comment }}
|
||||
# Generated by Ansible role {{ ansible_role_name }}
|
||||
#
|
||||
# Configuration for locking the user after multiple failed
|
||||
# authentication attempts.
|
||||
#
|
||||
# The directory where the user files with the failure records are kept.
|
||||
# The default is /var/run/faillock.
|
||||
# dir = /var/run/faillock
|
||||
#
|
||||
# Will log the user name into the system log if the user is not found.
|
||||
# Enabled if option is present.
|
||||
# audit
|
||||
#
|
||||
# Don't print informative messages.
|
||||
# Enabled if option is present.
|
||||
# silent
|
||||
#
|
||||
# Don't log informative messages via syslog.
|
||||
# Enabled if option is present.
|
||||
# no_log_info
|
||||
#
|
||||
# Only track failed user authentications attempts for local users
|
||||
# in /etc/passwd and ignore centralized (AD, IdM, LDAP, etc.) users.
|
||||
# The `faillock` command will also no longer track user failed
|
||||
# authentication attempts. Enabling this option will prevent a
|
||||
# double-lockout scenario where a user is locked out locally and
|
||||
# in the centralized mechanism.
|
||||
# Enabled if option is present.
|
||||
# local_users_only
|
||||
#
|
||||
# Deny access if the number of consecutive authentication failures
|
||||
# for this user during the recent interval exceeds n tries.
|
||||
# The default is 3.
|
||||
deny = {{ os_auth_retries }}
|
||||
#
|
||||
# The length of the interval during which the consecutive
|
||||
# authentication failures must happen for the user account
|
||||
# lock out is <replaceable>n</replaceable> seconds.
|
||||
# The default is 900 (15 minutes).
|
||||
# fail_interval = 900
|
||||
#
|
||||
# The access will be re-enabled after n seconds after the lock out.
|
||||
# The value 0 has the same meaning as value `never` - the access
|
||||
# will not be re-enabled without resetting the faillock
|
||||
# entries by the `faillock` command.
|
||||
# The default is 600 (10 minutes).
|
||||
unlock_time = {{ os_auth_lockout_time }}
|
||||
#
|
||||
# Root account can become locked as well as regular accounts.
|
||||
# Enabled if option is present.
|
||||
even_deny_root
|
||||
#
|
||||
# This option implies the `even_deny_root` option.
|
||||
# Allow access after n seconds to root account after the
|
||||
# account is locked. In case the option is not specified
|
||||
# the value is the same as of the `unlock_time` option.
|
||||
# root_unlock_time = 900
|
||||
#
|
||||
# If a group name is specified with this option, members
|
||||
# of the group will be handled by this module the same as
|
||||
# the root account (the options `even_deny_root>` and
|
||||
# `root_unlock_time` will apply to them.
|
||||
# By default, the option is not set.
|
||||
# admin_group = <admin_group_name>
|
||||
@@ -0,0 +1,12 @@
|
||||
{{ ansible_managed | comment }}
|
||||
# Generated by Ansible role {{ ansible_role_name }}
|
||||
|
||||
Name: faillock boilerplate
|
||||
Default: yes
|
||||
Priority: 1024
|
||||
Auth-Type: Primary
|
||||
Auth:
|
||||
required pam_faillock.so preauth
|
||||
Account-Type: Primary
|
||||
Account:
|
||||
required pam_faillock.so
|
||||
@@ -0,0 +1,10 @@
|
||||
{{ ansible_managed | comment }}
|
||||
# Generated by Ansible role {{ ansible_role_name }}
|
||||
|
||||
Name: faillock lockout after failed attempts enforcement
|
||||
Default: yes
|
||||
Priority: 0
|
||||
Auth-Type: Primary
|
||||
Auth:
|
||||
required pam_faillock.so authfail
|
||||
|
||||
File renamed without changes.
@@ -1,8 +1,6 @@
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -27,6 +25,8 @@ os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 201
|
||||
os_auth_sys_gid_max: 999
|
||||
|
||||
os_auth_pam_sssd_enable: false
|
||||
|
||||
# defaults for useradd
|
||||
os_useradd_mail_dir: /var/spool/mail
|
||||
os_useradd_create_home: true
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
|
||||
os_packages_pam_ccreds: 'libpam-ccreds'
|
||||
os_packages_pam_passwdqc: 'libpam-passwdqc'
|
||||
os_packages_pam_cracklib: 'libpam-cracklib'
|
||||
os_nologin_shell_path: '/usr/sbin/nologin'
|
||||
|
||||
# Different distros use different standards for /etc/shadow perms, e.g.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -27,6 +25,8 @@ os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 201
|
||||
os_auth_sys_gid_max: 999
|
||||
|
||||
os_auth_pam_sssd_enable: true
|
||||
|
||||
# defaults for useradd
|
||||
os_useradd_mail_dir: /var/spool/mail
|
||||
os_useradd_create_home: true
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -27,6 +25,8 @@ os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 201
|
||||
os_auth_sys_gid_max: 999
|
||||
|
||||
os_auth_pam_sssd_enable: false
|
||||
|
||||
# defaults for useradd
|
||||
os_useradd_mail_dir: /var/spool/mail
|
||||
os_useradd_create_home: true
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -27,6 +25,8 @@ os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 201
|
||||
os_auth_sys_gid_max: 999
|
||||
|
||||
os_auth_pam_sssd_enable: false
|
||||
|
||||
# defaults for useradd
|
||||
os_useradd_mail_dir: /var/spool/mail
|
||||
os_useradd_create_home: true
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
|
||||
os_packages_pam_ccreds: 'pam_ccreds'
|
||||
os_nologin_shell_path: '/sbin/nologin'
|
||||
|
||||
# Different distros use different standards for /etc/shadow perms, e.g.
|
||||
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
|
||||
# You must provide key/value pairs for owner, group, and mode if overriding.
|
||||
os_shadow_perms:
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0000'
|
||||
|
||||
os_passwd_perms:
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
os_env_umask: '077'
|
||||
|
||||
os_auth_uid_min: 1000
|
||||
os_auth_gid_min: 1000
|
||||
os_auth_sys_uid_min: 201
|
||||
os_auth_sys_uid_max: 999
|
||||
os_auth_sys_gid_min: 201
|
||||
os_auth_sys_gid_max: 999
|
||||
|
||||
os_auth_pam_sssd_enable: true
|
||||
|
||||
# defaults for useradd
|
||||
os_useradd_mail_dir: /var/spool/mail
|
||||
os_useradd_create_home: true
|
||||
|
||||
modprobe_package: 'module-init-tools'
|
||||
auditd_package: 'audit'
|
||||
|
||||
hidepid_option: '2' # allowed values: 0, 1, 2
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
|
||||
os_packages_pam_ccreds: 'pam_ccreds'
|
||||
os_packages_pam_passwdqc: 'pam_passwdqc'
|
||||
os_packages_pam_cracklib: 'cracklib'
|
||||
os_nologin_shell_path: '/sbin/nologin'
|
||||
|
||||
# Different distros use different standards for /etc/shadow perms, e.g.
|
||||
|
||||
@@ -76,7 +76,10 @@ Warning: This role disables root-login on the target server! Please make sure yo
|
||||
- Description: false to disable pam authentication.
|
||||
- `ssh_gssapi_support`
|
||||
- Default: `false`
|
||||
- Description: true if SSH has GSSAPI support.
|
||||
- Description: Set to true to enable GSSAPI authentication (both client and server).
|
||||
- `ssh_gssapi_delegation`
|
||||
- Default: `false`
|
||||
- Description: Set to true to enable GSSAPI credential forwarding.
|
||||
- `ssh_kerberos_support`
|
||||
- Default: `true`
|
||||
- Description: true if SSH has Kerberos support.
|
||||
@@ -241,7 +244,7 @@ Warning: This role disables root-login on the target server! Please make sure yo
|
||||
collections:
|
||||
- devsec.hardening
|
||||
roles:
|
||||
- devsec.hardening.ssh_hardening
|
||||
- ssh_hardening
|
||||
```
|
||||
|
||||
## Configuring settings not listed in role-variables
|
||||
@@ -255,7 +258,7 @@ Example playbook:
|
||||
collections:
|
||||
- devsec.hardening
|
||||
roles:
|
||||
- devsec.hardening.ssh_hardening
|
||||
- ssh_hardening
|
||||
vars:
|
||||
ssh_custom_options:
|
||||
- "Include /etc/ssh/ssh_config.d/*"
|
||||
|
||||
@@ -91,9 +91,12 @@ ssh_use_pam: true # sshd
|
||||
# specify AuthenticationMethods
|
||||
sshd_authenticationmethods: 'publickey'
|
||||
|
||||
# true if SSH support GSSAPI
|
||||
# Set to true to enable GSSAPI authentication (both client and server)
|
||||
ssh_gssapi_support: false
|
||||
|
||||
# Set to true to enable GSSAPI credential forwarding
|
||||
ssh_gssapi_delegation: false
|
||||
|
||||
# if specified, login is disallowed for user names that match one of the patterns.
|
||||
ssh_deny_users: '' # sshd
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: restart sshd
|
||||
- name: Restart sshd
|
||||
service:
|
||||
name: '{{ sshd_service_name }}'
|
||||
state: restarted
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
- name: set ssh CA pub keys
|
||||
- name: Set ssh CA pub keys
|
||||
template:
|
||||
src: 'trusted_user_ca_keys.j2'
|
||||
dest: '{{ ssh_trusted_user_ca_keys_file }}'
|
||||
mode: '0644'
|
||||
owner: '{{ ssh_owner }}'
|
||||
group: '{{ ssh_group }}'
|
||||
notify: restart sshd
|
||||
notify: Restart sshd
|
||||
|
||||
- name: create ssh authorized principals directories
|
||||
- name: Create ssh authorized principals directories
|
||||
file:
|
||||
path: '{{ item.path | dirname }}'
|
||||
mode: '{{ item.directorymode | default(0700) }}'
|
||||
@@ -17,7 +17,7 @@
|
||||
state: directory
|
||||
loop: '{{ ssh_authorized_principals }}'
|
||||
|
||||
- name: set ssh authorized principals
|
||||
- name: Set ssh authorized principals
|
||||
template:
|
||||
src: 'authorized_principals.j2'
|
||||
dest: '{{ item.path }}'
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
- name: set ciphers according to openssh-version if openssh >= 5.3
|
||||
- name: Set ciphers according to openssh-version if openssh >= 5.3
|
||||
set_fact:
|
||||
ssh_ciphers: '{{ ssh_ciphers_53_default }}'
|
||||
when: sshd_version is version('5.3', '>=')
|
||||
|
||||
- name: set ciphers according to openssh-version if openssh >= 6.6
|
||||
- name: Set ciphers according to openssh-version if openssh >= 6.6
|
||||
set_fact:
|
||||
ssh_ciphers: '{{ ssh_ciphers_66_default }}'
|
||||
when: sshd_version is version('6.6', '>=')
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: replace default 2048 bits RSA keypair
|
||||
- name: Replace default 2048 bits RSA keypair
|
||||
community.crypto.openssh_keypair:
|
||||
state: present
|
||||
type: rsa
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
# In RHEL and Fedora, the 'ssh_keys' group is the group owner of the host private SSH keys.
|
||||
# Since the openssh_keypair module needs to read the key to provide idempotency, we need to set ownership and group based on specific OS vars.
|
||||
- name: change host private key ownership, group and permissions
|
||||
- name: Change host private key ownership, group and permissions
|
||||
file:
|
||||
path: "{{ ssh_host_keys_dir }}/ssh_host_rsa_key"
|
||||
owner: "{{ ssh_host_keys_owner }}"
|
||||
@@ -18,20 +18,20 @@
|
||||
mode: "0640"
|
||||
when: "ansible_facts.distribution in ['CentOS', 'OracleLinux', 'RedHat']"
|
||||
|
||||
- name: set hostkeys according to openssh-version if openssh >= 5.3
|
||||
- name: Set hostkeys according to openssh-version if openssh >= 5.3
|
||||
set_fact:
|
||||
ssh_host_key_files:
|
||||
- "{{ ssh_host_keys_dir }}/ssh_host_rsa_key"
|
||||
when: sshd_version is version('5.3', '>=')
|
||||
|
||||
- name: set hostkeys according to openssh-version if openssh >= 6.0
|
||||
- name: Set hostkeys according to openssh-version if openssh >= 6.0
|
||||
set_fact:
|
||||
ssh_host_key_files:
|
||||
- "{{ ssh_host_keys_dir }}/ssh_host_rsa_key"
|
||||
- "{{ ssh_host_keys_dir }}/ssh_host_ecdsa_key"
|
||||
when: sshd_version is version('6.0', '>=')
|
||||
|
||||
- name: set hostkeys according to openssh-version if openssh >= 6.3
|
||||
- name: Set hostkeys according to openssh-version if openssh >= 6.3
|
||||
set_fact:
|
||||
ssh_host_key_files:
|
||||
- "{{ ssh_host_keys_dir }}/ssh_host_rsa_key"
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
---
|
||||
- name: set kex according to openssh-version if openssh >= 5.9
|
||||
- name: Set kex according to openssh-version if openssh >= 5.9
|
||||
set_fact:
|
||||
ssh_kex: '{{ ssh_kex_59_default }}'
|
||||
when: sshd_version is version('5.9', '>=')
|
||||
|
||||
- name: set kex according to openssh-version if openssh >= 6.6
|
||||
- name: Set kex according to openssh-version if openssh >= 6.6
|
||||
set_fact:
|
||||
ssh_kex: '{{ ssh_kex_66_default }}'
|
||||
when: sshd_version is version('6.6', '>=')
|
||||
|
||||
- name: set kex according to openssh-version if openssh >= 8.0
|
||||
- name: Set kex according to openssh-version if openssh >= 8.0
|
||||
set_fact:
|
||||
ssh_kex: '{{ ssh_kex_80_default }}'
|
||||
when: sshd_version is version('8.0', '>=')
|
||||
|
||||
- name: Set kex according to openssh-version if openssh >= 8.5
|
||||
set_fact:
|
||||
ssh_kex: '{{ ssh_kex_85_default }}'
|
||||
when: sshd_version is version('8.5', '>=')
|
||||
@@ -1,27 +1,27 @@
|
||||
---
|
||||
- name: set macs according to openssh-version if openssh >= 5.3
|
||||
- name: Set macs according to openssh-version if openssh >= 5.3
|
||||
set_fact:
|
||||
ssh_macs: '{{ ssh_macs_53_default }}'
|
||||
when: sshd_version is version('5.3', '>=')
|
||||
|
||||
- name: set macs for Enterprise Linux >= 6.5 (openssh 5.3 with backports)
|
||||
- name: Set macs for Enterprise Linux >= 6.5 (openssh 5.3 with backports)
|
||||
set_fact:
|
||||
ssh_macs: '{{ ssh_macs_53_el_6_5_default }}'
|
||||
when:
|
||||
- ansible_facts.distribution in ['CentOS', 'OracleLinux', 'RedHat']
|
||||
- ansible_facts.distribution_version is version('6.5', '>=')
|
||||
|
||||
- name: set macs according to openssh-version if openssh >= 5.9
|
||||
- name: Set macs according to openssh-version if openssh >= 5.9
|
||||
set_fact:
|
||||
ssh_macs: '{{ ssh_macs_59_default }}'
|
||||
when: sshd_version is version('5.9', '>=')
|
||||
|
||||
- name: set macs according to openssh-version if openssh >= 6.6
|
||||
- name: Set macs according to openssh-version if openssh >= 6.6
|
||||
set_fact:
|
||||
ssh_macs: '{{ ssh_macs_66_default }}'
|
||||
when: sshd_version is version('6.6', '>=')
|
||||
|
||||
- name: set macs according to openssh-version if openssh >= 7.6
|
||||
- name: Set macs according to openssh-version if openssh >= 7.6
|
||||
set_fact:
|
||||
ssh_macs: '{{ ssh_macs_76_default }}'
|
||||
when: sshd_version is version('7.6', '>=')
|
||||
@@ -21,45 +21,45 @@
|
||||
when: "not lookup('varnames', '^' + item.key + '$')"
|
||||
with_dict: '{{ os_vars }}'
|
||||
|
||||
- name: get openssh-version
|
||||
- name: Get openssh-version
|
||||
command: ssh -V
|
||||
register: sshd_version_raw
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
|
||||
- name: parse openssh-version
|
||||
- name: Parse openssh-version
|
||||
set_fact:
|
||||
sshd_version: "{{ sshd_version_raw.stderr | regex_replace('.*_([0-9]*.[0-9]).*', '\\1') }}"
|
||||
|
||||
- name: set default for ssh_host_key_files if not supplied
|
||||
- name: Set default for ssh_host_key_files if not supplied
|
||||
include_tasks: crypto_hostkeys.yml
|
||||
when:
|
||||
- ssh_server_hardening | bool
|
||||
- not ssh_host_key_files
|
||||
|
||||
- name: set default for ssh_macs if not supplied
|
||||
- name: Set default for ssh_macs if not supplied
|
||||
include_tasks: crypto_macs.yml
|
||||
when: not ssh_macs
|
||||
|
||||
- name: set default for ssh_ciphers if not supplied
|
||||
- name: Set default for ssh_ciphers if not supplied
|
||||
include_tasks: crypto_ciphers.yml
|
||||
when: not ssh_ciphers
|
||||
|
||||
- name: set default for ssh_kex if not supplied
|
||||
- name: Set default for ssh_kex if not supplied
|
||||
include_tasks: crypto_kex.yml
|
||||
when: not ssh_kex
|
||||
|
||||
- name: create revoked_keys and set permissions to root/600
|
||||
- name: Create revoked_keys and set permissions to root/600
|
||||
template:
|
||||
src: 'revoked_keys.j2'
|
||||
dest: '/etc/ssh/revoked_keys'
|
||||
mode: '0600'
|
||||
owner: '{{ ssh_owner }}'
|
||||
group: '{{ ssh_group }}'
|
||||
notify: restart sshd
|
||||
notify: Restart sshd
|
||||
when: ssh_server_hardening | bool
|
||||
|
||||
- name: create sshd_config and set permissions to root/600
|
||||
- name: Create sshd_config and set permissions to root/600
|
||||
template:
|
||||
src: 'opensshd.conf.j2'
|
||||
dest: "{{ ssh_server_config_file }}"
|
||||
@@ -67,10 +67,10 @@
|
||||
owner: '{{ ssh_owner }}'
|
||||
group: '{{ ssh_group }}'
|
||||
validate: '{{ sshd_path }} -T -C user=root -C host=localhost -C addr=localhost -C lport=22 -f %s'
|
||||
notify: restart sshd
|
||||
notify: Restart sshd
|
||||
when: ssh_server_hardening | bool
|
||||
|
||||
- name: disable dynamic MOTD
|
||||
- name: Disable dynamic MOTD
|
||||
pamd:
|
||||
name: sshd
|
||||
type: session
|
||||
@@ -83,7 +83,7 @@
|
||||
- ssh_pam_support | bool
|
||||
- not (ssh_print_pam_motd | bool)
|
||||
|
||||
- name: create ssh_config and set permissions to root/644
|
||||
- name: Create ssh_config and set permissions to root/644
|
||||
template:
|
||||
src: 'openssh.conf.j2'
|
||||
dest: "{{ ssh_client_config_file }}"
|
||||
@@ -92,36 +92,36 @@
|
||||
group: '{{ ssh_group }}'
|
||||
when: ssh_client_hardening | bool
|
||||
|
||||
- name: check if {{ sshd_moduli_file }} contains weak DH parameters
|
||||
- name: Check if {{ sshd_moduli_file }} contains weak DH parameters
|
||||
shell: awk '$5 < {{ sshd_moduli_minimum }}' {{ sshd_moduli_file }}
|
||||
register: sshd_register_moduli
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
when: ssh_server_hardening | bool
|
||||
|
||||
- name: remove all small primes
|
||||
- name: Remove all small primes
|
||||
shell: awk '$5 >= {{ sshd_moduli_minimum }}' {{ sshd_moduli_file }} > {{ sshd_moduli_file }}.new ;
|
||||
[ -r {{ sshd_moduli_file }}.new -a -s {{ sshd_moduli_file }}.new ] && mv {{ sshd_moduli_file }}.new {{ sshd_moduli_file }} || true
|
||||
notify: restart sshd
|
||||
notify: Restart sshd
|
||||
when:
|
||||
- ssh_server_hardening | bool
|
||||
- sshd_register_moduli.stdout
|
||||
|
||||
- name: include tasks to setup ca keys and principals
|
||||
- name: Include tasks to setup ca keys and principals
|
||||
include_tasks: ca_keys_and_principals.yml
|
||||
when: ssh_trusted_user_ca_keys_file | length > 0
|
||||
|
||||
- name: include selinux specific tasks
|
||||
- name: Include selinux specific tasks
|
||||
include_tasks: selinux.yml
|
||||
when: ansible_facts.selinux and ansible_facts.selinux.status == "enabled"
|
||||
|
||||
- name: gather package facts
|
||||
- name: Gather package facts
|
||||
package_facts:
|
||||
check_mode: false
|
||||
when:
|
||||
- sshd_disable_crypto_policy | bool
|
||||
|
||||
- name: disable SSH server CRYPTO_POLICY
|
||||
- name: Disable SSH server CRYPTO_POLICY
|
||||
copy:
|
||||
src: sshd
|
||||
dest: /etc/sysconfig/sshd
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
- name: install selinux dependencies when selinux is installed
|
||||
- name: Install selinux dependencies when selinux is installed
|
||||
package:
|
||||
name: '{{ ssh_selinux_packages }}'
|
||||
state: present
|
||||
|
||||
- name: authorize {{ ssh_server_ports }} ports for selinux
|
||||
- name: Authorize {{ ssh_server_ports }} ports for selinux
|
||||
seport:
|
||||
ports: '{{ item }}'
|
||||
proto: tcp
|
||||
@@ -12,7 +12,7 @@
|
||||
state: present
|
||||
loop: '{{ ssh_server_ports }}'
|
||||
|
||||
- name: check if ssh_password module is already installed
|
||||
- name: Check if ssh_password module is already installed
|
||||
shell: 'set -o pipefail && semodule -l | grep ssh_password'
|
||||
args:
|
||||
executable: /bin/bash
|
||||
@@ -28,7 +28,7 @@
|
||||
- not (ssh_use_pam | bool)
|
||||
- ('ssh_password' not in ssh_password_module.stdout)
|
||||
block:
|
||||
- name: create selinux custom policy drop folder
|
||||
- name: Create selinux custom policy drop folder
|
||||
file:
|
||||
path: '{{ ssh_custom_selinux_dir }}'
|
||||
state: 'directory'
|
||||
@@ -36,7 +36,7 @@
|
||||
group: 'root'
|
||||
mode: '0750'
|
||||
|
||||
- name: distributing custom selinux policies
|
||||
- name: Distributing custom selinux policies
|
||||
copy:
|
||||
src: 'ssh_password'
|
||||
dest: '{{ ssh_custom_selinux_dir }}'
|
||||
@@ -44,20 +44,20 @@
|
||||
group: 'root'
|
||||
mode: '0600'
|
||||
|
||||
- name: check and compile policy
|
||||
- name: Check and compile policy
|
||||
command: checkmodule -M -m -o {{ ssh_custom_selinux_dir }}/ssh_password.mod {{ ssh_custom_selinux_dir }}/ssh_password
|
||||
|
||||
- name: create selinux policy module package
|
||||
- name: Create selinux policy module package
|
||||
command: semodule_package -o {{ ssh_custom_selinux_dir }}/ssh_password.pp -m {{ ssh_custom_selinux_dir }}/ssh_password.mod
|
||||
|
||||
- name: install selinux policy
|
||||
- name: Install selinux policy
|
||||
command: semodule -i {{ ssh_custom_selinux_dir }}/ssh_password.pp
|
||||
|
||||
|
||||
# The following tasks only get executed when selinux is installed, UsePam is
|
||||
# 'yes' and the ssh_password module is installed. See
|
||||
# http://danwalsh.livejournal.com/12333.html for more info
|
||||
- name: remove selinux-policy when Pam is used, because Allowing sshd to read the shadow file directly is considered a potential security risk
|
||||
- name: Remove selinux-policy when Pam is used, because Allowing sshd to read the shadow file directly is considered a potential security risk
|
||||
command: semodule -r ssh_password
|
||||
when:
|
||||
- ssh_use_pam | bool
|
||||
|
||||
@@ -104,8 +104,8 @@ RSAAuthentication yes
|
||||
PasswordAuthentication {{ 'yes' if ssh_client_password_login else 'no' }}
|
||||
|
||||
# Only use GSSAPIAuthentication if implemented on the network.
|
||||
GSSAPIAuthentication no
|
||||
GSSAPIDelegateCredentials no
|
||||
GSSAPIAuthentication {{ 'yes' if (ssh_gssapi_support|bool) else 'no' }}
|
||||
GSSAPIDelegateCredentials {{ 'yes' if (ssh_gssapi_delegation|bool) else 'no' }}
|
||||
|
||||
# Disable tunneling
|
||||
Tunnel no
|
||||
|
||||
@@ -50,3 +50,8 @@ ssh_kex_80_default:
|
||||
- [email protected]
|
||||
- [email protected]
|
||||
- diffie-hellman-group-exchange-sha256
|
||||
|
||||
ssh_kex_85_default:
|
||||
- [email protected]
|
||||
- [email protected]
|
||||
- diffie-hellman-group-exchange-sha256
|
||||
Reference in new issue
Block a user