Getting started

This commit is contained in:
Hoang Nguyen 2022-01-15 01:46:59 +07:00
parent a184804a51
commit 92382adbcd
No known key found for this signature in database
GPG Key ID: 813CF484F4993419
43 changed files with 1204 additions and 3 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) <year> <copyright holders>
Copyright (c) 2021 FollieHiyuki
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:

View File

@ -1,3 +1,46 @@
# sysconfig
# System configurations
System config for the desktop
This is an Ansible playbook to deploy system configurations for desktop usage.
## 🧰 Usage
- Have a fresh installation of Alpine (after running `setup-alpine` and reboot)
- Install `ansible` and `git`
- Clone this repository
- Create an encrypted file to store your user password:
```shell
# mkdir -p host_vars/YOUR_HOSTNAME
# touch host_vars/YOUR_HOSTNAME/secrets.yml
# ansible-vault encrypt host_vars/YOUR_HOSTNAME/secrets.yml
# ansible-vault edit host_vars/YOUR_HOSTNAME/secrets.yml
```
The file should look like this: `vault_password: <strong_&_secure_password>`
- Run the playbook:
```shell
# ansible-playbook -i hosts setup.yml
```
- Reboot and login as the newly created normal user
- Proceed with [dotfiles-ansible](https://git.disroot.org/FollieHiyuki/dotfiles-ansible) playbook
## 🖊️ Notes
- This playbook assumes that the person running it is me 😃. It might do specific things that you don't like. Use with your own risks.
- The playbook is intended to be run as **root**. Therefore, it is separated from [dotfiles-ansible](https://git.disroot.org/FollieHiyuki/dotfiles-ansible), which should only be run as a normal user.
## ✅ TODO
- [ ] ZFS on root
- [ ] EFI secure boot
## 📄 License
MIT

11
ansible.cfg Normal file
View File

@ -0,0 +1,11 @@
[defaults]
inventory = ./hosts
gathering = explicit
display_skipped_hosts = False
host_key_checking = False
interpreter_python = auto_silent
[ssh_connection]
pipelining = True
scp_if_ssh = smart
transfer_method = smart

6
group_vars/all.yml Normal file
View File

@ -0,0 +1,6 @@
---
rootfs: btrfs
username: follie
# Secrets encrypted with ansible-vault
password: {{ vault_password }}

2
hosts Normal file
View File

@ -0,0 +1,2 @@
[local]
localhost ansible_connection=local

View File

@ -0,0 +1,3 @@
---
- name: Update grub config
command: grub-mkconfig -o /boot/grub/grub.cfg

View File

@ -0,0 +1,53 @@
---
- name: apparmor | Enable writing cache and faster DFA transition table compression
lineinfile:
backup: yes
path: /etc/apparmor/parser.conf
state: present
search_string: '{{ item }}'
line: '{{ item }}'
owner: root
group: root
mode: 0644
loop:
- write-cache
- Optimize=compress-fast
- name: apparmor | Add busybox rule for dnsmasq profile
lineinfile:
path: /etc/apparmor.d/local/usr.sbin.dnsmasq
state: present
line: /bin/busybox ix,
owner: root
group: root
mode: 0644
validate: grep -F 'busybox' %s
- name: apparmor | Add apparmor service to runlevel 'boot'
service:
name: apparmor
runlevel: boot
enabled: yes
- name: apparmor | Check whether apparmor is presented in grub boot command
lineinfile:
backup: yes
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=".*page_alloc.shuffle=1 init_on_free=1 apparmor=1 security=apparmor'
state: absent
check_mode: yes
register: grub_cmdline_check
changed_when: no
- name: apparmor | Add apparmor to grub boot command if missing
lineinfile:
backrefs: yes
path: /etc/default/grub
regexp: '^(GRUB_CMDLINE_LINUX_DEFAULT=".*)"$'
line: '\1 page_alloc.shuffle=1 init_on_free=1 apparmor=1 security=apparmor"'
owner: root
group: root
mode: 0644
validate: grep -F 'page_alloc.shuffle=1 init_on_free=1 apparmor=1 security=apparmor' %s
when: grub_cmdline_check.found == 0
notify: Update grub config

View File

@ -0,0 +1,18 @@
---
- name: consolefont | Change the console font to ter-h22b
lineinfile:
path: /etc/conf.d/consolefont
state: present
regexp: '^consolefont='
line: 'consolefont="ter-h22b.psf.gz"'
owner: root
group: root
mode: 0644
validate: 'grep -F "ter-h22b" %s'
- name: consolefont | Start consolefont service on runlevel 'boot'
service:
name: consolefont
runlevel: boot
enabled: yes
state: started

View File

@ -0,0 +1,3 @@
#!/bin/sh
btrfs scrub start /

View File

@ -0,0 +1,3 @@
#!/bin/sh
rm -rf /var/tmp/*

3
roles/cron/files/fstrim Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
fstrim -a

33
roles/cron/tasks/main.yml Normal file
View File

@ -0,0 +1,33 @@
---
- name: cron | Create fstrim daily job
copy:
src: fstrim
dest: /etc/periodic/daily/fstrim
owner: root
group: root
mode: 0755
# It is recomended to preserve /var/tmp across reboots
- name: cron | Create empty /var/tmp/ monthly job
copy:
src: empty-tmp
dest: /etc/periodic/monthly/empty-tmp
owner: root
group: root
mode: 0755
- name: cron | Create btrfs-scrub monthly job
copy:
src: btrfs-scrub
dest: /etc/periodic/monthly/btrfs-scrub
owner: root
group: root
mode: 0755
when: rootfs == 'btrfs'
- name: cron | Add crond service to runlevel 'default'
service:
name: crond
runlevel: default
enabled: yes
state: started

View File

@ -0,0 +1,3 @@
blacklist vivid
blacklist bluetooth
blacklist btusb

View File

@ -0,0 +1,3 @@
---
- name: Regenerate initramfs
command: 'mkinitfs -c /etc/mkinitfs/mkinitfs.conf {{ ansible_kernel }}'

View File

@ -0,0 +1,83 @@
---
- name: essential | Install system dependencies
apk:
name: >
doas, nftables, zstd, fish, dbus, elogind, polkit-elogind, terminus-font,
apparmor, apparmor-profiles, libvirt-daemon, qemu-img, qemu-system-x86_64,
qemu-modules, libvirt-guests, shadow-login, unbound, openresolv
available: yes
update_cache: yes
state: present
- name: essential | Start elogind service on runlevel 'boot'
service:
name: elogind
runlevel: boot
enabled: yes
state: started
- name: essential | Start other services on runlevel 'default'
service:
name: '{{ item }}'
runlevel: default
enabled: yes
state: started
loop: [ dbus, ntpd, cgroups ]
- name: essential | Setup eudev
command:
cmd: setup-udev
creates: /etc/runlevels/sysinit/udev
- name: essential | Change the default motd
template:
src: motd.j2
dest: /etc/motd
owner: root
group: root
mode: 0644
- name: essential | Use zstd for initramfs
lineinfile:
backup: yes
path: /etc/mkinitfs/mkinitfs.conf
state: present
search_string: initfscomp=
line: initfscomp="zstd"
owner: root
group: root
mode: 0644
validate: grep -F 'initfscomp="zstd"' %s
notify: Regenerate initramfs
- name: essential | Enable logging for openrc
lineinfile:
backup: yes
path: /etc/rc.conf
state: present
search_string: rc_logger="
line: rc_logger="YES"
owner: root
group: root
mode: 0644
validate: grep -F 'rc_logger="YES"' %s
- name: essential | Enable unicode support for openrc
lineinfile:
backup: yes
path: /etc/rc.conf
state: present
search_string: unicode="
line: unicode="YES"
owner: root
group: root
mode: 0644
validate: grep -F 'unicode="YES"' %s
- name: essential | Blacklist bluetooth related kernel modules
copy:
src: bluetooth-blacklist.conf
dest: /etc/modprobe.d/bluetooth-blacklist.conf
owner: root
group: root
mode: 0644

View File

@ -0,0 +1,2 @@
Welcome to Alpine, {{ username }}!

BIN
roles/grub/files/hack.pf2 Normal file

Binary file not shown.

BIN
roles/grub/files/miku.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

46
roles/grub/tasks/main.yml Normal file
View File

@ -0,0 +1,46 @@
---
- name: grub | Copy Miku wallpaper
copy:
src: miku.png
dest: /boot/grub/background.png
owner: root
group: root
mode: 0644
# Download a release from https://github.com/source-foundry/Hack
# Decompress the archive
# Run: grub-mkfont -o hack.pf2 -s 24 Hack-Regular.ttf
- name: grub | Copy Hack font
copy:
src: hack.pf2
dest: /boot/grub/fonts/hack.pf2
owner: root
group: root
mode: 0644
- name: grub | Adjust GRUB_TIMEOUT to 10s
lineinfile:
path: /etc/default/grub
regexp: '^GRUB_TIMEOUT='
line: 'GRUB_TIMEOUT=10'
owner: root
group: root
mode: 0644
validate: grep -F 'GRUB_TIMEOUT=10' %s
- name: grub | Add font and background configurations to /etc/default/grub
blockinfile:
path: /etc/default/grub
insertafter: '^GRUB_CMDLINE_LINUX_DEFAULT='
block: |
GRUB_DISABLE_OS_PROBER=true
GRUB_GFXMODE=1920x1080x32,1280x720x32,auto
GRUB_GFXPAYLOAD_LINUX=keep
GRUB_BACKGROUND=/boot/grub/background.png
GRUB_FONT=/boot/grub/fonts/hack.pf2
marker: '# {mark} CUSTOM SETTINGS BLOCK'
owner: root
group: root
mode: 0644
validate: grep -F 'hack.pf2' %s
notify: Update grub config

39
roles/iwd/files/main.conf Normal file
View File

@ -0,0 +1,39 @@
# Note: The lines starting with # are ignored. To enable any of the
# configuration options below, remove # from the beginning of a respective line.
# this file is not distributed upstream as of iwd 1.0 version
# It is created as transitional config from latest version
# Please read iwd.config(5), iwd.network(5), iwctl(1), iwmon(1) before setting
# these parameters below
# main.conf format is changed with iwd 1.3 release
#[EAP]
#mtu=1400
#[EAPoL]
#max_4way_handshake_time=5
[General]
EnableNetworkConfiguration=True
UseDefaultInterface=True
ControlPortOverNL80211=True
#RoamThreshold=-70
[Network]
NameResolvingService=resolvconf
EnableIPv6=true
RoutePriorityOffset=200
[Scan]
DisablePeriodicScan=true
DisableRoamingScan=true
#[Blacklist]
#[Rank]
# BandModifier5Ghz=1.0

20
roles/iwd/tasks/main.yml Normal file
View File

@ -0,0 +1,20 @@
---
- name: iwd | Install iwd package
apk:
name: iwd
state: present
- name: iwd | Copy configuration
copy:
src: main.conf
dest: /etc/iwd/main.conf
owner: root
group: root
mode: 0644
- name: iwd | Start iwd service on runlevel 'default'
service:
name: iwd
runlevel: default
enabled: yes
state: started

View File

@ -0,0 +1,34 @@
--- nftables.nft
+++ nftables.nft
@@ -87,13 +87,31 @@
ip6 saddr fe80::/10 udp sport 547 udp dport 546 accept \
comment "Accept DHCPv6 replies from IPv6 link-local addresses"
+
+ iifname "virbr0" udp dport 53 accept
+ iifname "virbr0" tcp dport 53 accept
+ iifname "virbr0" udp dport 67 accept
+ iifname "virbr0" tcp dport 67 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
+ ct state invalid drop
+ oifname "virbr0" ip daddr 192.168.122.0/24 ct state { established, related } accept
+ iifname "virbr0" ip saddr 192.168.122.0/24 accept
+ iifname "virbr0" oifname "virbr0" accept
+ oifname "virbr0" reject with icmpx type port-unreachable
+ iifname "virbr0" reject with icmpx type port-unreachable
}
chain output {
type filter hook output priority 0; policy accept;
+ }
+}
+
+table inet nat {
+ chain postrouting {
+ type nat hook postrouting priority 100
+ ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 masquerade
}
}

View File

@ -0,0 +1,5 @@
---
- name: Reload nftables ruleset
service:
name: nftables
state: reloaded

View File

@ -0,0 +1,51 @@
---
- name: libvirt | Add nftables rules for libvirt bridge (NAT mode)
patch:
backup: yes
src: libvirt-nftables.patch
dest: /etc/nftables.nft
state: present
notify: Reload nftables ruleset
- name: libvirt | Allow IPv6 RA passthrough to libvirt NAT
lineinfile:
path: /etc/sysctl.d/custom.conf
owner: root
group: root
mode: 0644
search_string: eth0.accept_ra
line: net.ipv6.conf.eth0.accept_ra = 2
notify: Load custom sysctl settings
- name: libvirt | Allow the normal user to interact with qemu system instance
lineinfile:
path: /etc/libvirt/qemu.conf
owner: root
group: root
mode: 0644
regexp: '^#?user = "'
line: 'user = "{{ username }}"'
- name: libvirt | Allow kvm group to interact with qemu system instance
lineinfile:
path: /etc/libvirt/qemu.conf
owner: root
group: root
mode: 0644
regexp: '^#?group = "'
line: 'group = "kvm"'
- name: libvirt | Start modular services on runlevel 'default'
service:
name: '{{ item }}'
runlevel: default
enabled: yes
state: started
loop:
- virtinterfaced
- virtlockd
- virtlogd
- virtnetworkd
- virtnodedevd
- virtqemud
- virtstoraged

View File

@ -0,0 +1,99 @@
#!/usr/sbin/nft -f
# vim:set ts=4:
# You can find examples in /usr/share/nftables/.
# Clear all prior state
flush ruleset
# https://wiki.gentoo.org/wiki/Nftables#Family_netdev_and_ingress_hook
table netdev filter {
chain ingress {
type filter hook ingress device eth0 priority -500; policy accept;
# Drop all fragments.
ip frag-off & 0x1fff != 0 drop
# Drop XMAS packets.
tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg drop
# Drop NULL packets.
tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 drop
# Drop uncommon MSS values.
tcp flags syn tcp option maxseg size 1-535 drop
}
}
# Basic IPv4/IPv6 stateful firewall for server/workstation.
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept \
comment "Accept any localhost traffic"
iif != lo ip daddr 127.0.0.1/8 drop \
comment "Block spoofing as localhost (IPv4)"
iif != lo ip6 daddr ::1/128 drop \
comment "Block spoofing as localhost (IPv6)"
ct state { established, related } accept \
comment "Accept traffic originated from us"
ct state invalid drop \
comment "Drop invalid connections"
tcp dport 113 reject with icmpx type port-unreachable \
comment "Reject AUTH to make it fail fast"
# ICMPv4
ip protocol icmp icmp type {
echo-reply, # type 0
destination-unreachable, # type 3
echo-request, # type 8
time-exceeded, # type 11
parameter-problem, # type 12
} limit rate 1/second burst 4 packets accept \
comment "Accept ICMP"
# ICMPv6
ip6 nexthdr icmpv6 icmpv6 type {
destination-unreachable, # type 1
packet-too-big, # type 2
time-exceeded, # type 3
parameter-problem, # type 4
echo-request, # type 128
echo-reply, # type 129
} limit rate 1/second burst 4 packets accept \
comment "Accept basic IPv6 functionality"
ip6 nexthdr icmpv6 icmpv6 type {
nd-router-solicit, # type 133
nd-router-advert, # type 134
nd-neighbor-solicit, # type 135
nd-neighbor-advert, # type 136
} ip6 hoplimit 255 accept \
comment "Allow IPv6 SLAAC"
ip6 nexthdr icmpv6 icmpv6 type {
mld-listener-query, # type 130
mld-listener-report, # type 131
mld-listener-reduction, # type 132
mld2-listener-report, # type 143
} ip6 saddr fe80::/10 accept \
comment "Allow IPv6 multicast listener discovery on link-local"
ip6 saddr fe80::/10 udp sport 547 udp dport 546 accept \
comment "Accept DHCPv6 replies from IPv6 link-local addresses"
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}

View File

@ -0,0 +1,15 @@
---
- name: nftables | Copy firewall configuration
copy:
src: nftables.nft
dest: /etc/nftables.nft
owner: root
group: root
mode: 0644
- name: nftables | Add nftables service to runlevel 'default'
service:
name: nftables
runlevel: default
enabled: yes
state: started

View File

@ -0,0 +1,7 @@
# Custom path for core dump
kernel.core_pattern = /tmp/core-%e.%p.%h.%t
# Privacy extension for ipv6
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.eth0.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2

View File

@ -0,0 +1,3 @@
---
- name: Load custom sysctl settings
command: sysctl -p /etc/sysctl.d/custom.conf

View File

@ -0,0 +1,9 @@
---
- name: sysctl | Create a custom sysctl file
copy:
src: custom.conf
dest: /etc/sysctl.d/custom.conf
owner: root
group: root
mode: 0644
notify: Load custom sysctl settings

20
roles/tlp/tasks/main.yml Normal file
View File

@ -0,0 +1,20 @@
---
- name: tlp | Install tlp package
apk:
name: tlp
state: present
- name: tlp | Copy configuration
template:
src: 00-custom.j2
dest: /etc/tlp.d/00-custom.conf
owner: root
group: root
mode: 0644
- name: tlp | Add tlp service to runlevel 'default'
service:
name: tlp
enabled: yes
state: started
runlevel: default

View File

@ -0,0 +1 @@
{% include 'by_host/' + ansible_hostname + '/config.j2' ignore missing %}

View File

@ -0,0 +1,20 @@
TLP_DEFAULT_MODE=BAT
CPU_SCALING_MIN_FREQ_ON_BAT=1400000
CPU_SCALING_MAX_FREQ_ON_BAT=1700000
CPU_SCALING_MIN_FREQ_ON_AC=1400000
CPU_SCALING_MAX_FREQ_ON_AC=2100000
DISK_SPINDOWN_TIMEOUT_ON_AC="keep keep"
DISK_SPINDOWN_TIMEOUT_ON_BAT="keep 1"
DISK_IOSCHED="mq-deadline mq-deadline"
PCIE_ASPM_ON_BAT=default
PCIE_ASPM_ON_AC=default
DEVICES_TO_DISABLE_ON_STARTUP="bluetooth wifi wwan"
DEVICES_TO_DISABLE_ON_BAT_NOT_IN_USE="bluetooth wifi wwan"
START_CHARGE_THRESH_BAT0=75
STOP_CHARGE_THRESH_BAT0=90
RESTORE_THRESHOLDS_ON_BAT=1

View File

@ -0,0 +1,9 @@
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
pre-up resolvconf -u
iface eth0 inet6 auto

View File

@ -0,0 +1,8 @@
# Configuration for resolvconf(8)
# See resolvconf.conf(5) for details
resolv_conf=/etc/resolv.conf
# If you run a local name server, you should uncomment the below line and
# configure your subscribers configuration files below.
name_servers="127.0.0.1 ::1"
resolv_conf_options="trust-ad"

View File

@ -0,0 +1,306 @@
server:
###########################################################################
# LOGGING
###########################################################################
# Only log errors
verbosity: 0
# Do not print log lines to inform about local zone actions
log-local-actions: no
# Do not print one line per query to the log
log-queries: no
# Do not print one line per reply to the log
log-replies: no
# Do not print log lines that say why queries return SERVFAIL to clients
log-servfail: no
# Further limit logging
logfile: /dev/null
###########################################################################
# BASIC SETTINGS
###########################################################################
# the time to live (TTL) value cap for RRsets and messages in the
# cache. Items are not cached for longer. In seconds.
cache-max-ttl: 86400
# the time to live (TTL) value lower bound, in seconds. Default 0.
# If more than an hour could easily give trouble due to stale data.
cache-min-ttl: 300
# Set the working directory for the program.
directory: "/etc/unbound"
# RFC 6891. Number of bytes size to advertise as the EDNS reassembly buffer
# size. This is the value put into datagrams over UDP towards peers.
# The actual buffer size is determined by msg-buffer-size (both for TCP and
# UDP). Do not set higher than that value.
# Default is 1232 which is the DNS Flag Day 2020 recommendation.
# Setting to 512 bypasses even the most stringent path MTU problems, but
# is seen as extreme, since the amount of TCP fallback generated is
# excessive (probably also for this resolver, consider tuning the outgoing
# tcp number).
edns-buffer-size: 1472
# Listen to for queries from clients and answer from this network interface
# and port.
interface: 127.0.0.1
interface: ::1
port: 53
# Set to yes if you have IPv6
do-ip4: yes
do-udp: yes
do-tcp: yes
do-ip6: yes
prefer-ip6: no
# Rotates RRSet order in response (the pseudo-random number is taken from
# the query ID, for speed and thread safety).
rrset-roundrobin: yes
# Drop user privileges after binding the port.
username: "unbound"
# Use this only when you downloaded the list of primary root servers!
# If you use the default dns-root-data package, unbound will find it automatically
#root-hints: "/var/lib/unbound/root.hints"
###########################################################################
# PRIVACY SETTINGS
###########################################################################
# RFC 8198. Use the DNSSEC NSEC chain to synthesize NXDO-MAIN and other
# denials, using information from previous NXDO-MAINs answers. In other
# words, use cached NSEC records to generate negative answers within a
# range and positive answers from wildcards. This increases performance,
# decreases latency and resource utilization on both authoritative and
# recursive servers, and increases privacy. Also, it may help increase
# resilience to certain DoS attacks in some circumstances.
aggressive-nsec: yes
# Extra delay for timeouted UDP ports before they are closed, in msec.
# This prevents very delayed answer packets from the upstream (recursive)
# servers from bouncing against closed ports and setting off all sort of
# close-port counters, with eg. 1500 msec. When timeouts happen you need
# extra sockets, it checks the ID and remote IP of packets, and unwanted
# packets are added to the unwanted packet counter.
delay-close: 10000
# Prevent the unbound server from forking into the background as a daemon
do-daemonize: no
# Add localhost to the do-not-query-address list.
do-not-query-localhost: yes
# Number of bytes size of the aggressive negative cache.
neg-cache-size: 4m
# Send minimum amount of information to upstream servers to enhance
# privacy (best privacy).
qname-minimisation: yes
# Do not fall-back to sending full QNAME to potentially broken nameservers.
# A lot of domains will not be resolvable when this option in enabled.
# Only use if you know what you are doing.
# qname-minimisation-strict: yes
###########################################################################
# SECURITY SETTINGS
###########################################################################
# Only give access to recursion clients from LAN IPs
access-control: 127.0.0.1/8 allow
access-control: ::1/128 allow
# File with trust anchor for one zone, which is tracked with RFC5011
# probes.
auto-trust-anchor-file: "var/root.key"
# Enable chroot (i.e, change apparent root directory for the current
# running process and its children)
chroot: "/etc/unbound"
# Deny queries of type ANY with an empty response.
deny-any: yes
# Harden against algorithm downgrade when multiple algorithms are
# advertised in the DS record.
harden-algo-downgrade: yes
# RFC 8020. returns nxdomain to queries for a name below another name that
# is already known to be nxdomain.
harden-below-nxdomain: yes
# Require DNSSEC data for trust-anchored zones, if such data is absent, the
# zone becomes bogus. If turned off you run the risk of a downgrade attack
# that disables security for a zone.
harden-dnssec-stripped: yes
# Only trust glue if it is within the servers authority.
harden-glue: yes
# Ignore very large queries.
harden-large-queries: yes
# Perform additional queries for infrastructure data to harden the referral
# path. Validates the replies if trust anchors are configured and the zones
# are signed. This enforces DNSSEC validation on nameserver NS sets and the
# nameserver addresses that are encountered on the referral path to the
# answer. Experimental option.
harden-referral-path: no
# Ignore very small EDNS buffer sizes from queries.
harden-short-bufsize: yes
# Refuse id.server and hostname.bind queries
hide-identity: yes
# Refuse version.server and version.bind queries
hide-version: yes
# Report this identity rather than the hostname of the server.
identity: "DNS"
# These private network addresses are not allowed to be returned for public
# internet names. Any occurrence of such addresses are removed from DNS
# answers. Additionally, the DNSSEC validator may mark the answers bogus.
# This protects against DNS Rebinding
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10
private-address: ::ffff:0:0/96
# Enable ratelimiting of queries (per second) sent to nameserver for
# performing recursion. More queries are turned away with an error
# (servfail). This stops recursive floods (e.g., random query names), but
# not spoofed reflection floods. Cached responses are not rate limited by
# this setting. Experimental option.
ratelimit: 1000
# Use this certificate bundle for authenticating connections made to
# outside peers (e.g., auth-zone urls, DNS over TLS connections).
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
# Set the total number of unwanted replies to eep track of in every thread.
# When it reaches the threshold, a defensive action of clearing the rrset
# and message caches is taken, hopefully flushing away any poison.
# Unbound suggests a value of 10 million.
unwanted-reply-threshold: 10000
# Use 0x20-encoded random bits in the query to foil spoof attempts. This
# perturbs the lowercase and uppercase of query names sent to authority
# servers and checks if the reply still has the correct casing.
# This feature is an experimental implementation of draft dns-0x20.
# Experimental option.
use-caps-for-id: yes
# Help protect users that rely on this validator for authentication from
# potentially bad data in the additional section. Instruct the validator to
# remove data from the additional section of secure messages that are not
# signed properly. Messages that are insecure, bogus, indeterminate or
# unchecked are not affected.
val-clean-additional: yes
###########################################################################
# PERFORMANCE SETTINGS
###########################################################################
# https://nlnetlabs.nl/documentation/unbound/howto-optimise/
# https://nlnetlabs.nl/news/2019/Feb/05/unbound-1.9.0-released/
# Number of slabs in the infrastructure cache. Slabs reduce lock contention
# by threads. Must be set to a power of 2.
# infra-cache-slabs: 4
# Number of incoming TCP buffers to allocate per thread. Default
# is 10. If set to 0, or if do-tcp is "no", no TCP queries from
# clients are accepted. For larger installations increasing this
# value is a good idea.
# incoming-num-tcp: 10
# Number of slabs in the key cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2. Setting (close) to the number
# of cpus is a reasonable guess.
# key-cache-slabs: 4
# Number of bytes size of the message cache.
# Unbound recommendation is to Use roughly twice as much rrset cache memory
# as you use msg cache memory.
msg-cache-size: 260991658
# Number of slabs in the message cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2. Setting (close) to the number of
# cpus is a reasonable guess.
# msg-cache-slabs: 4
# The number of queries that every thread will service simultaneously. If
# more queries arrive that need servicing, and no queries can be jostled
# out (see jostle-timeout), then the queries are dropped.
# This is best set at half the number of the outgoing-range.
# This Unbound instance was compiled with libevent so it can efficiently
# use more than 1024 file descriptors.
num-queries-per-thread: 4096
# The number of threads to create to serve clients.
# This is set dynamically at run time to effectively use available CPUs
# resources
# num-threads: 3
# Number of ports to open. This number of file descriptors can be opened
# per thread.
# This Unbound instance was compiled with libevent so it can efficiently
# use more than 1024 file descriptors.
outgoing-range: 8192
# Number of bytes size of the RRset cache.
# Use roughly twice as much rrset cache memory as msg cache memory
rrset-cache-size: 260991658
# Number of slabs in the RRset cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2.
# rrset-cache-slabs: 4
# Do no insert authority/additional sections into response messages when
# those sections are not required. This reduces response size
# significantly, and may avoid TCP fallback for some responses. This may
# cause a slight speedup.
minimal-responses: yes
# Fetch the DNSKEYs earlier in the validation process, when a DS record
# is encountered. This lowers the latency of requests at the expense of
# little more CPU usage.
prefetch: yes
# Fetch the DNSKEYs earlier in the validation process, when a DS record is
# encountered. This lowers the latency of requests at the expense of little
# more CPU usage.
prefetch-key: yes
# Have unbound attempt to serve old responses from cache with a TTL of 0 in
# the response without waiting for the actual resolution to finish. The
# actual resolution answer ends up in the cache later on.
serve-expired: yes
# Open dedicated listening sockets for incoming queries for each thread and
# try to set the SO_REUSEPORT socket option on each socket. May distribute
# incoming queries to threads more evenly.
so-reuseport: yes
# Ensure kernel buffer is large enough to not lose messages in traffic spikes
# so-rcvbuf: 1m
# so-sndbuf: 1m
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 9.9.9.9@853#dns.quad9.net
forward-addr: 149.112.112.112@853#dns.quad9.net
forward-addr: 2620:fe::fe@853#dns.quad9.net
forward-addr: 2620:fe::9@853#dns.quad9.net
remote-control:
control-enable: no

View File

@ -0,0 +1,62 @@
---
- name: unbound | Copy unbound config
copy:
src: unbound.conf
dest: /etc/unbound/unbound.conf
owner: root
group: root
mode: 0644
- name: unbound | Create /dev directory inside unbound chroot
file:
path: /etc/unbound/dev
state: directory
owner: root
group: root
mode: 0755
- name: unbound | Copy needed devices to unbound chroot
command:
cmd: cp -a /dev/random /dev/urandom /dev/null /etc/unbound/dev/
creates: /etc/unbound/dev/random
- name: unbound | Create var directory inside unbound chroot
file:
path: /etc/unbound/var
state: directory
- name: unbound | Generate root key
command:
cmd: /usr/sbin/unbound-anchor -a /etc/unbound/var/root.key
creates: /etc/unbound/var/root.key
- name: unbound | Ensure proper permissions of var directory
file:
path: /etc/unbound/var
state: directory
owner: unbound
group: unbound
mode: 0700
- name: unbound | Add unbound service to runlevel 'default'
service:
name: unbound
runlevel: default
enabled: yes
state: started
- name: unbound | Update resolvconf config
copy:
src: resolvconf.conf
dest: /etc/resolvconf.conf
owner: root
group: root
mode: 0644
- name: unbound | Rewrite network interface settings
copy:
src: interfaces
dest: /etc/network/interfaces
owner: root
group: root
mode: 0644

58
roles/user/tasks/main.yml Normal file
View File

@ -0,0 +1,58 @@
---
- name: user | Create a normal user
user:
name: '{{ username }}'
password: '{{ password | password_hash("sha512") }}'
update_password: on_create
append: yes
groups:
- wheel
- input
- audio
- video
- kvm
- libvirt
- users
create_home: yes
home: '/home/{{ username }}'
shell: /usr/bin/fish
state: present
comment: Kawaii Linux user
- name: user | Double check that group '{{ username }}' exists
group:
name: '{{ username }}'
state: present
- name: user | Set subuid and subgid for podman rootless usage
template:
src: subid.j2
dest: '/etc/{{ item }}'
owner: root
group: root
mode: 0644
loop:
- subgid
- subuid
- name: user | Ensure correct permission for /etc/doas.d/
file:
path: /etc/doas.d
state: directory
owner: root
group: root
mode: 0750
- name: user | Add wheel config to doas.conf
blockinfile:
path: /etc/doas.d/doas.conf
block: |
permit persist :wheel
permit nopass :wheel cmd halt
permit nopass :wheel cmd reboot
permit nopass :wheel cmd poweroff
marker: '# {mark} CUSTOM SETTINGS FOR WHEEL'
owner: root
group: root
mode: 0600
validate: grep -F ':wheel' %s

View File

@ -0,0 +1 @@
{{ username }}:100000:65536

View File

@ -0,0 +1 @@
options zram num_devices=3

View File

@ -0,0 +1,11 @@
#!/bin/sh
swapoff /dev/zram0
swapoff /dev/zram1
swapoff /dev/zram2
echo 1 > /sys/block/zram0/reset
echo 1 > /sys/block/zram1/reset
echo 1 > /sys/block/zram2/reset
modprobe -r zram

38
roles/zram/tasks/main.yml Normal file
View File

@ -0,0 +1,38 @@
---
- name: zram | Print notice
debug:
msg:
- There is little point creating a zram of greater than twice the size of memory since we expect a 2:1 compression ratio
- Note that zram uses about 0.1% of the size of the disk when not in use so a huge zram is wasteful
- But we will use 3 zram devices at estimated (hopefully) 3:1 compression ratio with zstd
- name: zram | Configure 3 zram nodes
copy:
src: zram.conf
dest: /etc/modprobe.d/zram.conf
owner: root
group: root
mode: 0644
- name: zram | Add zram.start hook for local service
template:
src: zram-start.j2
dest: /etc/local.d/zram.start
owner: root
group: root
mode: 0755
- name: zram | Add zram.stop hook for local service
copy:
src: zram.stop
dest: /etc/local.d/zram.stop
owner: root
group: root
mode: 0755
- name: zram | Add local service to runlevel 'default'
service:
name: local
runlevel: default
enabled: yes
state: started

View File

@ -0,0 +1,29 @@
#!/bin/sh
# ensure zram module is loaded
modprobe zram
# set compression algorithm
echo zstd > /sys/block/zram0/comp_algorithm
echo zstd > /sys/block/zram1/comp_algorithm
echo zstd > /sys/block/zram2/comp_algorithm
# set disksize
echo {{ ansible_memtotal_mb }}M > /sys/block/zram0/disksize
echo {{ ansible_memtotal_mb }}M > /sys/block/zram1/disksize
echo {{ ansible_memtotal_mb }}M > /sys/block/zram2/disksize
# set memory limit
echo {{ ansible_memtotal_mb }}M > /sys/block/zram0/mem_limit
echo {{ ansible_memtotal_mb }}M > /sys/block/zram1/mem_limit
echo {{ ansible_memtotal_mb }}M > /sys/block/zram2/mem_limit
# activate swaps
mkswap --label zram0 /dev/zram0
mkswap --label zram1 /dev/zram1
mkswap --label zram2 /dev/zram2
# swapon
swapon /dev/zram0 -p 10
swapon /dev/zram1 -p 10
swapon /dev/zram2 -p 10

40
setup.yml Normal file
View File

@ -0,0 +1,40 @@
---
- name: Gather information
hosts: all
gather_facts: yes
tags: always
- name: Check whether the current user is 'root'
fail:
msg: This playbook should only be run as 'root'
when: ansible_real_user_id != 0
- name: Setup the system
hosts: all
roles:
- role: essential
tags: essential
- role: sysctl
tags: sysctl
- role: nftables
tags: nftables
- role: apparmor
tags: apparmor
- role: consolefont
tags: consolefont
- role: cron
tags: cron
- role: grub
tags: grub
- role: iwd
tags: [ laptop, iwd ]
- role: libvirt
tags: libvirt
- role: tlp
tags: [ laptop, tlp ]
- role: unbound
tags: unbound
- role: zram
tags: zram
- role: user
tags: user