Quick start guide

For the users who want to try the role quickly this guide provides an example of how to:

  • Configure Ansible and install the role

  • Create inventory and playbook

Then, on the controller, run the playbook and configure the remote host:

  • Set hostname and timezone

  • Install packages

  • Create users and update authorized SSH keys

  • Configure sshd and sudo.

Requirements on the remote host

  • Password-less ssh by admin (or any other user by your choice)

  • Login shell for admin is /bin/sh

  • User admin is granted unlimited sudo

  • Python and Perl are installed.

Installation

Configure Ansible. Fit the paths to the inventory (3) and to the roles (4) to your needs. Disable retry_files (5). Don’t’ display ok and skipped hosts (6-8). Pipelining (12) should speedup the execution of the playbook

 1shell> cat ansible.cfg
 2[defaults]
 3inventory = $PWD/hosts
 4roles_path = $HOME/.ansible/roles
 5retry_files_enabled = false
 6stdout_callback = default
 7display_ok_hosts=false
 8display_skipped_hosts=false
 9log_path = /var/log/ansible.log
10
11[ssh_connection]
12pipelining = true

Install the role vbotka.freebsd_postinstall

shell> ansible-galaxy role install vbotka.freebsd_postinstall

Install the library vbotka.ansible_lib

shell> ansible-galaxy role install vbotka.ansible_lib

Install the collections if necessary

shell> ansible-galaxy collection install ansible.posix
shell> ansible-galaxy collection install community.general

Review the role

1shell> ls ~/.ansible/roles/vbotka.freebsd_postinstall
2contrib  defaults  docs  handlers  LICENSE  meta  README.md
3tasks  templates  tests  vars

Inventory and playbook

Create the inventory hosts

1shell> cat hosts
2test_14.example.com ansible_host=10.1.0.64
3
4[example_com]
5test_14.example.com
6
7[example_com:vars]
8ansible_python_interpreter=/usr/local/bin/python3.8
9ansible_perl_interpreter=/usr/local/bin/perl

Create the playbook playbook.yml for single host test_14.example.com

 1shell> cat playbook.yml
 2- hosts: test_14.example.com
 3  gather_facts: true
 4  connection: ssh
 5  remote_user: admin
 6  become: true
 7  become_user: root
 8  become_method: sudo
 9  roles:
10    - vbotka.freebsd_postinstall

Test syntax of the playbook

1shell> ansible-playbook playbook.yml --syntax-check
2
3playbook: playbook.yml

Set hostname and timezone

Create host_vars with customized variables. Enable hostname (2) and timezone (5). Disable debug output (7) and backup of changed files (8)

1shell> cat host_vars/test_14.example.com/fp-common.yml
2fp_hostname: true
3rc_conf_hostname: test_14.example.com
4fp_domain: example.com
5fp_timezone: true
6fp_zoneinfo: UTC
7fp_debug: false
8fp_backup: false

Set hostname and timezone

 1shell> ansible-playbook playbook.yml -t fp_hostname,fp_timezone
 2
 3PLAY [test_14.example.com] *******************************************************************
 4
 5TASK [vbotka.freebsd_postinstall : hostname: Configure hostname in /etc/rc.conf] *************
 6changed: [test_14.example.com] => (item={'key': 'hostname', 'value': 'test_14.example.com'})
 7
 8RUNNING HANDLER [vbotka.freebsd_postinstall : set hostname] **********************************
 9changed: [test_14.example.com]
10
11PLAY RECAP ***********************************************************************************
12test_14.example.com: ok=4 changed=2 unreachable=0 failed=0 skipped=22 rescued=0 ignored=0

UTC is the default timezone. Therefore, no changes were reported.

Install packages

Enable the installation of packages (2) and pick the lists to be installed (3). See available lists in defaults/main/pkgdict_*.yml

1shell> cat host_vars/test_14.example.com/fp-packages.yml
2fp_install: true
3fp_packages:
4  - {list: minimal, enabled: true}

Install packages

1shell> ansible-playbook playbook.yml -t fp_packages
2  ...

Create users

Enable the management of users (2) and create the configuration data (3). Delete default user (7)

1shell> cat host_vars/test_14.example.com/fp-users.yml
2fp_users: true
3fp_users_conf:
4  - {name: admin, shell: /bin/sh, groups: [wheel]}
5  - {name: devel, shell: /usr/local/bin/bash, groups: [wheel]}
6  - {name: responder, shell: /usr/sbin/nologin}
7  - {name: freebsd, state: absent}

Manage users

 1shell> ansible-playbook playbook.yml -t fp_users
 2
 3PLAY [test_14.example.com] *******************************************************************
 4
 5TASK [vbotka.freebsd_postinstall : users: Manage user accounts] ******************************
 6changed: [test_14.example.com] => (item=admin)
 7changed: [test_14.example.com] => (item=devel)
 8changed: [test_14.example.com] => (item=responder)
 9
10PLAY RECAP ***********************************************************************************
11test_14.example.com: ok=2 changed=1 unreachable=0 failed=0 skipped=22 rescued=0 ignored=0

Update authorized SSH keys

Enable the installation of authorized keys (2). Remove other keys if already configured (3). Install the keys in batches (4). Create the list of the public keys to be installed (5)

1shell> cat host_vars/test_14.example.com/fp-authorized-key.yml
2fp_authorized_key: true
3fp_authorized_key_install_exclusive: true
4fp_authorized_key_install_individually: false
5fp_authorized_key_conf:
6  - user: admin
7    key: "{{ lookup('file', '~/.ansible/ssh-pub-keys/devel-srv1/id_rsa.pub') }}"
8  - user: admin
9    key: "{{ lookup('file', '~/.ansible/ssh-pub-keys/devel-srv2/id_rsa.pub') }}"

Update authorized keys

1shell> ansible-playbook playbook.yml -t fp_authorized_key
2  ...

Configure sshd

Enable the configuration of sshd (2), enable sshd service (3), and create the configuration data (10)

 1shell> cat host_vars/test_14.example.com/fp-sshd.yml
 2fp_sshd: true
 3fp_sshd_enable: true
 4fp_sshd_passwordauthentication: 'no'
 5fp_sshd_challengeresponseauthentication: 'no'
 6fp_sshd_permitrootlogin: 'no'
 7fp_sshd_permittunnel: 'no'
 8fp_sshd_allowtcpforwarding: 'yes'
 9fp_sshd_x11forwarding: 'no'
10fp_sshd_conf:
11  - {key: PasswordAuthentication, value: "{{ fp_sshd_passwordauthentication }}"}
12  - {key: ChallengeResponseAuthentication, value: "{{ fp_sshd_challengeresponseauthentication }}"}
13  - {key: PermitRootLogin, value: "{{ fp_sshd_permitrootlogin }}"}
14  - {key: PermitTunnel, value: "{{ fp_sshd_permittunnel }}"}
15  - {key: AllowTcpForwarding, value: "{{ fp_sshd_allowtcpforwarding }}"}
16  - {key: X11Forwarding, value: "{{ fp_sshd_x11forwarding }}"}
17  - {key: UseBlacklist, value: 'yes'}

Configure sshd

 1shell> ansible-playbook playbook.yml -t fp_sshd
 2
 3PLAY [test_14.example.com] *******************************************************************
 4
 5TASK [vbotka.freebsd_postinstall : sshd: Configure /etc/ssh/sshd_config] *********************
 6changed: [test_14.example.com] => (item={'key': 'PasswordAuthentication', 'value': 'no'})
 7changed: [test_14.example.com] => (item={'key': 'ChallengeResponseAuthentication', 'value': 'no'})
 8changed: [test_14.example.com] => (item={'key': 'PermitRootLogin', 'value': 'no'})
 9changed: [test_14.example.com] => (item={'key': 'PermitTunnel', 'value': 'no'})
10changed: [test_14.example.com] => (item={'key': 'AllowTcpForwarding', 'value': 'yes'})
11changed: [test_14.example.com] => (item={'key': 'X11Forwarding', 'value': 'no'})
12changed: [test_14.example.com] => (item={'key': 'UseBlacklist', 'value': 'yes'})
13
14RUNNING HANDLER [vbotka.freebsd_postinstall : reload sshd] ***********************************
15changed: [test_14.example.com]
16
17PLAY RECAP ***********************************************************************************
18test_14.example.com: ok=4 changed=2 unreachable=0 failed=0 skipped=23 rescued=0 ignored=0

Configure sudo

Enable the configuration of sudoers (2) and create the configuration data (3)

1shell> cat host_vars/test_14.example.com/fp-sudoers.yml
2fp_sudoers: true
3fp_sudoers_conf:
4  - {key: admin, value: "ALL=(ALL) NOPASSWD: ALL"}
5  - {key: devel, value: "ALL=(ALL) NOPASSWD: ALL"}

Configure sudoers

1shell> ansible-playbook playbook.yml -t fp_sudoers
2
3PLAY [test_14.example.com] *******************************************************************
4
5TASK [vbotka.freebsd_postinstall : sudoers: Configure /usr/local/etc/sudoers] ****************
6changed: [test_14.example.com] => (item={'key': 'devel', 'value': 'ALL=(ALL) NOPASSWD: ALL'})
7
8PLAY RECAP ***********************************************************************************
9test_14.example.com: ok=2 changed=1 unreachable=0 failed=0 skipped=22 rescued=0 ignored=0

The user admin has already been enabled. Otherwise the Ansible escalation become: true wouldn’t work. Therefore, only the user devel reported changes.

Complete role

To show the functionality of the role, the tasks in the previous examples (fp_hostname, fp_timezone, fp_packages, fp_users, fp_authorized_key, fp_sshd, fp_sudoers) were run separately. You can create the data and run the tasks all in one play

 1shell> tree .
 2.
 3├── ansible.cfg
 4├── playbook.yml
 5├── hosts
 6└── host_vars
 7    └── test_14.example.com
 8        ├── fp-authorized-key.yml
 9        ├── fp-common.yml
10        ├── fp-packages.yml
11        ├── fp-sshd.yml
12        ├── fp-sudoers.yml
13        └── fp-users.yml
14
152 directories, 9 files

Run all enabled tasks in the playbook again. Optionally, disable installation to speedup the execution

1shell> ansible-playbook playbook.yml -e fp_install=false
2
3PLAY [test_14.example.com] *******************************************************************
4
5PLAY RECAP ***********************************************************************************
6test_14.example.com: ok=10 changed=0 unreachable=0 failed=0 skipped=172 rescued=0 ignored=0

Warning

The host has not been secured by this playbook and should be used for testing only.