Ansibleでサーバーを強化する

## はじめに

[devsec.hardening](https://github.com/dev-sec/ansible-collection-hardening) というサーバーハードリングを行う Ansible Collection を [Reddit](https://www.reddit.com/r/ansible/comments/jsq2cc/devsechardening_collection_released/?utm_source=share&utm_medium=web2x&context=3) で見かけたので試してみました。

サーバーハードニングを行うことにより、 OS やアプリケーションの設定をより強固なものにしてくれます。この Ansible Collection を利用してサーバーの設定を行えば、 CIS Benchmark なども満たせるのかもしれません。

## devsec.hardening について

この Ansible Collection は [DevSec Hardening Framework](https://dev-sec.io) として、 Chef や Puppet でも自動化できるように開発されています。このコレクションで強化を行える対象は以下の通りです。 OS だけでなく、 SSH や Nginx などのミドルウェアの設定も行えるようです。

* Linux
* SSH
* Nginx
* MySQL
* Apache(開発中)
* Windows(開発中)

コレクションは以下のコマンドでインストールできます。

```sh
ansible-galaxy collection install devsec.hardening
```

## Play

試しにVagrant環境で実行します。以下の Vagrant ファイルと Playbook を同じディレクトリーに配置すれば同じように試せます。

```ruby
# Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/focal64"

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
  end
end
```

```yaml
# playbook.yml
- hosts: all
  become: true
  collections:
    - devsec.hardening
  roles:
    - devsec.hardening.os_hardening
    - devsec.hardening.ssh_hardening
    - devsec.hardening.nginx_hardening
  vars:
    sysctl_overwrite:
      net.ipv4.ip_forward: 1
  pre_tasks:
    - name: Install Nginx
      package:
        name: nginx
```

## 適用結果

適用したところ、よくある以下のような設定を行なってくれていますね。

* OS
    * auditdの設定
    * sysctlの強化
* SSH
    * sshd_configの強化
* Nginx
    * TLSの設定強化
    * CROSSなのどのheader追加

こういった設定を入れると良いんだなと、勉強になりました。

<details><summary>長いですが、Ansibleのログ</summary><div>

```
PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [default]

TASK [Install Nginx] ***********************************************************
The following additional packages will be installed:
  fontconfig-config fonts-dejavu-core libfontconfig1 libgd3 libjbig0
  libjpeg-turbo8 libjpeg8 libnginx-mod-http-image-filter
  libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libtiff5
  libwebp6 libxpm4 nginx-common nginx-core
Suggested packages:
  libgd-tools fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:
  fontconfig-config fonts-dejavu-core libfontconfig1 libgd3 libjbig0
  libjpeg-turbo8 libjpeg8 libnginx-mod-http-image-filter
  libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libtiff5
  libwebp6 libxpm4 nginx nginx-common nginx-core
0 upgraded, 17 newly installed, 0 to remove and 0 not upgraded.
changed: [default]

TASK [devsec.hardening.os_hardening : Set OS family dependent variables] *******
ok: [default]

TASK [devsec.hardening.os_hardening : Set OS dependent variables] **************

TASK [devsec.hardening.os_hardening : install auditd package | package-08] *****
The following additional packages will be installed:
  libauparse0
Suggested packages:
  audispd-plugins
The following NEW packages will be installed:
  auditd libauparse0
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
changed: [default]

TASK [devsec.hardening.os_hardening : configure auditd | package-08] ***********
--- before: /etc/audit/auditd.conf
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmppogqkpxk/auditd.conf.j2
@@ -1,32 +1,28 @@
 #
-# This file controls the configuration of the audit daemon
+# Ansible managed
 #

-local_events = yes
-write_logs = yes
 log_file = /var/log/audit/audit.log
-log_group = adm
 log_format = RAW
-flush = INCREMENTAL_ASYNC
-freq = 50
-max_log_file = 8
+log_group = root
+priority_boost = 4
+flush = INCREMENTAL
+freq = 20
 num_logs = 5
-priority_boost = 4
 disp_qos = lossy
 dispatcher = /sbin/audispd
 name_format = NONE
 ##name = mydomain
-max_log_file_action = ROTATE
+max_log_file = 6
+max_log_file_action = keep_logs
 space_left = 75
 space_left_action = SYSLOG
-verify_email = yes
 action_mail_acct = root
 admin_space_left = 50
 admin_space_left_action = SUSPEND
 disk_full_action = SUSPEND
 disk_error_action = SUSPEND
-use_libwrap = yes
-##tcp_listen_port = 60
+##tcp_listen_port =
 tcp_listen_queue = 5
 tcp_max_per_addr = 1
 ##tcp_client_ports = 1024-65535
@@ -34,4 +30,3 @@
 enable_krb5 = no
 krb5_principal = auditd
 ##krb5_key_file = /etc/audit/audit.key
-distribute_network = no

changed: [default]

TASK [devsec.hardening.os_hardening : create limits.d-directory if it does not exist | sysctl-31a, sysctl-31b] ***
ok: [default]

TASK [devsec.hardening.os_hardening : create additional limits config file -> 10.hardcore.conf | sysctl-31a, sysctl-31b] ***
changed: [default]

TASK [devsec.hardening.os_hardening : set 10.hardcore.conf perms to 0400 and root ownership] ***
--- before
+++ after
@@ -1,5 +1,5 @@
 {
-    "mode": "0644",
+    "mode": "0440",
     "path": "/etc/security/limits.d/10.hardcore.conf",
-    "state": "file"
+    "state": "touch"
 }

changed: [default]

TASK [devsec.hardening.os_hardening : remove 10.hardcore.conf config file] *****
skipping: [default]

TASK [devsec.hardening.os_hardening : create login.defs | os-05, os-05b] *******
--- before: /etc/login.defs
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpracx7jkv/login.defs.j2
@@ -1,307 +1,176 @@
 #
-# /etc/login.defs - Configuration control definitions for the login package.
-#
-# Three items must be defined:  MAIL_DIR, ENV_SUPATH, and ENV_PATH.
-# If unspecified, some arbitrary (and possibly incorrect) value will
-# be assumed.  All other items are optional - if not specified then
-# the described action or option will be inhibited.
-#
-# Comment lines (lines beginning with "#") and blank lines are ignored.
-#
-# Modified for Linux.  --marekm
-
-# REQUIRED for useradd/userdel/usermod
-#   Directory where mailboxes reside, _or_ name of file, relative to the
-#   home directory.  If you _do_ define MAIL_DIR and MAIL_FILE,
-#   MAIL_DIR takes precedence.
-#
-#   Essentially:
-#      - MAIL_DIR defines the location of users mail spool files
-#        (for mbox use) by appending the username to MAIL_DIR as defined
-#        below.
-#      - MAIL_FILE defines the location of the users mail spool files as the
-#        fully-qualified filename obtained by prepending the user home
-#        directory before $MAIL_FILE
-#
-# NOTE: This is no more used for setting up users MAIL environment variable
-#       which is, starting from shadow 4.0.12-1 in Debian, entirely the
-#       job of the pam_mail PAM modules
-#       See default PAM configuration files provided for
-#       login, su, etc.
-#
-# This is a temporary situation: setting these variables will soon
-# move to /etc/default/useradd and the variables will then be
-# no more supported
-MAIL_DIR        /var/mail
-#MAIL_FILE      .mail
-
-#
-# Enable logging and display of /var/log/faillog login failure info.
-# This option conflicts with the pam_tally PAM module.
-#
-FAILLOG_ENAB           yes
-
-#
+# Ansible managed
+#
+
+# Configuration control definitions for the login package.
+#
+# Three items must be defined:  `MAIL_DIR`, `ENV_SUPATH`, and `ENV_PATH`. If unspecified, some arbitrary (and possibly incorrect) value will be assumed.  All other items are optional - if not specified then the described action or option will be inhibited.
+#
+# Comment lines (lines beginning with `#`) and blank lines are ignored.
+#
+#-- Modified for Linux.  --marekm
+
+# *REQUIRED for useradd/userdel/usermod*
+#
+# Directory where mailboxes reside, _or_ name of file, relative to the home directory.  If you _do_ define `MAIL_DIR` and `MAIL_FILE`, `MAIL_DIR` takes precedence.
+# Essentially:
+#
+# * `MAIL_DIR` defines the location of users mail spool files (for mbox use) by appending the username to `MAIL_DIR` as defined below.
+# * `MAIL_FILE` defines the location of the users mail spool files as the fully-qualified filename obtained by prepending the user home directory before `$MAIL_FILE`
+#
+# *NOTE*: This is no more used for setting up users MAIL environment variable which is, starting from shadow 4.0.12-1 in Debian, entirely the job of the pam_mail PAM modules.
+#
+# See default PAM configuration files provided for login, su, etc.
+# This is a temporary situation: setting these variables will soon move to `/etc/default/useradd` and the variables will then be no more supported
+MAIL_DIR          /var/mail
+
+# Enable logging and display of `/var/log/faillog` login failure info. This option conflicts with the `pam_tally` PAM module.
+FAILLOG_ENAB      yes
+
 # Enable display of unknown usernames when login failures are recorded.
 #
-# WARNING: Unknown usernames may become world readable.
-# See #290803 and #298773 for details about how this could become a security
-# concern
-LOG_UNKFAIL_ENAB       no
-
-#
+# *WARNING*: Unknown usernames may become world readable. See #290803 and #298773 for details about how this could become a security concern
+LOG_UNKFAIL_ENAB  no
+
 # Enable logging of successful logins
-#
-LOG_OK_LOGINS          no
-
-#
+LOG_OK_LOGINS     yes
+
 # Enable "syslog" logging of su activity - in addition to sulog file logging.
-# SYSLOG_SG_ENAB does the same for newgrp and sg.
-#
-SYSLOG_SU_ENAB         yes
-SYSLOG_SG_ENAB         yes
-
-#
+SYSLOG_SU_ENAB    yes
+
+# Enable "syslog" logging of newgrp and sg.
+SYSLOG_SG_ENAB    yes
+
 # If defined, all su activity is logged to this file.
-#
-#SULOG_FILE    /var/log/sulog
-
-#
-# If defined, file which maps tty line to TERM environment parameter.
-# Each line of the file is in a format something like "vt100  tty01".
-#
-#TTYTYPE_FILE  /etc/ttytype
-
-#
-# If defined, login failures will be logged here in a utmp format
-# last, when invoked as lastb, will read /var/log/btmp, so...
-#
-FTMP_FILE      /var/log/btmp
-
-#
-# If defined, the command name to display when running "su -".  For
-# example, if this is defined as "su" then a "ps" will display the
-# command is "-su".  If not defined, then "ps" would display the
-# name of the shell actually being run, e.g. something like "-sh".
-#
-SU_NAME                su
-
-#
-# If defined, file which inhibits all the usual chatter during the login
-# sequence.  If a full pathname, then hushed mode will be enabled if the
-# user's name or shell are found in the file.  If not a full pathname, then
-# hushed mode will be enabled if the file exists in the user's home directory.
-#
-HUSHLOGIN_FILE .hushlogin
-#HUSHLOGIN_FILE        /etc/hushlogins
-
-#
-# *REQUIRED*  The default PATH settings, for superuser and normal users.
-#
-# (they are minimal, add the rest in the shell startup files)
-ENV_SUPATH     PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-ENV_PATH       PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
-
-#
+#SULOG_FILE        /var/log/sulog
+
+# If defined, file which maps tty line to `TERM` environment parameter. Each line of the file is in a format something like "vt100  tty01".
+#TTYTYPE_FILE      /etc/ttytype
+
+# If defined, login failures will be logged here in a utmp format last, when invoked as lastb, will read `/var/log/btmp`, so...
+FTMP_FILE         /var/log/btmp
+
+# If defined, the command name to display when running "su -".  For # example, if this is defined as "su" then a "ps" will display the command is "-su".  If not defined, then "ps" would display the name of the shell actually being run, e.g. something like "-sh".
+SU_NAME           su
+
+# If defined, file which inhibits all the usual chatter during the login sequence.  If a full pathname, then hushed mode will be enabled if the user's name or shell are found in the file.  If not a full pathname, then hushed mode will be enabled if the file exists in the user's home directory.
+#HUSHLOGIN_FILE    /etc/hushlogins
+HUSHLOGIN_FILE    .hushlogin
+
+# *REQUIRED*: The default PATH settings, for superuser and normal users. (they are minimal, add the rest in the shell startup files)
+ENV_SUPATH        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+ENV_PATH          PATH=/usr/local/bin:/usr/bin:/bin:
+
 # Terminal permissions
-#
-#      TTYGROUP        Login tty will be assigned this group ownership.
-#      TTYPERM         Login tty will be set to this permission.
-#
-# If you have a "write" program which is "setgid" to a special group
-# which owns the terminals, define TTYGROUP to the group number and
-# TTYPERM to 0620.  Otherwise leave TTYGROUP commented out and assign
-# TTYPERM to either 622 or 600.
-#
-# In Debian /usr/bin/bsd-write or similar programs are setgid tty
-# However, the default and recommended value for TTYPERM is still 0600
-# to not allow anyone to write to anyone else console or terminal
-
-# Users can still allow other people to write them by issuing
-# the "mesg y" command.
-
-TTYGROUP       tty
-TTYPERM                0600
-
-#
-# Login configuration initializations:
-#
-#      ERASECHAR       Terminal ERASE character ('\010' = backspace).
-#      KILLCHAR        Terminal KILL character ('\025' = CTRL/U).
-#      UMASK           Default "umask" value.
-#
-# The ERASECHAR and KILLCHAR are used only on System V machines.
-#
-# UMASK is the default umask value for pam_umask and is used by
-# useradd and newusers to set the mode of the new home directories.
-# 022 is the "historical" value in Debian for UMASK
-# 027, or even 077, could be considered better for privacy
-# There is no One True Answer here : each sysadmin must make up his/her
-# mind.
-#
-# If USERGROUPS_ENAB is set to "yes", that will modify this UMASK default value
-# for private user groups, i. e. the uid is the same as gid, and username is
-# the same as the primary group name: for these, the user permissions will be
-# used as group permissions, e. g. 022 will become 002.
-#
-# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
-#
-ERASECHAR      0177
-KILLCHAR       025
-UMASK          022
-
-#
-# Password aging controls:
-#
-#      PASS_MAX_DAYS   Maximum number of days a password may be used.
-#      PASS_MIN_DAYS   Minimum number of days allowed between password changes.
-#      PASS_WARN_AGE   Number of days warning given before a password expires.
-#
-PASS_MAX_DAYS  99999
-PASS_MIN_DAYS  0
-PASS_WARN_AGE  7
-
-#
+# --------------------
+
+# Login tty will be assigned this group ownership.
+# If you have a "write" program which is "setgid" to a special group which owns the terminals, define `TTYGROUP` to the group number and `TTYPERM` to `0620`.  Otherwise leave `TTYGROUP` commented out and assign `TTYPERM` to either `622` or `600`.
+TTYGROUP          tty
+
+# Login tty will be set to this permission.
+# In Debian `/usr/bin/bsd-write` or similar programs are setgid tty. However, the default and recommended value for `TTYPERM` is still `0600` to not allow anyone to write to anyone else console or terminal
+# Users can still allow other people to write them by issuing the `mesg y` command.
+TTYPERM           0600
+
+# Login conf initializations
+# --------------------------
+
+# Terminal ERASE character ('\010' = backspace). Only used on System V.
+ERASECHAR         0177
+
+# Terminal KILL character ('\025' = CTRL/U). Only used on System V.
+KILLCHAR          025
+
+# The default umask value for `pam_umask` and is used by useradd and newusers to set the mode of the new home directories.
+# If `USERGROUPS_ENAB` is set to `yes`, that will modify this `UMASK` default value for private user groups, i. e. the uid is the same as gid, and username is the same as the primary group name: for these, the user permissions will be used as group permissions, e. g. `022` will become `002`.
+# Prefix these values with `0` to get octal, `0x` to get hexadecimal.
+# `022` is the "historical" value in Debian for UMASK
+# `027`, or even `077`, could be considered better for privacy.
+UMASK             027
+
+# Enable setting of the umask group bits to be the same as owner bits (examples: `022` -> `002`, `077` -> `007`) for non-root users, if the uid is the same as gid, and username is the same as the primary group name.
+# If set to yes, userdel will remove the user´s group if it contains no more members, and useradd will create by default a group with the name of the user.
+USERGROUPS_ENAB   yes
+
+
+# Password aging controls
+# -----------------------
+
+# Maximum number of days a password may be used.
+PASS_MAX_DAYS     60
+
+# Minimum number of days allowed between password changes.
+PASS_MIN_DAYS     7
+
+# Number of days warning given before a password expires.
+PASS_WARN_AGE     7
+
 # Min/max values for automatic uid selection in useradd
-#
-UID_MIN                         1000
-UID_MAX                        60000
+UID_MIN           1000
+UID_MAX           60000
 # System accounts
-#SYS_UID_MIN             100
-#SYS_UID_MAX             999
-
-#
+SYS_UID_MIN       100
+SYS_UID_MAX       999
+
 # Min/max values for automatic gid selection in groupadd
-#
-GID_MIN                         1000
-GID_MAX                        60000
+GID_MIN           1000
+GID_MAX           60000
 # System accounts
-#SYS_GID_MIN             100
-#SYS_GID_MAX             999
-
-#
-# Max number of login retries if password is bad. This will most likely be
-# overriden by PAM, since the default pam_unix module has it's own built
-# in of 3 retries. However, this is a safe fallback in case you are using
-# an authentication module that does not enforce PAM_MAXTRIES.
-#
-LOGIN_RETRIES          5
-
-#
+SYS_GID_MIN       100
+SYS_GID_MAX       999
+
+# Max number of login retries if password is bad. This will most likely be overriden by PAM, since the default pam_unix module has it's own built in of 3 retries. However, this is a safe fallback in case you are using an authentication module that does not enforce PAM_MAXTRIES.
+LOGIN_RETRIES     5
+
 # Max time in seconds for login
-#
-LOGIN_TIMEOUT          60
-
-#
-# Which fields may be changed by regular users using chfn - use
-# any combination of letters "frwh" (full name, room number, work
-# phone, home phone).  If not defined, no changes are allowed.
+LOGIN_TIMEOUT     60
+
+# Which fields may be changed by regular users using chfn - use any combination of letters "frwh" (full name, room number, work phone, home phone).  If not defined, no changes are allowed.
 # For backward compatibility, "yes" = "rwh" and "no" = "frwh".
-#
-CHFN_RESTRICT          rwh
-
-#
 # Should login be allowed if we can't cd to the home directory?
-# Default in no.
-#
-DEFAULT_HOME   yes
-
-#
+DEFAULT_HOME      no
+
 # If defined, this command is run when removing a user.
 # It should remove any at/cron/print jobs etc. owned by
 # the user to be removed (passed as the first argument).
-#
-#USERDEL_CMD   /usr/sbin/userdel_local
-
-#
-# Enable setting of the umask group bits to be the same as owner bits
-# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
-# the same as gid, and username is the same as the primary group name.
-#
-# If set to yes, userdel will remove the user's group if it contains no
-# more members, and useradd will create by default a group with the name
-# of the user.
-#
-USERGROUPS_ENAB yes
-
-#
-# Instead of the real user shell, the program specified by this parameter
-# will be launched, although its visible name (argv[0]) will be the shell's.
-# The program may do whatever it wants (logging, additional authentification,
-# banner, ...) before running the actual shell.
-#
-# FAKE_SHELL /bin/fakeshell
-
-#
-# If defined, either full pathname of a file containing device names or
-# a ":" delimited list of device names.  Root logins will be allowed only
-# upon these devices.
-#
+#USERDEL_CMD       /usr/sbin/userdel_local
+
+# Instead of the real user shell, the program specified by this parameter will be launched, although its visible name (`argv[0]`) will be the shell's. The program may do whatever it wants (logging, additional authentification, banner, ...) before running the actual shell.
+#FAKE_SHELL        /bin/fakeshell
+
+# If defined, either full pathname of a file containing device names or a ":" delimited list of device names.  Root logins will be allowed only upon these devices.
 # This variable is used by login and su.
-#
-#CONSOLE       /etc/consoles
-#CONSOLE       console:tty01:tty02:tty03:tty04
-
-#
-# List of groups to add to the user's supplementary group set
-# when logging in on the console (as determined by the CONSOLE
-# setting).  Default is none.
-#
-# Use with caution - it is possible for users to gain permanent
-# access to these groups, even when not logged in on the console.
-# How to do it is left as an exercise for the reader...
-#
+#CONSOLE           /etc/consoles
+#CONSOLE           console:tty01:tty02:tty03:tty04
+
+# List of groups to add to the user's supplementary group set when logging in on the console (as determined by the `CONSOLE` setting).  Default is none.
+# Use with caution - it is possible for users to gain permanent access to these groups, even when not logged in on the console. How to do it is left as an exercise for the reader...
 # This variable is used by login and su.
-#
-#CONSOLE_GROUPS                floppy:audio:cdrom
-
-#
-# If set to "yes", new passwords will be encrypted using the MD5-based
-# algorithm compatible with the one used by recent releases of FreeBSD.
-# It supports passwords of unlimited length and longer salt strings.
-# Set to "no" if you need to copy encrypted passwords to other systems
-# which don't understand the new algorithm.  Default is "no".
-#
-# This variable is deprecated. You should use ENCRYPT_METHOD.
-#
-#MD5_CRYPT_ENAB        no
-
-#
-# If set to MD5 , MD5-based algorithm will be used for encrypting password
-# If set to SHA256, SHA256-based algorithm will be used for encrypting password
-# If set to SHA512, SHA512-based algorithm will be used for encrypting password
-# If set to DES, DES-based algorithm will be used for encrypting password (default)
+#CONSOLE_GROUPS    floppy:audio:cdrom
+
+# If set to `MD5`, MD5-based algorithm will be used for encrypting password
+# If set to `SHA256`, SHA256-based algorithm will be used for encrypting password
+# If set to `SHA512`, SHA512-based algorithm will be used for encrypting password
+# If set to `DES`, DES-based algorithm will be used for encrypting password (default)
 # Overrides the MD5_CRYPT_ENAB option
 #
 # Note: It is recommended to use a value consistent with
 # the PAM modules configuration.
-#
-ENCRYPT_METHOD SHA512
-
-#
-# Only used if ENCRYPT_METHOD is set to SHA256 or SHA512.
-#
-# Define the number of SHA rounds.
-# With a lot of rounds, it is more difficult to brute forcing the password.
-# But note also that it more CPU resources will be needed to authenticate
-# users.
-#
-# If not specified, the libc will choose the default number of rounds (5000).
-# The values must be inside the 1000-999999999 range.
-# If only one of the MIN or MAX values is set, then this value will be used.
+MD5_CRYPT_ENAB    no
+ENCRYPT_METHOD    SHA512
+
+# Only used if `ENCRYPT_METHOD` is set to `SHA256` or `SHA512`: Define the number of SHA rounds.
+# With a lot of rounds, it is more difficult to brute forcing the password. But note also that it more CPU resources will be needed to authenticate users.
+# If not specified, the libc will choose the default number of rounds (5000). The values must be inside the 1000-999999999 range. If only one of the MIN or MAX values is set, then this value will be used.
 # If MIN > MAX, the highest value will be used.
-#
-# SHA_CRYPT_MIN_ROUNDS 5000
-# SHA_CRYPT_MAX_ROUNDS 5000
-
-################# OBSOLETED BY PAM ##############
-#                                              #
-# These options are now handled by PAM. Please #
-# edit the appropriate file in /etc/pam.d/ to  #
-# enable the equivelants of them.
-#
-###############
-
+#SHA_CRYPT_MIN_ROUNDS    5000
+#SHA_CRYPT_MAX_ROUNDS    5000
+
+
+# Obsoleted by PAM
+# ================
+# These options are now handled by PAM. Please edit the appropriate file in `/etc/pam.d/` to enable the equivelants of them.
 #MOTD_FILE
 #DIALUPS_CHECK_ENAB
 #LASTLOG_ENAB
@@ -323,19 +192,17 @@
 #CHSH_AUTH
 #FAIL_DELAY

-################# OBSOLETED #######################
-#                                                #
-# These options are no more handled by shadow.    #
-#                                                 #
-# Shadow utilities will display a warning if they #
-# still appear.                                   #
-#                                                 #
-###################################################
-
-# CLOSE_SESSIONS
-# LOGIN_STRING
-# NO_PASSWORD_CONSOLE
-# QMAIL_DIR
-
-
-
+# Obsoleted
+# =========
+# These options are no more handled by shadow.
+# Shadow utilities will display a warning if they still appear.
+#CLOSE_SESSIONS
+#LOGIN_STRING
+#NO_PASSWORD_CONSOLE
+#QMAIL_DIR
+
+# If set to `yes`, new passwords will be encrypted using the MD5-based algorithm compatible with the one used by recent releases of FreeBSD. It supports passwords of unlimited length and longer salt strings.
+# Set to `no` if you need to copy encrypted passwords to other systems which don't understand the new algorithm.  Default is `no`.
+# This variable is deprecated. You should use ENCRYPT_METHOD.
+#
+#MD5_CRYPT_ENAB no

changed: [default]

TASK [devsec.hardening.os_hardening : find files with write-permissions for group] ***
ok: [default] => (item=/usr/local/sbin)
ok: [default] => (item=/usr/local/bin)
ok: [default] => (item=/usr/sbin)
ok: [default] => (item=/usr/bin)
ok: [default] => (item=/sbin)
ok: [default] => (item=/bin)

TASK [devsec.hardening.os_hardening : minimize access on found files] **********

TASK [devsec.hardening.os_hardening : change shadow ownership to root and mode to 0600 | os-02] ***
ok: [default]

TASK [devsec.hardening.os_hardening : change passwd ownership to root and mode to 0644 | os-03] ***
ok: [default]

TASK [devsec.hardening.os_hardening : change su-binary to only be accessible to user and group root] ***
--- before
+++ after
@@ -1,4 +1,4 @@
 {
-    "mode": "04755",
+    "mode": "0750",
     "path": "/bin/su"
 }

changed: [default]

TASK [devsec.hardening.os_hardening : set option hidepid for proc filesystem] ***
changed: [default]

TASK [devsec.hardening.os_hardening : update pam on Debian systems] ************
ok: [default]

TASK [devsec.hardening.os_hardening : remove pam ccreds to disable password caching] ***
ok: [default]

TASK [devsec.hardening.os_hardening : remove pam_cracklib, because it does not play nice with passwdqc] ***
ok: [default]

TASK [devsec.hardening.os_hardening : install the package for strong password checking] ***
The following additional packages will be installed:
  libpasswdqc0 passwdqc
The following NEW packages will be installed:
  libpam-passwdqc libpasswdqc0 passwdqc
0 upgraded, 3 newly installed, 0 to remove and 3 not upgraded.
changed: [default]

TASK [devsec.hardening.os_hardening : configure passwdqc] **********************
--- before: /usr/share/pam-configs/passwdqc
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmp4ndshk0b/pam_passwdqd.j2
@@ -1,7 +1,11 @@
+#
+# Ansible managed
+#
+
 Name: passwdqc password strength enforcement
 Default: yes
 Priority: 1024
 Conflicts: cracklib
 Password-Type: Primary
 Password:
-       requisite                       pam_passwdqc.so
+  requisite     pam_passwdqc.so min=disabled,disabled,16,12,8

changed: [default]

TASK [devsec.hardening.os_hardening : remove passwdqc] *************************
skipping: [default]

TASK [devsec.hardening.os_hardening : install tally2] **************************
skipping: [default]

TASK [devsec.hardening.os_hardening : configure tally2] ************************
skipping: [default]

TASK [devsec.hardening.os_hardening : delete tally2 when retries is 0] *********
skipping: [default]

TASK [devsec.hardening.os_hardening : remove pam_cracklib, because it does not play nice with passwdqc] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : install the package for strong password checking] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : remove passwdqc] *************************
skipping: [default]

TASK [devsec.hardening.os_hardening : configure passwdqc and tally via central system-auth confic] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : Gather package facts] ********************
ok: [default]

TASK [devsec.hardening.os_hardening : NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : install modprobe to disable filesystems | os-10] ***
ok: [default]

TASK [devsec.hardening.os_hardening : check if efi is installed] ***************
ok: [default]

TASK [devsec.hardening.os_hardening : remove vfat from fs-list if efi is used] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : remove used filesystems from fs-list] ****
ok: [default]

TASK [devsec.hardening.os_hardening : disable unused filesystems | os-10] ******
--- before
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmputq_jwz0/modprobe.j2
@@ -0,0 +1,15 @@
+#
+# Ansible managed
+#
+
+install cramfs /bin/true
+install freevxfs /bin/true
+install jffs2 /bin/true
+install hfs /bin/true
+install hfsplus /bin/true
+install udf /bin/true
+install vfat /bin/true
+install tipc /bin/true
+install sctp /bin/true
+install dccp /bin/true
+install rds /bin/true

changed: [default]

TASK [devsec.hardening.os_hardening : add pinerolo_profile.sh to profile.d] ****
--- before
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpbgtr5nr4/profile.conf.j2
@@ -0,0 +1,6 @@
+#
+# Ansible managed
+#
+
+# Disable core dumps via soft limits for all users. Compliance to this setting is voluntary and can be modified by users up to a hard limit. This setting is a sane default.
+ulimit -S -c 0 > /dev/null 2>&1

changed: [default]

TASK [devsec.hardening.os_hardening : remove pinerolo_profile.sh from profile.d] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : create securetty] ************************
--- before
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpfvwh097x/securetty.j2
@@ -0,0 +1,13 @@
+#
+# Ansible managed
+#
+
+# A list of TTYs, from which root can log in
+# see `man securetty` for reference
+console
+tty1
+tty2
+tty3
+tty4
+tty5
+tty6

changed: [default]

TASK [devsec.hardening.os_hardening : remove suid/sgid bit from binaries in blacklist | os-06] ***
ok: [default] => (item=/usr/bin/rcp)
ok: [default] => (item=/usr/bin/rlogin)
ok: [default] => (item=/usr/bin/rsh)
ok: [default] => (item=/usr/libexec/openssh/ssh-keysign)
--- before
+++ after
@@ -1,4 +1,4 @@
 {
-    "mode": "04755",
+    "mode": "0755",
     "path": "/usr/lib/openssh/ssh-keysign"
 }

changed: [default] => (item=/usr/lib/openssh/ssh-keysign)
ok: [default] => (item=/sbin/netreport)
ok: [default] => (item=/usr/sbin/usernetctl)
ok: [default] => (item=/usr/sbin/userisdnctl)
ok: [default] => (item=/usr/sbin/pppd)
ok: [default] => (item=/usr/bin/lockfile)
ok: [default] => (item=/usr/bin/mail-lock)
ok: [default] => (item=/usr/bin/mail-unlock)
ok: [default] => (item=/usr/bin/mail-touchlock)
ok: [default] => (item=/usr/bin/dotlockfile)
ok: [default] => (item=/usr/bin/arping)
ok: [default] => (item=/usr/sbin/uuidd)
ok: [default] => (item=/usr/bin/mtr)
ok: [default] => (item=/usr/lib/evolution/camel-lock-helper-1.2)
ok: [default] => (item=/usr/lib/pt_chown)
--- before
+++ after
@@ -1,4 +1,4 @@
 {
-    "mode": "04755",
+    "mode": "0755",
     "path": "/usr/lib/eject/dmcrypt-get-device"
 }

changed: [default] => (item=/usr/lib/eject/dmcrypt-get-device)
ok: [default] => (item=/usr/lib/mc/cons.saver)

TASK [devsec.hardening.os_hardening : find binaries with suid/sgid set | os-06] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : gather files from which to remove suids/sgids and remove system white-listed files | os-06] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : remove suid/sgid bit from all binaries except in system and user whitelist | os-06] ***

TASK [devsec.hardening.os_hardening : protect sysctl.conf] *********************
--- before
+++ after
@@ -1,5 +1,5 @@
 {
-    "mode": "0644",
+    "mode": "0440",
     "path": "/etc/sysctl.conf",
-    "state": "file"
+    "state": "touch"
 }

changed: [default]

TASK [devsec.hardening.os_hardening : set Daemon umask, do config for rhel-family | NSA 2.2.4.1] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : install initramfs-tools] *****************
ok: [default]

TASK [devsec.hardening.os_hardening : rebuild initramfs with starting pack of modules, if module loading at runtime is disabled] ***
--- before: /etc/initramfs-tools/modules
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpyqzwoznb/modules.j2
@@ -1,11 +1,95 @@
-# List of modules that you want to include in your initramfs.
-# They will be loaded at boot time in the order below.
 #
-# Syntax:  module_name [args ...]
+# Ansible managed
 #
-# You must run update-initramfs(8) to effect this change.
+
+# This file contains the names of kernel modules that should be loaded at boot time, one per line. Lines beginning with "#" are ignored.
 #
-# Examples:
+# A list of all available kernel modules kann be found with `find /lib/modules/$(uname -r)/kernel/`
+# We will sort by folder.
+
+
+# Arch
+# ----
 #
-# raid1
-# sd_mod
+# Modules for certains builds, contains support modules and some CPU-specific optimizations.
+
+# Optimize for x86_64 cryptographic features
+twofish-x86_64-3way
+twofish-x86_64
+aes-x86_64
+salsa20-x86_64
+blowfish-x86_64
+
+# Intel-specific optimizations
+ghash-clmulni-intel
+aesni-intel
+kvm-intel
+
+kvm
+
+# Crypto
+# ------
+
+# Some core modules which comprise strong cryptography.
+blowfish_common
+blowfish_generic
+ctr
+cts
+lrw
+lzo
+rmd160
+rmd256
+rmd320
+serpent
+sha512_generic
+twofish_common
+twofish_generic
+xts
+zlib
+
+
+# Drivers
+# -------
+
+# Basics
+lp
+rtc
+loop
+
+# Filesystems
+ext2
+btrfs
+
+
+# Lib
+# ---
+xz
+
+
+# Net
+# ---
+
+# All packets needed for netfilter rules (ie iptables, ebtables).
+ip_tables
+x_tables
+iptable_filter
+iptable_nat
+
+# Targets
+ipt_LOG
+ipt_REJECT
+
+# Modules
+xt_connlimit
+xt_tcpudp
+xt_recent
+xt_limit
+xt_conntrack
+nf_conntrack
+nf_conntrack_ipv4
+nf_defrag_ipv4
+xt_state
+nf_nat
+
+# Addons
+xt_pknock

changed: [default]

TASK [devsec.hardening.os_hardening : create a combined sysctl-dict if overwrites are defined] ***
ok: [default]

TASK [devsec.hardening.os_hardening : Change various sysctl-settings, look at the sysctl-vars file for documentation] ***
changed: [default] => (item={'key': 'net.ipv4.ip_forward', 'value': 1})
changed: [default] => (item={'key': 'net.ipv6.conf.all.forwarding', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.all.accept_ra', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.accept_ra', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.all.rp_filter', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.conf.default.rp_filter', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.icmp_echo_ignore_broadcasts', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.icmp_ignore_bogus_error_responses', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.icmp_ratelimit', 'value': 100})
changed: [default] => (item={'key': 'net.ipv4.icmp_ratemask', 'value': 88089})
changed: [default] => (item={'key': 'net.ipv6.conf.all.disable_ipv6', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.tcp_timestamps', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.all.arp_ignore', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.conf.all.arp_announce', 'value': 2})
changed: [default] => (item={'key': 'net.ipv4.tcp_rfc1337', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.conf.all.shared_media', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.conf.default.shared_media', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.conf.all.accept_source_route', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.default.accept_source_route', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.default.accept_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.all.accept_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.all.secure_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.default.secure_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.accept_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.all.accept_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.all.send_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.default.send_redirects', 'value': 0})
changed: [default] => (item={'key': 'net.ipv4.conf.all.log_martians', 'value': 1})
changed: [default] => (item={'key': 'net.ipv4.conf.default.log_martians', 'value': 1})
changed: [default] => (item={'key': 'net.ipv6.conf.default.router_solicitations', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.accept_ra_rtr_pref', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.accept_ra_pinfo', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.accept_ra_defrtr', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.autoconf', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.dad_transmits', 'value': 0})
changed: [default] => (item={'key': 'net.ipv6.conf.default.max_addresses', 'value': 1})
changed: [default] => (item={'key': 'kernel.sysrq', 'value': 0})
changed: [default] => (item={'key': 'fs.suid_dumpable', 'value': 0})
changed: [default] => (item={'key': 'kernel.randomize_va_space', 'value': 2})
changed: [default] => (item={'key': 'kernel.core_uses_pid', 'value': 1})
changed: [default] => (item={'key': 'kernel.yama.ptrace_scope', 'value': 1})
changed: [default] => (item={'key': 'vm.mmap_min_addr', 'value': 65536})
changed: [default] => (item={'key': 'fs.protected_hardlinks', 'value': 1})
changed: [default] => (item={'key': 'fs.protected_symlinks', 'value': 1})
changed: [default] => (item={'key': 'vm.mmap_rnd_bits', 'value': 32})
changed: [default] => (item={'key': 'vm.mmap_rnd_compat_bits', 'value': 16})
changed: [default] => (item={'key': 'kernel.kptr_restrict', 'value': 2})
changed: [default] => (item={'key': 'kernel.kexec_load_disabled', 'value': 1})

TASK [devsec.hardening.os_hardening : Change various sysctl-settings on rhel6-hosts or older, look at the sysctl-vars file for documentation] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : Apply ufw defaults] **********************
--- before: /etc/default/ufw
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpjo6mjbdg/ufw.j2
@@ -1,10 +1,14 @@
+#
+# Ansible managed
+#
+
 # /etc/default/ufw
 #

 # Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
 # accepted). You will need to 'disable' and then 'enable' the firewall for
 # the changes to take affect.
-IPV6=yes
+IPV6=no

 # Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
 # you change this you will most likely want to adjust your rules.
@@ -26,22 +30,19 @@
 # By default, ufw only touches its own chains. Set this to 'yes' to have ufw
 # manage the built-in chains too. Warning: setting this to 'yes' will break
 # non-ufw managed firewall rules
-MANAGE_BUILTINS=no
+MANAGE_BUILTINS="no"

 #
 # IPT backend
 #
-# only enable if using iptables backend
-IPT_SYSCTL=/etc/ufw/sysctl.conf
+# only enable if using iptables backend and want to overwrite /etc/sysctl.conf
+#IPT_SYSCTL=

-# Extra connection tracking modules to load. IPT_MODULES should typically be
-# empty for new installations and modules added only as needed. See
-# 'CONNECTION HELPERS' from 'man ufw-framework' for details. Complete list can
-# be found in net/netfilter/Kconfig of your kernel source. Some common modules:
+# Extra connection tracking modules to load. Complete list can be found in
+# net/netfilter/Kconfig of your kernel source. Some common modules:
 # nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support
 # nf_conntrack_netbios_ns: NetBIOS (samba) client support
 # nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT
 # nf_conntrack_ftp, nf_nat_ftp: active FTP support
 # nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side)
-# nf_conntrack_sane: sane support
-IPT_MODULES=""
+IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns"

changed: [default]

TASK [devsec.hardening.os_hardening : get UID_MIN from login.defs] *************
ok: [default]

TASK [devsec.hardening.os_hardening : calculate UID_MAX from UID_MIN by substracting 1] ***
ok: [default]

TASK [devsec.hardening.os_hardening : set UID_MAX on Debian-systems if no login.defs exist] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : set UID_MAX on other systems if no login.defs exist] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : get all system accounts] *****************
ok: [default]

TASK [devsec.hardening.os_hardening : remove always ignored system accounts from list] ***
ok: [default]

TASK [devsec.hardening.os_hardening : change system accounts not on the user provided ignore-list] ***
ok: [default] => (item=daemon)
ok: [default] => (item=bin)
ok: [default] => (item=sys)
ok: [default] => (item=games)
ok: [default] => (item=man)
ok: [default] => (item=lp)
ok: [default] => (item=mail)
ok: [default] => (item=news)
ok: [default] => (item=uucp)
ok: [default] => (item=proxy)
ok: [default] => (item=www-data)
ok: [default] => (item=backup)
ok: [default] => (item=list)
ok: [default] => (item=irc)
ok: [default] => (item=gnats)
ok: [default] => (item=systemd-network)
ok: [default] => (item=systemd-resolve)
ok: [default] => (item=systemd-timesync)
ok: [default] => (item=messagebus)
ok: [default] => (item=syslog)
ok: [default] => (item=_apt)
changed: [default] => (item=tss)
ok: [default] => (item=uuidd)
ok: [default] => (item=tcpdump)
ok: [default] => (item=sshd)
ok: [default] => (item=landscape)
changed: [default] => (item=pollinate)
changed: [default] => (item=systemd-coredump)
changed: [default] => (item=lxd)

TASK [devsec.hardening.os_hardening : Get user accounts | os-09] ***************
ok: [default]

TASK [devsec.hardening.os_hardening : delete rhosts-files from system | os-09] ***
ok: [default] => (item=root)
ok: [default] => (item=daemon)
ok: [default] => (item=bin)
ok: [default] => (item=sys)
ok: [default] => (item=sync)
ok: [default] => (item=games)
ok: [default] => (item=man)
ok: [default] => (item=lp)
ok: [default] => (item=mail)
ok: [default] => (item=news)
ok: [default] => (item=uucp)
ok: [default] => (item=proxy)
ok: [default] => (item=www-data)
ok: [default] => (item=backup)
ok: [default] => (item=list)
ok: [default] => (item=irc)
ok: [default] => (item=gnats)
ok: [default] => (item=nobody)
ok: [default] => (item=systemd-network)
ok: [default] => (item=systemd-resolve)
ok: [default] => (item=systemd-timesync)
ok: [default] => (item=messagebus)
ok: [default] => (item=syslog)
ok: [default] => (item=_apt)
ok: [default] => (item=tss)
ok: [default] => (item=uuidd)
ok: [default] => (item=tcpdump)
ok: [default] => (item=sshd)
ok: [default] => (item=landscape)
ok: [default] => (item=pollinate)
ok: [default] => (item=vagrant)
ok: [default] => (item=systemd-coredump)
ok: [default] => (item=ubuntu)
ok: [default] => (item=lxd)

TASK [devsec.hardening.os_hardening : delete hosts.equiv from system | os-01] ***
ok: [default]

TASK [devsec.hardening.os_hardening : delete .netrc-files from system | os-09] ***
ok: [default] => (item=root)
ok: [default] => (item=daemon)
ok: [default] => (item=bin)
ok: [default] => (item=sys)
ok: [default] => (item=sync)
ok: [default] => (item=games)
ok: [default] => (item=man)
ok: [default] => (item=lp)
ok: [default] => (item=mail)
ok: [default] => (item=news)
ok: [default] => (item=uucp)
ok: [default] => (item=proxy)
ok: [default] => (item=www-data)
ok: [default] => (item=backup)
ok: [default] => (item=list)
ok: [default] => (item=irc)
ok: [default] => (item=gnats)
ok: [default] => (item=nobody)
ok: [default] => (item=systemd-network)
ok: [default] => (item=systemd-resolve)
ok: [default] => (item=systemd-timesync)
ok: [default] => (item=messagebus)
ok: [default] => (item=syslog)
ok: [default] => (item=_apt)
ok: [default] => (item=tss)
ok: [default] => (item=uuidd)
ok: [default] => (item=tcpdump)
ok: [default] => (item=sshd)
ok: [default] => (item=landscape)
ok: [default] => (item=pollinate)
ok: [default] => (item=vagrant)
ok: [default] => (item=systemd-coredump)
ok: [default] => (item=ubuntu)
ok: [default] => (item=lxd)

TASK [devsec.hardening.os_hardening : remove unused repositories] **************
skipping: [default] => (item=CentOS-Debuginfo)
skipping: [default] => (item=CentOS-Media)
skipping: [default] => (item=CentOS-Vault)

TASK [devsec.hardening.os_hardening : get yum-repository-files] ****************
skipping: [default]

TASK [devsec.hardening.os_hardening : activate gpg-check for yum-repository-files] ***

TASK [devsec.hardening.os_hardening : activate gpg-check for config files] *****
skipping: [default] => (item=/etc/yum.conf)
skipping: [default] => (item=/etc/dnf/dnf.conf)
skipping: [default] => (item=/etc/yum/pluginconf.d/rhnplugin.conf)

TASK [devsec.hardening.os_hardening : remove deprecated or insecure packages | package-01 - package-09] ***
skipping: [default]

TASK [devsec.hardening.os_hardening : remove deprecated or insecure packages | package-01 - package-09] ***
ok: [default]

TASK [devsec.hardening.os_hardening : configure selinux | selinux-01] **********
skipping: [default]

TASK [devsec.hardening.ssh_hardening : include_tasks] **************************
included: /Users/zyun/.ansible/collections/ansible_collections/devsec/hardening/roles/ssh_hardening/tasks/hardening.yml for default

TASK [devsec.hardening.ssh_hardening : set OS dependent variables] *************
ok: [default] => (item=/Users/zyun/.ansible/collections/ansible_collections/devsec/hardening/roles/ssh_hardening/vars/Debian.yml)

TASK [devsec.hardening.ssh_hardening : get openssh-version] ********************
ok: [default]

TASK [devsec.hardening.ssh_hardening : parse openssh-version] ******************
ok: [default]

TASK [devsec.hardening.ssh_hardening : set default for ssh_host_key_files if not supplied] ***
included: /Users/zyun/.ansible/collections/ansible_collections/devsec/hardening/roles/ssh_hardening/tasks/crypto_hostkeys.yml for default

TASK [devsec.hardening.ssh_hardening : set hostkeys according to openssh-version if openssh >= 5.3] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set hostkeys according to openssh-version if openssh >= 6.0] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set hostkeys according to openssh-version if openssh >= 6.3] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set default for ssh_macs if not supplied] ***
included: /Users/zyun/.ansible/collections/ansible_collections/devsec/hardening/roles/ssh_hardening/tasks/crypto_macs.yml for default

TASK [devsec.hardening.ssh_hardening : set macs according to openssh-version if openssh >= 5.3] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set macs for Enterprise Linux >= 6.5 (openssh 5.3 with backports)] ***
skipping: [default]

TASK [devsec.hardening.ssh_hardening : set macs according to openssh-version if openssh >= 5.9] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set macs according to openssh-version if openssh >= 6.6] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set macs according to openssh-version if openssh >= 7.6] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set default for ssh_ciphers if not supplied] ***
included: /Users/zyun/.ansible/collections/ansible_collections/devsec/hardening/roles/ssh_hardening/tasks/crypto_ciphers.yml for default

TASK [devsec.hardening.ssh_hardening : set ciphers according to openssh-version if openssh >= 5.3] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set ciphers according to openssh-version if openssh >= 6.6] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set default for ssh_kex if not supplied] ***
included: /Users/zyun/.ansible/collections/ansible_collections/devsec/hardening/roles/ssh_hardening/tasks/crypto_kex.yml for default

TASK [devsec.hardening.ssh_hardening : set kex according to openssh-version if openssh >= 5.9] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set kex according to openssh-version if openssh >= 6.6] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : set kex according to openssh-version if openssh >= 8.0] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : create revoked_keys and set permissions to root/600] ***
--- before
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpbgjsebxg/revoked_keys.j2
@@ -0,0 +1,4 @@
+#
+# Ansible managed
+#
+

changed: [default]

TASK [devsec.hardening.ssh_hardening : create sshd_config and set permissions to root/600] ***
--- before: /etc/ssh/sshd_config
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpphj31r13/opensshd.conf.j2
@@ -1,123 +1,173 @@
-#      $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
+#
+# Ansible managed
+#

-# This is the sshd server system-wide configuration file.  See
-# sshd_config(5) for more information.
+# This is the ssh client system-wide configuration file.
+# See sshd_config(5) for more information on any settings used. Comments will be added only to clarify why a configuration was chosen.

-# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin

-# The strategy used for options in the default sshd_config shipped with
-# OpenSSH is to specify options with their default value where
-# possible, but leave them commented.  Uncommented options override the
-# default value.
+# Basic configuration
+# ===================

-Include /etc/ssh/sshd_config.d/*.conf
+# Either disable or only allow root login via certificates.
+PermitRootLogin no

-#Port 22
-#AddressFamily any
-#ListenAddress 0.0.0.0
-#ListenAddress ::
+# Define which port sshd should listen to. Default to `22`.
+Port 22

-#HostKey /etc/ssh/ssh_host_rsa_key
-#HostKey /etc/ssh/ssh_host_ecdsa_key
-#HostKey /etc/ssh/ssh_host_ed25519_key
+# Address family should always be limited to the active network configuration.
+AddressFamily inet

-# Ciphers and keying
-#RekeyLimit default none
+# Define which addresses sshd should listen to. Default to `0.0.0.0`, ie make sure you put your desired address in here, since otherwise sshd will listen to everyone.
+ListenAddress 0.0.0.0

-# Logging
-#SyslogFacility AUTH
-#LogLevel INFO
+# List HostKeys here.
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key

-# Authentication:
+# Specifies the host key algorithms that the server offers.
+#
+# HostKeyAlgorithms
+#

-#LoginGraceTime 2m
-#PermitRootLogin prohibit-password
-#StrictModes yes
-#MaxAuthTries 6
-#MaxSessions 10
+# Security configuration
+# ======================

-#PubkeyAuthentication yes
+# Set the protocol version to 2 for security reasons. Disables legacy support.
+Protocol 2

-# Expect .ssh/authorized_keys2 to be disregarded by default in future.
-#AuthorizedKeysFile    .ssh/authorized_keys .ssh/authorized_keys2
+# Make sure sshd checks file modes and ownership before accepting logins. This prevents accidental misconfiguration.
+StrictModes yes

-#AuthorizedPrincipalsFile none
+# Logging, obsoletes QuietMode and FascistLogging
+SyslogFacility AUTH
+LogLevel VERBOSE

-#AuthorizedKeysCommand none
-#AuthorizedKeysCommandUser nobody
+# Cryptography
+# ------------

-# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
-#HostbasedAuthentication no
-# Change to yes if you don't trust ~/.ssh/known_hosts for
-# HostbasedAuthentication
-#IgnoreUserKnownHosts no
-# Don't read the user's ~/.rhosts and ~/.shosts files
-#IgnoreRhosts yes
+# **Ciphers** -- If your clients don't support CTR (eg older versions), cbc will be added
+# CBC: is true if you want to connect with OpenSSL-base libraries
+# eg ruby Net::SSH::Transport::CipherFactory requires cbc-versions of the given openssh ciphers to work
+# -- see: (http://net-ssh.github.com/net-ssh/classes/Net/SSH/Transport/CipherFactory.html)
+#

-# To disable tunneled clear text passwords, change to no here!
+Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
+
+# **Hash algorithms** -- Make sure not to use SHA1 for hashing, unless it is really necessary.
+# Weak HMAC is sometimes required if older package versions are used
+# eg Ruby's Net::SSH at around 2.2.* doesn't support sha2 for hmac, so this will have to be set true in this case.
+#
+
+MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
+
+# Alternative setting, if OpenSSH version is below v5.9
+#MACs hmac-ripemd160
+
+# **Key Exchange Algorithms** -- Make sure not to use SHA1 for kex, unless it is really necessary
+# Weak kex is sometimes required if older package versions are used
+# eg ruby's Net::SSH at around 2.2.* doesn't support sha2 for kex, so this will have to be set true in this case.
+# based on: https://bettercrypto.org/static/applied-crypto-hardening.pdf
+
+KexAlgorithms sntrup4591761x25519-sha512@tinyssh.org,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
+
+# Authentication
+# --------------
+
+# Secure Login directives.
+
+LoginGraceTime 30s
+MaxAuthTries 2
+MaxSessions 10
+MaxStartups 10:30:100
+
+# Enable public key authentication
+PubkeyAuthentication yes
+
+# Never use host-based authentication. It can be exploited.
+IgnoreRhosts yes
+IgnoreUserKnownHosts yes
+HostbasedAuthentication no
+
+# Enable PAM to enforce system wide rules
+UsePAM yes
+
+# Set AuthenticationMethods per default to publickey
+# AuthenticationMethods was introduced in OpenSSH 6.2 - https://www.openssh.com/txt/release-6.2
+AuthenticationMethods publickey
+
+# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
 PasswordAuthentication no
-#PermitEmptyPasswords no
-
-# Change to yes to enable challenge-response passwords (beware issues with
-# some PAM modules and threads)
+PermitEmptyPasswords no
 ChallengeResponseAuthentication no

-# Kerberos options
-#KerberosAuthentication no
-#KerberosOrLocalPasswd yes
-#KerberosTicketCleanup yes
+# Only enable Kerberos authentication if it is configured.
+KerberosAuthentication no
+KerberosOrLocalPasswd no
+KerberosTicketCleanup yes
 #KerberosGetAFSToken no

-# GSSAPI options
-#GSSAPIAuthentication no
-#GSSAPICleanupCredentials yes
-#GSSAPIStrictAcceptorCheck yes
-#GSSAPIKeyExchange no
+# Only enable GSSAPI authentication if it is configured.
+GSSAPIAuthentication no
+GSSAPICleanupCredentials yes

-# Set this to 'yes' to enable PAM authentication, account processing,
-# and session processing. If this is enabled, PAM authentication will
-# be allowed through the ChallengeResponseAuthentication and
-# PasswordAuthentication.  Depending on your PAM configuration,
-# PAM authentication via ChallengeResponseAuthentication may bypass
-# the setting of "PermitRootLogin without-password".
-# If you just want the PAM account and session checks to run without
-# PAM authentication, then enable this but set PasswordAuthentication
-# and ChallengeResponseAuthentication to 'no'.
-UsePAM yes
+# In case you don't use PAM (`UsePAM no`), you can alternatively restrict users and groups here. For key-based authentication this is not necessary, since all keys must be explicitely enabled.

-#AllowAgentForwarding yes
-#AllowTcpForwarding yes
-#GatewayPorts no
-X11Forwarding yes
-#X11DisplayOffset 10
-#X11UseLocalhost yes
-#PermitTTY yes
+
+
+
+
+
+# Network
+# -------
+
+# Disable TCP keep alive since it is spoofable. Use ClientAlive messages instead, they use the encrypted channel
+TCPKeepAlive no
+
+# Manage `ClientAlive..` signals via interval and maximum count. This will periodically check up to a `..CountMax` number of times within `..Interval` timeframe, and abort the connection once these fail.
+ClientAliveInterval 300
+ClientAliveCountMax 3
+
+# Disable tunneling
+PermitTunnel no
+
+# Disable forwarding tcp connections.
+# no real advantage without denied shell access
+AllowTcpForwarding no
+
+# Disable agent forwarding, since local agent could be accessed through forwarded connection.
+# no real advantage without denied shell access
+AllowAgentForwarding no
+
+# Do not allow remote port forwardings to bind to non-loopback addresses.
+GatewayPorts no
+
+# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
+X11Forwarding no
+X11UseLocalhost yes
+
+# User environment configuration
+# ==============================
+
+PermitUserEnvironment no
+
+
+# Misc. configuration
+# ===================
+
+Compression no
+
+UseDNS no
+
 PrintMotd no
-#PrintLastLog yes
-#TCPKeepAlive yes
-#PermitUserEnvironment no
-#Compression delayed
-#ClientAliveInterval 0
-#ClientAliveCountMax 3
-#UseDNS no
-#PidFile /var/run/sshd.pid
-#MaxStartups 10:30:100
-#PermitTunnel no
-#ChrootDirectory none
-#VersionAddendum none

-# no default banner path
-#Banner none
+PrintLastLog no

-# Allow client to pass locale environment variables
-AcceptEnv LANG LC_*
+Banner none

-# override default of no subsystems
-Subsystem      sftp    /usr/lib/openssh/sftp-server
+DebianBanner no

-# Example of overriding settings on a per-user basis
-#Match User anoncvs
-#      X11Forwarding no
-#      AllowTcpForwarding no
-#      PermitTTY no
-#      ForceCommand cvs server
+# Reject keys that are explicitly blacklisted
+RevokedKeys /etc/ssh/revoked_keys
+

changed: [default]

TASK [devsec.hardening.ssh_hardening : disable dynamic MOTD] *******************
changed: [default]

TASK [devsec.hardening.ssh_hardening : create ssh_config and set permissions to root/644] ***
--- before: /etc/ssh/ssh_config
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmp1ymv_ayi/openssh.conf.j2
@@ -1,52 +1,99 @@
+#
+# Ansible managed
+#

-# This is the ssh client system-wide configuration file.  See
-# ssh_config(5) for more information.  This file provides defaults for
-# users, and the values can be changed in per-user configuration files
-# or on the command line.
+# This is the ssh client system-wide configuration file.
+# See ssh_config(5) for more information on any settings used. Comments will be added only to clarify why a configuration was chosen.

-# Configuration data is parsed as follows:
-#  1. command line options
-#  2. user-specific file
-#  3. system-wide file
-# Any configuration value is only changed the first time it is set.
-# Thus, host-specific definitions should be at the beginning of the
-# configuration file, and defaults at the end.

-# Site-wide defaults for some commonly used options.  For a comprehensive
-# list of available options, their meanings and defaults, please see the
-# ssh_config(5) man page.
+# Basic configuration
+# ===================

-Include /etc/ssh/ssh_config.d/*.conf
+# Address family should always be limited to the active network configuration.
+AddressFamily inet

+
+# Global defaults for all Hosts
 Host *
-#   ForwardAgent no
-#   ForwardX11 no
-#   ForwardX11Trusted yes
-#   PasswordAuthentication yes
-#   HostbasedAuthentication no
-#   GSSAPIAuthentication no
-#   GSSAPIDelegateCredentials no
-#   GSSAPIKeyExchange no
-#   GSSAPITrustDNS no
-#   BatchMode no
-#   CheckHostIP yes
-#   AddressFamily any
-#   ConnectTimeout 0
-#   StrictHostKeyChecking ask
-#   IdentityFile ~/.ssh/id_rsa
-#   IdentityFile ~/.ssh/id_dsa
-#   IdentityFile ~/.ssh/id_ecdsa
-#   IdentityFile ~/.ssh/id_ed25519
-#   Port 22
-#   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc
-#   MACs hmac-md5,hmac-sha1,umac-64@openssh.com
-#   EscapeChar ~
-#   Tunnel no
-#   TunnelDevice any:any
-#   PermitLocalCommand no
-#   VisualHostKey no
-#   ProxyCommand ssh -q -W %h:%p gateway.example.com
-#   RekeyLimit 1G 1h
-    SendEnv LANG LC_*
-    HashKnownHosts yes
-    GSSAPIAuthentication yes
+
+# The port at the destination should be defined
+Port 22
+
+# Identity file configuration. You may restrict available identity files. Otherwise ssh will search for a pattern and use any that matches.
+#IdentityFile ~/.ssh/identity
+#IdentityFile ~/.ssh/id_rsa
+#IdentityFile ~/.ssh/id_dsa
+
+
+# Security configuration
+# ======================
+
+# Set the protocol version to 2 for security reasons. Disables legacy support.
+Protocol 2
+
+# Make sure passphrase querying is enabled
+BatchMode no
+
+# Prevent IP spoofing by checking to host IP against the `known_hosts` file.
+CheckHostIP yes
+
+# Always ask before adding keys to the `known_hosts` file. Do not set to `yes`.
+StrictHostKeyChecking ask
+
+
+# **Ciphers** -- If your clients don't support CTR (eg older versions), cbc will be added
+# CBC: is true if you want to connect with OpenSSL-base libraries
+# eg ruby Net::SSH::Transport::CipherFactory requires cbc-versions of the given openssh ciphers to work
+# -- see: (http://net-ssh.github.com/net-ssh/classes/Net/SSH/Transport/CipherFactory.html)
+#
+
+Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
+
+# **Hash algorithms** -- Make sure not to use SHA1 for hashing, unless it is really necessary.
+# Weak HMAC is sometimes required if older package versions are used
+# eg Ruby's Net::SSH at around 2.2.* doesn't support sha2 for hmac, so this will have to be set true in this case.
+#
+
+MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
+
+# Alternative setting, if OpenSSH version is below v5.9
+#MACs hmac-ripemd160
+
+# **Key Exchange Algorithms** -- Make sure not to use SHA1 for kex, unless it is really necessary
+# Weak kex is sometimes required if older package versions are used
+# eg ruby's Net::SSH at around 2.2.* doesn't support sha2 for kex, so this will have to be set true in this case.
+# based on: https://bettercrypto.org/static/applied-crypto-hardening.pdf
+
+KexAlgorithms sntrup4591761x25519-sha512@tinyssh.org,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
+
+# Disable agent forwarding, since local agent could be accessed through forwarded connection.
+ForwardAgent no
+
+# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
+ForwardX11 no
+
+# Never use host-based authentication. It can be exploited.
+HostbasedAuthentication no
+
+# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
+PasswordAuthentication no
+
+# Only use GSSAPIAuthentication if implemented on the network.
+GSSAPIAuthentication no
+GSSAPIDelegateCredentials no
+
+# Disable tunneling
+Tunnel no
+
+# Disable local command execution.
+PermitLocalCommand no
+
+
+# Misc. configuration
+# ===================
+
+Compression no
+
+#EscapeChar ~
+#VisualHostKey yes
+

changed: [default]

TASK [devsec.hardening.ssh_hardening : check if /etc/ssh/moduli contains weak DH parameters] ***
ok: [default]

TASK [devsec.hardening.ssh_hardening : remove all small primes] ****************
changed: [default]

TASK [devsec.hardening.ssh_hardening : include tasks to setup ca keys and principals] ***
skipping: [default]

TASK [devsec.hardening.ssh_hardening : include selinux specific tasks] *********
skipping: [default]

TASK [devsec.hardening.ssh_hardening : gather package facts] *******************
ok: [default]

TASK [devsec.hardening.ssh_hardening : disable SSH server CRYPTO_POLICY] *******
skipping: [default]

TASK [devsec.hardening.nginx_hardening : create additional configuration] ******
--- before
+++ after: /Users/zyun/.ansible/tmp/ansible-local-17596sli22rgo/tmpvs4781gq/hardening.conf.j2
@@ -0,0 +1,20 @@
+# #
+# Ansible managed
+#
+# Additional configuration for Nginx.
+
+client_header_buffer_size   1k;
+large_client_header_buffers 2 1k;
+client_body_timeout         10;
+client_header_timeout       10;
+send_timeout                10;
+limit_conn_zone             $binary_remote_addr zone=default:10m;
+limit_conn                  default 5;
+ssl_ciphers                 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
+ssl_session_tickets         off;
+ssl_dhparam                 /etc/nginx/dh2048.pem;
+add_header                  X-Frame-Options SAMEORIGIN;
+add_header                  X-Content-Type-Options nosniff;
+add_header                  X-XSS-Protection "1; mode=block";
+add_header                  Strict-Transport-Security max-age=15768000;
+add_header                  Content-Security-Policy "script-src 'self'; object-src 'self'";

changed: [default]

TASK [devsec.hardening.nginx_hardening : change configuration in main nginx.conf] ***
--- before: /etc/nginx/nginx.conf (content)
+++ after: /etc/nginx/nginx.conf (content)
@@ -9,6 +9,7 @@
 }

 http {
+    server_tokens off;

        ##
        # Basic Settings

--- before: /etc/nginx/nginx.conf (file attributes)
+++ after: /etc/nginx/nginx.conf (file attributes)
@@ -1,3 +1,3 @@
 {
-    "mode": "0644"
+    "mode": "0640"
 }

changed: [default]

TASK [devsec.hardening.nginx_hardening : change ssl_protocols in main nginx.conf] ***
--- before: /etc/nginx/nginx.conf (content)
+++ after: /etc/nginx/nginx.conf (content)
@@ -32,7 +32,7 @@
        # SSL Settings
        ##

-       ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
+    ssl_protocols TLSv1.2;
        ssl_prefer_server_ciphers on;

        ##

changed: [default]

TASK [devsec.hardening.nginx_hardening : change ssl_prefer_server_ciphers in main nginx.conf] ***
--- before: /etc/nginx/nginx.conf (content)
+++ after: /etc/nginx/nginx.conf (content)
@@ -33,7 +33,7 @@
        ##

     ssl_protocols TLSv1.2;
-       ssl_prefer_server_ciphers on;
+    ssl_prefer_server_ciphers on;

        ##
        # Logging Settings

changed: [default]

TASK [devsec.hardening.nginx_hardening : change client_max_body_size in main nginx.conf] ***
--- before: /etc/nginx/nginx.conf (content)
+++ after: /etc/nginx/nginx.conf (content)
@@ -9,6 +9,7 @@
 }

 http {
+    client_max_body_size 1k;
     server_tokens off;

        ##

changed: [default]

TASK [devsec.hardening.nginx_hardening : change client_body_buffer_size in main nginx.conf] ***
--- before: /etc/nginx/nginx.conf (content)
+++ after: /etc/nginx/nginx.conf (content)
@@ -9,6 +9,7 @@
 }

 http {
+    client_body_buffer_size 1k;
     client_max_body_size 1k;
     server_tokens off;


changed: [default]

TASK [devsec.hardening.nginx_hardening : change keepalive_timeout in main nginx.conf] ***
--- before: /etc/nginx/nginx.conf (content)
+++ after: /etc/nginx/nginx.conf (content)
@@ -20,7 +20,7 @@
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
-       keepalive_timeout 65;
+    keepalive_timeout 5 5;
        types_hash_max_size 2048;
        # server_tokens off;


changed: [default]

TASK [devsec.hardening.nginx_hardening : remove default.conf] ******************
ok: [default] => (item=/etc/nginx/conf.d/default.conf)
--- before
+++ after
@@ -1,4 +1,4 @@
 {
     "path": "/etc/nginx/sites-enabled/default",
-    "state": "link"
+    "state": "absent"
 }

changed: [default] => (item=/etc/nginx/sites-enabled/default)

TASK [devsec.hardening.nginx_hardening : generate dh group] ********************
changed: [default]

RUNNING HANDLER [devsec.hardening.os_hardening : update-initramfs] *************
changed: [default]

RUNNING HANDLER [devsec.hardening.ssh_hardening : restart sshd] ****************
changed: [default]

RUNNING HANDLER [devsec.hardening.nginx_hardening : restart nginx] *************
changed: [default]

PLAY RECAP *********************************************************************
default                    : ok=82   changed=36   unreachable=0    failed=0    skipped=31   rescued=0    ignored=0
```

</div></details>