overhauls of most service docs
All checks were successful
Podman DDNS Image / build-and-push-ddns (push) Successful in 33s
All checks were successful
Podman DDNS Image / build-and-push-ddns (push) Successful in 33s
This commit is contained in:
BIN
active/device_framework_16/icc_profile.icm
Normal file
BIN
active/device_framework_16/icc_profile.icm
Normal file
Binary file not shown.
@@ -5,11 +5,16 @@
|
||||
- [Schlage Door Lock](#schlage-door-lock)
|
||||
- [Philips Hue Lights](#philips-hue-lights)
|
||||
- [Shelly](#shelly)
|
||||
- [Relative Humidity Calculator](#relative-humidity-calculator)
|
||||
- [Barometer](#barometer)
|
||||
- [Relative Humidity Calculator](#relative-humidity-calculator)
|
||||
- [Font Colors](#font-colors)
|
||||
- [Light Indicator for Voice Assistant](#light-indicator-for-voice-assistant)
|
||||
- [Blank Button (Spacer)](#blank-button-spacer)
|
||||
- [Roku Remote](#roku-remote)
|
||||
- [Flair Vent Battery](#flair-vent-battery)
|
||||
- [Voice](#voice)
|
||||
- [Custom Sentences](#custom-sentences)
|
||||
- [Notifications](#notifications)
|
||||
|
||||
## Setup and Configuration
|
||||
|
||||
@@ -48,7 +53,51 @@ is quicker to pick up and transmit device information. Note that "gateway mode"
|
||||
just enable bluetooth and rpc or select "active" from the configuration menu for the shelly
|
||||
device.
|
||||
|
||||
### Relative Humidity Calculator
|
||||
#### Barometer
|
||||
|
||||
<https://www.thoughtco.com/how-to-read-a-barometer-3444043>
|
||||
|
||||
A barometric reading over 30.20 inHg is generally considered high, and high pressure is associated with clear skies and calm weather.
|
||||
|
||||
If the reading is over 30.20 inHg (102268.9 Pa or 1022.689 mb):
|
||||
|
||||
- Rising or steady pressure means continued fair weather.
|
||||
- Slowly falling pressure means fair weather.
|
||||
- Rapidly falling pressure means cloudy and warmer conditions.
|
||||
|
||||
A barometric reading in the range of 29.80 and 30.20 inHg can be considered normal, and normal pressure is associated with steady weather.
|
||||
|
||||
If the reading falls between 29.80 and 30.20 inHg (100914.4–102268.9 Pa or 1022.689–1009.144 mb):
|
||||
|
||||
- Rising or steady pressure means present conditions will continue.
|
||||
- Slowly falling pressure means little change in the weather.
|
||||
- Rapidly falling pressure means that rain is likely, or snow if it is cold enough.
|
||||
|
||||
A barometric reading below 29.80 inHg is generally considered low, and low pressure is associated with warm air and rainstorms.
|
||||
|
||||
If the reading is under 29.80 inHg (100914.4 Pa or 1009.144 mb):
|
||||
|
||||
- Rising or steady pressure indicates clearing and cooler weather.
|
||||
- Slowly falling pressure indicates rain.
|
||||
- Rapidly falling pressure indicates a storm is coming.
|
||||
|
||||
A basic automation would look like
|
||||
|
||||
```yaml
|
||||
It's {{ int(states("sensor.grouse_temp")) }} degrees and {{ states("weather.grouse_weather") }}. The relative humidity is {{ states("sensor.grouse_humidity") }}%. I'm seeing {{ int(states("sensor.grouse_wind_speed")) }}mph wind with gusts up to {{ int(states("sensor.grouse_wind_gust")) }}mph.
|
||||
|
||||
{% set pressure = float(states("sensor.grouse_rel_pressure")) %}
|
||||
The barometer reads {{ pressure }}inHg.
|
||||
{% if pressure > 30.20 %}
|
||||
Fair weather is expected
|
||||
{% elif pressure > 29.80 %}
|
||||
Rain is possible
|
||||
{% else %}
|
||||
Rain is coming.
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
#### Relative Humidity Calculator
|
||||
|
||||
<https://www.wikihow.com/Calculate-Humidity>
|
||||
|
||||
@@ -335,4 +384,32 @@ cards:
|
||||
hold_action:
|
||||
action: none
|
||||
title: Left Living Room TV
|
||||
```
|
||||
```
|
||||
|
||||
### Flair Vent Battery
|
||||
|
||||
Flair vents report low battery at 2.4v. 3v is nominal/full.
|
||||
|
||||
```yaml
|
||||
{% set volt_min=2.4 %}
|
||||
{% set volt_max=3.0 %}
|
||||
{% set volt_diff_max=0.6 %}
|
||||
|
||||
{{ (min(float(states("sensor.main_bedroom_29bf_voltage")) - volt_min, volt_diff_max) / volt_diff_max) * 100 }}
|
||||
```
|
||||
|
||||
## Voice
|
||||
|
||||
### Custom Sentences
|
||||
|
||||
<https://developers.home-assistant.io/docs/voice/intent-recognition/template-sentence-syntax/#sentence-templates-syntax>
|
||||
|
||||
## Notifications
|
||||
|
||||
Notification Information:
|
||||
|
||||
<https://www.home-assistant.io/docs/automation/templating/>
|
||||
|
||||
```yaml
|
||||
Triggered by {{ trigger.entity_id }}, Date: {{ now().strftime('%Y-%m-%d') }}, Time: {{ now().strftime('%H:%M') }}
|
||||
```
|
||||
|
||||
21
active/notes_freedesktop/freedesktop.md
Normal file
21
active/notes_freedesktop/freedesktop.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Freedesktop Notes
|
||||
|
||||
Notes pertaining to the `.desktop` extension and desktop entries.
|
||||
|
||||
## Keys
|
||||
|
||||
<https://specifications.freedesktop.org/desktop-entry-spec/1.5/recognized-keys.html>
|
||||
|
||||
## Icons
|
||||
|
||||
<https://freedesktop.org/wiki/Specifications/icon-theme-spec/>
|
||||
|
||||
By default, apps should look in $HOME/.icons (for backwards compatibility), in $XDG_DATA_DIRS/icons and in /usr/share/pixmaps (in that order).
|
||||
|
||||
## Testing
|
||||
|
||||
Run a `.desktop` file from terminal with this:
|
||||
|
||||
```bash
|
||||
gtk-launch gnome-system-monitor.desktop
|
||||
```
|
||||
@@ -210,35 +210,7 @@ Now the status should be correct even after connecting/disconnecting when the co
|
||||
|
||||
## SSH
|
||||
|
||||
Generate a key with password protection:
|
||||
|
||||
```bash
|
||||
# Omit "-N 'password'" to have it prompt you
|
||||
ssh-keygen -f ~/.ssh/test-key -N 'PASSWORD'
|
||||
```
|
||||
|
||||
Change the password for an ssh key:
|
||||
|
||||
```bash
|
||||
# Use "-N ''" to remove the password
|
||||
ssh-keygen -p -N 'PASSWORD' -f ~/.ssh/test-key
|
||||
```
|
||||
|
||||
This is an example config entry in `~/.ssh/config`:
|
||||
|
||||
```conf
|
||||
Host my-host
|
||||
Hostname my-host.reeselink.com
|
||||
User root
|
||||
ProxyCommand none
|
||||
ForwardAgent no
|
||||
ForwardX11 no
|
||||
Port 22
|
||||
KeepAlive yes
|
||||
IdentityFile ~/.ssh/id_my-host_rsa
|
||||
```
|
||||
|
||||
You can ssh to that host with `ssh my-host` after adding a config entry.
|
||||
See [README](/README.md#ssh-setup)
|
||||
|
||||
## Templates
|
||||
|
||||
@@ -652,7 +624,6 @@ Custom profiles are located at
|
||||
|
||||
Sync this with something like Nextcloud.
|
||||
|
||||
|
||||
## Orca Slicer
|
||||
|
||||
<https://github.com/SoftFever/OrcaSlicer>
|
||||
|
||||
@@ -14,55 +14,7 @@ and the operator will store information about each server.
|
||||
|
||||
## Setup SSH
|
||||
|
||||
On the operator:
|
||||
|
||||
```bash
|
||||
export SSH_HOST=kube
|
||||
ssh-keygen -t rsa -b 4096 -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${SSH_HOST}_rsa
|
||||
|
||||
# Note: If you get "too many authentication failures" it's likely because you have too many private
|
||||
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.
|
||||
ssh-copy-id -o PubkeyAuthentication=no -i ~/.ssh/id_${SSH_HOST}_rsa.pub ducoterra@${SSH_HOST}.reeselink.com
|
||||
ssh -i ~/.ssh/id_${SSH_HOST}_rsa -o 'PubkeyAuthentication=yes' ducoterra@${SSH_HOST}.reeselink.com
|
||||
```
|
||||
|
||||
On the server:
|
||||
|
||||
```bash
|
||||
# Copy authorized_keys to root
|
||||
sudo cp ~/.ssh/authorized_keys /root/.ssh/authorized_keys
|
||||
|
||||
# Change your password
|
||||
passwd
|
||||
|
||||
sudo su -
|
||||
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/01-prohibit-password.conf
|
||||
echo '%sudo ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/01-nopasswd-sudo
|
||||
systemctl restart ssh
|
||||
```
|
||||
|
||||
On the operator:
|
||||
|
||||
```bash
|
||||
cat <<EOF >> ~/.ssh/config
|
||||
|
||||
Host $SSH_HOST
|
||||
Hostname ${SSH_HOST}.reeselink.com
|
||||
User root
|
||||
ProxyCommand none
|
||||
ForwardAgent no
|
||||
ForwardX11 no
|
||||
Port 22
|
||||
KeepAlive yes
|
||||
IdentityFile ~/.ssh/id_${SSH_HOST}_rsa
|
||||
EOF
|
||||
|
||||
# Test if you can SSH with a password
|
||||
ssh -o PubkeyAuthentication=no ducoterra@${SSH_HOST}.reeselink.com
|
||||
|
||||
# Test that you can log into the server with ssh config
|
||||
ssh $SSH_HOST
|
||||
```
|
||||
See [README](/README.md#ssh-setup)
|
||||
|
||||
## Fail2Ban
|
||||
|
||||
|
||||
@@ -285,4 +285,4 @@ output.eDP-2.enable \
|
||||
output.eDP-2.mode.1920x1080@60 \
|
||||
output.eDP-2.scale.1 \
|
||||
output.eDP-2.position.0,0
|
||||
```
|
||||
```
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
- [Fail2Ban](#fail2ban)
|
||||
- [BTRFS Parent Volumes](#btrfs-parent-volumes)
|
||||
- [BTRFS Snapshots](#btrfs-snapshots)
|
||||
- [BTRFS Maintenance](#btrfs-maintenance)
|
||||
- [TPM2 Luks Decryption](#tpm2-luks-decryption)
|
||||
- [Change your password](#change-your-password)
|
||||
- [Automatic Updates](#automatic-updates)
|
||||
@@ -73,48 +74,7 @@ and the operator will store information about each server.
|
||||
|
||||
## Setup SSH
|
||||
|
||||
In this setup we'll allow ssh to the root user via key and keep the admin user for cockpit.
|
||||
|
||||
On the operator:
|
||||
|
||||
```bash
|
||||
export SSH_HOST=kube
|
||||
ssh-keygen -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${SSH_HOST}_rsa
|
||||
|
||||
# Note: If you get "too many authentication failures" it's likely because you have too many private
|
||||
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.
|
||||
ssh-copy-id -o PubkeyAuthentication=no -i ~/.ssh/id_${SSH_HOST}_rsa.pub ducoterra@${SSH_HOST}.reeselink.com
|
||||
ssh -i ~/.ssh/id_${SSH_HOST}_rsa ducoterra@${SSH_HOST}.reeselink.com
|
||||
# Copy authorized_keys to root
|
||||
sudo cp ~/.ssh/authorized_keys /root/.ssh/authorized_keys
|
||||
exit
|
||||
|
||||
cat <<EOF >> ~/.ssh/config
|
||||
|
||||
Host ${SSH_HOST}
|
||||
Hostname ${SSH_HOST}.reeselink.com
|
||||
User root
|
||||
Port 22
|
||||
KeepAlive yes
|
||||
IdentityFile ~/.ssh/id_${SSH_HOST}_rsa
|
||||
EOF
|
||||
|
||||
ssh ${SSH_HOST}
|
||||
# Disable password auth
|
||||
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/01-prohibit-password.conf
|
||||
systemctl restart sshd
|
||||
|
||||
# OPTIONAL: Disable sudo password
|
||||
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/01-nopasswd-wheel
|
||||
|
||||
exit
|
||||
|
||||
# Test if you can SSH with a password
|
||||
ssh -o PubkeyAuthentication=no ducoterra@${SSH_HOST}.reeselink.com
|
||||
|
||||
# Test that you can log into the server with ssh config
|
||||
ssh $SSH_HOST
|
||||
```
|
||||
See [README](/README.md#ssh-setup)
|
||||
|
||||
## DNF
|
||||
|
||||
@@ -224,6 +184,13 @@ snapper -c root delete 1
|
||||
Note - you probably don't want to keep yearly snapshots.
|
||||
Edit `/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
||||
|
||||
## BTRFS Maintenance
|
||||
|
||||
```bash
|
||||
# Start a scrub in the foreground (-B) at /
|
||||
btrfs scrub start -B /
|
||||
```
|
||||
|
||||
## TPM2 Luks Decryption
|
||||
|
||||
Mostly taken from here:
|
||||
@@ -324,7 +291,7 @@ TODO
|
||||
|
||||
## Common Storage Mounts
|
||||
|
||||
Note: mount these before you install the relavant package!
|
||||
Note: mount these before you install the relevant package!
|
||||
|
||||
1. For virtual machines: `/var/lib/libvirt`
|
||||
2. For podman: `/var/lib/containers`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Apps
|
||||
|
||||
- [Apps](#apps)
|
||||
- [Common CLI Apps](#common-cli-apps)
|
||||
- [Gear Lever](#gear-lever)
|
||||
- [VSCode](#vscode)
|
||||
- [DNF](#dnf)
|
||||
@@ -47,6 +48,11 @@
|
||||
- [KDiskMark](#kdiskmark)
|
||||
- [Local Send](#local-send)
|
||||
- [Evolution](#evolution)
|
||||
- [Virtualization](#virtualization)
|
||||
- [NVM](#nvm)
|
||||
- [Ollama](#ollama)
|
||||
- [UV](#uv)
|
||||
- [Pipenv](#pipenv)
|
||||
|
||||
Flatpak installs are from Flathub unless otherwise noted.
|
||||
|
||||
@@ -58,6 +64,66 @@ flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.f
|
||||
|
||||
When prompted, prefer flathub.
|
||||
|
||||
## Common CLI Apps
|
||||
|
||||
Some common apps you'll probably want available.
|
||||
|
||||
```bash
|
||||
sudo dnf install \
|
||||
# Advanced text editor for code editing and other tasks.
|
||||
vim \
|
||||
# Network bandwidth measuring tool.
|
||||
iperf3 \
|
||||
# Command-line interface for managing Kubernetes clusters.
|
||||
kubectl \
|
||||
# Package manager and deployment tool for Kubernetes.
|
||||
helm \
|
||||
# Utility to monitor real-time network usage of processes.
|
||||
nethogs \
|
||||
# DevOps configuration management tool.
|
||||
ansible \
|
||||
# Terminal multiplexer.
|
||||
tmux \
|
||||
# Multimedia player with support for a wide range of codecs and file formats.
|
||||
ffmpeg \
|
||||
# Microsoft Windows compatibility layer.
|
||||
wine \
|
||||
# Archive utility similar to GNU tar, used to package files into single archive files.
|
||||
unzip \
|
||||
# A terminal activity monitor (top clone).
|
||||
btop \
|
||||
# Command-line JSON processor.
|
||||
jq \
|
||||
# YAML-based configuration-as-code tool for command-line interfaces written in Go, Rust, Python, and more.
|
||||
yq \
|
||||
# An image manipulation software suite based on ImageMagick.
|
||||
ImageMagick \
|
||||
# The Go programming language environment including a toolchain (gc) and libraries.
|
||||
go \
|
||||
# Rust package manager and compiler installation utility.
|
||||
rust rustup \
|
||||
# Distributed version control system, Git extension that adds support for large files like multimedia assets.
|
||||
git git-lfs \
|
||||
# Provides traditional network tools such as ifconfig, netstat, hostname, etc., in a single package.
|
||||
net-tools \
|
||||
# Document conversion tool and markup language converter.
|
||||
pandoc \
|
||||
# Comprehensive LaTeX distribution for high-quality typesetting of documents.
|
||||
texlive-latex \
|
||||
# Generate strong passwords.
|
||||
pwgen \
|
||||
# Reattach to running processes
|
||||
reptyr \
|
||||
# Netcat, for basic tcp/udp operations
|
||||
netcat \
|
||||
# 7zip support
|
||||
p7zip \
|
||||
# Make
|
||||
make \
|
||||
# GCC for compile
|
||||
gcc
|
||||
```
|
||||
|
||||
## Gear Lever
|
||||
|
||||
I would recommend you install Gear Lever to manage App Images:
|
||||
@@ -296,6 +362,12 @@ At the very top of the config you can add a pin for a printer permanently with:
|
||||
}
|
||||
```
|
||||
|
||||
You'll need to open port 2021 udp
|
||||
|
||||
```bash
|
||||
firewall-cmd --add-port=2021/udp --permanent
|
||||
```
|
||||
|
||||
## Freecad
|
||||
|
||||
Benchy benchy benchy oh no, I can't do that, this is hard.
|
||||
@@ -402,10 +474,11 @@ flatpak install io.github.thetumultuousunicornofdarkness.cpu-x
|
||||
|
||||
## Ungoogled Chromium
|
||||
|
||||
Chrom
|
||||
<https://github.com/ungoogled-software/ungoogled-chromium?tab=readme-ov-file#automated-or-maintained-builds>
|
||||
|
||||
```bash
|
||||
flatpak install io.github.ungoogled_software.ungoogled_chromium
|
||||
sudo dnf copr enable wojnilowicz/ungoogled-chromium
|
||||
sudo dnf install ungoogled-chromium
|
||||
```
|
||||
|
||||
## Signal
|
||||
@@ -507,4 +580,36 @@ You still use email? I still use email.
|
||||
|
||||
```bash
|
||||
flatpak install org.gnome.Evolution
|
||||
```
|
||||
```
|
||||
|
||||
## Virtualization
|
||||
|
||||
```bash
|
||||
# Virtualization
|
||||
sudo dnf group install --with-optional virtualization
|
||||
```
|
||||
|
||||
## NVM
|
||||
|
||||
<https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating>
|
||||
|
||||
## Ollama
|
||||
|
||||
<https://ollama.com/download>
|
||||
|
||||
Run the installation script as normal. Make sure you have the [ROCM](#rocm)
|
||||
drivers installed for GPU acceleration. The script *should* automatically pull
|
||||
the ROCM drivers after installing the base packages. If not, you should install
|
||||
them manually.
|
||||
|
||||
For starting ollama as a service, follow the link below:
|
||||
|
||||
<https://github.com/ollama/ollama/blob/main/docs/linux.md#adding-ollama-as-a-startup-service-recommended>
|
||||
|
||||
## UV
|
||||
|
||||
<https://docs.astral.sh/uv/getting-started/installation/>
|
||||
|
||||
## Pipenv
|
||||
|
||||
<https://pipenv.pypa.io/en/latest/installation.html#installing-pipenv>
|
||||
@@ -4,37 +4,28 @@
|
||||
- [Framework 16 Fixes](#framework-16-fixes)
|
||||
- [Wake from Sleep](#wake-from-sleep)
|
||||
- [Wrong keys pressed in the browser](#wrong-keys-pressed-in-the-browser)
|
||||
- [Fix wifi disconnecting and reconnecting repeatedly on reboot/resume](#fix-wifi-disconnecting-and-reconnecting-repeatedly-on-rebootresume)
|
||||
- [Wifi Powersave](#wifi-powersave)
|
||||
- [Podman](#podman)
|
||||
- [Autostarting services with quadlets](#autostarting-services-with-quadlets)
|
||||
- [Toolbox](#toolbox)
|
||||
- [Network](#network)
|
||||
- [Firewall](#firewall)
|
||||
- [VLAN Setup with nmcli](#vlan-setup-with-nmcli)
|
||||
- [ZRAM](#zram)
|
||||
- [Libraries](#libraries)
|
||||
- [Common Libraries](#common-libraries)
|
||||
- [Apps](#apps)
|
||||
- [Common CLI Apps](#common-cli-apps)
|
||||
- [Ungoogled Chromium](#ungoogled-chromium)
|
||||
- [VSCode](#vscode)
|
||||
- [Virtualization](#virtualization)
|
||||
- [NVM](#nvm)
|
||||
- [Ollama](#ollama)
|
||||
- [UV](#uv)
|
||||
- [Pipenv](#pipenv)
|
||||
- [Backups](#backups)
|
||||
- [BTRFS Snapshots](#btrfs-snapshots)
|
||||
- [ROCM](#rocm)
|
||||
- [Display](#display)
|
||||
- [Scripted Display Modes](#scripted-display-modes)
|
||||
- [Fixing generic Wayland icons on task alt tab](#fixing-generic-wayland-icons-on-task-alt-tab)
|
||||
|
||||
## Framework 16 Fixes
|
||||
|
||||
### Wake from Sleep
|
||||
|
||||
The keyboard/mouse can be pressed through the lid while in a backpack. Disable them to
|
||||
prevent wake from sleep.
|
||||
The keyboard/mouse can be pressed through the lid while in a backpack. Disable
|
||||
them to prevent wake from sleep.
|
||||
|
||||
`/etc/udev/rules.d/69-suspend.rules`
|
||||
|
||||
@@ -55,61 +46,15 @@ sudo udevadm control --reload-rules && sudo udevadm trigger
|
||||
|
||||
### Wrong keys pressed in the browser
|
||||
|
||||
Sometimes keys will stop working when using search bars or do strange things like move the page around. This seems to be caused by some "alt" keypress combination. Pressing "alt" twice fixes it.
|
||||
|
||||
### Fix wifi disconnecting and reconnecting repeatedly on reboot/resume
|
||||
|
||||
Create a file in `/etc/systemd/system/reset-iwlwifi.service` with the following content:
|
||||
|
||||
```conf
|
||||
[Unit]
|
||||
Description=Reload iwlwifi on wake-up
|
||||
After=suspend.target
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecStartPre=rmmod iwlmvm iwlwifi
|
||||
ExecStart=modprobe iwlwifi
|
||||
|
||||
[Install]
|
||||
WantedBy=suspend.target
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
systemctl enable reset-iwlwifi.service
|
||||
```
|
||||
|
||||
### Wifi Powersave
|
||||
|
||||
**NOTE: THIS DOESN'T WORK. IT CAUSES WIFI DISCONNECT AND RECONNECT ISSUES.**
|
||||
|
||||
<https://www.networkmanager.dev/docs/api/latest/settings-802-11-wireless.html>
|
||||
|
||||
<https://gist.github.com/jcberthon/ea8cfe278998968ba7c5a95344bc8b55>
|
||||
|
||||
<https://askubuntu.com/questions/1230525/ubuntu-20-04-network-performance-extremely-slow>
|
||||
|
||||
```bash
|
||||
vim /etc/NetworkManager/conf.d/wifi-powersave-off.conf
|
||||
```
|
||||
|
||||
```conf
|
||||
[connection]
|
||||
# Values are 0 (use default), 1 (ignore/don't touch), 2 (disable) or 3 (enable).
|
||||
wifi.powersave = 2
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl restart NetworkManager
|
||||
```
|
||||
Sometimes keys will stop working when using search bars or do strange things
|
||||
like move the page around. This seems to be caused by some "alt" keypress
|
||||
combination. Pressing "alt" twice fixes it.
|
||||
|
||||
## Podman
|
||||
|
||||
Since you'll be using podman for most container-based services, you'll want to set the
|
||||
the podman auth file to somewhere persistent, otherwise it'll get deleted every time you
|
||||
reboot.
|
||||
Since you'll be using podman for most container-based services, you'll want to
|
||||
set the the podman auth file to somewhere persistent, otherwise it'll get
|
||||
deleted every time you reboot.
|
||||
|
||||
Add this to your `.bashrc`:
|
||||
|
||||
@@ -122,8 +67,8 @@ Source that and then run `podman login` to create the file.
|
||||
|
||||
### Autostarting services with quadlets
|
||||
|
||||
If you want to run something as your user at boot (like a systemd process, think ollama) you can
|
||||
create a user quadlets like so:
|
||||
If you want to run something as your user at boot (like a systemd process,
|
||||
think ollama) you can create a user quadlets like so:
|
||||
|
||||
```bash
|
||||
# Generate the .container file
|
||||
@@ -153,6 +98,65 @@ toolbox enter
|
||||
|
||||
## Network
|
||||
|
||||
### Firewall
|
||||
|
||||
Set the default firewall to `drop`
|
||||
|
||||
```bash
|
||||
firewall-cmd --set-default-zone=drop
|
||||
firewall-cmd --reload
|
||||
```
|
||||
|
||||
Allow KDE Connect via 1714-1764 tcp/udp
|
||||
|
||||
```bash
|
||||
firewall-cmd --add-port=1714-1764/udp --add-port=1714-1764/tcp --permanent
|
||||
```
|
||||
|
||||
You can check if the firewall is working via `nmap` from another machine
|
||||
|
||||
Note, add `-r` to scan ports in order.
|
||||
|
||||
Note, add `-vv` to increase verbosity.
|
||||
|
||||
Note, add `-A` to perform OS detection, host lookup, etc.
|
||||
|
||||
Note, use `-F` to perform a quick scan against common ports.
|
||||
|
||||
```bash
|
||||
export NMAP_HOST=10.2.0.49
|
||||
|
||||
# Scan for common ports on TCP
|
||||
nmap -sT $NMAP_HOST
|
||||
|
||||
# Scan all ports on TCP
|
||||
nmap -sT -p- $NMAP_HOST
|
||||
|
||||
# Scan specific port on TCP
|
||||
nmap -sT -p5432 $NMAP_HOST
|
||||
|
||||
# Scan range of ports on TCP
|
||||
nmap -sT -p1024-9999 $NMAP_HOST
|
||||
|
||||
# Scan for common ports on UDP
|
||||
nmap -sU $NMAP_HOST
|
||||
|
||||
# Skip host up checking
|
||||
nmap -Pn -sT $NMAP_HOST
|
||||
|
||||
# Scan all ports for everything (takes a really really long time)
|
||||
nmap -Pn -sT -sU -p- $NMAP_HOST
|
||||
|
||||
# Scan using TCP ACK Ping (More serious check that attempts to bypass firewall, See nmap man page)
|
||||
nmap -PA -p- $NMAP_HOST
|
||||
```
|
||||
|
||||
Then, while running a scan:
|
||||
|
||||
v / V: Increase / decrease the verbosity level d / D: Increase / decrease the
|
||||
debugging Level p / P: Turn on / off packet tracing ?: Print a runtime
|
||||
interaction help screen
|
||||
|
||||
### VLAN Setup with nmcli
|
||||
|
||||
```bash
|
||||
@@ -199,106 +203,6 @@ xz-devel \
|
||||
libgle-devel
|
||||
```
|
||||
|
||||
## Apps
|
||||
|
||||
### Common CLI Apps
|
||||
|
||||
```bash
|
||||
sudo dnf install \
|
||||
# Advanced text editor for code editing and other tasks.
|
||||
vim \
|
||||
# Network bandwidth measuring tool.
|
||||
iperf3 \
|
||||
# Command-line interface for managing Kubernetes clusters.
|
||||
kubectl \
|
||||
# Package manager and deployment tool for Kubernetes.
|
||||
helm \
|
||||
# Utility to monitor real-time network usage of processes.
|
||||
nethogs \
|
||||
# DevOps configuration management tool.
|
||||
ansible \
|
||||
# Terminal multiplexer.
|
||||
tmux \
|
||||
# Multimedia player with support for a wide range of codecs and file formats.
|
||||
ffmpeg \
|
||||
# Microsoft Windows compatibility layer.
|
||||
wine \
|
||||
# Archive utility similar to GNU tar, used to package files into single archive files.
|
||||
unzip \
|
||||
# A terminal activity monitor (top clone).
|
||||
btop \
|
||||
# Command-line JSON processor.
|
||||
jq \
|
||||
# YAML-based configuration-as-code tool for command-line interfaces written in Go, Rust, Python, and more.
|
||||
yq \
|
||||
# An image manipulation software suite based on ImageMagick.
|
||||
ImageMagick \
|
||||
# The Go programming language environment including a toolchain (gc) and libraries.
|
||||
go \
|
||||
# Rust package manager and compiler installation utility.
|
||||
rust rustup \
|
||||
# Distributed version control system, Git extension that adds support for large files like multimedia assets.
|
||||
git git-lfs \
|
||||
# Provides traditional network tools such as ifconfig, netstat, hostname, etc., in a single package.
|
||||
net-tools \
|
||||
# Document conversion tool and markup language converter.
|
||||
pandoc \
|
||||
# Comprehensive LaTeX distribution for high-quality typesetting of documents.
|
||||
texlive-latex \
|
||||
# Generate strong passwords.
|
||||
pwgen \
|
||||
# Reattach to running processes
|
||||
reptyr \
|
||||
# Netcat, for basic tcp/udp operations
|
||||
netcat \
|
||||
# 7zip support
|
||||
p7zip
|
||||
```
|
||||
|
||||
### Ungoogled Chromium
|
||||
|
||||
<https://github.com/ungoogled-software/ungoogled-chromium?tab=readme-ov-file#automated-or-maintained-builds>
|
||||
|
||||
```bash
|
||||
sudo dnf copr enable wojnilowicz/ungoogled-chromium
|
||||
sudo dnf install ungoogled-chromium
|
||||
```
|
||||
|
||||
### VSCode
|
||||
|
||||
<https://code.visualstudio.com/docs/setup/linux#_rhel-fedora-and-centos-based-distributions>
|
||||
|
||||
### Virtualization
|
||||
|
||||
```bash
|
||||
# Virtualization
|
||||
sudo dnf group install --with-optional virtualization
|
||||
```
|
||||
|
||||
### NVM
|
||||
|
||||
<https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating>
|
||||
|
||||
### Ollama
|
||||
|
||||
<https://ollama.com/download>
|
||||
|
||||
Run the installation script as normal. Make sure you have the [ROCM](#rocm) drivers installed
|
||||
for GPU acceleration. The script *should* automatically pull the ROCM drivers after installing
|
||||
the base packages. If not, you should install them manually.
|
||||
|
||||
For starting ollama as a service, follow the link below:
|
||||
|
||||
<https://github.com/ollama/ollama/blob/main/docs/linux.md#adding-ollama-as-a-startup-service-recommended>
|
||||
|
||||
### UV
|
||||
|
||||
<https://docs.astral.sh/uv/getting-started/installation/>
|
||||
|
||||
### Pipenv
|
||||
|
||||
<https://pipenv.pypa.io/en/latest/installation.html#installing-pipenv>
|
||||
|
||||
## Backups
|
||||
|
||||
### BTRFS Snapshots
|
||||
@@ -307,7 +211,8 @@ For starting ollama as a service, follow the link below:
|
||||
|
||||
<http://snapper.io/manpages/snapper-configs.html>
|
||||
|
||||
We'll be using snapper, a tool for automating and controlling snapshot behavior.
|
||||
We'll be using snapper, a tool for automating and controlling snapshot
|
||||
behavior.
|
||||
|
||||
```bash
|
||||
dnf install snapper dnf-plugin-snapper
|
||||
@@ -335,8 +240,8 @@ snapper -c root create --description "test snapshot"
|
||||
snapper -c root delete 1
|
||||
```
|
||||
|
||||
Note - you probably don't want to keep yearly snapshots.
|
||||
Edit `/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
||||
Note - you probably don't want to keep yearly snapshots. Edit
|
||||
`/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
||||
|
||||
## ROCM
|
||||
|
||||
@@ -400,4 +305,41 @@ output.eDP-2.position.0,0 \
|
||||
output.eDP-2.primary \
|
||||
output.eDP-2.mode.1920x1080@165 \
|
||||
output.eDP-2.scale.1'
|
||||
```
|
||||
```
|
||||
|
||||
## Fixing generic Wayland icons on task alt tab
|
||||
|
||||
<https://epergo.com/posts/fix-generic-wayland-icon/>
|
||||
|
||||
1. Access Window Rules
|
||||
|
||||
Go to “System Settings > Window Management > Window Rules”.
|
||||
|
||||
2. Create a New Rule (If None Exist)
|
||||
|
||||
If the application does not have any rules already, create a new one:
|
||||
|
||||
1. Click on “Add New…”
|
||||
2. Add a description (e.g., “Application settings for sublime_merge”)
|
||||
3. Specify the “Window class (application)”
|
||||
|
||||
If you’re unsure of the value for the window class, click “Detect Window
|
||||
Properties”, then click on the application window. A pop-up with the
|
||||
detected properties will be shown, and you can select the correct value.
|
||||
|
||||
3. Add Property
|
||||
|
||||
1. Click on “Add Property” and select “Desktop File Name”.
|
||||
|
||||
4. Find the Correct Desktop File Name
|
||||
|
||||
Standard Applications: If the application is installed using your distro’s
|
||||
repositories, check the name in /usr/share/applications/. Flatpak
|
||||
Applications: If it’s a Flatpak package, check the name in
|
||||
/var/lib/flatpak/exports/share/applications/. For example, for Obsidian, it
|
||||
will be md.obsidian.Obsidian (do not include the .desktop suffix).
|
||||
|
||||
5. Apply Settings
|
||||
|
||||
Apply the new settings and close the application if it was open. The next
|
||||
time you open the application, it should show the correct icon.
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
kscreen-doctor \
|
||||
output.eDP-2.enable \
|
||||
output.eDP-2.position.0,0 \
|
||||
output.eDP-2.primary \
|
||||
output.eDP-2.mode.1920x1080@60 \
|
||||
output.eDP-2.scale.1
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
kscreen-doctor \
|
||||
output.eDP-2.enable \
|
||||
output.eDP-2.position.0,0 \
|
||||
output.eDP-2.primary \
|
||||
output.eDP-2.mode.2560x1600@165 \
|
||||
output.eDP-2.scale.1.25
|
||||
@@ -161,4 +161,4 @@ p = Path(\"%\"); \
|
||||
realpath = (str(p.parent) + '/' if str(p.parent) != '.' else '') + p.stem + '.mp4'; \
|
||||
subprocess.run(['mkdir', '-p', to_folder + str(Path(realpath).parent)]); \
|
||||
subprocess.run(['ffmpeg', '-i', '%', '-c', 'copy', to_folder + realpath])"
|
||||
```
|
||||
```
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
- [Cleaning up old snapshots](#cleaning-up-old-snapshots)
|
||||
- [Creating and restoring snapshots](#creating-and-restoring-snapshots)
|
||||
- [Filesystem ACLs](#filesystem-acls)
|
||||
- [ISCSI Backup Volumes](#iscsi-backup-volumes)
|
||||
- [Create Backup ZVOL](#create-backup-zvol)
|
||||
- [Create Backup ISCSI Target](#create-backup-iscsi-target)
|
||||
- [ISCSI](#iscsi)
|
||||
- [Create ZVOL](#create-zvol)
|
||||
- [Create ISCSI Target](#create-iscsi-target)
|
||||
- [VMs](#vms)
|
||||
- [Converting zvol to qcow2](#converting-zvol-to-qcow2)
|
||||
- [Converting qcow2 to zvol](#converting-qcow2-to-zvol)
|
||||
@@ -41,7 +41,7 @@
|
||||
- [UPS Monitoring](#ups-monitoring)
|
||||
- [ZFS Size Data](#zfs-size-data)
|
||||
- [ZFS Rename](#zfs-rename)
|
||||
- [ISCSI](#iscsi)
|
||||
- [ISCSI](#iscsi-1)
|
||||
- [ISCSI Base Name](#iscsi-base-name)
|
||||
- [Archiving](#archiving)
|
||||
- [Deleting snapshots](#deleting-snapshots)
|
||||
@@ -247,9 +247,9 @@ Dataset -> Dataset details (edit) -> Advanced Options -> ACL Type (inherit)
|
||||
setfacl -b -R /mnt/enc0/smb/media
|
||||
```
|
||||
|
||||
## ISCSI Backup Volumes
|
||||
## ISCSI
|
||||
|
||||
### Create Backup ZVOL
|
||||
### Create ZVOL
|
||||
|
||||
1. Create a new dataset called "iscsi" and then a dataset under that called "backups"
|
||||
1. Set sync to always
|
||||
@@ -258,18 +258,22 @@ setfacl -b -R /mnt/enc0/smb/media
|
||||
2. Create a new dataset under backups with the same name as your server hostname
|
||||
3. Set the size to something reasonable (Note you may need to "force size")
|
||||
|
||||
### Create Backup ISCSI Target
|
||||
### Create ISCSI Target
|
||||
|
||||
1. In System -> Services -> ISCSI set the Base Name following [these rules](#iscsi-base-name)
|
||||
2. In Shared -> ISCSI -> Authorized Access -> Create a new authorized access
|
||||
In Shared -> Block (iSCSI) Shares Targets
|
||||
|
||||
1. Global Target Configuration -> Base Name
|
||||
1. set the Base Name following [these rules](#iscsi-base-name)
|
||||
2. Authorized Access -> Add
|
||||
1. Group ID arbitrary - just pick a number you haven't used
|
||||
2. User: The connecting machine's ISCSI Base Name
|
||||
3. Secret: A 16 character password with no special characters
|
||||
3. Wizard -> Create New
|
||||
1. Extent Name: `backup-<hostname>`
|
||||
2. Extent Type: `Device`
|
||||
3. Extent Device: The ZVOL you just created
|
||||
4. Extent Sharing Platform: `Modern OS`
|
||||
2. Discovery Authentication: Chap
|
||||
3. User: The connecting machine's ISCSI Base Name
|
||||
4. Secret: A 16 character password with no special characters
|
||||
3. Extents -> Add
|
||||
1. Name: `some-name`
|
||||
2. Type: `Device`
|
||||
3. Device: The ZVOL you just created
|
||||
4. Sharing Platform: `Modern OS`
|
||||
5. Protocol Options Portal: Either create new (0.0.0.0 and ::) or select your existing portal
|
||||
6. Protocol Options Initiators: The base name of the connecting machine following [these rules](#iscsi-base-name)
|
||||
4. Targets -> Select the backup-<hostname> target -> Edit
|
||||
|
||||
@@ -16,55 +16,7 @@ and the operator will store information about each server.
|
||||
|
||||
## Setup SSH
|
||||
|
||||
On the operator:
|
||||
|
||||
```bash
|
||||
export SSH_HOST=kube
|
||||
ssh-keygen -t rsa -b 4096 -C ducoterra@${SSH_HOST}.reeselink.com -f ~/.ssh/id_${SSH_HOST}_rsa
|
||||
|
||||
# Note: If you get "too many authentication failures" it's likely because you have too many private
|
||||
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.
|
||||
ssh-copy-id -o PubkeyAuthentication=no -i ~/.ssh/id_${SSH_HOST}_rsa.pub ducoterra@${SSH_HOST}.reeselink.com
|
||||
ssh -i ~/.ssh/id_${SSH_HOST}_rsa -o 'PubkeyAuthentication=yes' ducoterra@${SSH_HOST}.reeselink.com
|
||||
```
|
||||
|
||||
On the server:
|
||||
|
||||
```bash
|
||||
# Copy authorized_keys to root
|
||||
sudo cp ~/.ssh/authorized_keys /root/.ssh/authorized_keys
|
||||
|
||||
# Change your password
|
||||
passwd
|
||||
|
||||
sudo su -
|
||||
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/01-prohibit-password.conf
|
||||
echo '%sudo ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/01-nopasswd-sudo
|
||||
systemctl restart ssh
|
||||
```
|
||||
|
||||
On the operator:
|
||||
|
||||
```bash
|
||||
cat <<EOF >> ~/.ssh/config
|
||||
|
||||
Host $SSH_HOST
|
||||
Hostname ${SSH_HOST}.reeselink.com
|
||||
User root
|
||||
ProxyCommand none
|
||||
ForwardAgent no
|
||||
ForwardX11 no
|
||||
Port 22
|
||||
KeepAlive yes
|
||||
IdentityFile ~/.ssh/id_${SSH_HOST}_rsa
|
||||
EOF
|
||||
|
||||
# Test if you can SSH with a password
|
||||
ssh -o PubkeyAuthentication=no ducoterra@${SSH_HOST}.reeselink.com
|
||||
|
||||
# Test that you can log into the server with ssh config
|
||||
ssh $SSH_HOST
|
||||
```
|
||||
See [README](/README.md#ssh-setup)
|
||||
|
||||
## Fail2Ban
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Podman Server
|
||||
|
||||
## Notes
|
||||
|
||||
- create a btrfs subvolume for each user
|
||||
68
active/podman_bricktracker/bricktracker.md
Normal file
68
active/podman_bricktracker/bricktracker.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Brick Tracker
|
||||
|
||||
<https://gitea.baerentsen.space/FrederikBaerentsen/BrickTracker/src/branch/master/docs/quickstart.md>
|
||||
|
||||
## Setup
|
||||
|
||||
1. Copy the `.env.sample` from <https://gitea.baerentsen.space/FrederikBaerentsen/BrickTracker/src/branch/master/.env.sample> to `.env`
|
||||
2. Set the following:
|
||||
1. `BK_AUTHENTICATION_PASSWORD`
|
||||
2. `BK_AUTHENTICATION_KEY`
|
||||
3. `BK_DATABASE_PATH`
|
||||
4. `BK_INSTRUCTIONS_FOLDER`
|
||||
5. `BK_MINIFIGURES_FOLDER`
|
||||
6. `BK_PARTS_FOLDER`
|
||||
7. `BK_REBRICKABLE_API_KEY`
|
||||
8. `BK_SETS_FOLDER`
|
||||
3. Create the docker compose yaml
|
||||
|
||||
```yaml
|
||||
services:
|
||||
bricktracker:
|
||||
container_name: BrickTracker
|
||||
restart: unless-stopped
|
||||
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
|
||||
ports:
|
||||
- "3333:3333"
|
||||
volumes:
|
||||
- ./data:/var/lib/bricktracker
|
||||
- ./static/instructions:/app/static/instructions
|
||||
- ./static/minifigures:/app/static/minifigures
|
||||
- ./static/parts:/app/static/parts
|
||||
- ./static/sets:/app/static/sets
|
||||
env_file: ".env"
|
||||
```
|
||||
|
||||
4. Start the service: `docker compose up -d`
|
||||
|
||||
## Caddy
|
||||
|
||||
1. Create the new DNS record for your website
|
||||
2. Create the Caddyfile at `./Caddyfile`
|
||||
|
||||
```conf
|
||||
https://connors-legos.reeseapps.com:443 {
|
||||
reverse_proxy 127.0.0.1:3333
|
||||
}
|
||||
```
|
||||
|
||||
3. Create the Caddy compose.yaml
|
||||
|
||||
```yaml
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:<version>
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
```
|
||||
16
active/podman_bricktracker/compose.yaml
Normal file
16
active/podman_bricktracker/compose.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
services:
|
||||
bricktracker:
|
||||
container_name: BrickTracker
|
||||
restart: unless-stopped
|
||||
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
|
||||
ports:
|
||||
- "3333:3333"
|
||||
volumes:
|
||||
- /home/connorbricktracker/data:/var/lib/bricktracker
|
||||
- /home/connorbricktracker/static/instructions:/app/static/instructions
|
||||
- /home/connorbricktracker/static/minifigures:/app/static/minifigures
|
||||
- /home/connorbricktracker/static/parts:/app/static/parts
|
||||
- /home/connorbricktracker/static/sets:/app/static/sets
|
||||
env_file: "/home/connorbricktracker/.env"
|
||||
security_opt:
|
||||
- label=disable
|
||||
17
active/podman_bricktracker/quadlets/bricktracker.container
Normal file
17
active/podman_bricktracker/quadlets/bricktracker.container
Normal file
@@ -0,0 +1,17 @@
|
||||
[Container]
|
||||
ContainerName=BrickTracker
|
||||
EnvironmentFile=/home/connorbricktracker/.env
|
||||
Image=gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
|
||||
PublishPort=3333:3333
|
||||
SecurityLabelDisable=true
|
||||
Volume=/home/connorbricktracker/data:/var/lib/bricktracker
|
||||
Volume=/home/connorbricktracker/static/instructions:/app/static/instructions
|
||||
Volume=/home/connorbricktracker/static/minifigures:/app/static/minifigures
|
||||
Volume=/home/connorbricktracker/static/parts:/app/static/parts
|
||||
Volume=/home/connorbricktracker/static/sets:/app/static/sets
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -1,20 +1,10 @@
|
||||
# Caddy Reverse Proxy
|
||||
|
||||
- [Caddy Reverse Proxy](#caddy-reverse-proxy)
|
||||
- [DNS Records](#dns-records)
|
||||
- [Install Caddy](#install-caddy)
|
||||
- [Ansible](#ansible)
|
||||
- [Manual](#manual)
|
||||
|
||||
## DNS Records
|
||||
|
||||
Before you can create a Caddyfile you need records that point to your server.
|
||||
|
||||
You can either create them manually in your DNS provider of choice or use the provided
|
||||
ddns service:
|
||||
|
||||
1. Update the [ddns caddy records](/active/podman_ddns/secrets/caddy_records.yaml)
|
||||
2. Run the [caddy ansible playbook](/active/podman_ddns/ddns.md#ansible-caddy-records)
|
||||
- [Adding a new Caddy Record](#adding-a-new-caddy-record)
|
||||
|
||||
## Install Caddy
|
||||
|
||||
@@ -101,4 +91,15 @@ WantedBy=default.target
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
systemctl restart caddy
|
||||
```
|
||||
```
|
||||
|
||||
## Adding a new Caddy Record
|
||||
|
||||
Before you can create a Caddyfile you need records that point to your server.
|
||||
|
||||
You can either create them manually in your DNS provider of choice or use the provided
|
||||
ddns service:
|
||||
|
||||
1. Update the [ddns caddy records](/active/podman_ddns/secrets/caddy_records.yaml)
|
||||
2. (Optional) Update the Caddyfile at `active/podman_caddy/secrets/Caddyfile`
|
||||
3. Run the [caddy ansible playbook](/active/podman_ddns/ddns.md#ansible-caddy-records)
|
||||
@@ -1,26 +1,32 @@
|
||||
# DDNS for Route53
|
||||
|
||||
- [DDNS for Route53](#ddns-for-route53)
|
||||
- [Install](#install)
|
||||
- [As a Systemd Service](#as-a-systemd-service)
|
||||
- [Ansible Caddy Records](#ansible-caddy-records)
|
||||
- [Ansible Git Record](#ansible-git-record)
|
||||
- [Ansible Unifi External Records](#ansible-unifi-external-records)
|
||||
- [Ansible Hostname reeselink records](#ansible-hostname-reeselink-records)
|
||||
- [Quickly Update DDNS Records](#quickly-update-ddns-records)
|
||||
- [Install a New DDNS Service](#install-a-new-ddns-service)
|
||||
- [Ansible 3D Server Records](#ansible-3d-server-records)
|
||||
- [Ansible Podman Record](#ansible-podman-record)
|
||||
- [Ansible Unifi External Records](#ansible-unifi-external-records)
|
||||
- [Ansible Hostname reeselink records](#ansible-hostname-reeselink-records)
|
||||
- [Development](#development)
|
||||
- [Testing](#testing)
|
||||
- [Building Container Image](#building-container-image)
|
||||
|
||||
This service will automatically keep ipv4 and ipv6 records updated in AWS Route53.
|
||||
This service will automatically keep ipv4 and ipv6 records updated in AWS
|
||||
Route53.
|
||||
|
||||
**NOTE**: This requires the aws cli to be installed on each node with
|
||||
credentials that can modify records in route53. See
|
||||
[aws_iam](/active/aws_iam/aws_iam.md) and
|
||||
[aws_cli](/active/aws_cli/aws_cli.md)
|
||||
[aws_iam](/active/aws_iam/aws_iam.md) and [aws_cli](/active/aws_cli/aws_cli.md)
|
||||
|
||||
## Install
|
||||
## Quickly Update DDNS Records
|
||||
|
||||
### As a Systemd Service
|
||||
In the event of a record change you can quickly trigger the ddns services with
|
||||
|
||||
```bash
|
||||
systemctl start --all ddns*.service
|
||||
```
|
||||
|
||||
## Install a New DDNS Service
|
||||
|
||||
You need two files:
|
||||
|
||||
@@ -45,7 +51,12 @@ records:
|
||||
hosted_zone_id: ABC123456789
|
||||
```
|
||||
|
||||
Then you can install the ddns service with something like
|
||||
Then you'll need to pick a server responsible for keeping those records
|
||||
updated. Whichever host you run the service on will also be the host which
|
||||
provides the public IP. Choose the host accordingly if it will be updating a
|
||||
public IP on behalf of another server, as the IPv6 address will not be correct.
|
||||
|
||||
Now you can install the DDNS service with something like:
|
||||
|
||||
```bash
|
||||
ansible-playbook \
|
||||
@@ -60,27 +71,32 @@ active/podman_ddns/install_ddns.yaml \
|
||||
|
||||
See ansible playbook [install_ddns.yaml](/install_ddns.yaml)
|
||||
|
||||
#### Ansible Caddy Records
|
||||
It's recommended that you have multiple secret `foobar-records.yaml` files for
|
||||
multiple servers. If you have a podman server, it'll have its own
|
||||
`podman-records.yaml`. If you have a docker server, it'll have its own
|
||||
`docker-records.yaml`. Etc. etc.
|
||||
|
||||
### Ansible 3D Server Records
|
||||
|
||||
```bash
|
||||
ansible-playbook \
|
||||
-i ansible/inventory.yaml \
|
||||
-l 3dserver \
|
||||
active/podman_ddns/install_ddns.yaml \
|
||||
-e "@active/podman_ddns/secrets/caddy_records.yaml"
|
||||
-e "@active/podman_ddns/secrets/3dserver_records.yaml"
|
||||
```
|
||||
|
||||
#### Ansible Git Record
|
||||
### Ansible Podman Record
|
||||
|
||||
```bash
|
||||
ansible-playbook \
|
||||
-i ansible/inventory.yaml \
|
||||
-l podman \
|
||||
active/podman_ddns/install_ddns.yaml \
|
||||
-e "@active/podman_ddns/secrets/git_record.yaml"
|
||||
-e "@active/podman_ddns/secrets/podman_records.yaml"
|
||||
```
|
||||
|
||||
#### Ansible Unifi External Records
|
||||
### Ansible Unifi External Records
|
||||
|
||||
```bash
|
||||
ansible-playbook \
|
||||
@@ -90,7 +106,7 @@ active/podman_ddns/install_ddns.yaml \
|
||||
-e "@active/podman_ddns/secrets/unifi_external_record.yaml"
|
||||
```
|
||||
|
||||
#### Ansible Hostname reeselink records
|
||||
### Ansible Hostname reeselink records
|
||||
|
||||
```bash
|
||||
export PLAYBOOK_PATH=active/podman_ddns
|
||||
|
||||
@@ -5,8 +5,6 @@ services:
|
||||
image: docker.gitea.com/gitea:1.24
|
||||
container_name: gitea
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- GITEA__database__DB_TYPE=postgres
|
||||
- GITEA__database__HOST=postgres:5432
|
||||
- GITEA__database__NAME=gitea
|
||||
@@ -16,15 +14,13 @@ services:
|
||||
networks:
|
||||
- gitea
|
||||
volumes:
|
||||
- /home/gitea/gitea_data:/data
|
||||
- /home/gitea/gitea_data:/data:Z
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:2222"
|
||||
depends_on:
|
||||
- postgres
|
||||
security_opt:
|
||||
- label=disable
|
||||
labels:
|
||||
- "io.containers.autoupdate=registry"
|
||||
|
||||
@@ -39,9 +35,9 @@ services:
|
||||
networks:
|
||||
- gitea
|
||||
volumes:
|
||||
- /home/gitea/gitea_postgres:/var/lib/postgresql/data
|
||||
security_opt:
|
||||
- label=disable
|
||||
- /home/gitea/gitea_postgres:/var/lib/postgresql/data:Z
|
||||
labels:
|
||||
- "io.containers.autoupdate=registry"
|
||||
|
||||
networks:
|
||||
gitea:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
- [Gitea](#gitea)
|
||||
- [Gitea on Rootless Podman](#gitea-on-rootless-podman)
|
||||
- [A note on directories](#a-note-on-directories)
|
||||
- [Create the gitea user](#create-the-gitea-user)
|
||||
- [Convert Compose to Quadlet](#convert-compose-to-quadlet)
|
||||
- [Install Quadlets](#install-quadlets)
|
||||
@@ -15,6 +16,18 @@
|
||||
|
||||
## Gitea on Rootless Podman
|
||||
|
||||
### A note on directories
|
||||
|
||||
```bash
|
||||
RunMode: prod
|
||||
AppPath: /usr/local/bin/gitea
|
||||
WorkPath: /data/gitea
|
||||
CustomPath: /data/gitea
|
||||
ConfigFile: /data/gitea/conf/app.ini
|
||||
|
||||
Data: /data/gitea/data/
|
||||
```
|
||||
|
||||
### Create the gitea user
|
||||
|
||||
```bash
|
||||
|
||||
@@ -4,13 +4,11 @@ Requires=postgres.service
|
||||
[Container]
|
||||
AutoUpdate=registry
|
||||
ContainerName=gitea
|
||||
Environment=USER_UID=1000 USER_GID=1000 GITEA__database__DB_TYPE=postgres GITEA__database__HOST=postgres:5432 GITEA__database__NAME=gitea GITEA__database__USER=gitea GITEA__database__PASSWD=gitea
|
||||
Image=docker.gitea.com/gitea:1.24
|
||||
Network=gitea.network
|
||||
PublishPort=3000:3000
|
||||
PublishPort=2222:2222
|
||||
SecurityLabelDisable=true
|
||||
Volume=/home/gitea/gitea_data:/data
|
||||
Volume=/home/gitea/gitea_data:/data:Z
|
||||
Volume=/etc/localtime:/etc/localtime:ro
|
||||
|
||||
[Service]
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
[Container]
|
||||
AutoUpdate=registry
|
||||
ContainerName=postgres
|
||||
Environment=POSTGRES_USER=gitea POSTGRES_PASSWORD=gitea POSTGRES_DB=gitea
|
||||
Image=docker.io/library/postgres:15
|
||||
Network=gitea.network
|
||||
SecurityLabelDisable=true
|
||||
Volume=/home/gitea/gitea_postgres:/var/lib/postgresql/data
|
||||
Volume=/home/gitea/gitea_postgres:/var/lib/postgresql/data:Z
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
31
active/podman_minecraft/compose.yaml
Normal file
31
active/podman_minecraft/compose.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
services:
|
||||
testcraft:
|
||||
image: gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||
stdin_open: true
|
||||
tty: true
|
||||
volumes:
|
||||
- /home/minecraft/testcraft:/mc_data
|
||||
ports:
|
||||
- 25565:25565
|
||||
environment:
|
||||
- MAX_RAM=4
|
||||
- MIN_RAM=1
|
||||
security_opt:
|
||||
- "label=disable"
|
||||
userns_mode: keep-id
|
||||
restart: always
|
||||
nimcraft:
|
||||
image: gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||
stdin_open: true
|
||||
tty: true
|
||||
volumes:
|
||||
- /home/minecraft/nimcraft:/mc_data
|
||||
ports:
|
||||
- 25566:25565
|
||||
environment:
|
||||
- MAX_RAM=4
|
||||
- MIN_RAM=1
|
||||
security_opt:
|
||||
- "label=disable"
|
||||
userns_mode: keep-id
|
||||
restart: always
|
||||
108
active/podman_minecraft/minecraft.md
Normal file
108
active/podman_minecraft/minecraft.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Podman Template
|
||||
|
||||
- [Podman Template](#podman-template)
|
||||
- [Install minecraft](#install-minecraft)
|
||||
- [Create the minecraft user](#create-the-minecraft-user)
|
||||
- [Convert Compose to Quadlet](#convert-compose-to-quadlet)
|
||||
- [Install Quadlets](#install-quadlets)
|
||||
- [Upgrade Quadlets](#upgrade-quadlets)
|
||||
- [Expose minecraft](#expose-minecraft)
|
||||
- [Backup minecraft](#backup-minecraft)
|
||||
|
||||
## Install minecraft
|
||||
|
||||
Find and replace minecraft with the name of the service.
|
||||
|
||||
### Create the minecraft user
|
||||
|
||||
```bash
|
||||
useradd minecraft
|
||||
|
||||
su - minecraft
|
||||
ssh-keygen
|
||||
exit
|
||||
cp ~/.ssh/authorized_keys /home/minecraft/.ssh/authorized_keys
|
||||
chown minecraft:minecraft /home/minecraft/.ssh/authorized_keys
|
||||
loginctl enable-linger $(id -u minecraft)
|
||||
```
|
||||
|
||||
SSH into the server as minecraft
|
||||
|
||||
```bash
|
||||
systemctl --user enable podman-restart
|
||||
systemctl --user enable --now podman.socket
|
||||
mkdir -p ~/.config/containers/systemd
|
||||
```
|
||||
|
||||
### Convert Compose to Quadlet
|
||||
|
||||
Create a folder called `quadlets` in your podman_minecraft project.
|
||||
|
||||
```bash
|
||||
# Generate the systemd service
|
||||
podman run \
|
||||
--security-opt label=disable \
|
||||
--rm \
|
||||
-v $(pwd)/active/podman_minecraft:/compose \
|
||||
-v $(pwd)/active/podman_minecraft/quadlets:/quadlets \
|
||||
quay.io/k9withabone/podlet \
|
||||
-f /quadlets \
|
||||
-i \
|
||||
--overwrite \
|
||||
compose /compose/compose.yaml
|
||||
|
||||
# Copy the files to the server
|
||||
scp -r active/podman_minecraft/quadlets/. minecraft:~/.config/containers/systemd/
|
||||
```
|
||||
|
||||
### Install Quadlets
|
||||
|
||||
```bash
|
||||
ssh minecraft
|
||||
|
||||
export GAME_SERVER_NAME=testcraft
|
||||
mkdir $GAME_SERVER_NAME
|
||||
|
||||
# Download the server jar (only needed once)
|
||||
podman run \
|
||||
-it \
|
||||
--rm \
|
||||
-e SERVER_VERSION=1.21.8 \
|
||||
-v $(pwd)/$GAME_SERVER_NAME:/downloads \
|
||||
--security-opt label=disable \
|
||||
--userns keep-id \
|
||||
docker.io/ducoterra/get-minecraft:latest
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user restart $GAME_SERVER_NAME
|
||||
```
|
||||
|
||||
### Upgrade Quadlets
|
||||
|
||||
```bash
|
||||
scp -r quadlets/. minecraft:~/.config/containers/systemd/
|
||||
ssh minecraft systemctl --user daemon-reload
|
||||
ssh minecraft systemctl --user restart minecraft
|
||||
```
|
||||
|
||||
## Expose minecraft
|
||||
|
||||
1. Create your minecraft ddns record first [following these docs](/active/podman_ddns/ddns.md#)
|
||||
2. Create a SRV record in your DNS provider like the following:
|
||||
|
||||
| Field | Value |
|
||||
| ----------- | -------------------------------------- |
|
||||
| Record name | _minecraft._tcp.testcraft.reeseapps.com |
|
||||
| Value | 0 5 25566 minecraft.reeseapps.com |
|
||||
|
||||
3. Test your record with `nslookup`
|
||||
|
||||
```bash
|
||||
nslookup -q=srv _minecraft._tcp.testcraft.reeseapps.com
|
||||
```
|
||||
|
||||
4. Access your server at your domain "testcraft.reeseapps.com"
|
||||
|
||||
## Backup minecraft
|
||||
|
||||
Follow the Borg [Create a Backup Service Docs](/active/systemd_borg/borg.md#create-a-backup-service)
|
||||
14
active/podman_minecraft/quadlets/nimcraft.container
Normal file
14
active/podman_minecraft/quadlets/nimcraft.container
Normal file
@@ -0,0 +1,14 @@
|
||||
[Container]
|
||||
Environment=MAX_RAM=4 MIN_RAM=1
|
||||
Image=gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||
PodmanArgs=--interactive --tty
|
||||
PublishPort=25566:25565
|
||||
SecurityLabelDisable=true
|
||||
UserNS=keep-id
|
||||
Volume=/home/minecraft/nimcraft:/mc_data
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
14
active/podman_minecraft/quadlets/testcraft.container
Normal file
14
active/podman_minecraft/quadlets/testcraft.container
Normal file
@@ -0,0 +1,14 @@
|
||||
[Container]
|
||||
Environment=MAX_RAM=4 MIN_RAM=1
|
||||
Image=gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||
PodmanArgs=--interactive --tty
|
||||
PublishPort=25565:25565
|
||||
SecurityLabelDisable=true
|
||||
UserNS=keep-id
|
||||
Volume=/home/minecraft/testcraft:/mc_data
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,26 @@
|
||||
[Unit]
|
||||
Description=Nextcloud AIO Master Container
|
||||
Documentation=https://github.com/nextcloud/all-in-one/blob/main/docker-rootless.md
|
||||
After=local-fs.target
|
||||
Requires=podman.socket
|
||||
|
||||
[Container]
|
||||
ContainerName=nextcloud-aio-mastercontainer
|
||||
Image=docker.io/nextcloud/all-in-one:latest
|
||||
PublishPort=0.0.0.0:11001:8080
|
||||
Volume=nextcloud_aio_mastercontainer:/mnt/docker-aio-config
|
||||
Volume=/run/user/1001/podman/podman.sock:/var/run/docker.sock:Z
|
||||
Network=bridge
|
||||
SecurityLabelDisable=true
|
||||
|
||||
Environment=APACHE_PORT=11000
|
||||
Environment=APACHE_IP_BINDING=0.0.0.0
|
||||
Environment=WATCHTOWER_DOCKER_SOCKET_PATH=/run/user/1001/podman/podman.sock
|
||||
Environment=NEXTCLOUD_DATADIR="/home/nextcloud/nextcloud_data"
|
||||
Environment=SKIP_DOMAIN_VALIDATION=true
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target default.target
|
||||
@@ -55,7 +55,9 @@ systemctl --user enable --now podman.socket
|
||||
|
||||
### Create the container autostart service
|
||||
|
||||
As the nextcloud user.
|
||||
Edit the autostart service to include "unless-stopped" containers.
|
||||
|
||||
As the nextcloud user:
|
||||
|
||||
`systemctl --user edit podman-restart.service`
|
||||
|
||||
@@ -63,7 +65,6 @@ As the nextcloud user.
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/podman $LOGGING start --all --filter restart-policy=always --filter restart-policy=unless-stopped
|
||||
ExecStop=
|
||||
ExecStop=/bin/sh -c '/usr/bin/podman $LOGGING stop $(/usr/bin/podman container ls --filter restart-policy=always --filter restart-policy=unless-stopped -q)'
|
||||
```
|
||||
|
||||
@@ -73,42 +74,21 @@ systemctl --user daemon-reload
|
||||
|
||||
### Install Nextcloud
|
||||
|
||||
`mkdir -p ~/.config/containers/systemd`
|
||||
|
||||
`vim ~/.config/containers/systemd/nextcloud-aio-mastercontainer.container`
|
||||
|
||||
```conf
|
||||
[Unit]
|
||||
Description=Nextcloud AIO Master Container
|
||||
Documentation=https://github.com/nextcloud/all-in-one/blob/main/docker-rootless.md
|
||||
After=local-fs.target
|
||||
Requires=podman.socket
|
||||
|
||||
[Container]
|
||||
ContainerName=nextcloud-aio-mastercontainer
|
||||
Image=docker.io/nextcloud/all-in-one:latest
|
||||
PublishPort=0.0.0.0:11001:8080
|
||||
Volume=nextcloud_aio_mastercontainer:/mnt/docker-aio-config
|
||||
Volume=/run/user/1001/podman/podman.sock:/var/run/docker.sock:Z
|
||||
Network=bridge
|
||||
SecurityLabelDisable=true
|
||||
|
||||
Environment=APACHE_PORT=11000
|
||||
Environment=APACHE_IP_BINDING=0.0.0.0
|
||||
Environment=WATCHTOWER_DOCKER_SOCKET_PATH=/run/user/1001/podman/podman.sock
|
||||
Environment=NEXTCLOUD_DATADIR="/home/nextcloud/nextcloud_data"
|
||||
Environment=SKIP_DOMAIN_VALIDATION=true
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target default.target
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user start nextcloud-aio-mastercontainer
|
||||
# Make the container systemd directory (if needed)
|
||||
ssh nextcloud mkdir -p ~/.config/containers/systemd
|
||||
|
||||
# Create the nextcloud network with ipv6
|
||||
ssh nextcloud podman network create --ipv6 nextcloud-aio
|
||||
|
||||
# Copy the quadlet files
|
||||
scp \
|
||||
active/podman_nextcloud/nextcloud-aio-mastercontainer.container \
|
||||
nextcloud:.config/containers/systemd/
|
||||
|
||||
# Reload and restart the service
|
||||
ssh nextcloud systemctl --user daemon-reload
|
||||
ssh nextcloud systemctl --user restart nextcloud-aio-mastercontainer
|
||||
```
|
||||
|
||||
### Install Caddy
|
||||
@@ -167,7 +147,6 @@ systemctl daemon-reload
|
||||
systemctl start caddy
|
||||
```
|
||||
|
||||
|
||||
### Firewall
|
||||
|
||||
Allow traffic to 11000 from your reverse proxy
|
||||
|
||||
@@ -51,4 +51,4 @@ Compile and flash.
|
||||
{+KC_ENT}{-KC_ENT}{1000}
|
||||
// full screen
|
||||
{+KC_LGUI}{+KC_PGUP}{-KC_PGUP}{-KC_LGUI}
|
||||
```
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Runs backup script for {{ repo_name }}
|
||||
After=network.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Restart=no
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/script/backup-{{ repo_name }}.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -33,6 +33,7 @@ borg create \
|
||||
--exclude-caches \
|
||||
--exclude 'home/*/.cache/*' \
|
||||
--exclude 'var/tmp/*' \
|
||||
--exclude 'home/*/.snapshots/*' \
|
||||
{% for dir in exclude_dirs %}
|
||||
--exclude '{{ dir }}' \
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[Unit]
|
||||
Description=Run Backup backup_{{ repo_name }}.service every hour
|
||||
Description=Run Backup backup-{{ repo_name }}.service every day
|
||||
|
||||
[Timer]
|
||||
OnCalendar=hourly
|
||||
OnCalendar=*-*-* 2:00:00
|
||||
AccuracySec=10min
|
||||
Persistent=true
|
||||
Unit=ddns.{{ item.record }}.service
|
||||
Unit=backup-{{ repo_name }}.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# Borg Backup
|
||||
|
||||
- [Borg Backup](#borg-backup)
|
||||
- [Server Setup](#server-setup)
|
||||
- [Adding a Client](#adding-a-client)
|
||||
- [Installing the Backup Service](#installing-the-backup-service)
|
||||
- [Adding Nextcloud](#adding-nextcloud)
|
||||
- [Manual Client Use](#manual-client-use)
|
||||
- [Install Borg](#install-borg)
|
||||
- [Set up a new root client](#set-up-a-new-root-client)
|
||||
- [Create a Backup Service](#create-a-backup-service)
|
||||
- [Check backup service logs](#check-backup-service-logs)
|
||||
- [Run a Manual Backup](#run-a-manual-backup)
|
||||
- [Back up and Entire System](#back-up-and-entire-system)
|
||||
|
||||
## Server Setup
|
||||
## Install Borg
|
||||
|
||||
<https://borgbackup.readthedocs.io/en/stable/deployment/central-backup-server.html#user-and-group>
|
||||
|
||||
@@ -28,14 +29,16 @@ touch /home/backup/.ssh/authorized_keys
|
||||
chown -R backup:backup /home/backup/.ssh
|
||||
```
|
||||
|
||||
### Adding a Client
|
||||
## Set up a new root client
|
||||
|
||||
Note: See [adding nextcloud](#adding-nextcloud) for nextcloud instructions here.
|
||||
Backups will be run as the root user. Generate them an SSH key to
|
||||
|
||||
On the server as root:
|
||||
|
||||
```bash
|
||||
export BACKUP_HOST=""
|
||||
export BACKUP_HOST="borg.reeselink.com"
|
||||
|
||||
ssh-keygen -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
|
||||
ssh-keygen -C root@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
|
||||
|
||||
cat <<EOF >> ~/.ssh/config
|
||||
Host ${BACKUP_HOST}
|
||||
@@ -43,39 +46,20 @@ Host ${BACKUP_HOST}
|
||||
IdentityFile ~/.ssh/id_${BACKUP_HOST}
|
||||
User backup
|
||||
Port 22
|
||||
KeepAlive yes
|
||||
EOF
|
||||
```
|
||||
|
||||
Now on the server:
|
||||
Now on borg.reeselink.com as root:
|
||||
|
||||
```bash
|
||||
export CLIENT_FQDN=""
|
||||
# Should look like ssh-rsa abcd1234 backup@fqdn.something.com
|
||||
export SSH_PUBKEY=""
|
||||
export AUTHKEY_ENTRY="command=\"cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}\",restrict ${SSH_PUBKEY}"
|
||||
export CLIENT_FQDN="fqdn.reeseapps.com"
|
||||
export SSH_PUBKEY="ssh-rsa abcd1234 backup@fqdn.something.com"
|
||||
export BORG_COMMAND="cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}"
|
||||
export AUTHKEY_ENTRY="command=\"${BORG_COMMAND}\",restrict ${SSH_PUBKEY}"
|
||||
echo $AUTHKEY_ENTRY >> /home/backup/.ssh/authorized_keys
|
||||
|
||||
mkdir /home/backup/repos/${CLIENT_FQDN}
|
||||
chown backup:backup /home/backup/repos/${CLIENT_FQDN}
|
||||
```
|
||||
|
||||
Then back on the client:
|
||||
|
||||
```bash
|
||||
ssh borg.reeselink.com
|
||||
|
||||
# root
|
||||
borg init --encryption none backup@${BACKUP_HOST}:root
|
||||
# home
|
||||
borg init --encryption none backup@${BACKUP_HOST}:home
|
||||
# app
|
||||
borg init --encryption none backup@${BACKUP_HOST}:gitea
|
||||
# another app
|
||||
borg init --encryption none backup@${BACKUP_HOST}:nextcloud
|
||||
```
|
||||
|
||||
### Installing the Backup Service
|
||||
## Create a Backup Service
|
||||
|
||||
Create your vars file in `secrets/host_vars.yaml`
|
||||
|
||||
@@ -97,30 +81,29 @@ stop_user_services:
|
||||
```
|
||||
|
||||
```bash
|
||||
# Update all existing backup services for podman
|
||||
for var_file in $(ls active/systemd_borg/secrets); do
|
||||
ansible-playbook \
|
||||
-i active/ansible/inventory.yaml \
|
||||
-i ansible/inventory.yaml \
|
||||
-l podman \
|
||||
active/systemd_borg/install_backup.yaml \
|
||||
-e "@active/systemd_borg/secrets/gitea_vars.yaml"
|
||||
-e "@active/systemd_borg/secrets/$var_file"
|
||||
done
|
||||
```
|
||||
|
||||
#### Adding Nextcloud
|
||||
## Check backup service logs
|
||||
|
||||
Rather than creating a client, just set the borg backup location to:
|
||||
|
||||
```text
|
||||
backup@borg.reeselink.com:nextcloud
|
||||
```bash
|
||||
ssh podman journalctl -u 'backup-*' -f
|
||||
```
|
||||
|
||||
Then run the backup. It will generate a pubkey. Copy this into the authorized_keys file.
|
||||
|
||||
## Manual Client Use
|
||||
## Run a Manual Backup
|
||||
|
||||
```bash
|
||||
borg list borg.reeselink.com:home
|
||||
|
||||
# Do not include the first / in the path
|
||||
export PATH_TO_BACKUP=var/home/ducoterra
|
||||
export PATH_TO_BACKUP=home/ducoterra
|
||||
export BORG_REPO=borg.reeselink.com:home
|
||||
|
||||
# If not initialized, do that now
|
||||
@@ -148,6 +131,10 @@ borg create \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.config/libvirt" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/containers" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/docker" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.npm" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/.ollama" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/Downloads" \
|
||||
-e "pp:/${PATH_TO_BACKUP}/Nextcloud" \
|
||||
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
||||
/${PATH_TO_BACKUP}
|
||||
|
||||
@@ -156,4 +143,31 @@ borg mount $BORG_REPO::2025-05-14-00-44-05 /mnt/
|
||||
|
||||
# Restore a borg archive to a location (dry run)
|
||||
borg extract --dry-run --list --strip-components 1 $BORG_REPO::my-files home/USERNAME
|
||||
```
|
||||
```
|
||||
|
||||
### Back up and Entire System
|
||||
|
||||
```bash
|
||||
export BORG_REPO=borg.reeselink.com:root
|
||||
|
||||
borg create \
|
||||
--verbose \
|
||||
--filter AME \
|
||||
--list \
|
||||
--stats \
|
||||
--progress \
|
||||
--show-rc \
|
||||
--compression lz4 \
|
||||
--exclude root/.cache \
|
||||
--exclude var/lib/docker \
|
||||
--exclude var/lib/containers \
|
||||
--exclude usr/share/ollama \
|
||||
--exclude home \
|
||||
--exclude proc \
|
||||
--exclude dev \
|
||||
--exclude sys \
|
||||
--exclude tmp \
|
||||
--exclude .snapshots \
|
||||
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
||||
/
|
||||
```
|
||||
|
||||
@@ -8,36 +8,32 @@
|
||||
path: /usr/local/script
|
||||
state: directory
|
||||
mode: '0755'
|
||||
- name: Copy backup.service
|
||||
- name: Copy backup-{{ repo_name }}.service
|
||||
template:
|
||||
src: backup.service
|
||||
dest: /etc/systemd/system/backup-{{ repo_name }}.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
- name: Copy backup.timer
|
||||
- name: Copy backup-{{ repo_name }}.timer
|
||||
template:
|
||||
src: backup.timer
|
||||
dest: /etc/systemd/system/backup-{{ repo_name }}.timer
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
- name: Template backup.sh
|
||||
- name: Template backup-{{ repo_name }}.sh
|
||||
template:
|
||||
src: backup.sh.j2
|
||||
dest: /usr/local/script/backup-{{ repo_name }}.sh
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0744'
|
||||
# - name: Reload ddns timer
|
||||
# ansible.builtin.systemd_service:
|
||||
# state: restarted
|
||||
# name: ddns.{{ item.record }}.timer
|
||||
# enabled: true
|
||||
# daemon_reload: true
|
||||
# loop: "{{ records }}"
|
||||
# - name: Run ddns service
|
||||
# ansible.builtin.systemd_service:
|
||||
# state: restarted
|
||||
# name: ddns.{{ item.record }}.service
|
||||
# loop: "{{ records }}"
|
||||
- name: Initialize Repo {{ borg_user }}@{{ borg_host }}:{{ repo_name }}
|
||||
script: /usr/bin/borg init -e none {{ borg_user }}@{{ borg_host }}:{{ repo_name }}
|
||||
ignore_errors: yes
|
||||
- name: Reload backup timer backup-{{ repo_name }}.timer
|
||||
ansible.builtin.systemd_service:
|
||||
name: backup-{{ repo_name }}.timer
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
|
||||
8
active/systemd_wireguard/Dockerfile
Normal file
8
active/systemd_wireguard/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk add -U wireguard-tools
|
||||
COPY wg0.conf /etc/wireguard/wg0.conf
|
||||
|
||||
CMD wg-quick up wg0 && \
|
||||
wg set wg0 peer 'lvghTtIHSXzOfpruVHtRnnAiZJeUi8A6lzhE21GSJjA=' allowed-ips 10.10.0.2/32 && \
|
||||
watch -n 1 wg
|
||||
35
active/systemd_wireguard/install.sh
Executable file
35
active/systemd_wireguard/install.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
# TODO
|
||||
# 1. Ask for listen port
|
||||
# 2. Ask for name of eth interface
|
||||
|
||||
apt-get update
|
||||
apt-get upgrade -y
|
||||
apt-get install -y raspberrypi-kernel-headers
|
||||
apt install -y wireguard qrencode iptables
|
||||
|
||||
cat > /etc/sysctl.conf <<EOF
|
||||
net.ipv4.ip_forward=1
|
||||
net.ipv6.conf.all.forwarding=1
|
||||
EOF
|
||||
|
||||
reboot
|
||||
|
||||
cd /etc/wireguard
|
||||
umask 077
|
||||
export PRIVKEY=$(wg genkey)
|
||||
echo $PRIVKEY | tee privatekey | wg pubkey | tee publickey
|
||||
echo $PRIVKEY | tee --append /etc/wireguard/wg0.conf
|
||||
cat > /etc/wireguard/wg0.conf <<EOF
|
||||
[Interface]
|
||||
Address = 10.10.0.1/24
|
||||
Address = fd86:ea04:1111::1/64
|
||||
SaveConfig = true
|
||||
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||||
ListenPort = 51820
|
||||
PrivateKey = $PRIVKEY
|
||||
EOF
|
||||
|
||||
sysctl -p
|
||||
wg-quick up wg0
|
||||
wg
|
||||
28
active/systemd_wireguard/install_wireguard.yaml
Normal file
28
active/systemd_wireguard/install_wireguard.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
- name: Create Backup Service
|
||||
hosts: all
|
||||
vars_files:
|
||||
- secrets/vars.yaml
|
||||
tasks:
|
||||
- name: Install the latest version of Wireguard Tools
|
||||
ansible.builtin.dnf:
|
||||
name: wireguard-tools
|
||||
state: latest
|
||||
- name: Create wg0.conf
|
||||
template:
|
||||
dest: /etc/wireguard/wg0.conf
|
||||
src: wg0.conf.j2
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0600'
|
||||
- name: enable and persist ip forwarding
|
||||
sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: "1"
|
||||
state: present
|
||||
sysctl_set: yes
|
||||
reload: yes
|
||||
- name: start wireguard and enable on boot
|
||||
systemd:
|
||||
name: wg-quick@wg0
|
||||
enabled: yes
|
||||
state: started
|
||||
47
active/systemd_wireguard/newclient.sh
Executable file
47
active/systemd_wireguard/newclient.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
# TODO
|
||||
# 1. Read server pubkey from file
|
||||
|
||||
wg
|
||||
|
||||
echo -n 'Client Name: '
|
||||
read name
|
||||
echo -n 'Last digit of client IP \(10.10.0.?\): '
|
||||
read ip
|
||||
echo -n 'Server PubKey: '
|
||||
read server_pubkey
|
||||
|
||||
mkdir $name
|
||||
cd $name
|
||||
export PRIVKEY=$(wg genkey)
|
||||
echo $PRIVKEY | tee $name"_privkey"
|
||||
export PUBKEY=$(echo $PRIVKEY | wg pubkey)
|
||||
echo $PUBKEY | tee $name"_pubkey"
|
||||
|
||||
cat > $name".conf" <<EOF
|
||||
[Interface]
|
||||
PrivateKey = $PRIVKEY
|
||||
Address = 10.10.0.$ip/32, fd86:ea04:1111::$ip/128
|
||||
DNS = 10.10.0.1
|
||||
|
||||
[Peer]
|
||||
PublicKey = $server_pubkey
|
||||
Endpoint = wireguard.reeseapps.com:51820
|
||||
AllowedIPs = 0.0.0.0/0, ::/0
|
||||
EOF
|
||||
|
||||
cat >> /etc/wireguard/wg0.conf <<EOF
|
||||
|
||||
# $name
|
||||
[Peer]
|
||||
PublicKey = $PUBKEY
|
||||
AllowedIPs = 10.10.0.$ip/32
|
||||
EOF
|
||||
|
||||
wg set wg0 peer $PUBKEY allowed-ips 10.10.0.$ip/32
|
||||
|
||||
qrencode -t ansiutf8 < $name".conf"
|
||||
|
||||
cd ..
|
||||
chmod -R 600 $name
|
||||
|
||||
wg
|
||||
1
active/systemd_wireguard/qr.sh
Executable file
1
active/systemd_wireguard/qr.sh
Executable file
@@ -0,0 +1 @@
|
||||
qrencode -t ansiutf8
|
||||
5
active/systemd_wireguard/wg0.conf.j2
Normal file
5
active/systemd_wireguard/wg0.conf.j2
Normal file
@@ -0,0 +1,5 @@
|
||||
# {{ ansible_managed }}
|
||||
[Interface]
|
||||
Address = 10.0.1.1/24
|
||||
ListenPort = 51820
|
||||
PrivateKey = {{ server_privkey }}
|
||||
39
active/systemd_wireguard/wireguard.md
Executable file
39
active/systemd_wireguard/wireguard.md
Executable file
@@ -0,0 +1,39 @@
|
||||
# Wireguard
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
ansible-playbook \
|
||||
-i ansible/inventory.yaml \
|
||||
-l wireguard \
|
||||
active/systemd_wireguard/install_backup.yaml \
|
||||
-e "@active/systemd_wireguard/secrets/vars.yaml"
|
||||
```
|
||||
|
||||
## Add a client
|
||||
|
||||
```bash
|
||||
export WG_IP_SUFFIX=$(cat IP && echo $(($(cat IP) + 1)) > IP)
|
||||
export PRIVKEY=$(wg genkey)
|
||||
export PUBKEY=$(echo $PRIVKEY | wg pubkey)
|
||||
export SERVER_PUBKEY=$(cat publickey)
|
||||
cat <<EOF > id_$WG_IP_SUFFIX
|
||||
[Interface]
|
||||
PrivateKey = $PRIVKEY
|
||||
Address = 10.10.0.$WG_IP_SUFFIX/32
|
||||
DNS = 10.10.0.1
|
||||
|
||||
[Peer]
|
||||
PublicKey = $SERVER_PUBKEY
|
||||
Endpoint = pihole.reeserelease.com:51820
|
||||
AllowedIPs = 10.10.0.1/32
|
||||
EOF
|
||||
|
||||
cat id_$WG_IP_SUFFIX | qrencode -t ansiutf8
|
||||
echo "Added ID $WG_IP_SUFFIX"
|
||||
echo "Press enter to continue"
|
||||
read
|
||||
|
||||
wg set wg0 peer $PUBKEY allowed-ips 10.10.0.$WG_IP_SUFFIX/32
|
||||
wg-quick down wg0 && wg-quick up wg0
|
||||
```
|
||||
Reference in New Issue
Block a user