docs(all): fix markdown syntax and snippets

This commit is contained in:
2026-05-09 20:54:32 +09:00
parent 81244d55a7
commit 64aad4fcf0
43 changed files with 229 additions and 209 deletions
+7 -7
View File
@@ -14,22 +14,22 @@
## Context
- Maintaining multi nodes requires a huge amount of resources, including hardware, electricity, even administrative efforts
- All units which responsible for a single role should follow the Principle of Least Privilege \(PoLP\).
- All units which responsible for a single role should follow the Principle of Least Privilege (PoLP).
- All units should be interchangeable on standard to avoid vendor lock-in.
## Consideration
### Hypervisor
- Proxmox Virutal Environment \(PVE\)
- Proxmox Virutal Environment (PVE)
- Based on Debian.
- PVE uses `qm` command which is not a standard to implement the virtual environment.
- VMware ESXi
- Based on UNIX, deveoped by VMware \(Licence is not free\)
- Based on UNIX, deveoped by VMware (Licence is not free)
- Hyper-V
- Based on Microsoft Windows \(Licence is not free\)
- Based on Microsoft Windows (Licence is not free)
- Debian Stable
- Based on standard linux \(conservative\)
- Based on standard linux (conservative)
- Standard virtualization technology 'Libvirt, QEMU, KVM'
### Container
@@ -37,7 +37,7 @@
- Docker
- Daemon is used to run containers
- Root authority required
- Socket and network problem is complex \(Docker bridge\)
- Socket and network problem is complex (Docker bridge)
- docker-compose is an orchestration tool
- Rootless Podman
- Daemonless design
@@ -58,7 +58,7 @@
## Decisions
- Use Libvirt/KVM/QEMU on pure linux \(Debian stable\).
- Use Libvirt/KVM/QEMU on pure linux (Debian stable).
- Separate all services by VM, and podman rootless containers without K3S.
- Orchestration stack is not needed in single node system
- Services will be defined by Quadelt to integrate into systemd and to manage them declaratively
+5 -5
View File
@@ -23,15 +23,15 @@
- OPNSense/pfSense
- vendor lock-in
- GUI environment \(WebGUI\) can contain vulnerability
- GUI environment (WebGUI) can contain vulnerability
- It is hard to manage configurations by IaC
- iptables
- Previous standard of Linux
- IPv4 and IPv6 configuration is separated \(no inet\)
- IPv4 and IPv6 configuration is separated (no inet)
- nftables
- New standard of Linux
- English grammar friendly
- IPv4 and IPv6 configuration can be set on the same table \(inet\)
- IPv4 and IPv6 configuration can be set on the same table (inet)
### Flat network structure
- LAN only
@@ -48,8 +48,8 @@
- VLAN 20: user (DHCP allocated devices)
- wg0: VPN connections
- Manage the rules based on roles fundamentally, furthermore manage them based on ip and ports when it is needed
- All L3 communication which needs to pass gateway should be on control of firewall \(fw\)
- All nodes including firewall uses nftables \(modern standard\) to manage the packets based on zone concept
- All L3 communication which needs to pass gateway should be on control of firewall (fw)
- All nodes including firewall uses nftables (modern standard) to manage the packets based on zone concept
- IPv6 has two track strategy
- Client and server, wg nodes has static ULA IP, and use NAT66 for permanency
- User nodes has GUA SLAAC IP from ISP for compatibility
+7 -7
View File
@@ -24,7 +24,7 @@
### Automate protocol
- JWK/JWT provisioner
- It is hard to manage pre-shared secret values than ACME \(Especially nsupdate\)
- It is hard to manage pre-shared secret values than ACME (Especially nsupdate)
- authorized_keys
- When the nodes are increased, it is hard to manage authorized_key.
- SSH ca.pub allow all the certificates signed by ca key, so it is not needed to manage authroized_keys from each hosts.
@@ -39,19 +39,19 @@
## Decisions
- Operate private CA
- Root CA \(Store on coldstorage\) - 10 years
- Intermediate CA \(Online server as Step-CA\) - 5 years
- Root CA (Store on coldstorage) - 10 years
- Intermediate CA (Online server as Step-CA) - 5 years
- SSH CA - No period
- Manage certificates with two track
- ACME with nsupdate \(using private DNS\) for web services via Caddy - 90 days
- ACME with nsupdate (using private DNS) for web services via Caddy - 90 days
- Manual issuing and managing leaf certificate for infra services for independency - 2.5 years
- All manual issuing leaf certificate expiry date is observed by x509-exporter on infra vm
- Manage SSH certificates
- *-cert.pub for host \(with -h options\)
- *-cert.pub for client \(without -h options\)
- *-cert.pub for host (with -h options)
- *-cert.pub for client (without -h options)
## Consequences
- Private PKI is operated
- Private SSH CA is operated
- All external/internal communication is encrypted as TLS re-encryption. \(E2EE\)
- All external/internal communication is encrypted as TLS re-encryption. (E2EE)
+4 -4
View File
@@ -12,9 +12,9 @@
## Context
- Private authoritative DNS is required to use private reserved root domain \(.internal\)
- Private authoritative DNS is required to use private reserved root domain (.internal)
- Split horizon DNS needs DNS resolver, because authoritative DNS must not send queries to other DNS.
- Automatical issuing certificates needs private authoritative DNS which supports nsupdate \(RFC 2136\)
- Automatical issuing certificates needs private authoritative DNS which supports nsupdate (RFC 2136)
## Consideration
@@ -22,13 +22,13 @@
- AdGuard Home
- More powerful query routing than blocky
- Web UI dependency
- Extra function which is not useful \(DHCP, etc ..\)
- Extra function which is not useful (DHCP, etc ..)
- Unbound DNS
- Cache and forward zone management is powerful
- more complex than blocky
- cache function is not that needed in this environment
- Internal authoritative DNS only takes charge of internal communication
- All security function is delegated to public DNS like cloudflare \(DNSSEC, etc\)
- All security function is delegated to public DNS like cloudflare (DNSSEC, etc)
## Decisions
+3 -3
View File
@@ -29,8 +29,8 @@
- Regex based log parsing is less structured than CrowdSec's parser/scenario model
- Crowdsec
- Community based rules and sinario \(CAPI\)
- Prevention based on local machines and parsers \(LAPI\)
- Community based rules and sinario (CAPI)
- Prevention based on local machines and parsers (LAPI)
- Bouncers can use nftables to prevent threats
- Parser can detect even L7 attack under TLS
@@ -43,7 +43,7 @@
- Operate Crowdsec as IPS
- CrowdSec uses two API server, CAPI, LAPI.
- CAPI updates malicious IPs based on community decisions
- LAPI decides malicious attack based on log from its parser and scenario \(Suricata, caddy, etc\)
- LAPI decides malicious attack based on log from its parser and scenario (Suricata, caddy, etc)
- When CAPI, and LAPI decides block some IP based on log parsed by parser and scenarios, bouncer block the malicious accesses.
- Crowdsec register blacklist on nftables or iptables.
+3 -3
View File
@@ -20,7 +20,7 @@
- HashiCorp Vault or Infisical
- Very powerful, but introduces significant compute/memory overhead.
- Creates a "Secret Zero" problem for a single-node homelab environment because of dependency \(DB, or etc\).
- Creates a "Secret Zero" problem for a single-node homelab environment because of dependency (DB, or etc).
- It is hard to operate hardware separated key servers.
### Systemd-credential
@@ -37,10 +37,10 @@
## Decisions
- All secret data which has yaml format is encrypted by sops with age-key in `secret.yaml`.
- age-key is encrypted by gpg and ansible vault with master key \(including upper, lower case, number, special letters) above 40 characters.
- age-key is encrypted by gpg and ansible vault with master key (including upper, lower case, number, special letters) above 40 characters.
- All secret data always decrypt by `edit_secret.sh` script or ansible tasks from secrets.yaml using age-key encrypted by ansible-vault.
- decrypted secret data is always processed on ramfs, they are never saved on disk.
- Master key is never saved on disk, but only cold storage \(USB, M-DISC, operators' memory\)
- Master key is never saved on disk, but only cold storage (USB, M-DISC, operators' memory)
- The secret data will be saved on each servers specific directory or podman secret.
- OS:
- path: /etc/secrets
+5 -5
View File
@@ -17,7 +17,7 @@
## Context
- All configuration file is managed by git \(IaC\)
- All configuration file is managed by git (IaC)
- All data file should be backed up by kopia
- All backup should follow 3-2-1 backup cycle
@@ -45,14 +45,14 @@
- All configuration files are managed by Git
- Configuration files are based on text
- It is necessary to version, history management.
- Local git -> private Gitea -> github private project \(mirrored\)
- Local git -> private Gitea -> github private project (mirrored)
- This fulfills 3-2-1 backup rules
- Data files are managed by Kopia and DSM
- Local storage - kopia -> DSM's Kopia repository server - CloudSync -> Cloud server such as OneDrive or Google Drive
- This fulfills 3-2-1 backup rules
- Data files which needs backup
- DB data files: dump
- DB data files are located on infra:/home/infra/containers/postgresql/backups/\{cluster,$service\}/
- DB data files are located on infra:/home/infra/containers/postgresql/backups/{cluster,$service}/
- App data files: Photos, Media, etc ..
- App data files are located on app:/home/app/data/
- Backed up files: kopia
@@ -60,7 +60,7 @@
- Kopia over DSM configuration is managed by runbook with equivalent CLI commands due to vendor limitation
- Restore will be processed manually
- DB data files
- From kopia server to console:$HOMELAB_PATH/data/volume/infra/postgresql/\{cluster,data\}
- From kopia server to console:$HOMELAB_PATH/data/volume/infra/postgresql/{cluster,data}
- APP data files
- From kopia server to APP vm after initiating before deploy services
- Automatic backup does not guarantee integrity of data system, so before reset the system conduct manual backup after making sure all services are shutdown.
@@ -74,4 +74,4 @@
## Consequences
- All files including configuration and data back ups will fulfill 3-2-1 \(3 Copies, 2 different media, 1 offsite\) back up rules
- All files including configuration and data back ups will fulfill 3-2-1 (3 Copies, 2 different media, 1 offsite) back up rules
+1 -1
View File
@@ -11,7 +11,7 @@
## Context
- App VM needs GPU for heavy workloads like Immich \(hardware transcoding and machine learning\)
- App VM needs GPU for heavy workloads like Immich (hardware transcoding and machine learning)
- App VM needs huge data storage for its own services
## Considerations
+2 -2
View File
@@ -18,7 +18,7 @@
### Hypervisor
- As a pure hypervisor, it should only operate virtualization for VM.
- Hypervisor just provides resources and dummy hub \(br\)
- Hypervisor just provides resources and dummy hub (br)
### VM
@@ -30,7 +30,7 @@
### Services
- Services should be distinguished based on their needs \(Privilege\)
- Services should be distinguished based on their needs (Privilege)
- Network stack, backup stack needs special privilege for low level ACL or networks.
- application stack doesn't need low level privilege usually
+1 -1
View File
@@ -27,7 +27,7 @@
- Removing
- Formatting
- Destroying
- Certificates and CA \([ADR-003](./003-pki.md)\)
- Certificates and CA ([ADR-003](./003-pki.md))
- Etc. what operator decides that is sensitive
## Consequences
+2 -2
View File
@@ -19,7 +19,7 @@
### Apply mTLS
- implementing mTLS needs both client certificate and server certificate
- Managing a number of certificates makes a huge operational burden \(expiry date, revocation, etc ..\)
- Managing a number of certificates makes a huge operational burden (expiry date, revocation, etc ..)
## Decisions
@@ -30,4 +30,4 @@
- The policy is set simple
- The overhead is increased little
- Exclude the exceptions on operation \(For the administrator\)
- Exclude the exceptions on operation (For the administrator)