Merge sysconfig repo

The other repo is not large enough to be standalone, so include it here
as a single role.

More changes:
- Update onedark pallete (https://github.com/Binaryify/OneDark-Pro/blob/master/src/themes/data/oneDarkPro.ts)
- Fix ansible-lint warnings
This commit is contained in:
Hoang Nguyen 2024-02-16 00:00:00 +07:00
parent db2efc5aac
commit 922733dcde
Signed by: folliehiyuki
GPG Key ID: B0567C20730E9B11
127 changed files with 4693 additions and 279 deletions

View File

@ -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

View File

@ -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
View File

@ -1,3 +1,4 @@
/filter_plugins/__pycache__/
/.ropeproject/
/playbooks/dist-newstyle/
/host_vars/

5
.yamllint Normal file
View File

@ -0,0 +1,5 @@
---
rules:
indentation:
spaces: 2
indent-sequences: consistent

View File

@ -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:

49
TODO.md
View File

@ -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)

View File

@ -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

View 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
View 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

View File

@ -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

View File

@ -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
View 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 }}'

View File

@ -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

View File

@ -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
View File

@ -0,0 +1,2 @@
[local.hosts]
localhost = { ansible_connection = "local" }

View File

@ -1,5 +0,0 @@
---
local:
hosts:
localhost:
ansible_connection: local

View File

@ -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

View File

@ -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
View 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

View File

@ -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

View File

@ -1,5 +1,6 @@
---
collections:
- name: ansible.posix
- name: community.crypto
- name: community.general
- name: containers.podman

View File

@ -1,4 +0,0 @@
---
chroot_dir: '{{ ansible_user_dir }}/Alpine-chroot'
apk_repository:
- https://dl-cdn.alpinelinux.org/alpine

View File

@ -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'

View File

@ -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"

View File

@ -1,6 +0,0 @@
{% for repo in apk_repository %}
{{ repo }}/edge/main
{{ repo }}/edge/community
{{ repo }}/edge/testing
{% endfor %}

View File

@ -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

View File

@ -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'

View File

@ -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"

View File

@ -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

View File

@ -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 %}

View File

@ -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') }}

View File

@ -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

View File

@ -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 }}'

View 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

View File

@ -0,0 +1,2 @@
#!/bin/sh
echo mem > /sys/power/state

View 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

View 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

View 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

View File

@ -0,0 +1,4 @@
#!/bin/sh
# auditd rotates its logfile on receiving SIGUSR1
/usr/bin/pkill -USR1 -x /usr/sbin/auditd

View 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 {} \;

View 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

View 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.*

View File

@ -0,0 +1,6 @@
################################
# Cloaking rules #
################################
localhost 127.0.0.1
localhost ::1

View 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

View 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

View 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

View 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"

View 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

View 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

View 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

View 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 %}

View 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

View 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'

View 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

View 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

View 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

View 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

View 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'

View 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

View 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

View 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

View 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 }}'

View 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 }}'

View 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

View 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'

View 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

View 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

View 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

View 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']

View 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

View 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"] }}'

View 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)

View 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"

View 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'

View 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

View 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

View 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']

View 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

View 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'

View 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.

View 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

View 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

View 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

View 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

View 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

View File

@ -0,0 +1,3 @@
---
- name: snapshot | Setup {{ snapshot_tool }}
include_tasks: 'snapshot/{{ snapshot_tool }}.yml'

View 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 }}'

View 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

View 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

View File

@ -0,0 +1 @@
---

View 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

View 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

View 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'

View 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

View 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

View 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

View 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

View 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

View 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"

View File

@ -0,0 +1 @@
KERNEL=="uinput", MODE="0660", OWNER="{{ username }}", OPTIONS+="static_node=uinput"

Some files were not shown because too many files have changed in this diff Show More