Skip to content

rakhinskiy/ansible-role-common

Repository files navigation

Common Role

Server bootstrap role

Requirements

  • ansible >= 2.16
  • python >= 3.6

Tasks

Number Task Description Tests
00 always Check OS and install ansible dependencies ---
01 hostname Set server hostname
02 hosts Manage /etc/hosts ---
03 timezone Set server timezone
04 repositories Add or enable/disable repositories
05 packages Install packages
06 locale Configure locales
07 users Manage local users
08 sudo Install sudo and configure
09 ssh Configure ssh client keys
10 dirs Create local folders
11 environments Configure env vars
12 limits Configure limits.conf
13 sysctl Configure sysctl.conf
14 sysfs Configure sysfs utils
15 tuned Install and configure tuned
16 firewall Configure iptables
17 selinux Simple SELinux configuration
18 aide Install and configure Aide
19 atop Install atop
20 auditd Configure auditd ---
21 chrony Configure chrony
22 cron Configure cron[d] and add tasks
23 logwatch Configure logwatch
24 nscd Configure NSCD
25 rkhunter Configure rkhunter
26 smartmontools Configure smartmontools
27 sshd Configure SSHD daemon
28 zsh Configure ZSH

TODO

  • Audisp plugins config for auditd
  • Add support for go-audit (Slack) / go-libaudit (Elastic) versions of audit daemons
  • Rewrite rkhunter configure tasks
  • Add to iptables output zone rules | low priority
  • Add to iptables src nat / dst nat zone rules | low priority
  • Add iptables restart script with save docker / k8s rules | low priority
  • Add firewalld support | low priority
  • Add ufw support | low priority

Role Variables

By default, role only run always task, other tasks only if exist config in inventory

# 01 # Hostname

# default: none
common_hostname: "{{ inventory_hostname }}"
# 02 # Hosts

# default: []
common_hosts:
  - ip: "192.168.0.1"
    name: "gw-1 gw-1.example.com"
# 03 # Timezone

# default: none
common_timezone: "Etc/UTC"
# 04 # Repositories

# default: []
common_repositories_manager:
  # Debian / Ubuntu example:
  - option: "Acquire::http::proxy"
    value: "https://user:password@hostname:port"
  - option: "Acquire::https::proxy"
    value: "https://user:password@hostname:port"
  - option: "Acquire::::Proxy"
    value: "true"
  - option: "Acquire::ForceIPv4"
    value: "true"
  # CentOS / AlmaLinux / Rocky example (section main is default)
  - option: "gpgcheck"
    value: "1"
    section: "main"
  - option: "installonly_limit"
    value: "3"
    section: "main"
  - option: "clean_requirements_on_remove"
    value: "True"
    section: "main"
  - option: "skip_if_unavailable"
    value: "False"
    section: "main"

# default: []
common_repositories_add:
  # Debian / Ubuntu example:
  - name: "zabbix"
    url: "https://repo.zabbix.com/zabbix/6.4/ubuntu {{ dist_codename }} main"
    gpg: "https://repo.zabbix.com/RPM-GPG-KEY-ZABBIX-08EFA7DD"
    # deb or deb-src | default deb | ignored on dnf / yum
    type: "deb"
    options:
      arch: "amd64"
  # CentOS / AlmaLinux / Rocky example
  - name: "epel"
    url: "https://download.fedoraproject.org/pub/epel/$releasever/$basearch/"
    gpg: "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{{ dist_version }}"
    options:
      module_hotfixes: "1"
      skip_if_unavailable: "true"
  - name: "example"
    url: "https://example.com/...."
    options:
      gpgcheck: "0"

common_repositories_enable:
  # Debian / Ubuntu example:
  - "zabbix"  # Uncomment all deb / deb-src in /etc/apt/sources.list.d/zabbix.list
  # CentOS / AlmaLinux / Rocky example:
  - "crb"
  - "extras"
  - "highavailability"
  - "plus"

common_repositories_disable:
  # Debian / Ubuntu example:
  - "zabbix"  # Comment all deb / deb-src in /etc/apt/sources.list.d/zabbix.list
  # CentOS / AlmaLinux / Rocky example:
  - "epel"
# 05 # Packages

# default: []
common_packages:
  - "strace"
  - "tcpdump"
  - "nano"

# default: []
common_packages_additional:
  - "zsh"
# 06 # Locale

# default: none
common_locale: "en_US.UTF-8"
# 07 # Users

# default: []
common_users:
  - name: "deploy"
    group: "deploy"       # default: item.name
    groups: ["docker"]    # default: []
    shell: "/bin/zsh"     # default: /bin/bash
    create_home: yes      # default: yes
    system: no            # default: no
    append: yes           # default: no
    state: present        # default: present

# default: []
# Same as common_users and will be merged
#   into common_users before run tasks
common_users_additional: []
# 08 # Sudo

# default: []
common_sudo:
  # user example
  - name: "deploy"
    defaults:
      - "!requiretty"
      - "env_keep += 'TZ'"
    permissions:
      - host: "ALL"
        runas: "root"
        nopasswd: no
        cmd: "ALL"
  # group example
  - name: "%wheel"
    defaults:
      - "!requiretty"
      - "env_keep += 'TZ'"
    permissions:
      - host: "ALL"
        runas: "root"
        nopasswd: yes
        cmd: "ALL"
# 09 # SSH

# default: []
common_ssh_authorized_keys:
  - user: deploy
    key: "ssh-rsa ..."
    state: "present"

# default: []
common_ssh_keys:
  - user: deploy
    key_name: "id_rsa"
    key_public: "ssh-rsa ..."
    key_private: "..."
# 10 # Dirs

# default: []
common_dirs:
  - path: "/var/shared/backups"
    state: "directory"
    owner: "root"
    group: "root"
    mode: "0750"
    force: no
    follow: yes
# 11 # Environments

# default: []
common_environments:
  - user: ~     # Global
    variables:
      YII_DEBUG: "no"
  - user: "deploy"
    variables:
      PATH: "${PATH}:/usr/local/bin:~/.bin/:~/bin/"
# 12 # Limits

# default: []
common_limits:
  - domain: "root"        # Required user / @group
    limit_type: "hard"    # Required hard / soft
    limit_item: "core"    # Required
    value: "100000"       # Required
    use_min: no           # default: no | Use min between exist limits.conf and new values
    use_max: yes          # default: no | Use max between exist limits.conf and new values
    comment: ""
# 13 # Sysctl

# default:
# common_sysctl_file: "ansible"
common_sysctl_file: "k8s"

# common_sysctl_keys: []
common_sysctl_keys:
  - name: "net.core.somaxconn"
    value: "50000"
# 14 # SysFS

# default: []
common_sysfs:
  - attribute: "power/state"
    value: "0660"
    type: "mode"
  - attribute: "power/state"
    value: "root:power"
    type: "owner"
  - attribute: "devices/system/cpu/cpu0/cpufreq/scaling_governor"
    value: "userspace"
    type: "attribute"
  - attribute: "sys/kernel/mm/transparent_hugepage/enabled"
    value: "madvise"
    type: "attribute"
# 15 # Tuned

# default: no
common_tuned_enable: yes

# default: "profile-custom"
common_tuned_profile_name: "profile-kubernetes"

# default: []
common_tuned_profile_config:
  - name: "main"
    params:
      - option: "summary"
        value: "Test"
      - option: "include"
        value: "throughput-performance"
  - name: "sysctl"
    params:
      - option: "vm.dirty_ratio"
        value: "30"
      - option: "vm.swappiness"
        value: "30"
  - name: "vm"
    params:
      - option: "transparent_hugepages"
        value: "never"
# 16 # Firewall

# default:
#   Alma Linux / Rocky Linux -> firewalld
#   Debian / Ubuntu -> ufw
#   Only iptables currently supported
common_firewall_backend: "iptables"

common_firewall_ipset_zones:
  - zone: "WHITELIST"
    sources:
      - "192.168.23.0/24"
      - "192.168.99.0/24"
  - zone: "VPN_OPEN_CONNECT_NETWORKS"
    sources:
      - "192.168.199.0/24"
  - zone: "VPN_IPSEC_NETWORKS"
    sources:
      - "192.168.200.0/24"
      - "192.168.201.0/24"
  - zone: "DMZ"
    sources:
      - "192.168.202.0/24"
  - zone: "ALL"
    sources:
        - "0.0.0.0/0"

# default: []
# default input / forward policy is DROP
# default zone chains policy is RETURN
common_firewall:
  tcp_mss: yes
  masquerade:
    interfaces:
      - "eth0"
  filter:
    input:
      # eth0:vip VRRP
      - zone: "public"
        ip_addresses:
          - "10.0.10.10"
        default: "drop"  # Chain policy
        services:
          - name: "HTTP"
            ports:
              - "tcp/80"
              - "tcp/443"
            sources:
              - "any"
          - name: "Kubernetes"
            ports:
              - "tcp/6443"
            sources:
              - "BLACKLIST"
            action: "reject" # default action is accept

      # For IP / Network in sources for service
      #   created ipset zone Z-ZONE-S-SERVICE
      #   example Z-DMZ-S-SSH
      # And you can use custom zones from
      #   common_firewall_ipset_zones as sources

      # eth0 internal network
      - zone: "dmz"
        interfaces:
          - "eth0"
        default: "return"
        services:
          - name: "Whitelist"
            ports:
              - "any"
            sources:
              - "1.1.1.1"
              - "10.0.0.0/16"
          - name: "SSH"
            ports:
              - "tcp/22"
            sources:
              - "192.168.1.0/24"
              - "10.0.0.0/16"
          - name: "HTTP"
            ports:
              - "tcp/80"
              - "tcp/443"
            sources:
              - "any"
          - name: "IPSec"
            # ports rules:
            # udp/53 -> protocol: udp  / port: 53
            # tcp/80 -> protocol: tcp  / port: 80
            # 80     -> protocol: tcp  / port: 80
            # gre/   -> protocol: gre  / port: not used | enable GRE on chain
            # icmp/  -> protocol: icmp / port: not used | enable pings on chain
            ports:
              - "esp/"
              - "gre/"
              - "udp/500"
              - "udp/4500"
            sources:
              - "any"
  forward:
    # Allow forward between all pairs
    #    ppp+ <-> tun+
    #    ppp+ <-> eth0
    #    tun+ <-> eth0
    - interfaces:
      - 'ppp+'
      - 'tun+'
      - 'eth0'
    - networks:
      - '192.168.23.0/24'
      - '192.168.24.0/24'
    - zones:
      - "ALL"
      - "DMZ"
    - zones:
      - "ALL"
      - "VPN_OPEN_CONNECT_NETWORKS"

  # Direct rules example
  direct:
    mangle: # *mangle table | first rules
      - "-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu"
    raw: # *raw table | first rules
      - "-A PREROUTING -s 10.0.0.0/8 -d 10.0.0.0/8 -j NOTRACK"
    filter: # *filter table | first rules
      - "-A INPUT -i eth0 -p esp -j ACCEPT"
      - "-A INPUT -i eth0 -p gre -j ACCEPT"
    nat: # *nat table | first rules
      - "-A POSTROUTING -o eht0 -j MASQUERADE"

# default: no
common_firewall_allow_restart_docker: yes
# default: no
common_firewall_allow_restart_kube_proxy: yes
# 17 # SELinux

# default: no | yes only run selinux tasks
common_selinux_enable: yes

# default: targeted | ["targeted", "minimum", "mls"]
common_selinux_policy: "targeted"

# default: enforcing | ["disabled", "enforcing", "permissive"]
common_selinux_state: "enforcing"

# default: no
common_selinux_update_kernel: no

# default: []
# https://docs.ansible.com/ansible/latest/collections/ansible/posix/seboolean_module.html
common_selinux_booleans:
  - name: "httpd_can_network_connect"
    state: yes
    persistent: yes
  - name: "httpd_use_nfs"
    state: yes
    persistent: yes

# default: []
# https://docs.ansible.com/ansible/latest/collections/community/general/sefcontext_module.html
common_selinux_file_contexts:
  - target: "/srv/git_repos(/.*)?"
    setype: httpd_sys_rw_content_t
    state: present
  - target: /srv/containers
    substitute: /var/lib/containers
    state: present

# default: []
# https://docs.ansible.com/ansible/latest/collections/community/general/seport_module.html
common_selinux_ports:
  - port: 6443
    proto: tcp
    setype: http_port_t
    state: present
# 18 # AIDE

# By default, only install aide and init database
# You can write your own aide.conf and put it to
# inventory and set common_aide_config_file
# then your config uploaded to servers
# don't forget to set common_aide_db_new
# and common_aide_db if not standard path used

# default: no
common_aide_enable: yes

# default: not defined | not required
common_aide_config_file: "{{ inventory_dir }}/.files/{{ ansible_os_family | lower }}/aide.conf"

# default:
#   debian family: /var/lib/aide/aide.db.new
#   redhat family: /var/lib/aide/aide.db.new.gz
common_aide_db_new: "/var/lib/aide/aide.db.new.gz"
# default:
#   debian family: /var/lib/aide/aide.db
#   redhat family: /var/lib/aide/aide.db.gz
common_aide_db: "/var/lib/aide/aide.db.gz"
# 19 # Atop

# default: no
common_atop_enable: yes

# default: []
common_atop_options:
  # Load snapshot interval (default 600)
  - option: "LOGINTERVAL"
    value: "10"
  # Load history (default 28 days)
  - option: "LOGGENERATIONS"
    value: "14"
# 20 # Auditd

# Before enable auditd, please open templates/auditd/audit.rules.j2
# Before enable `common_auditd_rules_predefined` READ RULES IN TEMPLATE

common_auditd_enable: yes

# default: []
# Your custom rules
common_auditd_rules:
  - '## Use these rules if you want to log container events'
  - '## watch for container creation'
  - '-a always,exit -F arch=b32 -S clone -F a0&0x7C020000 -F key=container-create'
  - '-a always,exit -F arch=b64 -S clone -F a0&0x7C020000 -F key=container-create'

# default: no
common_auditd_rules_predefined: no

# default: no | After enable immutable, you need to reboot for apply new rules
common_auditd_rules_immutable: no

common_auditd_rules_buffers: "8192"
common_auditd_rules_backlog_wait_time: "60000"
# 21 # Chrony

common_chrony_enable: no

common_chrony_allows:
  - "10/8"
  - "192.168/16"
  - "172.16/12"
common_chrony_command_key: ~
common_chrony_dump_dir: "/var/lib/chrony"
common_chrony_drift_file: "{{ common_chrony_dump_dir }}/chrony.drift"
common_chrony_dump_on_exit: yes
common_chrony_generate_command_key: no
common_chrony_hw_clock_file: ~
common_chrony_hw_timestamp: ~
common_chrony_keyfile: "/etc/chrony/chrony.keys"
common_chrony_leap_sec_tz: "right/UTC"
common_chrony_local_stratum: "10"
common_chrony_log:
  - "tracking"
  - "measurements"
  - "statistics"
common_chrony_log_change: "1"
common_chrony_log_dir: "/var/log/chrony"
common_chrony_mail_on_change: ~
common_chrony_make_step: "1.0 3"
common_chrony_max_update_skew: "100.0"
common_chrony_min_sources: ~
common_chrony_no_client_log: yes
common_chrony_pools:
  - "pool.ntp.org iburst maxsources 5"
common_chrony_rtc_file: ~
common_chrony_rtc_on_utc: yes
common_chrony_rtc_sync: yes
common_chrony_servers: ~
common_chrony_stratum_weight: "0.001"
# 22 # Cron

# default: []
common_cron_environments:
  - user: "deploy"
    vars:
      - name: "MAILTO"
        value: "{{ admin_email }}"

# default: []
common_cron_tasks:
  - name: "My super job"          # required
    job: "/opt/scripts/notify.sh" # required
    minute: "0"                   # default: 0
    hour: "1"                     # default: 0
    day: "*"                      # default: *
    month: "*"                    # default: *
    weekday: "*"                  # default: *
    user: "root"                  # default: root
    disabled: "no"                # default: no
# 23 # Logwatch

# default: no
common_logwatch_enable: yes

common_logwatch_config: "/etc/logwatch/conf/logwatch.conf"
common_logwatch_packages:
  - "logwatch"
common_logwatch_log_dir: "/var/log"
common_logwatch_tmp_dir: "/var/cache/logwatch"
common_logwatch_output: "stdout"
common_logwatch_format: "text"
common_logwatch_encode: "none"
common_logwatch_mail_to: "root"
common_logwatch_mail_from: "logwatch"
common_logwatch_hostname: ~
common_logwatch_filename: ~
common_logwatch_archives: "Yes"
common_logwatch_range: "yesterday"
common_logwatch_detail: "Low"
common_logwatch_services:
  - "All"
  - "-zz-network"
  - "-zz-sys"
  - "-eximstats"
  - "-puppet"
common_logwatch_logfile: ~
common_logwatch_mailer: "/usr/sbin/sendmail -t"
common_logwatch_hostlimit: ~
# 24 # NSCD

# default: no
common_nscd_enable: yes

common_nscd_logfile: "/var/log/nscd.log"
common_nscd_threads: ~
common_nscd_max_threads: ~
common_nscd_stat_user: ~
common_nscd_debug_level: "0"
common_nscd_reload_count: ~
common_nscd_paranoia: "no"
common_nscd_restart_interval: ~

common_nscd_passwd_enable_cache: "yes"
common_nscd_passwd_positive_time_to_live: "600"
common_nscd_passwd_negative_time_to_live: "20"
common_nscd_passwd_suggested_size: "211"
common_nscd_passwd_check_files: "yes"
common_nscd_passwd_persistent: "yes"
common_nscd_passwd_shared: "yes"
common_nscd_passwd_max_db_size: "33554432"
common_nscd_passwd_auto_propagate: "yes"

common_nscd_group_enable_cache: "yes"
common_nscd_group_positive_time_to_live: "3600"
common_nscd_group_negative_time_to_live: "60"
common_nscd_group_suggested_size: "211"
common_nscd_group_check_files: "yes"
common_nscd_group_persistent: "yes"
common_nscd_group_shared: "yes"
common_nscd_group_max_db_size: "33554432"
common_nscd_group_auto_propagate: "yes"

common_nscd_hosts_enable_cache: "yes"
common_nscd_hosts_positive_time_to_live: "3600"
common_nscd_hosts_negative_time_to_live: "20"
common_nscd_hosts_suggested_size: "211"
common_nscd_hosts_check_files: "yes"
common_nscd_hosts_persistent: "yes"
common_nscd_hosts_shared: "yes"
common_nscd_hosts_max_db_size: "33554432"

common_nscd_services_enable_cache: "yes"
common_nscd_services_positive_time_to_live: "28800"
common_nscd_services_negative_time_to_live: "20"
common_nscd_services_suggested_size: "211"
common_nscd_services_check_files: "yes"
common_nscd_services_persistent: "yes"
common_nscd_services_shared: "yes"
common_nscd_services_max_db_size: "33554432"

common_nscd_netgroup_enable_cache: "no"
common_nscd_netgroup_positive_time_to_live: "28800"
common_nscd_netgroup_negative_time_to_live: "20"
common_nscd_netgroup_suggested_size: "211"
common_nscd_netgroup_check_files: "yes"
common_nscd_netgroup_persistent: "yes"
common_nscd_netgroup_shared: "yes"
common_nscd_netgroup_max_db_size: "33554432"
# 25 # RKHunter

common_rkhunter_enable: yes
common_rkhunter_options:
  - option: "SCRIPTWHITELIST"
    value: "/usr/sbin/adduser"
    state: "present"  # default: present
  - option: "DISABLE_TESTS"
    value: "(.*)"
    state: "absent"
# 26 # Smartmontools

# default: no
# Enable on bare-metal servers
common_smartmontools_enable: "{{ ansible_virtualization_role != 'guest' }}"
common_smartmontools_daemon_options:
  - option: "smartd_opts"
    value: "-q never --capabilities"
    state: "present"
common_smartmontools_mail_to: "root"
# default:
#   Alma/Rocky Linux:    "-d removable -n standby,10,q -H -M exec /usr/libexec/smartmontools/smartdnotify"
#   Debian/Ubuntu Linux: "-d removable -n standby,10,q -H -M exec /usr/share/smartmontools/smartd-runner"
common_smartmontools_devicescan: "-H -d removable -n standby,10,q"
common_smartmontools_devices: ~
# 27 # SSHD

# default: []
# config location: /etc/ssh/sshd_config.d/00-custom.conf
# option name converted at filter_plugins -> filter.py -> def get_sshd_option
common_sshd_options:
  - option: "pub_key_authentication"
    value: "yes"
  - option: "password_authentication"
    value: "no"
  - option: "gss_api_authentication"
    value: "no"
  - option: "kerberos_authentication"
    value: "no"
# 28 # ZSH

# default: []
common_zsh:
  - user: "deploy"
  - user: "root"

# default: []
# Same as common_zsh and will be merged
#   into common_zsh before run tasks
common_zsh_additional:
  - user: "dba"

Dependencies

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

License

MIT

About

Simple server bootstrap role

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published