Compare commits
2 commits
db2efc5aac
...
fc531935fd
Author | SHA1 | Date | |
---|---|---|---|
fc531935fd | |||
922733dcde |
128 changed files with 4715 additions and 287 deletions
|
@ -11,7 +11,3 @@ warn_list:
|
|||
- name[template]
|
||||
- latest[git]
|
||||
- yaml[line-length]
|
||||
|
||||
# NOTE: Use busybox here so that's fine
|
||||
- command-instead-of-module
|
||||
- risky-shell-pipe
|
||||
|
|
|
@ -11,3 +11,4 @@ roles/packages/tasks/pnpm-packages.yml key-order[task]
|
|||
roles/packages/tasks/pip-packages.yml key-order[task]
|
||||
roles/theme/tasks/main.yml key-order[task]
|
||||
roles/scripts/tasks/curl.yml key-order[task]
|
||||
roles/system/tasks/main.yml key-order[task]
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
/filter_plugins/__pycache__/
|
||||
/.ropeproject/
|
||||
/playbooks/dist-newstyle/
|
||||
/host_vars/
|
||||
|
|
5
.yamllint
Normal file
5
.yamllint
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
rules:
|
||||
indentation:
|
||||
spaces: 2
|
||||
indent-sequences: consistent
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021-2023 Hoang Nguyen
|
||||
Copyright (c) 2021-2024 Hoang Nguyen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
|
30
README.md
30
README.md
|
@ -2,27 +2,41 @@
|
|||
|
||||
This is the continuation of [my old dotfiles](/folliehiyuki/dotfiles) without all the Xorg stuff I don't use.
|
||||
|
||||
## 🧰 Setup
|
||||
## 🧰 Usage
|
||||
|
||||
```bash
|
||||
# Install `community.general` for 'apk' and 'doas' module if you only installed ansible-core
|
||||
# Install non-core Ansible modules if only ansible-core package is installed
|
||||
ansible-galaxy collection install -r requirements/collections.yml
|
||||
|
||||
# Create an encrypted vars file to store secret variables
|
||||
# (see "Variables" section below)
|
||||
mkdir -p host_vars/$HOSTNAME
|
||||
touch host_vars/$HOSTNAME/secrets.yml
|
||||
ansible-vault encrypt host_vars/$HOSTNAME/secrets.yml
|
||||
ansible-vault edit host_vars/$HOSTNAME/secrets.yml
|
||||
|
||||
# Run the playbook
|
||||
ansible-playbook playbooks/system.yml
|
||||
ansible-playbook playbooks/dotfiles.yml
|
||||
```
|
||||
|
||||
`extend.yml` playbook contains tasks unrelated to dotfiles deployment, but useful (for me).
|
||||
## Variables
|
||||
|
||||
Optional variables (not listed inside `group_vars/all/`) as they should be kept confidential:
|
||||
- `pixiv_refresh_token`: used in gallery-dl config
|
||||
Beside variables defined in [group_vars/all/](./group_vars/all), these are also available:
|
||||
- `vault_password` (required): the password of the created user (used by [system.yml](./playbooks/system.yml) playbook)
|
||||
- `pixiv_refresh_token`: in-browser refresh token used in gallery-dl to access Pixiv
|
||||
- `google_calendar_id`, `google_oauth_client_id`, `google_oauth_client_secret`: used in calcurse CalDAV config
|
||||
- `user_ssh_key_path`: configure Git to sign commits with this SSH key
|
||||
|
||||
## Playbooks
|
||||
|
||||
- [system.yml](./playbooks/system.yml) should be the first to be run. Needs to be run as `root`.
|
||||
- [dotfiles.yml](./playbooks/dotfiles.yml) configures `$HOME` directory.
|
||||
- [extend.yml](./playbooks/extend.yml) contains additional tasks unrelated to dotfiles and system deployment, but useful (for me).
|
||||
|
||||
## 📓 Notes
|
||||
|
||||
The main playbook probably works on whatever Linux distribution you are running (*haven't tested*).
|
||||
|
||||
The additional playbook gears toward my Linux distribution of choice - [Alpine Linux](https://alpinelinux.org). Tasks included in them might not work on other distributions (e.g. `apk` tasks)
|
||||
The playbooks gear toward my Linux distribution of choice - [Alpine Linux](https://alpinelinux.org). Tasks included in them might not work on other distributions (e.g. `apk` tasks)
|
||||
|
||||
## 🌟 Credits
|
||||
|
||||
|
|
49
TODO.md
49
TODO.md
|
@ -2,7 +2,50 @@
|
|||
|
||||
Plans for the future of this dotfiles.
|
||||
|
||||
## Software
|
||||
## General
|
||||
|
||||
- [ ] Add [GuixWL](https://guixwl) workflow
|
||||
|
||||
## System
|
||||
|
||||
### Configuration
|
||||
|
||||
- [ ] /etc/security/access.conf
|
||||
- [ ] Filesystem snapshot:
|
||||
- [ ] zrepl (rootfs=zfs)
|
||||
- [ ] Root on tmpfs
|
||||
- [ ] Filesystem backup (I don't have spare hard drives -_- so not supported for now):
|
||||
- [ ] Local incremental backups (to spare disk)
|
||||
- [ ] Remote backups
|
||||
- [ ] incron
|
||||
- [ ] bees
|
||||
- [ ] kea as another option for dhcp client
|
||||
- [ ] booster and dracut options for initramfs_generator
|
||||
- [ ] `i915.enable_guc=3` (/etc/modprobe.d/kms.conf)
|
||||
- [ ] turnstile as an alternative to pam-rundir/elogind
|
||||
|
||||
### Cosmetic
|
||||
|
||||
- [ ] Packer + Terraform / Pulumi (zfs + btrfs VMs) for testing the playbook
|
||||
|
||||
### Just in case I forget
|
||||
|
||||
- [ ] nftables with rootful podman (<https://github.com/greenpau/cni-plugins>)
|
||||
- [ ] Write docs about AlpineLinux installation:
|
||||
- [ ] BTRFS on LUKS (no encrypted /boot) / ZFS on root
|
||||
- [ ] Bootloader configuration:
|
||||
- [ ] limine / grub (BTRFS)
|
||||
- [ ] gummyboot (a.k.a systemd-boot) / stubbyboot / direct efistub (ZFS)
|
||||
- [ ] [APK post-commit hook](https://ptrcnull.me/posts/alpine-commit-hooks/) in the case of gummyboot, stubbyboot, efistub and limine
|
||||
- [ ] EFI secure boot (also sign fwupd efi binary)
|
||||
- [ ] Add EFI entries for EFI shell and fwupd
|
||||
- [ ] Common kernel parameters: `init_on_free=1 page_alloc.shuffle=1 lockdown=integrity quiet`
|
||||
- [ ] ZFS: `root=ZFS=rpool/ROOT/alpine`
|
||||
- [ ] BTRFS: `modules=sd-mod,usb-storage,btrfs,nvme rootfstype=btrfs cryptroot=UUID=<...> cryptdm=alpine`
|
||||
|
||||
## Dotfiles
|
||||
|
||||
### Software
|
||||
|
||||
- [ ] ~~[wayout](https://git.sr.ht/~proycon/wayout)~~
|
||||
- [x] ~~Use [bubblewrap](https://github.com/containers/bubblewrap) for some applications~~ ==> replace with rootless [podman](https://podman.io) and [apptainer](https://apptainer.org)
|
||||
|
@ -26,7 +69,7 @@ Plans for the future of this dotfiles.
|
|||
- [ ] vimiv-qt
|
||||
- [ ] mpd-mpris (as an alternative to mpDris2)
|
||||
|
||||
## Cosmetic
|
||||
### Cosmetic
|
||||
|
||||
- [ ] GTK/Icons/Cursor theme, Sarasa font bootstrapping
|
||||
- [ ] Waybar config file for River
|
||||
|
@ -39,7 +82,7 @@ Plans for the future of this dotfiles.
|
|||
- [ ] Build podman container images with ansible-bender or stacker
|
||||
- [ ] Add `target-determinator` and `aspect-cli` to packages (or containers, with underlying `bazel`)
|
||||
|
||||
## Sandboxing
|
||||
### Sandboxing
|
||||
|
||||
- [ ] Dockerfile for [animdl](https://github.com/justfoolingaround/animdl) + mpv
|
||||
- [ ] podman rootless with dbus access (without ANONYMOUS authentication) + socket permissions (wayland / dbus/ pipewire / pulseaudio) in container (777 is no good)
|
||||
|
|
|
@ -5,7 +5,7 @@ display_skipped_hosts = False
|
|||
host_key_checking = False
|
||||
deprecation_warnings = True
|
||||
# Relocate directories
|
||||
inventory = ./inventory.yml
|
||||
inventory = ./inventory.toml
|
||||
filter_plugins = ./filter_plugins
|
||||
roles_path = ./roles
|
||||
# Make the targets follow XDG specs
|
||||
|
|
48
filter_plugins/system_filters.py
Normal file
48
filter_plugins/system_filters.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
from ansible.errors import AnsibleFilterTypeError
|
||||
from ansible.module_utils.six import string_types, integer_types
|
||||
|
||||
|
||||
# Ansible's "quote" filter is only applied to shell module
|
||||
|
||||
def quote_single(str):
|
||||
"""
|
||||
Quote a string with single quote.
|
||||
|
||||
Example: a string -> 'a string'
|
||||
"""
|
||||
if isinstance(str, string_types):
|
||||
return "'" + str + "'"
|
||||
else:
|
||||
raise AnsibleFilterTypeError(
|
||||
"|quote_single expects string, got %s instead." % type(str))
|
||||
|
||||
def quote_double(str):
|
||||
"""
|
||||
Quote a string with double quote.
|
||||
|
||||
Example: a string -> "a string"
|
||||
"""
|
||||
if isinstance(str, string_types):
|
||||
return '"' + str + '"'
|
||||
else:
|
||||
raise AnsibleFilterTypeError(
|
||||
"|quote_double expects string, got %s instead." % type(str))
|
||||
|
||||
def random_hex(num):
|
||||
"""
|
||||
Generate a random hex number within the range [0, num)
|
||||
|
||||
Example: random_hex(2**16 - 1) = 446c
|
||||
"""
|
||||
if isinstance(num, integer_types):
|
||||
import random
|
||||
return '{:x}'.format(random.randint(0, num))
|
||||
else:
|
||||
raise AnsibleFilterTypeError(
|
||||
"|random_hex expects integer, got %s instead." % type(num))
|
||||
|
||||
class FilterModule(object):
|
||||
"""Custom Ansible jinja2 filters for sysconfig playbook."""
|
||||
|
||||
def filters(self):
|
||||
return {'quote_single': quote_single, 'quote_double': quote_double, 'random_hex': random_hex}
|
100
group_vars/all/dotfiles.yml
Normal file
100
group_vars/all/dotfiles.yml
Normal file
|
@ -0,0 +1,100 @@
|
|||
---
|
||||
# Choices of components ────────────────────────────────────────────────────────────
|
||||
|
||||
launcher: rofi
|
||||
|
||||
wallpaper_engine: swww
|
||||
|
||||
image_viewer: qimgv
|
||||
|
||||
clipboard: cliphist
|
||||
|
||||
screenshot: grim
|
||||
|
||||
notification: dunst
|
||||
|
||||
# TODO: mopidy backends orther than local files
|
||||
music_daemon: mpd
|
||||
|
||||
# 'openssh' --> openssh-client-default
|
||||
# 'dropbear' --> dropbear-dbclient
|
||||
ssh_client: openssh
|
||||
|
||||
# NOTE: only OpenSSH can be used for SSH commit signing
|
||||
gitcommit_sign_method: openpgp
|
||||
|
||||
# List of terminal emulators, in precedence order
|
||||
terminal_emulators:
|
||||
- foot
|
||||
- alacritty
|
||||
|
||||
buildkit:
|
||||
# Set to false to use OCI worker. All other options will be ignored
|
||||
containerd_worker: true
|
||||
# "k8s.io" for Kubernetes, "default" for normal containerd, "buildkit" for buildkit
|
||||
containerd_namespace: default
|
||||
# Use "native" on ZFS
|
||||
containerd_snapshotter: overlayfs
|
||||
|
||||
# RedHat recommends 0077 for a secure server
|
||||
# 0027 is a good in-between for desktop usage (0022 is the default)
|
||||
umask: '0027'
|
||||
|
||||
# Leave jq behind! `jaq`, `gojq` and `yq` are here for the rescue
|
||||
jq_binary: /usr/bin/gojq
|
||||
|
||||
# XDG directory spec (need to be absolute paths here)
|
||||
xdg_dir:
|
||||
bin_home: '{{ ansible_user_dir }}/.local/bin'
|
||||
cache_home: '{{ ansible_user_dir }}/.cache'
|
||||
config_home: '{{ ansible_user_dir }}/.config'
|
||||
data_home: '{{ ansible_user_dir }}/.local/share'
|
||||
state_home: '{{ ansible_user_dir }}/.local/state'
|
||||
|
||||
# This is not in XDG spec, but it's used here as a user-scoped /usr/libexec
|
||||
libexec_dir: '{{ ansible_user_dir }}/.local/libexec'
|
||||
|
||||
# Font settings ────────────────────────────────────────────────────────────
|
||||
|
||||
cjk_term_font: Sarasa Term J
|
||||
|
||||
cjk_monospace_font: Sarasa Mono J
|
||||
|
||||
cjk_sans_font: Sarasa Fixed J
|
||||
|
||||
cjk_serif_font: Sarasa Fixed Slab J
|
||||
|
||||
term_font: IosevkaTerm Nerd Font
|
||||
|
||||
monospace_font: Iosevka
|
||||
|
||||
sans_font: Iosevka Aile
|
||||
|
||||
serif_font: Iosevka Etoile
|
||||
|
||||
font_size: 13.5
|
||||
|
||||
# Theme settings ────────────────────────────────────────────────────────────
|
||||
|
||||
theme: nord
|
||||
|
||||
gtk_theme: Nordic
|
||||
|
||||
icon_theme: Papirus-Dark
|
||||
|
||||
cursor_theme: Bibata-Modern-Ice
|
||||
|
||||
cursor_size: 24
|
||||
|
||||
# Transparency of Waybar, launchers (wofi, rofi, fuzzle) and terminals
|
||||
ui_opacity: 0.96
|
||||
|
||||
# User information ──────────────────────────────────────────────────────────
|
||||
|
||||
user_fullname: Hoang Nguyen
|
||||
|
||||
user_email: folliekazetani@protonmail.com
|
||||
|
||||
user_agent: Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0
|
||||
|
||||
user_gpg_signature: B0567C20730E9B11
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
cjk_term_font: Sarasa Term J
|
||||
|
||||
cjk_monospace_font: Sarasa Mono J
|
||||
|
||||
cjk_sans_font: Sarasa Fixed J
|
||||
|
||||
cjk_serif_font: Sarasa Fixed Slab J
|
||||
|
||||
term_font: IosevkaTerm Nerd Font
|
||||
|
||||
monospace_font: Iosevka
|
||||
|
||||
sans_font: Iosevka Aile
|
||||
|
||||
serif_font: Iosevka Etoile
|
||||
|
||||
font_size: 13.5
|
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
launcher: rofi
|
||||
|
||||
wallpaper_engine: swww
|
||||
|
||||
image_viewer: qimgv
|
||||
|
||||
clipboard: cliphist
|
||||
|
||||
screenshot: grim
|
||||
|
||||
notification: dunst
|
||||
|
||||
# TODO: mopidy backends orther than local files
|
||||
music_daemon: mpd
|
||||
|
||||
# 'openssh' --> openssh-client-default
|
||||
# 'dropbear' --> dropbear-dbclient
|
||||
ssh_client: openssh
|
||||
|
||||
# NOTE: only OpenSSH can be used for SSH commit signing
|
||||
gitcommit_sign_method: openpgp
|
||||
|
||||
# List of terminal emulators, in precedence order
|
||||
terminal_emulators:
|
||||
- foot
|
||||
- alacritty
|
||||
|
||||
buildkit:
|
||||
# Set to false to use OCI worker. All other options will be ignored
|
||||
containerd_worker: true
|
||||
# "k8s.io" for Kubernetes, "default" for normal containerd, "buildkit" for buildkit
|
||||
containerd_namespace: default
|
||||
# Use "native" on ZFS
|
||||
containerd_snapshotter: overlayfs
|
||||
|
||||
# RedHat recommends 0077 for a secure server
|
||||
# 0027 is a good in-between for desktop usage (0022 is the default)
|
||||
umask: '0027'
|
||||
|
||||
# Leave jq behind! `jaq`, `gojq` and `yq` are here for the rescue
|
||||
jq_binary: /usr/bin/gojq
|
||||
|
||||
# XDG directory spec (need to be absolute paths here)
|
||||
xdg_dir:
|
||||
bin_home: '{{ ansible_user_dir }}/.local/bin'
|
||||
cache_home: '{{ ansible_user_dir }}/.cache'
|
||||
config_home: '{{ ansible_user_dir }}/.config'
|
||||
data_home: '{{ ansible_user_dir }}/.local/share'
|
||||
state_home: '{{ ansible_user_dir }}/.local/state'
|
||||
|
||||
# This is not in XDG spec, but it's used here as a user-scoped /usr/libexec
|
||||
libexec_dir: '{{ ansible_user_dir }}/.local/libexec'
|
219
group_vars/all/system.yml
Normal file
219
group_vars/all/system.yml
Normal file
|
@ -0,0 +1,219 @@
|
|||
---
|
||||
# Choices of components ────────────────────────────────────────────────────────────
|
||||
# NOTE: verified with `requirements/accepted_variables.yml`, so keep them as top-level
|
||||
|
||||
snapshot_tool: btrbk
|
||||
|
||||
initramfs_generator: mkinitfs
|
||||
|
||||
usershell: fish
|
||||
|
||||
seat_manager: seatd
|
||||
|
||||
dhcp_client: udhcpc
|
||||
|
||||
# acpid implementation to use when elogind is not present
|
||||
acpid_daemon: busybox
|
||||
|
||||
device_manager: udev
|
||||
|
||||
crond_provider: cronie
|
||||
|
||||
syslog_provider: busybox
|
||||
|
||||
ntp_client: ntpsec
|
||||
|
||||
dns_resolver: dnscrypt-proxy
|
||||
|
||||
sudo_provider: doas
|
||||
|
||||
# Configurations ───────────────────────────────────────────────────────────────────
|
||||
|
||||
repository: https://ftp.udx.icscoe.jp/Linux/alpine
|
||||
|
||||
username: follie
|
||||
|
||||
# Don't specify "seat" or "polkitd" group here
|
||||
usergroups: [wheel, input, audio, video, libvirt, users, pipewire]
|
||||
|
||||
# Commands the wheel group is allowed to run without password
|
||||
nopasswd_commands: [halt, reboot, poweroff, pm-suspend, dhcp_release]
|
||||
|
||||
# Public NTP pools: https://www.ntppool.org/en/use.html
|
||||
# Public NTS-enabled servers: https://github.com/jauderho/nts-servers
|
||||
ntp_opts:
|
||||
# NOTE: peer option isn't available in ntpsec.
|
||||
# Also, we are just the NTP client => no need to exchange time with anyone
|
||||
pools: []
|
||||
servers:
|
||||
- time.cloudflare.com
|
||||
- ntpmon.dcs1.biz
|
||||
- nts.netnod.se
|
||||
- ntp.zeitgitter.net
|
||||
- virginia.time.system76.com
|
||||
- ntp3.fau.de
|
||||
- gps.ntp.br
|
||||
# include 'nts' option on each server directive (common NTP pools don't support NTS yet)
|
||||
nts_enabled: true
|
||||
|
||||
dnscrypt:
|
||||
adblock: true
|
||||
server_names:
|
||||
- quad9-doh-ip4-port443-filter-pri
|
||||
- quad9-doh-ip6-port443-filter-pri
|
||||
- quad9-dnscrypt-ip4-filter-pri
|
||||
- cloudflare-security
|
||||
- cloudflare-security-ipv6
|
||||
bootstrap_resolvers: [9.9.9.9:53, 1.1.1.1:53]
|
||||
netprobe_address: 1.1.1.1:53
|
||||
local_doh:
|
||||
enabled: false
|
||||
listen_addresses: [127.0.0.1:3012]
|
||||
path: '/dns-query'
|
||||
anonymized_dns: # not compatible with DoH and ODoH servers
|
||||
enabled: false
|
||||
routes:
|
||||
- server_name: '*'
|
||||
via:
|
||||
- anon-tiarap
|
||||
- anon-tiarap-ipv6
|
||||
- anon-cs-tokyo
|
||||
- anon-cs-sk
|
||||
|
||||
unbound_upstream_nameservers:
|
||||
- 9.9.9.9@853#dns.quad9.net
|
||||
- 149.112.112.112@853#dns.quad9.net
|
||||
- 2620:fe::fe@853#dns.quad9.net
|
||||
- 2620:fe::9@853#dns.quad9.net
|
||||
- 1.1.1.1@853#cloudflare-dns.com
|
||||
- 1.0.0.1@853#cloudflare-dns.com
|
||||
- 2606:4700:4700::1111@853#cloudflare-dns.com
|
||||
- 2606:4700:4700::1001@853#cloudflare-dns.com
|
||||
|
||||
# Enable/Disable access to /sys/firmware/efi/efivars
|
||||
disable_uefi_access: false
|
||||
|
||||
# Should polkit be used
|
||||
# NOTE: have no effect when seat_manager == 'elogind'
|
||||
use_polkit: false
|
||||
|
||||
# Should be a file name existed inside /usr/share/consolefonts/
|
||||
console_font: ter-h22b.psf.gz
|
||||
|
||||
# 'virtlockd' and 'virtlogd' will always be started so don't list them here
|
||||
libvirt_daemons:
|
||||
- virtinterfaced
|
||||
- virtnetworkd
|
||||
- virtnodedevd
|
||||
- virtqemud
|
||||
- virtstoraged
|
||||
- virtproxyd
|
||||
|
||||
# Whether to use `iwd` or `eiwd`
|
||||
iwd_without_dbus: false
|
||||
|
||||
# RFC 7217: generate a stable IPv6 link-local address for SLAAC
|
||||
# NOTE: this is the default for dhcpcd (slaac private), and `stable-privacy` flag doesn't appear in `ip a` in this case
|
||||
ipv6_stable_privacy_addr: true
|
||||
|
||||
# Public facing network interfaces to configured
|
||||
# - ip4_addr, ip6_addr should include netmask (e.g. 192.168.1.10/24)
|
||||
# - don't include wireless interfaces here as they should use dhcp with iwctl
|
||||
# - udhcpc: https://wiki.alpinelinux.org/wiki/Configure_Networking
|
||||
network_interfaces:
|
||||
- name: eth0
|
||||
ip4_type: dhcp
|
||||
ip6_type: auto
|
||||
|
||||
# Punching holes on the machine
|
||||
# 546/UDP (IPv6 link-local client) is hardcoded (opened) so don't specify it here
|
||||
opened_ports:
|
||||
tcp: []
|
||||
udp: []
|
||||
|
||||
# earlyoom kills processes on its own so make it optional
|
||||
earlyoom:
|
||||
set_priority: true
|
||||
mem_min_percent: 5,2
|
||||
swap_min_percent: 10,5
|
||||
|
||||
# auditd by default rotates its logfile when reaching file size limit
|
||||
auditd_logrotate_daily: false
|
||||
|
||||
# Configuration for filesystem snapshot tools ─────────────────────────────────
|
||||
|
||||
snapper:
|
||||
- name: home
|
||||
subvolume: /home
|
||||
pre_post_cleanup:
|
||||
enabled: true
|
||||
number_cleanup:
|
||||
enabled: false
|
||||
timeline:
|
||||
cleanup_enabled: true
|
||||
min_age: 1800
|
||||
hourly: 8
|
||||
daily: 4
|
||||
weekly: 2
|
||||
monthly: 0
|
||||
yearly: 0
|
||||
- name: root
|
||||
subvolume: /
|
||||
pre_post_cleanup:
|
||||
enabled: true
|
||||
min_age: 900
|
||||
number_cleanup:
|
||||
enabled: true
|
||||
min_age: 1800
|
||||
limit: 10-30
|
||||
limit_important: 10
|
||||
timeline:
|
||||
cleanup_enabled: false
|
||||
|
||||
# NOTE: some caveats to reduce config complexity
|
||||
# - use the same targets for all subvolumes in each volume definition
|
||||
# - use the same global retention policy for snapshot/backup/archive
|
||||
# - there's only 1 global ssh config, 1 global crontab
|
||||
btrbk:
|
||||
cron:
|
||||
hourly: snapshot
|
||||
daily: resume
|
||||
options:
|
||||
lockfile: /var/lock/btrbk.lock
|
||||
logfile: /var/log/btrbk.log
|
||||
syslog: cron
|
||||
timestamp_format: long
|
||||
snapshot:
|
||||
min_age: 6h
|
||||
policy: 16h 8d 4w 2m
|
||||
volumes:
|
||||
- path: /mnt/root
|
||||
snapshot_dir: '@snapshots'
|
||||
subvolumes: ['@home', '@']
|
||||
- path: /mnt/media
|
||||
snapshot_dir: '@snapshots'
|
||||
subvolumes: ['@']
|
||||
|
||||
# See /etc/sanoid/sanoid.defaults.conf file for all config options
|
||||
sanoid:
|
||||
templates:
|
||||
production:
|
||||
frequent_period: 30
|
||||
hourly: 16
|
||||
daily: 8
|
||||
weekly: 4
|
||||
monthly: 2
|
||||
autosnap: 'yes'
|
||||
autoprune: 'yes'
|
||||
datasets:
|
||||
rpool/ALPINE/root:
|
||||
use_template: production
|
||||
rpool/ALPINE/home:
|
||||
use_template: production
|
||||
frequent_period: 15
|
||||
|
||||
zrepl:
|
||||
|
||||
# Secrets encrypted with ansible-vault ────────────────────────────────────────
|
||||
|
||||
password: '{{ vault_password }}'
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
theme: nord
|
||||
|
||||
gtk_theme: Nordic
|
||||
|
||||
icon_theme: Papirus-Dark
|
||||
|
||||
cursor_theme: Bibata-Modern-Ice
|
||||
|
||||
cursor_size: 24
|
||||
|
||||
# Transparency of Waybar, launchers (wofi, rofi, fuzzle) and terminals
|
||||
ui_opacity: 0.96
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
user_name: Hoang Nguyen
|
||||
|
||||
user_email: folliekazetani@protonmail.com
|
||||
|
||||
user_agent: Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0
|
||||
|
||||
user_gpg_signature: B0567C20730E9B11
|
2
inventory.toml
Normal file
2
inventory.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[local.hosts]
|
||||
localhost = { ansible_connection = "local" }
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
local:
|
||||
hosts:
|
||||
localhost:
|
||||
ansible_connection: local
|
|
@ -1,26 +1,25 @@
|
|||
---
|
||||
- name: Gather facts and do some checks
|
||||
- name: Deploy user configuration
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
tags: always
|
||||
tasks:
|
||||
- name: Check defined variables
|
||||
import_tasks: ../tasks/check_variables.yml
|
||||
- name: Check other facts
|
||||
import_tasks: ../tasks/check_other.yml
|
||||
- name: Import color variables for {{ theme }}
|
||||
include_vars:
|
||||
name: colors
|
||||
file: ../themes/{{ theme }}.yml
|
||||
|
||||
- name: Deploy dotfiles
|
||||
hosts: all
|
||||
# These variables shouldn't be changed
|
||||
vars:
|
||||
dmenu_flag: '{{ "-dmenu -i" if launcher == "rofi"
|
||||
else "-d -i -O default" if launcher == "wofi"
|
||||
else "-d" }}'
|
||||
font_size_px: '{{ (font_size * 96.0 / 72.0) | int }}' # 96px = 1in = 72pt --> e.g. 13.5pt = 18px
|
||||
pre_tasks:
|
||||
- name: Run pre-deploy checks
|
||||
tags: always
|
||||
block:
|
||||
- name: Check defined variables
|
||||
import_tasks: ../tasks/check_variables.yml
|
||||
- name: Check other facts
|
||||
import_tasks: ../tasks/check_other.yml
|
||||
- name: Import color variables for {{ theme }}
|
||||
include_vars:
|
||||
name: colors
|
||||
file: ../themes/{{ theme }}.yml
|
||||
roles:
|
||||
- role: scripts
|
||||
tags: scripts
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
---
|
||||
# This playbook should be run in trunks with tags
|
||||
# This playbook should be run in trunks using tags
|
||||
- name: Tasks unrelated to dotfiles management
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
roles:
|
||||
- role: chroot
|
||||
tags: chroot
|
||||
- role: containers
|
||||
tags: containers
|
||||
- role: packages
|
||||
|
|
26
playbooks/system.yml
Normal file
26
playbooks/system.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
- name: Setup the system
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
pre_tasks:
|
||||
- name: Sanity checks
|
||||
tags: always
|
||||
block:
|
||||
- name: Check user ID
|
||||
fail:
|
||||
msg: This playbook should be run as 'root'
|
||||
when: ansible_real_user_id != 0
|
||||
- name: Import list of accepted values for custom variables
|
||||
include_vars:
|
||||
name: accepted_values
|
||||
file: ../requirements/assert.yml
|
||||
- name: Check defined values of top-level variables
|
||||
fail:
|
||||
msg: 'Variable `{{ item }}` needs to be 1 of {{ accepted_values[item] }}'
|
||||
when: not vars[item] in accepted_values[item]
|
||||
loop: '{{ accepted_values | flatten }}'
|
||||
- name: Get ZFS pool facts
|
||||
community.general.zpool_facts:
|
||||
tags: always
|
||||
roles:
|
||||
- role: system
|
|
@ -1,4 +1,6 @@
|
|||
---
|
||||
# Dotfiles ────────────────────────────────────────────────────────────
|
||||
|
||||
theme:
|
||||
- nord
|
||||
- onedark
|
||||
|
@ -43,3 +45,78 @@ image_viewer:
|
|||
- qimgv
|
||||
- vimiv # the Qt version
|
||||
- imv
|
||||
|
||||
# System ────────────────────────────────────────────────────────────
|
||||
|
||||
initramfs_generator:
|
||||
- mkinitfs
|
||||
- dracut
|
||||
- booster
|
||||
|
||||
snapshot_tool:
|
||||
- btrbk
|
||||
- sanoid
|
||||
- snapper
|
||||
- zrepl
|
||||
|
||||
# NOTE: Keep this in sync with `shell_mappings` in roles/system/defaults/main.yml
|
||||
usershell:
|
||||
- ash
|
||||
- bash
|
||||
- dash
|
||||
- fish
|
||||
- hilbish
|
||||
- ion-shell
|
||||
- nushell
|
||||
- sh
|
||||
- xonsh
|
||||
- yash
|
||||
- zsh
|
||||
|
||||
seat_manager:
|
||||
- seatd
|
||||
- elogind
|
||||
|
||||
acpid_daemon:
|
||||
- busybox
|
||||
- acpid
|
||||
|
||||
device_manager:
|
||||
- mdev
|
||||
- mdevd
|
||||
- udev
|
||||
|
||||
# udhcpc, dhclient, dhcpcd are configured with 'networking' service using ifupdown-ng,
|
||||
# in that same priority (/usr/libexec/ifupdown-ng/dhcp)
|
||||
dhcp_client:
|
||||
- udhcpc # from busybox
|
||||
- dhcpcd
|
||||
- dhclient
|
||||
- connman
|
||||
- kea
|
||||
|
||||
crond_provider:
|
||||
- busybox
|
||||
- cronie
|
||||
- fcron
|
||||
|
||||
syslog_provider:
|
||||
- busybox
|
||||
- logbookd
|
||||
- rsyslog
|
||||
- sysklogd
|
||||
|
||||
ntp_client:
|
||||
- ntpsec
|
||||
- busybox
|
||||
- openntpd
|
||||
- chrony
|
||||
|
||||
dns_resolver:
|
||||
- dnscrypt-proxy
|
||||
- unbound
|
||||
|
||||
sudo_provider:
|
||||
- doas
|
||||
- please
|
||||
- sudo
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
collections:
|
||||
- name: ansible.posix
|
||||
- name: community.crypto
|
||||
- name: community.general
|
||||
- name: containers.podman
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
chroot_dir: '{{ ansible_user_dir }}/Alpine-chroot'
|
||||
apk_repository:
|
||||
- https://dl-cdn.alpinelinux.org/alpine
|
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
- name: chroot | Setup an AlpineLinux chroot
|
||||
become: true
|
||||
block:
|
||||
- name: chroot | Ensure the chroot directory exists
|
||||
file:
|
||||
path: '{{ chroot_dir }}'
|
||||
state: directory
|
||||
mode: '755'
|
||||
|
||||
- name: chroot | Create the chroot
|
||||
command:
|
||||
cmd: '/sbin/apk -X {{ apk_repository }}/edge/main -U --allow-untrusted -p {{ chroot_dir }} --initdb add alpine-base'
|
||||
creates: '{{ chroot_dir }}/bin/busybox'
|
||||
|
||||
- name: chroot | Update the repository urls
|
||||
template:
|
||||
src: repositories.j2
|
||||
dest: '{{ chroot_dir }}/etc/apk/repositories'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: chroot | Install a stupid script for chrooting
|
||||
template:
|
||||
src: alpine-chroot.j2
|
||||
dest: '{{ xdg_dir.bin_home }}/alpine-chroot'
|
||||
mode: '755'
|
|
@ -1,29 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Super stupid and lazy way to chroot
|
||||
# Borrow some stuff from https://github.com/alpinelinux/alpine-chroot-install
|
||||
|
||||
chroot_dir="{{ chroot_dir }}"
|
||||
|
||||
user='root'
|
||||
if [ $# -ge 2 ] && [ "$1" = '-u' ]; then
|
||||
user="$2"; shift 2
|
||||
fi
|
||||
|
||||
[ "$(id -u)" -eq 0 ] || _sudo='doas'
|
||||
|
||||
# Pre
|
||||
$_sudo mount -t proc none "${chroot_dir}/proc"
|
||||
$_sudo mount -o bind,ro /dev "${chroot_dir}/dev"
|
||||
$_sudo mount -o bind,ro /sys "${chroot_dir}/sys"
|
||||
$_sudo cp -L /etc/resolv.conf "${chroot_dir}/etc/"
|
||||
|
||||
# chroot
|
||||
$_sudo chroot "${chroot_dir}" /usr/bin/env -i su -l "$user" \
|
||||
sh -c ". /etc/profile; \"\$@\"" \
|
||||
-- "${@:-sh}"
|
||||
|
||||
# Post
|
||||
$_sudo umount -l "${chroot_dir}/dev"
|
||||
$_sudo umount -l "${chroot_dir}/proc"
|
||||
$_sudo umount -l "${chroot_dir}/sys"
|
|
@ -1,6 +0,0 @@
|
|||
{% for repo in apk_repository %}
|
||||
{{ repo }}/edge/main
|
||||
{{ repo }}/edge/community
|
||||
{{ repo }}/edge/testing
|
||||
|
||||
{% endfor %}
|
|
@ -62,7 +62,7 @@
|
|||
dest: '{{ xdg_dir.config_home }}/fish/functions/fzf_key_bindings.fish'
|
||||
mode: '644'
|
||||
|
||||
- name: fish | Install fisher
|
||||
- name: fish | Install fisher # noqa: risky-shell-pipe command-instead-of-module
|
||||
shell: /usr/bin/curl -sSL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher
|
||||
args:
|
||||
executable: /usr/bin/fish
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
dest: /tmp/Anime4K.zip
|
||||
mode: '644'
|
||||
|
||||
- name: mpv | Unzip Anime4K shaders
|
||||
- name: mpv | Unzip Anime4K shaders # noqa: command-instead-of-module
|
||||
command: unzip /tmp/Anime4K.zip -d ~/.config/mpv/shaders
|
||||
args:
|
||||
creates: '{{ xdg_dir.config_home }}/mpv/shaders/Anime4K_Clamp_Highlights.glsl'
|
||||
|
@ -43,7 +43,7 @@
|
|||
dest: /tmp/material-design-iconic-font.zip
|
||||
mode: '644'
|
||||
|
||||
- name: mpv | Unzip Material Design Iconic font
|
||||
- name: mpv | Unzip Material Design Iconic font # noqa: command-instead-of-module
|
||||
command: unzip -j /tmp/material-design-iconic-font.zip fonts/Material-Design-Iconic-Font.ttf -d ~/.config/mpv/fonts
|
||||
args:
|
||||
creates: '{{ xdg_dir.config_home }}/mpv/fonts/Material-Design-Iconic-Font.ttf'
|
||||
|
|
|
@ -54,25 +54,57 @@ end = { foreground = "{{ colors.green }}", background = "{{ colors.background }}
|
|||
foreground = "{{ colors.background }}"
|
||||
background = "{{ colors.foreground }}"
|
||||
|
||||
{% if theme == 'nord' %}
|
||||
[colors.normal]
|
||||
black = "{{ colors.color0 }}"
|
||||
red = "{{ colors.color1 }}"
|
||||
green = "{{ colors.color2 }}"
|
||||
yellow = "{{ colors.color3 }}"
|
||||
blue = "{{ colors.color4 }}"
|
||||
magenta = "{{ colors.color5 }}"
|
||||
cyan = "{{ colors.color6 }}"
|
||||
white = "{{ colors.color7 }}"
|
||||
black = "#3b4252"
|
||||
red = "#bf616a"
|
||||
green = "#a3be8c"
|
||||
yellow = "#ebcb8b"
|
||||
blue = "#81a1c1"
|
||||
magenta = "#b48ead"
|
||||
cyan = "#88c0d0"
|
||||
white = "#e5e9f0"
|
||||
|
||||
[colors.bright]
|
||||
black = "{{ colors.color8 }}"
|
||||
red = "{{ colors.color9 }}"
|
||||
green = "{{ colors.color10 }}"
|
||||
yellow = "{{ colors.color11 }}"
|
||||
blue = "{{ colors.color12 }}"
|
||||
magenta = "{{ colors.color13 }}"
|
||||
cyan = "{{ colors.color14 }}"
|
||||
white = "{{ colors.color15 }}"
|
||||
black = "#4c566a"
|
||||
red = "#bf616a"
|
||||
green = "#a3be8c"
|
||||
yellow = "#ebcb8b"
|
||||
blue = "#81a1c1"
|
||||
magenta = "#b48ead"
|
||||
cyan = "#8fbcbb"
|
||||
white = "#eceff4"
|
||||
|
||||
[colors.dim]
|
||||
black = "#373e4d"
|
||||
red = "#94545d"
|
||||
green = "#809575"
|
||||
yellow = "#b29e75"
|
||||
blue = "#68809a"
|
||||
magenta = "#8c738c"
|
||||
cyan = "#6d96a5"
|
||||
white = "#aeb3bb"
|
||||
{% elif theme == 'onedark' %}
|
||||
[colors.normal]
|
||||
black = "#282c34"
|
||||
red = "#be5046"
|
||||
green = "#98c379"
|
||||
yellow = "#d19a66"
|
||||
blue = "#61afef"
|
||||
magenta = "#c678dd"
|
||||
cyan = "#56b6c2"
|
||||
white = "#abb2bf"
|
||||
|
||||
[colors.bright]
|
||||
black = "#5c6370"
|
||||
red = "#e06c75"
|
||||
green = "#98c379"
|
||||
yellow = "#e5c07b"
|
||||
blue = "#61afef"
|
||||
magenta = "#c678dd"
|
||||
cyan = "#56b6c2"
|
||||
white = "#ffffff"
|
||||
{% endif %}
|
||||
|
||||
[bell]
|
||||
animation = "EaseOutExpo"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Some functionality uses this to identify you
|
||||
(setq user-full-name "{{ user_name }}"
|
||||
(setq user-full-name "{{ user_fullname }}"
|
||||
user-mail-address "{{ user_email }}")
|
||||
|
||||
(setq-default
|
||||
|
|
|
@ -35,20 +35,49 @@ alpha={{ ui_opacity }}
|
|||
foreground={{ colors.foreground | regex_replace('^#', '') }}
|
||||
background={{ colors.background | regex_replace('^#', '') }}
|
||||
|
||||
regular0={{ colors.color0 | regex_replace('^#', '') }}
|
||||
regular1={{ colors.color1 | regex_replace('^#', '') }}
|
||||
regular2={{ colors.color2 | regex_replace('^#', '') }}
|
||||
regular3={{ colors.color3 | regex_replace('^#', '') }}
|
||||
regular4={{ colors.color4 | regex_replace('^#', '') }}
|
||||
regular5={{ colors.color5 | regex_replace('^#', '') }}
|
||||
regular6={{ colors.color6 | regex_replace('^#', '') }}
|
||||
regular7={{ colors.color7 | regex_replace('^#', '') }}
|
||||
{% if theme == 'nord' %}
|
||||
regular0=3b4252
|
||||
regular1=bf616a
|
||||
regular2=a3be8c
|
||||
regular3=ebcb8b
|
||||
regular4=81a1c1
|
||||
regular5=b48ead
|
||||
regular6=88c0d0
|
||||
regular7=e5e9f0
|
||||
|
||||
bright0={{ colors.color8 | regex_replace('^#', '') }}
|
||||
bright1={{ colors.color9 | regex_replace('^#', '') }}
|
||||
bright2={{ colors.color10 | regex_replace('^#', '') }}
|
||||
bright3={{ colors.color11 | regex_replace('^#', '') }}
|
||||
bright4={{ colors.color12 | regex_replace('^#', '') }}
|
||||
bright5={{ colors.color13 | regex_replace('^#', '') }}
|
||||
bright6={{ colors.color14 | regex_replace('^#', '') }}
|
||||
bright7={{ colors.color15 | regex_replace('^#', '') }}
|
||||
bright0=4c566a
|
||||
bright1=bf616a
|
||||
bright2=a3be8c
|
||||
bright3=ebcb8b
|
||||
bright4=81a1c1
|
||||
bright5=b48ead
|
||||
bright6=8fbcbb
|
||||
bright7=eceff4
|
||||
|
||||
dim0=373e4d
|
||||
dim1=94545d
|
||||
dim2=809575
|
||||
dim3=b29e75
|
||||
dim4=68809a
|
||||
dim5=8c738c
|
||||
dim6=6d96a5
|
||||
dim7=aeb3bb
|
||||
{% elif theme == 'onedark' %}
|
||||
regular0=282c34
|
||||
regular1=be5046
|
||||
regular2=98c379
|
||||
regular3=d19a66
|
||||
regular4=61afef
|
||||
regular5=c678dd
|
||||
regular6=56b6c2
|
||||
regular7=abb2bf
|
||||
|
||||
bright0=5c6370
|
||||
bright1=e06c75
|
||||
bright2=98c379
|
||||
bright3=e5c07b
|
||||
bright4=61afef
|
||||
bright5=c678dd
|
||||
bright6=56b6c2
|
||||
bright7=ffffff
|
||||
{% endif %}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
sshCommand = dbclient -y
|
||||
{% endif %}
|
||||
[user]
|
||||
name = {{ user_name }}
|
||||
name = {{ user_fullname }}
|
||||
email = {{ user_email }}
|
||||
{% if ssh_client == 'openssh' and gitcommit_sign_method == 'ssh' %}
|
||||
signingKey = {{ user_ssh_key_path | default('~/.ssh/id_ed25519') }}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
ltex_ls_version: 16.0.0
|
||||
|
||||
marksman_version: 2023-12-09
|
||||
marksman_version: '2023-12-09'
|
||||
|
||||
translate_shell_version: 0.9.7.1
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
path: '{{ gcloud.dir }}/google-cloud-sdk'
|
||||
state: absent
|
||||
|
||||
- name: gcloud | Extract downloaded release tarball
|
||||
- name: gcloud | Extract downloaded release tarball # noqa: command-instead-of-module
|
||||
command:
|
||||
cmd: tar -xzf /tmp/gcloud.tar.gz
|
||||
chdir: '{{ gcloud.dir }}'
|
||||
|
|
105
roles/system/defaults/main.yml
Normal file
105
roles/system/defaults/main.yml
Normal file
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
# Lookup: https://dnscrypt.info/public-servers
|
||||
# List of servers:
|
||||
# - https://github.com/DNSCrypt/dnscrypt-resolvers
|
||||
# - https://github.com/DNSCrypt/dnscrypt-proxy/wiki/DNS-server-sources
|
||||
|
||||
dnscrypt_server_sources:
|
||||
- name: public-resolvers
|
||||
urls:
|
||||
- https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md
|
||||
- https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md
|
||||
- https://dnsr.evilvibes.com/v3/public-resolvers.md
|
||||
- https://cdn.staticaly.com/gh/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md
|
||||
- https://ipv6.download.dnscrypt.info/resolvers-list/v3/public-resolvers.md
|
||||
cache_file: /var/cache/dnscrypt-proxy/public-resolvers.md
|
||||
minisign_key: RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
||||
refresh_delay: 72
|
||||
prefix: ''
|
||||
|
||||
- name: relays
|
||||
urls:
|
||||
- https://download.dnscrypt.info/resolvers-list/v3/relays.md
|
||||
- https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/relays.md
|
||||
- https://dnsr.evilvibes.com/v3/relays.md
|
||||
- https://cdn.staticaly.com/gh/DNSCrypt/dnscrypt-resolvers/master/v3/relays.md
|
||||
cache_file: /var/cache/dnscrypt-proxy/relays.md
|
||||
minisign_key: RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
||||
refresh_delay: 72
|
||||
prefix: ''
|
||||
|
||||
- name: odoh-servers
|
||||
urls:
|
||||
- https://download.dnscrypt.info/resolvers-list/v3/odoh-servers.md
|
||||
- https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-servers.md
|
||||
- https://dnsr.evilvibes.com/v3/odoh-servers.md
|
||||
- https://cdn.staticaly.com/gh/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-servers.md
|
||||
cache_file: /var/cache/dnscrypt-proxy/odoh-servers.md
|
||||
minisign_key: RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
||||
refresh_delay: 24
|
||||
prefix: ''
|
||||
|
||||
- name: odoh-relays
|
||||
urls:
|
||||
- https://download.dnscrypt.info/resolvers-list/v3/odoh-relays.md
|
||||
- https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-relays.md
|
||||
- https://dnsr.evilvibes.com/v3/odoh-relays.md
|
||||
- https://cdn.staticaly.com/gh/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-relays.md
|
||||
cache_file: /var/cache/dnscrypt-proxy/odoh-relays.md
|
||||
minisign_key: RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
||||
refresh_delay: 24
|
||||
prefix: ''
|
||||
|
||||
- name: opennic
|
||||
urls:
|
||||
- https://download.dnscrypt.info/dnscrypt-resolvers/v3/opennic.md
|
||||
- https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/opennic.md
|
||||
- https://dnsr.evilvibes.com/v3/opennic.md
|
||||
- https://cdn.staticaly.com/gh/DNSCrypt/dnscrypt-resolvers/master/v3/opennic.md
|
||||
cache_file: /var/cache/dnscrypt-proxy/opennic.md
|
||||
minisign_key: RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
||||
refresh_delay: 72
|
||||
prefix: ''
|
||||
|
||||
# - name: quad9-resolvers
|
||||
# urls:
|
||||
# - https://www.quad9.net/quad9-resolvers.md
|
||||
# - https://raw.githubusercontent.com/Quad9DNS/dnscrypt-settings/main/dnscrypt/quad9-resolvers.md
|
||||
# - https://quad9.net/dnscrypt/quad9-resolvers.md
|
||||
# cache_file: /var/cache/dnscrypt-proxy/quad9.md
|
||||
# minisign_key: RWQBphd2+f6eiAqBsvDZEBXBGHQBJfeG6G+wJPPKxCZMoEQYpmoysKUN
|
||||
# refresh_delay: 72
|
||||
# prefix: 'quad9-'
|
||||
|
||||
# - name: onion-services
|
||||
# urls:
|
||||
# - https://download.dnscrypt.info/dnscrypt-resolvers/v3/onion-services.md
|
||||
# - https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/onion-services.md
|
||||
# - https://dnsr.evilvibes.com/v3/onion-services.md
|
||||
# - https://cdn.staticaly.com/gh/DNSCrypt/dnscrypt-resolvers/master/v3/onion-services.md
|
||||
# cache_file: /var/cache/dnscrypt-proxy/onion-services.md
|
||||
# minisign_key: RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3
|
||||
# refresh_delay: 72
|
||||
# prefix: ''
|
||||
|
||||
libvirt_daemons_conf:
|
||||
- unix_sock_group = "libvirt"
|
||||
- unix_sock_ro_perms = "0770"
|
||||
- unix_sock_rw_perms = "0770"
|
||||
- auth_unix_ro = "none"
|
||||
- auth_unix_rw = "none"
|
||||
|
||||
shells_mappings:
|
||||
ash: /bin/ash
|
||||
bash: /bin/bash
|
||||
dash: /usr/bin/dash
|
||||
fish: /usr/bin/fish
|
||||
hilbish: /usr/bin/hilbish
|
||||
ion-shell: /usr/bin/ion
|
||||
nushell: /usr/bin/nu
|
||||
sh: /bin/sh
|
||||
xonsh: /usr/bin/xonsh
|
||||
yash: /usr/bin/yash
|
||||
zsh: /bin/zsh
|
||||
|
||||
zram_num_devices: 3
|
2
roles/system/files/acpi/acpid_lid_close
Normal file
2
roles/system/files/acpi/acpid_lid_close
Normal file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
echo mem > /sys/power/state
|
30
roles/system/files/acpi/handler.sh
Normal file
30
roles/system/files/acpi/handler.sh
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/bin/sh
|
||||
|
||||
PATH="/usr/share/acpid:$PATH"
|
||||
alias log='logger -t acpid'
|
||||
|
||||
# <dev-class>:<dev-name>:<notif-value>:<sup-value>
|
||||
case "$1:$2:$3:$4" in
|
||||
|
||||
button/power:PWRF:* | button/power:PBTN:*)
|
||||
log 'Power button pressed'
|
||||
poweroff
|
||||
;;
|
||||
button/sleep:SLPB:*)
|
||||
log 'Sleep button pressed'
|
||||
# Suspend to RAM.
|
||||
echo mem > /sys/power/state
|
||||
;;
|
||||
button/lid:*:close:*)
|
||||
log 'Lid closed'
|
||||
# Suspend to RAM if AC adapter is not connected.
|
||||
[ "$(power-supply -d adapter -s)" = "offline" ] && echo mem > /sys/power/state
|
||||
;;
|
||||
ac_adapter:*:*:*0)
|
||||
log 'AC adapter unplugged'
|
||||
# Suspend to RAM if notebook's lid is closed.
|
||||
lid-state -c && echo mem > /sys/power/state
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
18
roles/system/files/acpi/logind.conf
Normal file
18
roles/system/files/acpi/logind.conf
Normal file
|
@ -0,0 +1,18 @@
|
|||
# See logind.conf(5) for details.
|
||||
|
||||
[Login]
|
||||
HandlePowerKey=poweroff
|
||||
HandleSuspendKey=suspend
|
||||
HandleLidSwitch=suspend
|
||||
HandleLidSwitchExternalPower=suspend
|
||||
PowerKeyIgnoreInhibited=no
|
||||
SuspendKeyIgnoreInhibited=no
|
||||
LidSwitchIgnoreInhibited=yes
|
||||
HoldoffTimeoutSec=30s
|
||||
IdleActionSec=30min
|
||||
|
||||
[Sleep]
|
||||
AllowSuspend=yes
|
||||
AllowPowerOffInterrupts=no
|
||||
AllowSuspendInterrupts=no
|
||||
SuspendState=mem standby freeze
|
25
roles/system/files/auditd/auditd.conf
Normal file
25
roles/system/files/auditd/auditd.conf
Normal file
|
@ -0,0 +1,25 @@
|
|||
# /etc/audit/auditd.conf
|
||||
# See auditd.conf(5)
|
||||
|
||||
local_events = yes
|
||||
log_file = /var/log/audit/audit.log
|
||||
write_logs = yes
|
||||
log_format = ENRICHED
|
||||
log_group = root
|
||||
flush = INCREMENTAL_ASYNC
|
||||
freq = 50
|
||||
num_logs = 7
|
||||
name_format = NONE
|
||||
max_log_file = 8
|
||||
max_log_file_action = ROTATE
|
||||
verify_email = yes
|
||||
space_left = 100
|
||||
space_left_action = SYSLOG
|
||||
admin_space_left = 75
|
||||
admin_space_left_action = SUSPEND
|
||||
disk_full_action = SUSPEND
|
||||
disk_error_action = SUSPEND
|
||||
overflow_action = SYSLOG
|
||||
max_restarts = 5
|
||||
plugin_dir = /etc/audit/plugins.d
|
||||
end_of_event_timeout = 2
|
4
roles/system/files/auditd/cron
Normal file
4
roles/system/files/auditd/cron
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
# auditd rotates its logfile on receiving SIGUSR1
|
||||
/usr/bin/pkill -USR1 -x /usr/sbin/auditd
|
4
roles/system/files/cron/empty-tmp
Normal file
4
roles/system/files/cron/empty-tmp
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
/usr/bin/find /var/tmp -type d -mindepth 1 -ctime +7 -exec rm -rf {} \;
|
||||
/usr/bin/find /var/tmp -mindepth 1 -ctime +7 -exec rm -rf {} \;
|
8
roles/system/files/cron/fstrim
Normal file
8
roles/system/files/cron/fstrim
Normal file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
# NOTE: we only trim things inside /etc/fstab to avoid ZFS mount paths
|
||||
# (they will be handled by `zpool trim` cron job)
|
||||
|
||||
# This needs fstrim from util-linux package.
|
||||
# For busybox's fstrim, use multiple 'fstrim /mount_point'.
|
||||
exec /sbin/fstrim -A
|
27
roles/system/files/dns/blocked-ips.txt
Normal file
27
roles/system/files/dns/blocked-ips.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
##############################
|
||||
# IP blocklist #
|
||||
##############################
|
||||
|
||||
# Localhost rebinding protection
|
||||
0.0.0.0
|
||||
127.0.0.*
|
||||
|
||||
# RFC1918 rebinding protection
|
||||
10.*
|
||||
172.16.*
|
||||
172.17.*
|
||||
172.18.*
|
||||
172.19.*
|
||||
172.20.*
|
||||
172.21.*
|
||||
172.22.*
|
||||
172.23.*
|
||||
172.24.*
|
||||
172.25.*
|
||||
172.26.*
|
||||
172.27.*
|
||||
172.28.*
|
||||
172.29.*
|
||||
172.30.*
|
||||
172.31.*
|
||||
192.168.*
|
6
roles/system/files/dns/cloaking-rules.txt
Normal file
6
roles/system/files/dns/cloaking-rules.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
################################
|
||||
# Cloaking rules #
|
||||
################################
|
||||
|
||||
localhost 127.0.0.1
|
||||
localhost ::1
|
33
roles/system/files/dns/domains-blocklist-local-additions.txt
Normal file
33
roles/system/files/dns/domains-blocklist-local-additions.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Local set of patterns to block
|
||||
|
||||
ad.*
|
||||
ads.*
|
||||
banner.*
|
||||
banners.*
|
||||
creatives.*
|
||||
oas.*
|
||||
oascentral.*
|
||||
tag.*
|
||||
telemetry.*
|
||||
tracker.*
|
||||
|
||||
# eth0.me is hardcoded in tools such as Archey, but is not available any
|
||||
# more, causing issues such as terminal sessions taking a long time to
|
||||
# start.
|
||||
|
||||
eth0.me
|
||||
|
||||
# ibpxl.com is a tracker that seems to frequently have issues, causing
|
||||
# page loads to stall.
|
||||
|
||||
ibpxl.com
|
||||
|
||||
# ditto for that one
|
||||
|
||||
internetbrands.com
|
||||
|
||||
# Ubuntu's motd script sends way too much information to Canonical
|
||||
|
||||
motd.ubuntu.com
|
||||
|
||||
*.zip
|
160
roles/system/files/dns/domains-blocklist.conf
Normal file
160
roles/system/files/dns/domains-blocklist.conf
Normal file
|
@ -0,0 +1,160 @@
|
|||
##################################################################################
|
||||
# #
|
||||
# Generate a block list of domains using public data sources, and the local #
|
||||
# domains-blocklist-local-additions.txt file. #
|
||||
# #
|
||||
# The default configuration is just indicative, and corresponds to the one #
|
||||
# used to produce the public "mybase" set. #
|
||||
# #
|
||||
# Comment out the URLs of the sources you wish to disable, leave the ones #
|
||||
# you would like enabled uncommented. Then run the script to build the #
|
||||
# dnscrypt-blocklist-domains.txt file: #
|
||||
# #
|
||||
# $ generate-domains-blocklist.py -o dnscrypt-blocklist-domains.txt #
|
||||
# #
|
||||
# Domains that should never be blocked can be put into a file named #
|
||||
# domains-allowlist.txt. #
|
||||
# #
|
||||
# That blocklist file can then be used in the dnscrypt-proxy.toml file: #
|
||||
# #
|
||||
# [blocked_names] #
|
||||
# #
|
||||
# blocked_names_file = 'dnscrypt-blocklist-domains.txt' #
|
||||
# #
|
||||
##################################################################################
|
||||
|
||||
# Local additions
|
||||
file:/etc/dnscrypt-proxy/adblock/domains-blocklist-local-additions.txt
|
||||
|
||||
# AdAway is an open source ad blocker for Android using the hosts file.
|
||||
# https://raw.githubusercontent.com/AdAway/adaway.github.io/master/hosts.txt
|
||||
|
||||
# EasyList
|
||||
https://easylist-downloads.adblockplus.org/easylist_noelemhide.txt
|
||||
|
||||
# EasyList China
|
||||
# https://easylist-downloads.adblockplus.org/easylistchina.txt
|
||||
|
||||
# RU AdList
|
||||
# https://easylist-downloads.adblockplus.org/advblock.txt
|
||||
|
||||
# Peter Lowe's Ad and tracking server list
|
||||
https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml
|
||||
|
||||
# Spam404
|
||||
https://raw.githubusercontent.com/Spam404/lists/master/main-blacklist.txt
|
||||
|
||||
# Malvertising filter list by Disconnect
|
||||
# https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt
|
||||
|
||||
# Ads filter list by Disconnect
|
||||
# https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
|
||||
|
||||
# Basic tracking list by Disconnect
|
||||
# https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
|
||||
|
||||
# KAD host file (fraud/adware)
|
||||
# https://raw.githubusercontent.com/PolishFiltersTeam/KADhosts/master/KADomains.txt
|
||||
|
||||
# BarbBlock list (spurious and invalid DMCA takedowns)
|
||||
https://paulgb.github.io/BarbBlock/blacklists/domain-list.txt
|
||||
|
||||
# Dan Pollock's hosts list
|
||||
https://someonewhocares.org/hosts/hosts
|
||||
|
||||
# NoTracking's list - blocking ads, trackers and other online garbage
|
||||
https://raw.githubusercontent.com/notracking/hosts-blocklists/master/dnscrypt-proxy/dnscrypt-proxy.blacklist.txt
|
||||
|
||||
# NextDNS CNAME cloaking list
|
||||
https://raw.githubusercontent.com/nextdns/cname-cloaking-blocklist/master/domains
|
||||
|
||||
# AdGuard Simplified Domain Names filter
|
||||
https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
|
||||
|
||||
# Geoffrey Frogeye's block list of first-party trackers - https://hostfiles.frogeye.fr/
|
||||
https://hostfiles.frogeye.fr/firstparty-trackers.txt
|
||||
|
||||
# CoinBlockerLists: blocks websites serving cryptocurrency miners - https://gitlab.com/ZeroDot1/CoinBlockerLists/ - Contains false positives
|
||||
# https://gitlab.com/ZeroDot1/CoinBlockerLists/raw/master/list_browser.txt
|
||||
|
||||
# Websites potentially publishing fake news
|
||||
# https://raw.githubusercontent.com/marktron/fakenews/master/fakenews
|
||||
|
||||
# Quidsup NoTrack Blocklist - Contains too many false positives to be enabled by default
|
||||
# https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-blocklist.txt
|
||||
|
||||
# Quidsup Malware Blocklist - Contains too many false positives to be enabled by default
|
||||
# https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-malware.txt
|
||||
|
||||
# AntiSocial Blacklist is an extensive collection of potentially malicious domains
|
||||
# https://theantisocialengineer.com/AntiSocial_Blacklist_Community_V1.txt
|
||||
|
||||
# Steven Black hosts file
|
||||
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||
|
||||
# A list of adserving and tracking sites maintained by @lightswitch05
|
||||
https://www.github.developerdan.com/hosts/lists/ads-and-tracking-extended.txt
|
||||
|
||||
# A list of adserving and tracking sites maintained by @anudeepND
|
||||
https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt
|
||||
|
||||
# Anudeep's Blacklist (CoinMiner) - Blocks cryptojacking sites
|
||||
# https://raw.githubusercontent.com/anudeepND/blacklist/master/CoinMiner.txt
|
||||
|
||||
### Spark < Blu Go < Blu < Basic < Ultimate
|
||||
### (With pornware blocking) Porn < Unified
|
||||
# Energized Ultimate
|
||||
# https://block.energized.pro/ultimate/formats/domains.txt
|
||||
|
||||
# Energized Basic
|
||||
# https://block.energized.pro/basic/formats/domains.txt
|
||||
|
||||
# Energized BLU
|
||||
# https://block.energized.pro/blu/formats/domains.txt
|
||||
|
||||
# OISD.NL - Blocks ads, phishing, malware, tracking and more. WARNING: this is a huge list.
|
||||
# https://dblw.oisd.nl/
|
||||
|
||||
# OISD.NL (smaller subset) - Blocks ads, phishing, malware, tracking and more. Tries to miminize false positives.
|
||||
https://dblw.oisd.nl/basic/
|
||||
|
||||
# OISD.NL (extra) - Blocks ads, phishing, malware, tracking and more. Protection over functionality.
|
||||
# https://dblw.oisd.nl/extra/
|
||||
|
||||
# Captain Miao ad list - Block ads and trackers, especially Chinese and Android trackers
|
||||
# https://raw.githubusercontent.com/jdlingyu/ad-wars/master/sha_ad_hosts
|
||||
|
||||
# Phishing Army - https://phishing.army/
|
||||
# https://phishing.army/download/phishing_army_blocklist.txt
|
||||
|
||||
# Block pornography
|
||||
# https://raw.githubusercontent.com/Clefspeare13/pornhosts/master/0.0.0.0/hosts
|
||||
# https://raw.githubusercontent.com/Sinfonietta/hostfiles/master/pornography-hosts
|
||||
# https://raw.githubusercontent.com/cbuijs/shallalist/master/porn/domains
|
||||
# https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/adult/domains
|
||||
# https://block.energized.pro/porn/formats/domains.txt
|
||||
# https://raw.githubusercontent.com/mhxion/pornaway/master/hosts/porn_sites.txt
|
||||
# https://dblw.oisd.nl/nsfw/
|
||||
|
||||
# Block gambling sites
|
||||
# https://raw.githubusercontent.com/Sinfonietta/hostfiles/master/gambling-hosts
|
||||
# https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/gambling/domains
|
||||
|
||||
# Block dating websites
|
||||
# https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/dating/domains
|
||||
# https://www.github.developerdan.com/hosts/lists/dating-services-extended.txt
|
||||
|
||||
# Block social media sites
|
||||
# https://raw.githubusercontent.com/Sinfonietta/hostfiles/master/social-hosts
|
||||
# https://block.energized.pro/extensions/social/formats/domains.txt
|
||||
# https://raw.githubusercontent.com/olbat/ut1-blacklists/master/blacklists/social_networks/domains
|
||||
# https://www.github.developerdan.com/hosts/lists/facebook-extended.txt
|
||||
|
||||
# Goodbye Ads - Specially designed for mobile ad protection
|
||||
# https://raw.githubusercontent.com/jerryn70/GoodbyeAds/master/Hosts/GoodbyeAds.txt
|
||||
|
||||
# NextDNS BitTorrent blocklist
|
||||
# https://raw.githubusercontent.com/nextdns/bittorrent-blocklist/master/domains
|
||||
|
||||
# Block spying and tracking on Windows
|
||||
# https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/dnscrypt/spy.txt
|
11
roles/system/files/dns/update_dnscrypt_blocklist
Normal file
11
roles/system/files/dns/update_dnscrypt_blocklist
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
dnscrypt_dir="/etc/dnscrypt-proxy"
|
||||
adblock_dir="${dnscrypt_dir}/adblock"
|
||||
|
||||
/usr/bin/python3 "${adblock_dir}"/generate-domains-blocklist.py \
|
||||
-i -a /dev/null -r /dev/null \
|
||||
-c "${adblock_dir}"/domains-blocklist.conf \
|
||||
-o "${dnscrypt_dir}"/blocked-names.txt
|
||||
|
||||
/bin/chmod 0644 "${dnscrypt_dir}"/blocked-names.txt
|
14
roles/system/files/networking/connman/connman.confd
Normal file
14
roles/system/files/networking/connman/connman.confd
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Configuration file for /etc/init.d/connman
|
||||
|
||||
# Path to ConnMan's configuration file.
|
||||
#cfgfile=/etc/connman/main.conf
|
||||
|
||||
# Additional arguments to pass to connmand.
|
||||
command_args="--nodnsproxy"
|
||||
|
||||
# Number of milliseconds to wait after starting and check that daemon is
|
||||
# still running.
|
||||
#start_wait=50
|
||||
|
||||
# Uncomment to use process supervisor.
|
||||
supervisor="supervise-daemon"
|
8
roles/system/files/networking/connman/main.conf
Normal file
8
roles/system/files/networking/connman/main.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
[General]
|
||||
AllowHostnameUpdates = false
|
||||
AllowDomainnameUpdates = false
|
||||
PreferredTechnologies = ethernet,wifi
|
||||
SingleConnectedTechnology = true
|
||||
NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,docker,veth,vnet,wlan,lxdbr,tap
|
||||
EnableOnlineCheck = false
|
||||
# AddressConflictDetection = true
|
8
roles/system/files/networking/hosts
Normal file
8
roles/system/files/networking/hosts
Normal file
|
@ -0,0 +1,8 @@
|
|||
127.0.0.1 localhost localhost.localdomain
|
||||
|
||||
::1 ipv6-localhost ipv6-loopback
|
||||
fe00::0 ipv6-localnet
|
||||
ff00::0 ipv6-mcastprefix
|
||||
ff02::1 ipv6-allnodes
|
||||
ff02::2 ipv6-allrouters
|
||||
ff02::3 ipv6-allhosts
|
16
roles/system/files/networking/iwd/main.conf
Normal file
16
roles/system/files/networking/iwd/main.conf
Normal file
|
@ -0,0 +1,16 @@
|
|||
# See iwd.config(5) for all options
|
||||
|
||||
[General]
|
||||
EnableNetworkConfiguration=true
|
||||
UseDefaultInterface=true
|
||||
AddressRandomization=network
|
||||
ControlPortOverNL80211=true
|
||||
|
||||
[Network]
|
||||
NameResolvingService=resolvconf
|
||||
EnableIPv6=true
|
||||
RoutePriorityOffset=200
|
||||
|
||||
[Scan]
|
||||
DisablePeriodicScan=false
|
||||
DisableRoamingScan=true
|
32
roles/system/handlers/main.yml
Normal file
32
roles/system/handlers/main.yml
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
- name: Notify apparmor kernel parameters
|
||||
debug:
|
||||
msg: Please add "apparmor=1 security=apparmor" to your current kernel parameters for apparmor to work
|
||||
|
||||
- name: Notify auditd kernel parameter
|
||||
debug:
|
||||
msg: Please add "audit=1" to your current kernel parameters for in-kernel audit support
|
||||
|
||||
- name: Recompile fcron systab
|
||||
command:
|
||||
cmd: /usr/bin/fcrontab -z -u systab
|
||||
removes: /var/spool/fcron/systab.orig
|
||||
|
||||
- name: Regenerate initramfs with mkinitfs
|
||||
command: '/sbin/mkinitfs -c /etc/mkinitfs/mkinitfs.conf {{ ansible_kernel }}'
|
||||
args:
|
||||
removes: /sbin/mkinitfs
|
||||
|
||||
- name: Create snapshots btrfs subvolumes manually
|
||||
debug:
|
||||
msg: |
|
||||
{% if snapshot_tool == 'snapper' %}
|
||||
Please create .snapshots/ directories and corresponding mounted subvolumes under {{ snapper | map(attribute='subvolume') | join(', ') }} paths manually.
|
||||
{% elif snapshot_tool == 'btrbk' %}
|
||||
Please create corresponding subvolumes:
|
||||
{% for volume in btrbk.volumes %}
|
||||
{% if volume.snapshot_dir is defined %}
|
||||
* {{ volume.snapshot_dir }} inside {{ volume.path }} path.
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
19
roles/system/tasks/acpi.yml
Normal file
19
roles/system/tasks/acpi.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
# elogind also handles acpi events
|
||||
- name: acpi | Configure elogind
|
||||
import_tasks: acpi/elogind.yml
|
||||
when: seat_manager == 'elogind'
|
||||
|
||||
- name: acpi | Configure apci daemon
|
||||
when: seat_manager != 'elogind'
|
||||
block:
|
||||
- name: acpi | Import tasks for the corresponding acpid daemon
|
||||
include_tasks: 'acpi/{{ acpid_daemon }}.yml'
|
||||
when: acpid_daemon == 'acpid'
|
||||
|
||||
- name: acpi | Enable acpid service on runlevel 'default'
|
||||
service:
|
||||
name: acpid
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
23
roles/system/tasks/acpi/acpid.yml
Normal file
23
roles/system/tasks/acpi/acpid.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
- name: acpid | Install acpid and acpi-utils
|
||||
community.general.apk:
|
||||
name: acpid, acpi-utils
|
||||
state: present
|
||||
|
||||
- name: acpid | Copy acpid event handler script
|
||||
copy:
|
||||
src: acpi/handler.sh
|
||||
dest: /etc/acpi/handler.sh
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: acpid | Use process supervisor for acpid service
|
||||
lineinfile:
|
||||
path: /etc/conf.d/acpid
|
||||
search_string: supervisor=
|
||||
line: supervisor="supervise-daemon"
|
||||
state: present
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
16
roles/system/tasks/acpi/busybox.yml
Normal file
16
roles/system/tasks/acpi/busybox.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
- name: busybox's acpid | Create directory for Lid Close event
|
||||
file:
|
||||
path: /etc/acpi/LID
|
||||
state: directory
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: busybox's acpid | Copy event handler for Lid Close
|
||||
copy:
|
||||
src: acpi/acpid_lid_close
|
||||
dest: /etc/acpi/LID/00000080
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
25
roles/system/tasks/acpi/elogind.yml
Normal file
25
roles/system/tasks/acpi/elogind.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
- name: elogind | Do not run acpid service
|
||||
service:
|
||||
name: acpid
|
||||
enabled: false
|
||||
state: stopped
|
||||
|
||||
- name: elogind | Manage acpid configuration
|
||||
tags: laptop
|
||||
block:
|
||||
- name: elogind | Create custom config directory for logind.conf
|
||||
file:
|
||||
path: /etc/elogind/logind.conf.d
|
||||
state: directory
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: elogind | Copy logind.conf
|
||||
copy:
|
||||
src: acpi/logind.conf
|
||||
dest: /etc/elogind/logind.conf.d/custom.conf
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
26
roles/system/tasks/apparmor.yml
Normal file
26
roles/system/tasks/apparmor.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
- name: apparmor | Install apparmor and default profiles
|
||||
community.general.apk:
|
||||
name: apparmor, apparmor-profiles
|
||||
state: present
|
||||
|
||||
- name: apparmor | Enable writing cache and faster DFA transition table compression
|
||||
lineinfile:
|
||||
path: /etc/apparmor/parser.conf
|
||||
state: present
|
||||
search_string: '{{ item }}'
|
||||
line: '{{ item }}'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
loop:
|
||||
- write-cache
|
||||
- Optimize=compress-fast
|
||||
|
||||
# Don't start it yet, as it requires the kernel parameters
|
||||
- name: apparmor | Add apparmor service to runlevel 'boot'
|
||||
service:
|
||||
name: apparmor
|
||||
runlevel: boot
|
||||
enabled: true
|
||||
notify: Notify apparmor kernel parameters
|
33
roles/system/tasks/auditd.yml
Normal file
33
roles/system/tasks/auditd.yml
Normal file
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
- name: auditd | Copy auditd configuration
|
||||
copy:
|
||||
src: auditd/auditd.conf
|
||||
dest: /etc/audit/auditd.conf
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: auditd | Copy audit rules
|
||||
template:
|
||||
src: auditd/audit.rules.j2
|
||||
dest: /etc/audit/audit.rules
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: auditd | Copy daily cron job to rotate audit log
|
||||
copy:
|
||||
src: auditd/cron
|
||||
dest: /etc/periodic/daily/rotate-audit-log
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
when: auditd_logrotate_daily | bool
|
||||
|
||||
- name: auditd | Start auditd service on runlevel 'boot'
|
||||
service:
|
||||
name: auditd
|
||||
enabled: true
|
||||
state: started
|
||||
runlevel: boot
|
||||
notify: Notify auditd kernel parameter
|
23
roles/system/tasks/cron.yml
Normal file
23
roles/system/tasks/cron.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
# It is recommended to preserve /var/tmp across reboots
|
||||
- name: cron | Create empty /var/tmp/ weekly job
|
||||
copy:
|
||||
src: cron/empty-tmp
|
||||
dest: /etc/periodic/weekly/empty-tmp
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
|
||||
- name: cron | Create trimming cron jobs
|
||||
import_tasks: cron/trim.yml
|
||||
|
||||
- name: cron | Create scrubbing cron jobs for zfs/btrfs
|
||||
import_tasks: cron/scrub.yml
|
||||
|
||||
- name: cron | Install logrotate and cpulimit
|
||||
community.general.apk:
|
||||
name: logrotate, cpulimit
|
||||
state: present
|
||||
|
||||
- name: cron | Import tasks specific to {{ crond_provider }}
|
||||
include_tasks: 'cron/{{ crond_provider }}.yml'
|
9
roles/system/tasks/cron/busybox.yml
Normal file
9
roles/system/tasks/cron/busybox.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
# busybox's crond already inherits PATH so no need to do anything.
|
||||
# It doesn't have allow/deny feature though
|
||||
- name: crond | Add crond service to runlevel 'default'
|
||||
service:
|
||||
name: crond
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
33
roles/system/tasks/cron/cronie.yml
Normal file
33
roles/system/tasks/cron/cronie.yml
Normal file
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
- name: cronie | Install cronie package
|
||||
community.general.apk:
|
||||
name: cronie
|
||||
state: present
|
||||
|
||||
- name: cronie | Allow access to crontabs for only root and {{ username }}
|
||||
copy:
|
||||
content: |
|
||||
{{ username }}
|
||||
dest: /etc/cron.allow
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
# btrbk runs btrfs command directly (without specifying /sbin prefix),
|
||||
# hence we need to inherit PATH here. Also log to syslog
|
||||
# (the default PATH is /usr/local/bin:/bin:/usr/bin)
|
||||
- name: cronie | Configure command options for cronie service
|
||||
copy:
|
||||
content: |
|
||||
CRON_OPTS="-s -P"
|
||||
dest: /etc/conf.d/cronie
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: cronie | Start cronie service in runlevel default
|
||||
service:
|
||||
name: cronie
|
||||
runlevel: default
|
||||
state: started
|
||||
enabled: true
|
43
roles/system/tasks/cron/fcron.yml
Normal file
43
roles/system/tasks/cron/fcron.yml
Normal file
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
- name: fcron | Install fcron package
|
||||
community.general.apk:
|
||||
name: fcron
|
||||
state: present
|
||||
|
||||
- name: fcron | Deny all users to access crontabs
|
||||
copy:
|
||||
content: |
|
||||
all
|
||||
dest: /etc/fcron/fcron.deny
|
||||
owner: root
|
||||
group: fcron
|
||||
mode: '640'
|
||||
|
||||
- name: fcron | Allow access to crontabs for root and {{ username }}
|
||||
copy:
|
||||
content: |
|
||||
root
|
||||
{{ username }}
|
||||
dest: /etc/fcron/fcron.allow
|
||||
owner: root
|
||||
group: fcron
|
||||
mode: '640'
|
||||
|
||||
# The default PATH is /bin:/usr/bin
|
||||
- name: fcron | Set PATH inside system crontab (systab)
|
||||
lineinfile:
|
||||
path: /var/spool/fcron/systab.orig
|
||||
line: "PATH=/bin:/usr/bin:/sbin:/usr/sbin"
|
||||
insertbefore: BOF
|
||||
mode: '640'
|
||||
owner: root
|
||||
group: root
|
||||
state: present
|
||||
notify: Recompile fcron systab
|
||||
|
||||
- name: fcron | Start fcron service on runlevel default
|
||||
service:
|
||||
name: fcron
|
||||
runlevel: default
|
||||
state: started
|
||||
enabled: true
|
23
roles/system/tasks/cron/scrub.yml
Normal file
23
roles/system/tasks/cron/scrub.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
- name: cron | Create BTRFS scrub monthly job
|
||||
copy:
|
||||
content: |
|
||||
#!/bin/sh
|
||||
exec /sbin/btrfs scrub start -B {{ item }}
|
||||
dest: /etc/periodic/monthly/scrub-btrfs-{{ item | regex_replace('/', '@') }}
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
# PERF: a shorter version but requires `py3-jmespath`: '{{ ansible_mounts | json_query("[?fstype == `btrfs`].mount") }}'
|
||||
loop: '{{ ansible_mounts | selectattr("fstype", "equalto", "btrfs") | map(attribute="mount") | list }}'
|
||||
|
||||
- name: cron | Create ZFS pool scrub monthly job
|
||||
copy:
|
||||
content: |
|
||||
#!/bin/sh
|
||||
exec /usr/sbin/zpool scrub -w {{ item }}
|
||||
dest: /etc/periodic/monthly/scrub-zfs-{{ item }}
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
loop: '{{ ansible_zfs_pools | map(attribute="name") | list }}'
|
25
roles/system/tasks/cron/trim.yml
Normal file
25
roles/system/tasks/cron/trim.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
# NOTE: dmcrypt discourages using `discard` mount option (as in BTRFS on LUKS),
|
||||
# so running trim manually in a cron job
|
||||
- name: cron | Create fstrim weekly job
|
||||
copy:
|
||||
src: cron/fstrim
|
||||
dest: /etc/periodic/weekly/fstrim
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
|
||||
- name: cron | Create ZFS pool trim weekly job
|
||||
copy:
|
||||
content: |
|
||||
#!/bin/sh
|
||||
if /usr/sbin/zpool status {{ item }} | grep -qF "trimming"; then
|
||||
exec /usr/sbin/zpool wait -t trim {{ item }}
|
||||
else
|
||||
exec /usr/sbin/zpool trim -w {{ item }}
|
||||
fi
|
||||
dest: /etc/periodic/weekly/trim-zfs-{{ item }}
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
loop: '{{ ansible_zfs_pools | map(attribute="name") | list }}'
|
50
roles/system/tasks/devd.yml
Normal file
50
roles/system/tasks/devd.yml
Normal file
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
# https://arvanta.net/alpine/libudev-zero/
|
||||
- name: devd | Specific tasks for non-udev device manager
|
||||
when: device_manager != 'udev'
|
||||
block:
|
||||
- name: devd | Install libudev-zero
|
||||
community.general.apk:
|
||||
name: libudev-zero
|
||||
state: present
|
||||
|
||||
- name: devd | Enable hwdrivers service on runlevel sysinit
|
||||
service:
|
||||
name: hwdrivers
|
||||
runlevel: sysinit
|
||||
enabled: true
|
||||
|
||||
- name: devd | udev doesn't need hwdrivers service
|
||||
service:
|
||||
name: hwdrivers
|
||||
runlevel: sysinit
|
||||
enabled: false
|
||||
when: device_manager == 'udev'
|
||||
|
||||
# https://github.com/illiliti/libudev-zero/blob/master/contrib/mdev.conf
|
||||
# mdevd-openrc on Alpine already comes with -O4 flag by default
|
||||
- name: devd | Specific tasks for busybox's mdev
|
||||
when: device_manager == 'mdev'
|
||||
block:
|
||||
- name: mdev | Install libudev-zero-helper
|
||||
community.general.apk:
|
||||
name: libudev-zero-helper
|
||||
state: present
|
||||
|
||||
- name: mdev | Enable hotplugging for DRM and INPUT uevents
|
||||
lineinfile:
|
||||
path: /etc/mdev.conf
|
||||
line: '{{ item }}'
|
||||
state: present
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
loop:
|
||||
- 'SUBSYSTEM=drm;.* root:video 660 */usr/libexec/libudev-zero-helper'
|
||||
- 'SUBSYSTEM=input;.* root:input 660 */usr/libexec/libudev-zero-helper'
|
||||
|
||||
- name: devd | Run setup-devd script
|
||||
command:
|
||||
cmd: '/sbin/setup-devd -C {{ device_manager }}'
|
||||
creates: '/etc/runlevels/sysinit/{{ device_manager }}'
|
||||
failed_when: false
|
17
roles/system/tasks/dns.yml
Normal file
17
roles/system/tasks/dns.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
- name: dns | Install openresolv and {{ dns_resolver }}
|
||||
community.general.apk:
|
||||
name: openresolv, {{ dns_resolver }}
|
||||
state: present
|
||||
|
||||
# Static import_tasks doesn't work here
|
||||
- name: dns | Configure {{ dns_resolver }}
|
||||
include_tasks: 'dns/{{ dns_resolver }}.yml'
|
||||
|
||||
- name: dns | Update resolvconf config
|
||||
template:
|
||||
src: dns/resolvconf.j2
|
||||
dest: /etc/resolvconf.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
112
roles/system/tasks/dns/dnscrypt-proxy.yml
Normal file
112
roles/system/tasks/dns/dnscrypt-proxy.yml
Normal file
|
@ -0,0 +1,112 @@
|
|||
---
|
||||
# Firefox needs to be setup manually:
|
||||
# https://github.com/DNSCrypt/dnscrypt-proxy/wiki/Local-DoH
|
||||
- name: dnscrypt-proxy | Prerequisite setup for local DoH server
|
||||
when: dnscrypt.local_doh.enabled
|
||||
block:
|
||||
- name: dnscrypt-proxy | Generate private key for local DoH server
|
||||
community.crypto.openssl_privatekey:
|
||||
path: '/etc/dnscrypt-proxy/{{ ansible_hostname }}.pem'
|
||||
type: Ed25519
|
||||
mode: '640'
|
||||
owner: root
|
||||
group: dnscrypt
|
||||
state: present
|
||||
|
||||
- name: dnscrypt-proxy | Generate self-signed certificate for local DoH server
|
||||
community.crypto.x509_certificate:
|
||||
path: '/etc/dnscrypt-proxy/{{ ansible_hostname }}.crt'
|
||||
privatekey_path: '/etc/dnscrypt-proxy/{{ ansible_hostname }}.pem'
|
||||
provider: selfsigned
|
||||
selfsigned_not_after: +5000d
|
||||
selfsigned_digest: sha512
|
||||
mode: '640'
|
||||
owner: root
|
||||
group: dnscrypt
|
||||
state: present
|
||||
|
||||
- name: dnscrypt-proxy | Copy blocked-ips.txt for rebinding protection
|
||||
copy:
|
||||
src: dns/blocked-ips.txt
|
||||
dest: /etc/dnscrypt-proxy/blocked-ips.txt
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: dnscrypt-proxy | Copy cloaking-rules.txt
|
||||
copy:
|
||||
src: dns/cloaking-rules.txt
|
||||
dest: /etc/dnscrypt-proxy/cloaking-rules.txt
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: dnscrypt-proxy | Configure DNS-based adblocking
|
||||
when: dnscrypt.adblock
|
||||
block:
|
||||
- name: dnscrypt-proxy | Create adblock directory for blocklist configurations
|
||||
file:
|
||||
path: /etc/dnscrypt-proxy/adblock
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
state: directory
|
||||
|
||||
- name: dnscrypt-proxy | Copy blocklists
|
||||
copy:
|
||||
src: 'dns/{{ item }}'
|
||||
dest: '/etc/dnscrypt-proxy/adblock/{{ item }}'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
loop:
|
||||
- domains-blocklist.conf
|
||||
- domains-blocklist-local-additions.txt
|
||||
|
||||
- name: dnscrypt-proxy | Download generate-domains-blocklist.py
|
||||
get_url:
|
||||
url: https://raw.githubusercontent.com/DNSCrypt/dnscrypt-proxy/master/utils/generate-domains-blocklist/generate-domains-blocklist.py
|
||||
dest: /etc/dnscrypt-proxy/adblock/generate-domains-blocklist.py
|
||||
checksum: sha256:5dfb8cab46384df6194724d35fbe0e5fc87945c63f0283f06534f66f581e0e1c
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: dnscrypt-proxy | Generate domain blocklist the 1st time
|
||||
command:
|
||||
cmd: /usr/bin/python3 generate-domains-blocklist.py -i -a /dev/null -r /dev/null -c domains-blocklist.conf -o /etc/dnscrypt-proxy/blocked-names.txt
|
||||
chdir: /etc/dnscrypt-proxy/adblock
|
||||
creates: /etc/dnscrypt-proxy/blocked-names.txt
|
||||
failed_when: false
|
||||
|
||||
- name: dnscrypt-proxy | Ensure proper permission on blocked-names.txt file
|
||||
file:
|
||||
path: /etc/dnscrypt-proxy/blocked-names.txt
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
state: file
|
||||
|
||||
- name: dnscrypt-proxy | Add daily cron job to update the blocklist
|
||||
copy:
|
||||
src: dns/update_dnscrypt_blocklist
|
||||
dest: /etc/periodic/daily/update_dnscrypt_blocklist
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: dnscrypt-proxy | Copy dnscrypt-proxy config
|
||||
template:
|
||||
src: dns/dnscrypt-proxy.j2
|
||||
dest: /etc/dnscrypt-proxy/dnscrypt-proxy.toml
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
validate: /usr/bin/dnscrypt-proxy -check -config %s
|
||||
|
||||
- name: dnscrypt-proxy | Start dnscrypt-proxy service on runlevel 'default'
|
||||
service:
|
||||
name: dnscrypt-proxy
|
||||
enabled: true
|
||||
state: started
|
||||
runlevel: default
|
111
roles/system/tasks/dns/unbound.yml
Normal file
111
roles/system/tasks/dns/unbound.yml
Normal file
|
@ -0,0 +1,111 @@
|
|||
---
|
||||
- name: unbound | Install dns-root-hints
|
||||
community.general.apk:
|
||||
name: dns-root-hints
|
||||
state: present
|
||||
|
||||
- name: unbound | Create /dev directory inside unbound chroot
|
||||
file:
|
||||
path: /etc/unbound/dev
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
|
||||
# We are operating on special devices
|
||||
# copy module doesn't seem to work
|
||||
- name: unbound | Copy needed devices to unbound chroot
|
||||
command:
|
||||
cmd: /bin/cp -a /dev/urandom /dev/null /etc/unbound/dev/
|
||||
creates: /etc/unbound/dev/urandom
|
||||
|
||||
# unbound user needs write permission to the anchor file, and also for the
|
||||
# directory it is in (to create a temporary file)
|
||||
- name: unbound | Create var directory inside unbound chroot
|
||||
file:
|
||||
path: /etc/unbound/var
|
||||
state: directory
|
||||
owner: root
|
||||
group: unbound
|
||||
mode: '775'
|
||||
|
||||
# unbound-anchor gives errors about connecting to IPv6 servers
|
||||
- name: unbound | Generate trusted anchor file
|
||||
command:
|
||||
cmd: /usr/sbin/unbound-anchor -a /etc/unbound/var/trusted-key.key
|
||||
creates: /etc/unbound/var/trusted-key.key
|
||||
failed_when: false
|
||||
|
||||
- name: unbound | Ensure proper permissions on trusted anchor file
|
||||
file:
|
||||
path: /etc/unbound/var/trusted-key.key
|
||||
state: file
|
||||
owner: unbound
|
||||
group: unbound
|
||||
mode: '640'
|
||||
|
||||
- name: unbound | Gather package facts
|
||||
package_facts:
|
||||
manager: 'apk'
|
||||
|
||||
# We only need to run the DNS root hints update the 1st time, as
|
||||
# dns-root-hints package comes with a monthly crontab
|
||||
- name: unbound | Check the current DNS root zone version
|
||||
lineinfile:
|
||||
backup: true
|
||||
path: /usr/share/dns-root-hints/named.root
|
||||
regexp: '^;[ \t]+related version of root zone:[ \t]+{{ ansible_facts.packages["dns-root-hints"][0].version }}$'
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: root_hints_check
|
||||
changed_when: false
|
||||
|
||||
- name: unbound | Get the latest DNS root hints
|
||||
command:
|
||||
cmd: /usr/bin/update-dns-root-hints
|
||||
removes: /usr/bin/update-dns-root-hints
|
||||
when: root_hints_check.found == 1
|
||||
|
||||
- name: unbound | Copy the updated root hints file to unbound chroot
|
||||
copy:
|
||||
src: /usr/share/dns-root-hints/named.root
|
||||
dest: /etc/unbound/var/named.root
|
||||
owner: root
|
||||
group: unbound
|
||||
mode: '640'
|
||||
|
||||
- name: unbound | Let dns-root-hints cron job copy root hints to unbound chroot
|
||||
blockinfile:
|
||||
path: /etc/periodic/monthly/dns-root-hints
|
||||
block: |
|
||||
updated_file="/usr/share/dns-root-hints/named.root"
|
||||
current_file="/etc/unbound/var/named.root"
|
||||
drh_new_ver=$(/bin/grep "related version of root zone:" $updated_file | /bin/grep -E -o '[0-9]{10}')
|
||||
drh_current_ver=$(/bin/grep "related version of root zone:" $current_file | /bin/grep -E -o '[0-9]{10}')
|
||||
|
||||
if [ "$drh_new_ver" != "$drh_current_ver" ]; then
|
||||
/bin/cp -f $updated_file $current_file
|
||||
/bin/chown root:unbound $current_file
|
||||
/bin/chmod 0640 $current_file
|
||||
fi
|
||||
marker: '# {mark} COPY THE UPDATED ROOT HINTS TO UNBOUND CHROOT'
|
||||
insertafter: 'EOF'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
|
||||
- name: unbound | Copy unbound config
|
||||
template:
|
||||
src: dns/unbound.j2
|
||||
dest: /etc/unbound/unbound.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
validate: /usr/sbin/unbound-checkconf %s
|
||||
|
||||
- name: unbound | Add unbound service to runlevel 'default'
|
||||
service:
|
||||
name: unbound
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
20
roles/system/tasks/earlyoom.yml
Normal file
20
roles/system/tasks/earlyoom.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
- name: earlyoom | Install earlyoom package
|
||||
community.general.apk:
|
||||
name: earlyoom
|
||||
state: present
|
||||
|
||||
- name: earlyoom | Copy service configuration
|
||||
template:
|
||||
src: earlyoom/conf.j2
|
||||
dest: /etc/conf.d/earlyoom
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: earlyoom | Start earlyoom service on runlevel 'default'
|
||||
service:
|
||||
name: earlyoom
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
105
roles/system/tasks/essential.yml
Normal file
105
roles/system/tasks/essential.yml
Normal file
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
- name: essential | Change repository URLs
|
||||
template:
|
||||
src: essential/repositories.j2
|
||||
dest: /etc/apk/repositories
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: essential | Update repository cache and the system
|
||||
community.general.apk:
|
||||
available: true
|
||||
upgrade: true
|
||||
update_cache: true
|
||||
|
||||
- name: essential | Install common dependencies
|
||||
community.general.apk:
|
||||
name: zstd, dbus, font-terminus, shadow-login
|
||||
state: present
|
||||
|
||||
- name: essential | Enable logging and unicode support for openrc
|
||||
lineinfile:
|
||||
path: /etc/rc.conf
|
||||
state: present
|
||||
search_string: '{{ item }}='
|
||||
line: '{{ item }}="YES"'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
loop:
|
||||
- rc_logger
|
||||
- unicode
|
||||
|
||||
# https://wiki.gentoo.org/wiki/Elogind
|
||||
# elogind still requires 'cgroup-hybrid' useflag
|
||||
- name: essential | Explicitly enable only cgroup v2 for OpenRC
|
||||
lineinfile:
|
||||
path: /etc/rc.conf
|
||||
state: present
|
||||
search_string: rc_cgroup_mode=
|
||||
line: rc_cgroup_mode="unified"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
when: seat_manager != 'elogind'
|
||||
|
||||
- name: essential | Change the default motd
|
||||
template:
|
||||
src: essential/motd.j2
|
||||
dest: /etc/motd
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: essential | Use zstd for initramfs
|
||||
lineinfile:
|
||||
path: /etc/mkinitfs/mkinitfs.conf
|
||||
state: present
|
||||
search_string: initfscomp=
|
||||
line: initfscomp="zstd"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
notify: Regenerate initramfs
|
||||
|
||||
- name: essential | Blacklist bluetooth related kernel modules
|
||||
community.general.kernel_blacklist:
|
||||
name: '{{ item }}'
|
||||
state: present
|
||||
loop:
|
||||
- vivid
|
||||
- bluetooth
|
||||
- btusb
|
||||
|
||||
- name: essential | Use /var/tmp for coredumps
|
||||
ansible.posix.sysctl:
|
||||
name: kernel.core_pattern
|
||||
value: /var/tmp/core-%e.%p.%h.%t
|
||||
state: present
|
||||
|
||||
- name: essential | Change the tty font to {{ console_font }}
|
||||
lineinfile:
|
||||
path: /etc/conf.d/consolefont
|
||||
state: present
|
||||
regexp: '^consolefont='
|
||||
line: 'consolefont="{{ console_font }}"'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: essential | Start services on runlevel 'boot'
|
||||
service:
|
||||
name: '{{ item }}'
|
||||
runlevel: boot
|
||||
enabled: true
|
||||
state: started
|
||||
loop: ['consolefont', 'seedrng', 'syslog']
|
||||
|
||||
- name: essential | Start services on runlevel 'default'
|
||||
service:
|
||||
name: '{{ item }}'
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
||||
loop: ['dbus', 'cgroups']
|
58
roles/system/tasks/fstab.yml
Normal file
58
roles/system/tasks/fstab.yml
Normal file
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
# pyenv, doom (cli of Doom Emacs), ... need exec inside /tmp
|
||||
- name: fstab | Harden mount options for /tmp
|
||||
ansible.posix.mount:
|
||||
src: tmpfs
|
||||
path: /tmp
|
||||
fstype: tmpfs
|
||||
opts: rw,nosuid,nodev,size=4G,mode=1777
|
||||
state: present
|
||||
|
||||
# /run is mounted with exec by default
|
||||
- name: fstab | Harden mount options for /run
|
||||
ansible.posix.mount:
|
||||
src: tmpfs
|
||||
path: /run
|
||||
fstype: tmpfs
|
||||
opts: rw,nosuid,nodev,noexec,size=1G,mode=0755
|
||||
state: present
|
||||
|
||||
# polkit daemon obviously needs access to /proc to work
|
||||
# Note: Add the normal user to polkitd group afterward
|
||||
- name: fstab | Configure /proc restriction
|
||||
vars:
|
||||
proc_group: '{{ (use_polkit or (seat_manager == "elogind")) | ternary("polkitd", "wheel") }}'
|
||||
block:
|
||||
# Busybox's mount doesn't interpret group name in GID, so check it
|
||||
# wheel group on Alpine by default has GID=10
|
||||
- name: fstab | Check GID of group {{ proc_group }} # noqa: risky-shell-pipe
|
||||
shell: /usr/bin/getent group {{ proc_group }} | awk -F':' '{print $3}'
|
||||
register: proc_gid
|
||||
changed_when: false
|
||||
|
||||
- name: fstab | Restrict read access on /proc for group {{ proc_group }}
|
||||
ansible.posix.mount:
|
||||
src: proc
|
||||
path: /proc
|
||||
fstype: proc
|
||||
opts: 'rw,nosuid,nodev,noexec,hidepid=2,gid={{ proc_gid.stdout }}'
|
||||
state: present
|
||||
|
||||
- name: fstab | Disable UEFI variable access
|
||||
ansible.posix.mount:
|
||||
src: efivarfs
|
||||
path: /sys/firmware/efi/efivars
|
||||
fstype: efivars
|
||||
opts: ro,nosuid,nodev,noexec
|
||||
state: present
|
||||
when: disable_uefi_access
|
||||
|
||||
- name: fstab | Allow UEFI variable access
|
||||
lineinfile:
|
||||
path: /etc/fstab
|
||||
search_string: /sys/firmware/efi/efivars
|
||||
state: absent
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
when: not disable_uefi_access
|
34
roles/system/tasks/libvirt.yml
Normal file
34
roles/system/tasks/libvirt.yml
Normal file
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
- name: libvirt | Install libvirt and qemu
|
||||
community.general.apk:
|
||||
name: libvirt-daemon, qemu-img, qemu-system-x86_64, qemu-system-arm, qemu-system-aarch64, qemu-modules
|
||||
state: present
|
||||
|
||||
# This is for PulseAudio
|
||||
- name: libvirt | Allow the normal user to interact with qemu system instance
|
||||
lineinfile:
|
||||
path: /etc/libvirt/qemu.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
regexp: '^#?user = "'
|
||||
line: 'user = "{{ username }}"'
|
||||
|
||||
- name: libvirt | Use file-based permissions when polkit is not available
|
||||
lineinfile:
|
||||
path: /etc/libvirt/{{ item[0] }}.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
regexp: '^#?{{ item[1] | regex_replace(" =.*$", "") }}'
|
||||
line: '{{ item[1] }}'
|
||||
loop: '{{ libvirt_daemons | product(libvirt_daemons_conf) | list }}'
|
||||
when: (not use_polkit) and (seat_manager != 'elogind')
|
||||
|
||||
- name: libvirt | Start modular services on runlevel 'default'
|
||||
service:
|
||||
name: '{{ item }}'
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
||||
loop: '{{ libvirt_daemons + ["virtlogd", "virtlockd"] }}'
|
39
roles/system/tasks/main.jsonnet
Normal file
39
roles/system/tasks/main.jsonnet
Normal file
|
@ -0,0 +1,39 @@
|
|||
local task(item) =
|
||||
local type = std.type(item);
|
||||
if type == 'string' then
|
||||
{
|
||||
name: 'Configure ' + item,
|
||||
import_tasks: item + '.yml',
|
||||
tags: item,
|
||||
}
|
||||
else if type == 'object' then
|
||||
{
|
||||
name: 'Configure ' + item.name,
|
||||
import_tasks: item.name + '.yml',
|
||||
tags: [item.name],
|
||||
} + item.opts
|
||||
else {};
|
||||
|
||||
local modules = [
|
||||
'acpi',
|
||||
'apparmor',
|
||||
'auditd',
|
||||
'cron',
|
||||
'devd',
|
||||
'dns',
|
||||
'earlyoom',
|
||||
'essential',
|
||||
'fstab',
|
||||
'libvirt',
|
||||
'networking',
|
||||
'nftables',
|
||||
'ntpd',
|
||||
'seat',
|
||||
'snapshot',
|
||||
{ name: 'tlp', opts: { tags+: ['laptop'] } },
|
||||
'usbguard',
|
||||
'user',
|
||||
'zram',
|
||||
];
|
||||
|
||||
std.manifestYamlDoc([task(x) for x in modules], quote_keys=false)
|
64
roles/system/tasks/main.yml
Normal file
64
roles/system/tasks/main.yml
Normal file
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
|
||||
# Auto-generated with Jsonnet from main.jsonnet
|
||||
# Do NOT edit!!
|
||||
|
||||
- import_tasks: "acpi.yml"
|
||||
name: "Configure acpi"
|
||||
tags: "acpi"
|
||||
- import_tasks: "apparmor.yml"
|
||||
name: "Configure apparmor"
|
||||
tags: "apparmor"
|
||||
- import_tasks: "auditd.yml"
|
||||
name: "Configure auditd"
|
||||
tags: "auditd"
|
||||
- import_tasks: "cron.yml"
|
||||
name: "Configure cron"
|
||||
tags: "cron"
|
||||
- import_tasks: "devd.yml"
|
||||
name: "Configure devd"
|
||||
tags: "devd"
|
||||
- import_tasks: "dns.yml"
|
||||
name: "Configure dns"
|
||||
tags: "dns"
|
||||
- import_tasks: "earlyoom.yml"
|
||||
name: "Configure earlyoom"
|
||||
tags: "earlyoom"
|
||||
- import_tasks: "essential.yml"
|
||||
name: "Configure essential"
|
||||
tags: "essential"
|
||||
- import_tasks: "fstab.yml"
|
||||
name: "Configure fstab"
|
||||
tags: "fstab"
|
||||
- import_tasks: "libvirt.yml"
|
||||
name: "Configure libvirt"
|
||||
tags: "libvirt"
|
||||
- import_tasks: "networking.yml"
|
||||
name: "Configure networking"
|
||||
tags: "networking"
|
||||
- import_tasks: "nftables.yml"
|
||||
name: "Configure nftables"
|
||||
tags: "nftables"
|
||||
- import_tasks: "ntpd.yml"
|
||||
name: "Configure ntpd"
|
||||
tags: "ntpd"
|
||||
- import_tasks: "seat.yml"
|
||||
name: "Configure seat"
|
||||
tags: "seat"
|
||||
- import_tasks: "snapshot.yml"
|
||||
name: "Configure snapshot"
|
||||
tags: "snapshot"
|
||||
- import_tasks: "tlp.yml"
|
||||
name: "Configure tlp"
|
||||
tags:
|
||||
- "tlp"
|
||||
- "laptop"
|
||||
- import_tasks: "usbguard.yml"
|
||||
name: "Configure usbguard"
|
||||
tags: "usbguard"
|
||||
- import_tasks: "user.yml"
|
||||
name: "Configure user"
|
||||
tags: "user"
|
||||
- import_tasks: "zram.yml"
|
||||
name: "Configure zram"
|
||||
tags: "zram"
|
47
roles/system/tasks/networking.yml
Normal file
47
roles/system/tasks/networking.yml
Normal file
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
- name: networking | Overwrite /etc/hosts to support IPv6
|
||||
copy:
|
||||
src: networking/hosts
|
||||
dest: /etc/hosts
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
# NOTE: already set in /lib/sysctl.d/00-alpine.conf but it doesn't hurt re-apply
|
||||
- name: networking | Set IPv6 Privacy Extension (RFC 4941)
|
||||
ansible.posix.sysctl:
|
||||
name: '{{ (item | split("=") | map("trim") | list)[0] }}'
|
||||
value: '{{ (item | split("=") | map("trim") | list)[1] }}'
|
||||
state: present
|
||||
loop:
|
||||
- net.ipv6.conf.all.use_tempaddr = 2
|
||||
- net.ipv6.conf.default.use_tempaddr = 2
|
||||
|
||||
- name: networking | Set IPv6 stable privacy address (RFC 7217)
|
||||
ansible.posix.sysctl:
|
||||
name: '{{ (item | split("=") | map("trim") | list)[0] }}'
|
||||
value: '{{ (item | split("=") | map("trim") | list)[1] }}'
|
||||
state: present
|
||||
loop:
|
||||
- net.ipv6.conf.default.addr_gen_mode = 2
|
||||
- net.ipv6.conf.all.addr_gen_mode = 2
|
||||
- net.ipv6.conf.default.stable_secret = {{ (2**16 - 1) | random_hex }}:{{ (2**16 - 1) | random_hex }}:{{ (2**16 - 1) | random_hex }}:{{ (2**16 - 1) | random_hex }}:{{ (2**16 - 1) | random_hex }}:{{ (2**16 - 1) | random_hex }}:{{ (2**16 - 1) | random_hex }}:{{ (2**16 - 1) | random_hex }} # noqa: yaml[line-length]
|
||||
when: ipv6_stable_privacy_addr | bool
|
||||
|
||||
- name: networking | Install {{ dhcp_client }}
|
||||
community.general.apk:
|
||||
name: '{{ dhcp_client }}'
|
||||
state: present
|
||||
when: dhcp_client != 'udhcpc'
|
||||
|
||||
# Assume 'networking' service is already started on 'boot' before the playbook is run
|
||||
- name: networking | Tweak the default 'networking' service
|
||||
import_tasks: networking/networking.yml
|
||||
|
||||
- name: networking | Configure iwd
|
||||
import_tasks: networking/iwd.yml
|
||||
tags: laptop
|
||||
|
||||
- name: networking | Configure connman
|
||||
import_tasks: networking/connman.yml
|
||||
when: dhcp_client == 'connman'
|
47
roles/system/tasks/networking/connman.yml
Normal file
47
roles/system/tasks/networking/connman.yml
Normal file
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
# connman itself is already installed in the parent task
|
||||
- name: networking | Install connman packages
|
||||
community.general.apk:
|
||||
name: connman-nftables, connman-resolvconf
|
||||
state: present
|
||||
|
||||
- name: networking | Copy connman configuration
|
||||
copy:
|
||||
src: networking/connman/main.conf
|
||||
dest: /etc/connman/main.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: networking | Make sure /var/lib/connman directory exists
|
||||
file:
|
||||
path: /var/lib/connman
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
state: directory
|
||||
|
||||
- name: networking | Configure connman Ethernet interfaces
|
||||
template:
|
||||
src: networking/connman-service.config.j2
|
||||
dest: /var/lib/connman/ethernet_services.config
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: networking | Copy connmand service configuration
|
||||
copy:
|
||||
src: networking/connman/connman.confd
|
||||
dest: /etc/conf.d/connman
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: networking | Start connman services on runlevel 'default'
|
||||
service:
|
||||
name: '{{ item }}'
|
||||
runlevel: default
|
||||
enabled: true
|
||||
loop:
|
||||
- connman
|
||||
- connman-resolvconf
|
31
roles/system/tasks/networking/iwd.yml
Normal file
31
roles/system/tasks/networking/iwd.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
- name: networking | Install iwd package
|
||||
community.general.apk:
|
||||
name: iwd
|
||||
state: present
|
||||
when: not iwd_without_dbus
|
||||
|
||||
# NOTE: connmanctl can't scan wifi with eiwd so we need iw
|
||||
# - iw dev <interface> scan | grep SSID
|
||||
# - printf <passphrase> | iwd_passphrase <ssid> > /var/lib/iwd/<ssid>.psk
|
||||
- name: networking | Install eiwd and iw packages
|
||||
community.general.apk:
|
||||
name: eiwd, iw
|
||||
state: present
|
||||
when: iwd_without_dbus
|
||||
|
||||
- name: networking | Copy iwd configuration
|
||||
copy:
|
||||
src: networking/iwd/main.conf
|
||||
dest: /etc/iwd/main.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: networking | Start iwd service on runlevel 'boot'
|
||||
vars:
|
||||
iwd_service: '{{ iwd_without_dbus | ternary("eiwd", "iwd") }}'
|
||||
service:
|
||||
name: '{{ iwd_service }}'
|
||||
runlevel: default
|
||||
enabled: true
|
25
roles/system/tasks/networking/networking.yml
Normal file
25
roles/system/tasks/networking/networking.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
- name: Reconfigure 'networking' service
|
||||
when: dhcp_client in ['udhcpc', 'dhcpcd', 'dhclient']
|
||||
block:
|
||||
- name: networking | Configure /etc/network/interfaces
|
||||
template:
|
||||
src: networking/interfaces.j2
|
||||
dest: /etc/network/interfaces
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: networking | Restart 'networking' service
|
||||
service:
|
||||
name: networking
|
||||
state: restarted
|
||||
enabled: true
|
||||
runlevel: boot
|
||||
|
||||
- name: networking | Stop 'networking' service on boot in favor of {{ dhcp_client }}
|
||||
service:
|
||||
name: networking
|
||||
enabled: false
|
||||
runlevel: boot
|
||||
when: not dhcp_client in ['udhcpc', 'dhcpcd', 'dhclient']
|
19
roles/system/tasks/nftables.yml
Normal file
19
roles/system/tasks/nftables.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
- name: nftables | Install nftables
|
||||
community.general.apk:
|
||||
name: nftables
|
||||
state: present
|
||||
|
||||
- name: nftables | Copy firewall configuration
|
||||
template:
|
||||
src: nftables/nftables.j2
|
||||
dest: /etc/nftables.nft
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: nftables | Add nftables service to runlevel 'boot'
|
||||
service:
|
||||
name: nftables
|
||||
runlevel: boot
|
||||
enabled: true
|
10
roles/system/tasks/ntpd.yml
Normal file
10
roles/system/tasks/ntpd.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
- name: ntpd | Install package {{ ntp_client }}
|
||||
community.general.apk:
|
||||
name: '{{ ntp_client }}'
|
||||
state: present
|
||||
when: ntp_client != 'busybox'
|
||||
|
||||
# NOTE: busybox's ntpd should be stopped (and disabled) manually before this
|
||||
- name: ntpd | Import corresponding tasks
|
||||
include_tasks: 'ntpd/{{ ntp_client }}.yml'
|
27
roles/system/tasks/ntpd/README.md
Normal file
27
roles/system/tasks/ntpd/README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Notes
|
||||
|
||||
Tasks not needed in NTP client mode but might come handy in the future.
|
||||
|
||||
## Generate NTP symetric key for chronyd
|
||||
|
||||
**NOTE**: NTS should be used if the server is publicly accessible. Otherwise, for a private NTP server, symetric key is sufficient.
|
||||
|
||||
```yaml
|
||||
- name: chrony | Generate the symetric key with chronyc
|
||||
command:
|
||||
cmd: /usr/bin/chronyc keygen {{ (2**32 - 1) | random }} SHA512 256
|
||||
creates: /etc/chrony/chrony.keys
|
||||
register: chrony_keys
|
||||
|
||||
- name: chrony | Create chrony.keys file from chronyc output
|
||||
copy:
|
||||
content: |
|
||||
{{ chrony_keys['stdout'] }}
|
||||
dest: /etc/chrony/chrony.keys
|
||||
mode: '400'
|
||||
owner: chrony
|
||||
group: root
|
||||
when: chrony_keys is defined
|
||||
```
|
||||
|
||||
Then add `keyfile /etc/chrony/chrony.keys` to ***/etc/chrony/chrony.conf*** file.
|
18
roles/system/tasks/ntpd/busybox.yml
Normal file
18
roles/system/tasks/ntpd/busybox.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
- name: ntpd | Adjust ntpd service configuration
|
||||
copy: # noqa: jinja[spacing]
|
||||
content: >
|
||||
NTPD_OPTS="-N
|
||||
{%- for pool in ntp_opts.pools %} -p {{ pool }}{% endfor %}
|
||||
{%- for server in ntp_opts.servers %} -p {{ server }}{% endfor %}"
|
||||
dest: /etc/conf.d/ntpd
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: ntpd | Start ntpd service at runlevel 'default'
|
||||
service:
|
||||
name: ntpd
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
32
roles/system/tasks/ntpd/chrony.yml
Normal file
32
roles/system/tasks/ntpd/chrony.yml
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
# NOTE: chrony package comes with a default /etc/chrony/chrony.conf
|
||||
# => No need to create a parent directory here
|
||||
- name: chrony | Copy chrony.conf
|
||||
template:
|
||||
src: ntpd/chrony.conf.j2
|
||||
dest: /etc/chrony/chrony.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
# - Basically just run chronyd on foreground
|
||||
# - https://wiki.archlinux.org/title/Chrony#For_intermittently_running_desktops
|
||||
- name: chrony | Change default configuration for chronyd service
|
||||
lineinfile:
|
||||
path: /etc/conf.d/chronyd
|
||||
line: '{{ item }}'
|
||||
search_string: '{{ item | regex_replace("=.*$", "") }}'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
state: present
|
||||
loop:
|
||||
- FAST_STARTUP=yes
|
||||
- ARGS="-s -r"
|
||||
|
||||
- name: chrony | Start chronyd service on runlevel 'default'
|
||||
service:
|
||||
name: chronyd
|
||||
enabled: true
|
||||
state: started
|
||||
runlevel: default
|
15
roles/system/tasks/ntpd/ntpsec.yml
Normal file
15
roles/system/tasks/ntpd/ntpsec.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: ntpsec | Copy ntp.conf
|
||||
template:
|
||||
src: ntpd/ntp.conf.j2
|
||||
dest: /etc/ntp.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: ntpsec | Start ntpsec service on runlevel 'default'
|
||||
service:
|
||||
name: ntpsec
|
||||
enabled: true
|
||||
state: started
|
||||
runlevel: default
|
17
roles/system/tasks/ntpd/openntpd.yml
Normal file
17
roles/system/tasks/ntpd/openntpd.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
# Validation can take up to 15s, so be patient
|
||||
- name: openntpd | Copy ntpd.conf
|
||||
template:
|
||||
src: ntpd/ntpd.conf.j2
|
||||
dest: /etc/ntpd.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
validate: /usr/sbin/ntpd -n -f %s
|
||||
|
||||
- name: openntpd | Start openntpd service on runlevel 'default'
|
||||
service:
|
||||
name: openntpd
|
||||
enabled: true
|
||||
state: started
|
||||
runlevel: default
|
46
roles/system/tasks/seat.yml
Normal file
46
roles/system/tasks/seat.yml
Normal file
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
- name: seat | Start elogind
|
||||
when: seat_manager == 'elogind'
|
||||
block:
|
||||
- name: seat | Install elogind and polkit-elogind
|
||||
community.general.apk:
|
||||
name: elogind, polkit-elogind
|
||||
state: present
|
||||
|
||||
# Some acpi functions might not work if elogind is started on
|
||||
# runlevel 'default'
|
||||
- name: seat | Start elogind service on runlevel 'default'
|
||||
service:
|
||||
name: elogind
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: seat | Start seatd
|
||||
when: seat_manager == 'seatd'
|
||||
block:
|
||||
- name: seat | Install seatd
|
||||
community.general.apk:
|
||||
name: seatd
|
||||
state: present
|
||||
|
||||
- name: seat | Start seatd service on runlevel 'default'
|
||||
service:
|
||||
name: seatd
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: seat | Install stuff when elogind doesn't exist
|
||||
when: seat_manager != 'elogind'
|
||||
block:
|
||||
- name: seat | Install pam-rundir
|
||||
community.general.apk:
|
||||
name: pam-rundir
|
||||
state: present
|
||||
|
||||
- name: seat | Install polkit
|
||||
community.general.apk:
|
||||
name: polkit
|
||||
state: present
|
||||
when: use_polkit
|
3
roles/system/tasks/snapshot.yml
Normal file
3
roles/system/tasks/snapshot.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
- name: snapshot | Setup {{ snapshot_tool }}
|
||||
include_tasks: 'snapshot/{{ snapshot_tool }}.yml'
|
26
roles/system/tasks/snapshot/btrbk.yml
Normal file
26
roles/system/tasks/snapshot/btrbk.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
- name: btrbk | Install btrbk package
|
||||
community.general.apk:
|
||||
name: btrbk
|
||||
state: present
|
||||
|
||||
- name: btrbk | Copy config btrbk.conf
|
||||
template:
|
||||
src: snapshot/btrbk.conf.j2
|
||||
dest: /etc/btrbk/btrbk.conf
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
notify:
|
||||
- Create snapshots btrfs subvolumes manually
|
||||
|
||||
- name: btrbk | Create btrbk crontabs
|
||||
copy:
|
||||
content: |
|
||||
#!/bin/sh
|
||||
TZ=UTC exec /usr/bin/btrbk -q {{ item.value }}
|
||||
dest: /etc/periodic/{{ item.key }}/btrbk
|
||||
mode: '755'
|
||||
owner: root
|
||||
group: root
|
||||
loop: '{{ btrbk.cron | dict2items }}'
|
14
roles/system/tasks/snapshot/sanoid.yml
Normal file
14
roles/system/tasks/snapshot/sanoid.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
- name: sanoid | Install sanoid and syncoid packages
|
||||
community.general.apk:
|
||||
name: sanoid, syncoid
|
||||
state: present
|
||||
|
||||
# 'sanoid' APK package comes with a 15min cronjob, so we only need to modify the configuration file
|
||||
- name: sanoid | Create configuration file
|
||||
template:
|
||||
src: snapshot/sanoid.conf.j2
|
||||
dest: /etc/sanoid/sanoid.conf
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
26
roles/system/tasks/snapshot/snapper.yml
Normal file
26
roles/system/tasks/snapshot/snapper.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
- name: snapper | Install snapper package
|
||||
community.general.apk:
|
||||
name: snapper
|
||||
state: present
|
||||
|
||||
- name: snapper | Install config for each target
|
||||
template:
|
||||
src: snapshot/snapper.j2
|
||||
dest: /etc/snapper/configs/{{ item.name }}
|
||||
mode: '600'
|
||||
owner: root
|
||||
group: root
|
||||
loop: '{{ snapper }}'
|
||||
|
||||
- name: snapper | Install main snapper config
|
||||
copy:
|
||||
content: |
|
||||
# List of snapper configurations.
|
||||
SNAPPER_CONFIGS="{{ snapper | map(attribute='name') | join(' ') }}"
|
||||
dest: /etc/snapper/snapper
|
||||
mode: '644'
|
||||
owner: root
|
||||
group: root
|
||||
notify:
|
||||
- Create snapshots btrfs subvolumes manually
|
1
roles/system/tasks/snapshot/zrepl.yml
Normal file
1
roles/system/tasks/snapshot/zrepl.yml
Normal file
|
@ -0,0 +1 @@
|
|||
---
|
27
roles/system/tasks/tlp.yml
Normal file
27
roles/system/tasks/tlp.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
- name: tlp | Install tlp package
|
||||
community.general.apk:
|
||||
name: tlp
|
||||
state: present
|
||||
|
||||
# I have a ThinkPad laptop :)
|
||||
- name: tlp | Install acpi_call kernel module
|
||||
community.general.apk:
|
||||
name: acpi_call-src
|
||||
state: present
|
||||
when: ansible_hostname == 'alpine-tp'
|
||||
|
||||
- name: tlp | Copy configuration
|
||||
template:
|
||||
src: tlp/00-custom.j2
|
||||
dest: /etc/tlp.d/00-custom.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: tlp | Add tlp service to runlevel 'default'
|
||||
service:
|
||||
name: tlp
|
||||
enabled: true
|
||||
state: started
|
||||
runlevel: default
|
47
roles/system/tasks/usbguard.yml
Normal file
47
roles/system/tasks/usbguard.yml
Normal file
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
- name: usbguard | Install usbguard
|
||||
community.general.apk:
|
||||
name: usbguard
|
||||
state: present
|
||||
|
||||
- name: usbguard | Allow normal user to control policy via IPC
|
||||
lineinfile:
|
||||
path: /etc/usbguard/usbguard-daemon.conf
|
||||
regexp: '^IPCAllowedUsers='
|
||||
line: 'IPCAllowedUsers=root {{ username }}'
|
||||
state: present
|
||||
owner: root
|
||||
group: root
|
||||
mode: '600'
|
||||
|
||||
- name: usbguard | Start usbguard service on runlevel 'default'
|
||||
service:
|
||||
name: usbguard
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: usbguard | Check whether there are defined policies
|
||||
stat:
|
||||
path: /etc/usbguard/rules.conf
|
||||
register: have_policies
|
||||
|
||||
# Or else you will be locked out from your desktop with no keyboards and mice
|
||||
- name: usbguard | Generate policies for currently connected devices
|
||||
shell: /usr/bin/usbguard generate-policy > /etc/usbguard/rules.conf
|
||||
args:
|
||||
removes: /usr/bin/usbguard
|
||||
when: have_policies.stat.size == 0
|
||||
|
||||
- name: usbguard | Ensure correct permissions for /etc/usbguard/rules.conf
|
||||
file:
|
||||
path: /etc/usbguard/rules.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '600'
|
||||
|
||||
- name: usbguard | Restart usbguard service to apply appended policies
|
||||
service:
|
||||
name: usbguard
|
||||
runlevel: default
|
||||
state: restarted
|
49
roles/system/tasks/user.yml
Normal file
49
roles/system/tasks/user.yml
Normal file
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
- name: user | Install {{ usershell }}
|
||||
community.general.apk:
|
||||
name: '{{ usershell }}'
|
||||
state: present
|
||||
when: usershell not in ['ash', 'sh']
|
||||
|
||||
- name: user | Create a normal user
|
||||
user:
|
||||
name: '{{ username }}'
|
||||
password: '{{ password | password_hash("sha512") }}'
|
||||
update_password: on_create
|
||||
append: true
|
||||
groups: '{{ usergroups }}'
|
||||
create_home: true
|
||||
home: '/home/{{ username }}'
|
||||
shell: '{{ shells_mappings[usershell] }}'
|
||||
state: present
|
||||
comment: Kawaii Linux user
|
||||
|
||||
- name: user | Double check the existence of group '{{ username }}'
|
||||
group:
|
||||
name: '{{ username }}'
|
||||
state: present
|
||||
|
||||
# We restrict /proc read permission to polkitd group
|
||||
- name: user | Add the user to polkitd group
|
||||
user:
|
||||
name: '{{ username }}'
|
||||
append: true
|
||||
groups:
|
||||
- polkitd
|
||||
when: use_polkit or (seat_manager == 'elogind')
|
||||
|
||||
- name: user | Add the user to seat group
|
||||
user:
|
||||
name: '{{ username }}'
|
||||
append: true
|
||||
groups:
|
||||
- seat
|
||||
when: seat_manager == 'seatd'
|
||||
|
||||
- name: user | Install {{ sudo_provider }}
|
||||
community.general.apk:
|
||||
name: '{{ sudo_provider }}'
|
||||
state: present
|
||||
|
||||
- name: user | Configure privilege escalation rules
|
||||
include_tasks: 'user/{{ sudo_provider }}.yml'
|
17
roles/system/tasks/user/doas.yml
Normal file
17
roles/system/tasks/user/doas.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
# pm-suspend is from pm-utils package (required by libvirt-client)
|
||||
- name: user | Add doas config for user {{ username }}
|
||||
blockinfile:
|
||||
path: /etc/doas.conf
|
||||
block: |
|
||||
permit persist :wheel
|
||||
{% if nopasswd_commands | length > 0 %}
|
||||
{% for command in nopasswd_commands %}
|
||||
permit nopass {{ username }} cmd {{ command }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
marker: '# {mark} ANSIBLE MANAGED SETTINGS'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '600'
|
||||
validate: /usr/bin/doas -C %s
|
49
roles/system/tasks/user/please.yml
Normal file
49
roles/system/tasks/user/please.yml
Normal file
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
# This allows the validation below to pass
|
||||
- name: user | Ensure /etc/please.ini exists
|
||||
file:
|
||||
path: /etc/please.ini
|
||||
mode: '600'
|
||||
owner: root
|
||||
group: root
|
||||
state: touch
|
||||
|
||||
- name: user | Configure please's privilege escalation rules
|
||||
blockinfile:
|
||||
path: /etc/please.ini
|
||||
block: |
|
||||
[wheel_run_as_anyone]
|
||||
name=wheel
|
||||
group=true
|
||||
target=^.*$
|
||||
regex=^.*$
|
||||
require_pass=true
|
||||
|
||||
[wheel_edit_anything]
|
||||
name=wheel
|
||||
group=true
|
||||
target=root
|
||||
type=edit
|
||||
regex=^.*$
|
||||
require_pass=true
|
||||
|
||||
[wheel_list_rules]
|
||||
name=wheel
|
||||
group=true
|
||||
target=^.*$
|
||||
type=list
|
||||
require_pass=false
|
||||
{% if nopasswd_commands | length > 0 %}
|
||||
|
||||
[{{ username }}_run_nopasswd]
|
||||
name={{ username }}
|
||||
target=root
|
||||
regex=^((/usr(/local)?)?/s?bin/)?{{ '(' ~ (nopasswd_commands | list | join('|')) ~ ')' }}(\s+.*)?$
|
||||
require_pass=false
|
||||
{% endif %}
|
||||
marker: ; {mark} ANSIBLE MANAGED SETTINGS
|
||||
validate: /usr/bin/please --check %s
|
||||
mode: '600'
|
||||
owner: root
|
||||
group: root
|
||||
state: present
|
23
roles/system/tasks/user/sudo.yml
Normal file
23
roles/system/tasks/user/sudo.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
- name: user | Allow wheel group to run commands as root
|
||||
community.general.sudoers:
|
||||
name: allow-wheel-group
|
||||
group: wheel
|
||||
commands: ALL
|
||||
host: ALL
|
||||
runas: ALL:ALL
|
||||
validation: required
|
||||
nopassword: false
|
||||
state: present
|
||||
|
||||
- name: user | Allow running commands as root without password for user {{ username }}
|
||||
community.general.sudoers:
|
||||
name: allow-{{ username }}-user
|
||||
user: '{{ username }}'
|
||||
commands: '{{ nopasswd_commands | list }}'
|
||||
host: ALL
|
||||
runas: ALL:ALL
|
||||
validation: required
|
||||
nopassword: true
|
||||
state: present
|
||||
when: nopasswd_commands | length > 0
|
31
roles/system/tasks/zram.yml
Normal file
31
roles/system/tasks/zram.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
- name: zram | Configure zram devices
|
||||
template:
|
||||
src: zram/zram.j2
|
||||
dest: /etc/modprobe.d/zram.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '644'
|
||||
|
||||
- name: zram | Add zram.start hook for local service
|
||||
template:
|
||||
src: zram/zram-start.j2
|
||||
dest: /etc/local.d/zram.start
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
|
||||
- name: zram | Add zram.stop hook for local service
|
||||
template:
|
||||
src: zram/zram-stop.j2
|
||||
dest: /etc/local.d/zram.stop
|
||||
owner: root
|
||||
group: root
|
||||
mode: '755'
|
||||
|
||||
- name: zram | Add local service to runlevel 'default'
|
||||
service:
|
||||
name: local
|
||||
runlevel: default
|
||||
enabled: true
|
||||
state: started
|
256
roles/system/templates/auditd/audit.rules.j2
Normal file
256
roles/system/templates/auditd/audit.rules.j2
Normal file
|
@ -0,0 +1,256 @@
|
|||
# /etc/audit/audit.rules
|
||||
# Adapted from https://github.com/Neo23x0/auditd/blob/master/audit.rules
|
||||
# Ref:
|
||||
# - auditctl(8)
|
||||
# - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-defining_audit_rules_and_controls
|
||||
|
||||
# Remove any existing rules
|
||||
-D
|
||||
|
||||
# Buffer Size
|
||||
## Feel free to increase this if the machine panic's
|
||||
-b 8192
|
||||
|
||||
# Failure Mode
|
||||
## Possible values: 0 (silent), 1 (printk, print a failure message), 2 (panic, halt the system)
|
||||
-f 1
|
||||
|
||||
# Ignore errors
|
||||
## e.g. caused by users or files not found in the local environment
|
||||
-i
|
||||
|
||||
# Self Auditing ---------------------------------------------------------------
|
||||
|
||||
## Audit the audit logs
|
||||
### Successful and unsuccessful attempts to read information from the audit records
|
||||
-a always,exit -F arch=b64 -F dir=/var/log/audit/ -F perm=wra -F key=auditlog
|
||||
|
||||
## Auditd configuration
|
||||
### Modifications to audit configuration that occur while the audit collection functions are operating
|
||||
-a always,exit -F arch=b64 -F dir=/etc/audit/ -F perm=wa -F key=auditconfig
|
||||
-a always,exit -F arch=b64 -F path=/etc/libaudit.conf -F perm=wa -F key=auditconfig
|
||||
|
||||
## Monitor for use of audit management tools
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/auditctl -F perm=x -F key=audittools
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/auditd -F perm=x -F key=audittools
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/augenrules -F perm=x -F key=audittools
|
||||
|
||||
## Access to all audit trails
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/ausearch -F perm=x -F key=auditlog_local_access
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/aureport -F perm=x -F key=auditlog_local_access
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/aulast -F perm=x -F key=auditlog_local_access
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/aulastlog -F perm=x -F key=auditlog_local_access
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/auvirt -F perm=x -F key=auditlog_local_access
|
||||
|
||||
# Filters ---------------------------------------------------------------------
|
||||
|
||||
### We put these early because audit is a first match wins system.
|
||||
|
||||
## Ignore current working directory records
|
||||
-a always,exclude -F msgtype=CWD
|
||||
|
||||
## This is not very interesting and wastes a lot of space if the server is public facing
|
||||
-a always,exclude -F msgtype=CRYPTO_KEY_USER
|
||||
|
||||
# This prevents ntpd daemons from overwhelming the logs
|
||||
-a never,exit -F arch=b64 -S adjtimex -F auid=unset -F uid=ntp
|
||||
{% if ntp_client == 'chrony' %}
|
||||
-a never,exit -F arch=b64 -S adjtimex -F auid=unset -F uid=chrony
|
||||
{% endif %}
|
||||
|
||||
## High Volume Event Filter (especially on Linux Workstations)
|
||||
-a never,exit -F arch=b64 -F dir=/dev/shm/ -F key=sharedmemaccess
|
||||
|
||||
# Rules -----------------------------------------------------------------------
|
||||
|
||||
## Kernel parameters
|
||||
-a always,exit -F arch=b64 -F path=/etc/sysctl.conf -F perm=wa -F key=sysctl
|
||||
-a always,exit -F arch=b64 -F dir=/etc/sysctl.d/ -F perm=wa -F key=sysctl
|
||||
|
||||
# Kernel module loading and unloading
|
||||
-a always,exit -F arch=b64 -F perm=x -F auid!=-1 -F path=/sbin/insmod -F key=modules
|
||||
-a always,exit -F arch=b64 -F perm=x -F auid!=-1 -F path=/sbin/modprobe -F key=modules
|
||||
-a always,exit -F arch=b64 -F perm=x -F auid!=-1 -F path=/sbin/rmmod -F key=modules
|
||||
-a always,exit -F arch=b64 -S finit_module,init_module,delete_module -F auid!=-1 -F key=modules
|
||||
|
||||
## Modprobe configuration
|
||||
-a always,exit -F arch=b64 -F path=/etc/modprobe.conf -F perm=wa -F key=modprobe
|
||||
-a always,exit -F arch=b64 -F dir=/etc/modprobe.d/ -F perm=wa -F key=modprobe
|
||||
|
||||
## KExec usage (all actions)
|
||||
-a always,exit -F arch=b64 -S kexec_load -F key=KEXEC
|
||||
|
||||
## Special files
|
||||
-a always,exit -F arch=b64 -S mknod,mknodat -F key=specialfiles
|
||||
|
||||
## Mount operations (only attributable)
|
||||
-a always,exit -F arch=b64 -S mount,umount2 -F auid!=-1 -F key=mount
|
||||
|
||||
## Change swap (only attributable)
|
||||
-a always,exit -F arch=b64 -S swapon,swapoff -F auid!=-1 -F key=swap
|
||||
|
||||
## Time
|
||||
-a always,exit -F arch=b64 -F uid!=ntp -S adjtimex,settimeofday,clock_settime -F key=time
|
||||
### Local time zone
|
||||
-a always,exit -F arch=b64 -F path=/etc/localtime -F perm=wa -F key=localtime
|
||||
|
||||
## Cron configuration & scheduled jobs
|
||||
-a always,exit -F arch=b64 -F dir=/etc/crontabs/ -F perm=wa -F key=cron
|
||||
-a always,exit -F arch=b64 -F dir=/var/spool/cron/ -F perm=wa -F key=cron
|
||||
-a always,exit -F arch=b64 -F dir=/etc/periodic/ -F perm=wa -F key=cron
|
||||
{% if crond_provider == 'cronie' %}
|
||||
-a always,exit -F arch=b64 -F dir=/etc/cron.d/ -F perm=wa -F key=cron
|
||||
-a always,exit -F arch=b64 -F path=/etc/cron.allow -F perm=wa -F key=cron
|
||||
-a always,exit -F arch=b64 -F path=/etc/cron.deny -F perm=wa -F key=cron
|
||||
{% endif %}
|
||||
{% if crond_provider == 'fcron' %}
|
||||
-a always,exit -F arch=b64 -F dir=/etc/fcron/ -F perm=wa -F key=cron
|
||||
-a always,exit -F arch=b64 -F dir=/var/spool/fcron/ -F perm=wa -F key=cron
|
||||
{% endif %}
|
||||
|
||||
## User, group, password databases
|
||||
-a always,exit -F arch=b64 -F path=/etc/group -F perm=wa -F key=etcgroup
|
||||
-a always,exit -F arch=b64 -F path=/etc/passwd -F perm=wa -F key=etcpasswd
|
||||
-a always,exit -F arch=b64 -F path=/etc/shadow -F perm=wa -F key=etcpasswd
|
||||
|
||||
# Changes to the privilege escalation programs' configurations
|
||||
-a always,exit -F arch=b64 -F path=/etc/doas.conf -F perm=wa -F key=actions
|
||||
-a always,exit -F arch=b64 -F path=/etc/please.ini -F perm=wa -F key=actions
|
||||
-a always,exit -F arch=b64 -F path=/etc/sudoers -F perm=wa -F key=actions
|
||||
-a always,exit -F arch=b64 -F dir=/etc/sudoers.d/ -F perm=wa -F key=actions
|
||||
|
||||
## Passwd
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/passwd -F perm=x -F key=passwd_modification
|
||||
|
||||
## Tools to change group identifiers
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/addgroup -F perm=x -F key=group_modification
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/adduser -F perm=x -F key=user_modification
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/delgroup -F perm=x -F key=user_modification
|
||||
-a always,exit -F arch=b64 -F path=/usr/sbin/deluser -F perm=x -F key=user_modification
|
||||
|
||||
## Login configuration and information
|
||||
-a always,exit -F arch=b64 -F path=/etc/securetty -F perm=wa -F key=login
|
||||
|
||||
## Network Environment
|
||||
### Changes to hostname
|
||||
-a always,exit -F arch=b64 -S sethostname,setdomainname -F key=network_modifications
|
||||
|
||||
### Successful IPv4 Connections
|
||||
-a always,exit -F arch=b64 -S connect -F a2=16 -F success=1 -F key=network_connect_4
|
||||
|
||||
### Successful IPv6 Connections
|
||||
-a always,exit -F arch=b64 -S connect -F a2=28 -F success=1 -F key=network_connect_6
|
||||
|
||||
### Changes to other files
|
||||
-a always,exit -F arch=b64 -F path=/etc/hosts -F perm=wa -F key=network_modifications
|
||||
-a always,exit -F arch=b64 -F path=/etc/netconfig -F perm=wa -F key=network_modifications
|
||||
-a always,exit -F arch=b64 -F dir=/etc/network/ -F perm=wa -F key=network
|
||||
|
||||
### Changes to issue
|
||||
-a always,exit -F arch=b64 -F path=/etc/issue -F perm=wa -F key=etcissue
|
||||
|
||||
## System startup scripts and service configurations
|
||||
-a always,exit -F arch=b64 -F path=/etc/inittab -F perm=wa -F key=init
|
||||
-a always,exit -F arch=b64 -F dir=/etc/init.d/ -F perm=wa -F key=init
|
||||
-a always,exit -F arch=b64 -F dir=/etc/conf.d/ -F perm=wa -F key=init
|
||||
|
||||
## Pam configuration
|
||||
-a always,exit -F arch=b64 -F dir=/etc/pam.d/ -F perm=wa -F key=pam
|
||||
-a always,exit -F arch=b64 -F path=/etc/security/limits.conf -F perm=wa -F key=pam
|
||||
-a always,exit -F arch=b64 -F path=/etc/security/limits.d -F perm=wa -F key=pam
|
||||
-a always,exit -F arch=b64 -F path=/etc/security/pam_env.conf -F perm=wa -F key=pam
|
||||
-a always,exit -F arch=b64 -F path=/etc/security/namespace.conf -F perm=wa -F key=pam
|
||||
-a always,exit -F arch=b64 -F path=/etc/security/namespace.d -F perm=wa -F key=pam
|
||||
-a always,exit -F arch=b64 -F path=/etc/security/namespace.init -F perm=wa -F key=pam
|
||||
|
||||
## Critical elements access failures
|
||||
-a always,exit -F arch=b64 -S open -F dir=/etc/ -F success=0 -F key=unauthedfileaccess
|
||||
-a always,exit -F arch=b64 -S open -F dir=/bin/ -F success=0 -F key=unauthedfileaccess
|
||||
-a always,exit -F arch=b64 -S open -F dir=/sbin/ -F success=0 -F key=unauthedfileaccess
|
||||
-a always,exit -F arch=b64 -S open -F dir=/usr/bin/ -F success=0 -F key=unauthedfileaccess
|
||||
-a always,exit -F arch=b64 -S open -F dir=/usr/sbin/ -F success=0 -F key=unauthedfileaccess
|
||||
-a always,exit -F arch=b64 -S open -F dir=/var/ -F success=0 -F key=unauthedfileaccess
|
||||
-a always,exit -F arch=b64 -S open -F dir=/home/ -F success=0 -F key=unauthedfileaccess
|
||||
|
||||
## Process ID change (switching accounts) applications
|
||||
-a always,exit -F arch=b64 -F path=/bin/su -F perm=x -F key=priv_esc
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/doas -F perm=x -F key=priv_esc
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/please -F perm=x -F key=priv_esc
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/pleaseedit -F perm=x -F key=priv_esc
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/sudo -F perm=x -F key=priv_esc
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/sudoedit -F perm=x -F key=priv_esc
|
||||
|
||||
## Power state
|
||||
-a always,exit -F arch=b64 -F path=/sbin/poweroff -F perm=x -F key=power
|
||||
-a always,exit -F arch=b64 -F path=/sbin/reboot -F perm=x -F key=power
|
||||
-a always,exit -F arch=b64 -F path=/sbin/halt -F perm=x -F key=power
|
||||
|
||||
## Session initiation information
|
||||
-a always,exit -F arch=b64 -F dir=/var/log/swtpm/ -F perm=wa -F key=session
|
||||
|
||||
# Special Rules ---------------------------------------------------------------
|
||||
|
||||
## dbus-send invocation
|
||||
### may indicate privilege escalation CVE-2021-3560
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/dbus-send -F perm=x -F key=dbus_send
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/gdbus -F perm=x -F key=gdubs_call
|
||||
|
||||
## pkexec invocation
|
||||
### may indicate privilege escalation CVE-2021-4034
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/pkexec -F perm=x -F key=pkexec
|
||||
|
||||
## Injection
|
||||
### These rules watch for code injection by the ptrace facility.
|
||||
### This could indicate someone trying to do something bad or just debugging
|
||||
-a always,exit -F arch=b64 -S ptrace -F a0=0x4 -F key=code_injection
|
||||
-a always,exit -F arch=b64 -S ptrace -F a0=0x5 -F key=data_injection
|
||||
-a always,exit -F arch=b64 -S ptrace -F a0=0x6 -F key=register_injection
|
||||
-a always,exit -F arch=b64 -S ptrace -F key=tracing
|
||||
|
||||
## Anonymous File Creation
|
||||
### These rules watch the use of memfd_create
|
||||
### "memfd_create" creates anonymous file and returns a file descriptor to access it
|
||||
### When combined with "fexecve" can be used to stealthily run binaries in memory without touching disk
|
||||
-a always,exit -F arch=b64 -S memfd_create -F key=anon_file_create
|
||||
|
||||
## Privilege Abuse
|
||||
### The purpose of this rule is to detect when an admin may be abusing power by looking in user's home dir.
|
||||
-a always,exit -F dir=/home/ -F auid=0 -F auid>=1000 -F auid!=-1 -F key=power_abuse
|
||||
|
||||
# Socket Creations
|
||||
# will catch both IPv4 and IPv6
|
||||
-a always,exit -F arch=b64 -S socket -F a0=2 -F key=exfiltration_over_other_network_medium
|
||||
-a always,exit -F arch=b64 -S socket -F a0=10 -F key=exfiltration_over_other_network_medium
|
||||
|
||||
# Software Management ---------------------------------------------------------
|
||||
-a always,exit -F arch=b64 -F path=/usr/bin/flatpak -F perm=x -F key=software_mgmt
|
||||
-a always,exit -F arch=b64 -F path=/sbin/apk -F perm=x -F key=software_mgmt
|
||||
-a always,exit -F arch=b64 -F dir=/etc/apk/ -F perm=wa -F key=software_mgmt
|
||||
|
||||
# High Volume Events ----------------------------------------------------------
|
||||
|
||||
## Disable these rules if they create too many events in your environment
|
||||
|
||||
## File Access
|
||||
### Unauthorized Access (unsuccessful)
|
||||
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=file_access
|
||||
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=file_access
|
||||
|
||||
### Unsuccessful Creation
|
||||
-a always,exit -F arch=b64 -S mkdir,creat,link,symlink,mknod,mknodat,linkat,symlinkat -F exit=-EACCES -F key=file_creation
|
||||
-a always,exit -F arch=b64 -S mkdir,link,symlink,mkdirat -F exit=-EPERM -F key=file_creation
|
||||
|
||||
### Unsuccessful Modification
|
||||
-a always,exit -F arch=b64 -S rename,renameat,truncate,chmod,setxattr,lsetxattr,removexattr,lremovexattr -F exit=-EACCES -F key=file_modification
|
||||
-a always,exit -F arch=b64 -S rename,renameat,truncate,chmod,setxattr,lsetxattr,removexattr,lremovexattr -F exit=-EPERM -F key=file_modification
|
||||
|
||||
## 32bit API Exploitation
|
||||
### If you are on a 64 bit platform, everything _should_ be running
|
||||
### in 64 bit mode. This rule will detect any use of the 32 bit syscalls
|
||||
### because this might be a sign of someone exploiting a hole in the 32
|
||||
### bit API.
|
||||
-a always,exit -F arch=b32 -S all -F key=32bit_api
|
||||
|
||||
# Make The Configuration Immutable --------------------------------------------
|
||||
|
||||
##-e 2
|
2
roles/system/templates/devd/51-android.j2
Normal file
2
roles/system/templates/devd/51-android.j2
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Galaxy A5 2016 (a5xelte)
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", ATTR{idProduct}=="6860", MODE="0660", OWNER="{{ username }}", ENV{ID_MTP_DEVICE}="1", SYMLINK+="libmtp"
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue