Chapter 1

AutomA Playbooks

Introduction

This chapter deals with the documentation on the part of the playbooks and the questions for all the recommendations made available to users. You will find the project AutomA-Playbooks on github as well as the procedure to follow to contribute to the project in the section Contribute.

Tree structure

The tree structure of the github repository is divided into the following form:

└── KERNEL
    └── OS
        └── VERSION
            ├── CATEGORY
            │   ├── REFERENCE
            │   │   └── LEVEL
            │   │       └── RXX_ACTION_NAME
            │   │           ├── playbook.yml.j2
            │   │           └── questions.yml
            │   └── REFERENCE2
            │       └── LEVEL2
            │           └── CXX_ACTION_NAME2
            │               ├── playbook.yml.j2
            │               └── questions.yml
            ├── CATEGORY2
            │   └── REFERENCE
            │       └── LEVEL
            │           └── RXX_ACTION_NAME3
            │               ├── playbook.yml.j2
            │               └── questions.yml
            └── CATEGORY3
                └── REFERENCE2
                    └── LEVEL
                        └── RXX_ACTION_NAME4
                            ├── playbook.yml.j2
                            └── questions.yml

As of November 30, 2023, the project looked like the following tree:

└── LINUX
    └── DEBIAN
        └── 12
            ├── KERNEL
            │   └── ANSSI
            │       └── 1_INTERMEDIATE
            │           └── R11_CONFIGURE_YAMA_LSM
            │               ├── playbook.yml.j2
            │               └── questions.yml
            ├── NETWORK_STACK
            │   └── ANSSI
            │       └── 1_INTERMEDIATE
            │           └── R13_DISABLE_IPV6
            │               ├── playbook.yml.j2
            │               └── questions.yml
            ├── PACKAGE_MANAGEMENT
            │   └── ANSSI
            │       └── 0_MINIMAL
            │           └── R61_PERFORM_REGULAR_UPDATES
            │               ├── playbook.yml.j2
            │               └── questions.yml
            ├── PERMISSIONS
            │   └── ANSSI
            │       ├── 0_MINIMAL
            │       │   └── R54_ACTIVATE_STICKY_BIT
            │       │       ├── playbook.yml.j2
            │       │       └── questions.yml
            │       └── 3_REINFORCED
            │           └── R36_CHANGE_UMASK_VALUE
            │               ├── playbook.yml.j2
            │               └── questions.yml
            └── USERS
                └── ANSSI
                    └── 0_MINIMAL
                        └── R30_DISABLE_UNUSED_USER_ACCOUNTS
                            ├── playbook.yml.j2
                            └── questions.yml

We thought about it and chose this folder structure to allow for better integration of future hardening rules and environments. The principle of this slightly substantial structure is to allow better modularity of the project.

Do you want to contribute to the project by adding hardening rules for Windows Server 2022?

You must create the tree (if it does not exist), here /WINDOWS/SERVER/2022/. Then you need to create the following structure according to the hardening actions you want to add. Genericly, here are the folders to create (in order):

  1. CATEGORY : The name of the category that the hardening rule fits into. It is possible that toughening actions could be in several categories. In this case, choose the category in which it would be the most logical but in case of questions, you can open an issue on the Github project or by email at automa.project@proton.me.
  2. REFERENCE : The reference frame in which the hardening action is taken. We base all of our actions on the recommendations of ANSSI but it is possible to use other repositories such as the CIS.
  3. LEVEL : This file is taken from the ANSSI level system in its guide to Security Recommendations relating to a GNU/Linux system. In this guide, they offer a grid of hardening levels which therefore allows you to locate the level of hardening action. It is necessary to carefully choose the level of hardening of the hardening rules to enable better segmentation and user experience. The possible levels are as follows:
    • 0_MINIMAL
    • 1_INTERMEDIATE
    • 2_REINFORCED
    • 3_HIGH
  4. HARDENING_ACTION : The name of the hardening action preceded by a non-necessarily unique identifier. In the case of Security Recommendations relating to a GNU/Linux system, the identifier consists of an R followed by a number, for example R30. The goal is to keep the same nomenclature for the same reference system.

When your folders are created, two files playbook.yml.j2 and questions.yml are no longer missing. The contents of these files will be described in parts playbook.yml.j2 and questions.yml.

Subsections of AutomA Playbooks

Playbooks testing

Once the playbooks have been created, they need to be tested to ensure that the hardening action has been carried out correctly. To simplify the process, we provide Dokcer containers for playbook testing. Each environment must have its own container with the correct version. For example, even if Debian 11 and Debian 12 are close in terms of operation, it’s still necessary to separate the two versions into two different docker images.

Note

It is likely that some hardening actions cannot be tested on a containerized environment. It will therefore be necessary to run the tests on a virtual machine.

Existing Docker images

Docker images can be found here. It will only be necessary to perform a pull.

Missing Docker images

Make a request

You can send us a request by e-mail or open an issue or discussion on AutomA’s Github.

Creating the image

In this section, we’ll deal with the example of a Debian 12 image, but the process will remain the same whatever the environment you’re using.

Prerequisites

The following list describes all the components required to create an image:

  • python3
  • python3-pip
  • python3-venv
  • sshpass

Then execute following commands :

python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install ansible-core

Dockerfile

In the file named Dockerfile:

FROM debian:12

RUN apt-get update -y && \
    apt-get install openssh-server sudo python3 -y

RUN sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin Yes/" /etc/ssh/sshd_config

RUN useradd -m -s /bin/bash user && \
    echo 'user:password!' | chpasswd && \
    echo 'root:password!' | chpasswd && \
    service ssh restart

EXPOSE 22

CMD ["/usr/sbin/sshd", "-D"]

To build your image: docker build -t automa-debian12 . (Do not forget the dot at the end !)

Once your build command is finished, you can instanciate it with:

docker run -d -p 2222:22  --name debian-ssh-container automa-debian12

Required files

inventory.yml

This file gives our container configurations to Ansible.

all:
  hosts:
    docker-debian12:
      ansible_host: 127.0.0.1
      ansible_port: 2222
      ansible_user: user
      ansible_password: password!
      ansible_become: yes
      ansible_become_method: sudo
      ansible_become_user: root
      ansible_become_password: password!

playbook.yml

The playbook file is the one that will be given to Ansible so that it can apply a rule to the container. Here’s an example:

---
- name: "Disable unused user accounts"
  hosts: "all"

  tasks:

    - name: "List all users"
      ansible.builtin.getent:
        database: "passwd"
        split: ":"
      register: "all_users"

    - name: "Disable user"
      ansible.builtin.user:
        name: "{{ item }}"
        state: "absent"
      with_items: "{{ all_users.ansible_facts.getent_passwd }}"
      when:
        - item not in ['root','user','_apt','sshd']

Testing !

You can execute the following command:

python3 -m ansible playbook -i inventory.yml -l all playbook_example.yml -vvv

playbook.yml.j2 file

The playbooks are jinja templates of Ansible playbooks. This allow us to render playbooks regarding the user probided parameters.

Example

---
- name: "Example rule"
  hosts: "all"

  tasks:

    - name: "Disable user"
      ansible.builtin.user:
        name: {% raw %}"{{ item }}"{% endraw %}
        state: "absent"
      with_items: "{{ used_users }}"

This rule is mixing AutomA jinja rendering and Ansible jinja rendering. The used_users variable is the one provided by the questions.yml, thus it will be hardcoded in the playbook. For the item variable, it is enclosed in raw jinja balises to enforce the no-rendering of this variable by the AutomA renderer as it is an Ansible rendered variable.

questions.yml file

This file contain the specification of the useful variables for the playbook jinja template.

Example

---
id: "The ID of the rule"
title: "The title of the Rule"
description: "The description of the rule"
author: "The author name"
last_modified: "MM/DD/YYYY of the corresponding last modifiction"
tags:
  - "Tag1"
  - "Tag2"

questions:
  - title: "The first value to fill"
    name: "The name of the variable to render with this result"
    required: "A boolean to say if the value can be None or not"
    type: "One of the defined types"
    value: "None by default, the value filled by this question"

  - title: "The first value to fill"
    name: "The name of the variable to render with this result"
    required: "A boolean to say if the value can be None or not"
    type: "One of the defined types"
    value: "None by default, the value filled by this question"

### EXAMPLE ###
---
id: "R42"
title: "This rule is an example"
description: "You will answer a famous question: what is the life answer ?"
author: "aiglematth"
last_modified: "10/24/2023"
tags:
  - "life"
  - "answer"

questions:
  - title: "What is the answer of the life ?"
    name: "life_answer"
    required: yes
    type: "u8"
    value:

  - title: "Are you sure of your answer ?"
    name: "are_you_sure"
    required: yes
    type: "bool"
    value:

Types

TypeDescription
strBasic string type
list<x>List of type x
choice<x>[y1,y2,...]List y1, y2, … choices of type x