🔧 master: work in progress [might break]

This commit is contained in:
Leon van Kammen 2026-03-05 14:02:37 +01:00
commit 70db1934be
6 changed files with 351 additions and 0 deletions

149
admin Executable file
View file

@ -0,0 +1,149 @@
#!/bin/bash
#
# curlcheck: https://playterm.org
# curlcheck: https://electribrary.electribers.com
# curlcheck: https://2wa.isvery.ninja
disk(){
space(){
df -h | awk '$6 ~ /^\/$/ {print $3" total used ("$5") of "$4}'
#echo '-------'
#ls /home | while read user; do du -hs /home/$user; done
}
"$@"
}
health(){
echo "URL ONLINE SSL TIME"
echo "- - - -"
awk '/^# curlcheck: / {print $3}' $0 | while read url; do
printf "%s" "$url" | sed 's|.*://||g'
curl -v -w 'Total: %{time_total}s\n' ${url} 2>&1 | \
awk '
BEGIN{
err="\033[5m\033[36;5;94m❌\033[0m"
ok="\033[1;36m♥\033[0m"
c["SSL"]=err
c["ONL"]=ok
c["TIM"]="?"
}
/SSL certificate verify ok/ {c["SSL"]=ok }
/Could not resolve host:/ {c["ONL"]=err }
/^Total: / {c["TIM"]=$2 }
END { printf "\r\t\t\t\t"c["ONL"]" "c["SSL"]" "c["TIM"]"\n" }
'
done
}
init(){
grep ulimit /etc/profile || echo 'ulimit -n 65535 || true' >> /etc/profile # compensate alpine's low fd's
}
proxy(){
install(){
echo -e "\n[forwarded ports]" > .ports
iptables -t nat -F # flush
iptables -t nat -X # flush
iptables -F # flush
ip6tables -F -t nat# flush
ip6tables -F # flush
ip6tables -X # flush
ip6tables -t nat -F
ip6tables -t nat -X
ip_external=$(curl -s https://checkip.amazonaws.com)
ipv6_external=$(ip addr | awk '/inet6.*scope global/ { print $2 }')
# proxies
proxyport(){
printf " %-5s => %-10s [%s]\n" $1 $2 $3 >> .ports
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $1 -j REDIRECT --to-ports $2
#ip6tables -t nat -A PREROUTING -i eth0 -p tcp --dport $1 -j REDIRECT --to-ports $2
#iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport $1 -j REDIRECT --to-ports $2
iptables -t nat -I OUTPUT -p tcp -d $ip_external --dport $1 -j REDIRECT --to-ports $2 # reverse ip
#ip6tables -t nat -I OUTPUT -p tcp -d $ipv6_external --dport $1 -j REDIRECT --to-ports $2 # reverse ip
ip6tables -A INPUT -p tcp --dport $1 -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport $1 -j ACCEPT
#iptables -t nat -A POSTROUTING -p tcp --dport $2 -j MASQUERADE
#iptables -t nat -A POSTROUTING -p tcp --dport $2 -j MASQUERADE
}
proxyport 80 8080 nginx-proxy-manager
#proxyport 81 8181 nginx-proxy-manager
proxyport 443 4443 nginx-proxy-manager
#proxyport 993 9993 stalwart-mail
#proxyport 25 2225 stalwart-mail
#proxyport 465 4465 stalwart-mail
#proxyport 587 5587 nodered
#proxyport 25 5587 nodered
# block port 3000 (nginx-proxy-manager exposes it)
iptables -A INPUT -p tcp -d $ip_external --dport 3000 -j REJECT
ip6tables -A INPUT -p tcp -d $ip_external --dport 3000 -j REJECT --reject-with icmp6-adm-unreach-3
# block port 25
#iptables -A INPUT -p tcp -d $ip_external --dport 25 -j REJECT
#ip6tables -A INPUT -p tcp -d $ip_external --dport 25-j REJECT
# block irc 0.0.0.0:6667 port except for nodered docker
iptables -A INPUT -i lo -p tcp --dport 6667 -j ACCEPT
iptables -A INPUT -s 10.0.2.2 -p tcp --dport 6667 -j ACCEPT
iptables -A INPUT -p tcp --dport 6667 -j REJECT
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -s fd00::/64 -p tcp --dport 6667 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 6667 -j REJECT
# rateliming per ip
#iptables --new-chain RATE-LIMIT
#iptables --append RATE-LIMIT \
# --match hashlimit \
# --hashlimit-mode srcip \
# --hashlimit-upto 50/sec \
# --hashlimit-burst 20 \
# --hashlimit-name conn_rate_limit \
# --jump ACCEPT
#iptables --append RATE-LIMIT --jump DROP
rc-update add iptables
rc-update add ip6tables
/etc/init.d/iptables save
/etc/init.d/ip6tables save
}
clear
"$@"
{
iptables -t nat -L -n -v
iptables -L
ip6tables -L
} | more
cat .ports
}
logs(){
tail -qf /home/2wa/nginx-proxy-manager/data/log/*.log | grep -v favicon | sed 's|\] \[.*|]|g'
}
backup(){
cd /root
echo "$(date) ./admin backup [start]" >> .cron.log
BACKUP=backup-2wa.isvery.ninja.zip
crontab -l > crontab.root.txt
apk list -i > alpine.packages.txt
echo "$(su -c 'crontab -l' 2wa)" > crontab.2wa.txt
nice -n 19 /usr/bin/ionice -c2 -n7 zip -r $BACKUP \
/root/admin /root/crontab.* /root/alpine*.txt /root/.ssh \
/home/2wa/.ssh /home/2wa/.config /home/2wa/nginx-proxy-manager/{app.sh,data,*.key} \
/home/2wa/weechat-redbean \
/home/2wa/invoiceninja \
/home/2wa/mailtrain \
/home/2wa/stalwart-mail \
/home/2wa/node-red \
/home/2wa/ntfy \
/home/2wa/portsleep* \
/home/2wa/tcgi* \
/home/2wa/stats \
-x '*.log.*' -x '*.weecha*' -x 'postfix/*' | awk '{ printf( "\r"$0 ) } END{ print ""}'
ls -lah $BACKUP
rclone copy $BACKUP stack:backup/. --progress
echo "$(date) ./admin backup [stop]" >> /root/.cron.log
}
test -z $1 && { echo "Usage: "; grep '(){' $0; }
"$@"

13
docker-compose.yaml Normal file
View file

@ -0,0 +1,13 @@
# docker-compose.yml
services:
traefik:
image: traefik:v3.6
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock

86
glance.yml Normal file
View file

@ -0,0 +1,86 @@
server:
host: localhost
port: 8081
pages:
- name: Home
columns:
- size: small
widgets:
- type: calendar
first-day-of-week: monday
- type: rss
limit: 10
collapse-after: 3
cache: 12h
feeds:
- url: https://selfh.st/rss/
title: selfh.st
limit: 4
- url: https://ciechanow.ski/atom.xml
- url: https://www.joshwcomeau.com/rss.xml
title: Josh Comeau
- url: https://samwho.dev/rss.xml
- url: https://ishadeed.com/feed.xml
title: Ahmad Shadeed
- type: twitch-channels
channels:
- theprimeagen
- j_blow
- piratesoftware
- cohhcarnage
- christitustech
- EJ_SA
- size: full
widgets:
- type: group
widgets:
- type: hacker-news
- type: lobsters
- type: videos
channels:
- UCXuqSBlHAE6Xw-yeJA0Tunw # Linus Tech Tips
- UCR-DXc1voovS8nhAvccRZhg # Jeff Geerling
- UCsBjURrPoezykLs9EqgamOA # Fireship
- UCBJycsmduvYEL83R_U4JriQ # Marques Brownlee
- UCHnyfMqiRRG1u-2MsSQLbXA # Veritasium
- type: group
widgets:
- type: reddit
subreddit: technology
show-thumbnails: true
- type: reddit
subreddit: selfhosted
show-thumbnails: true
- size: small
widgets:
- type: weather
location: London, United Kingdom
units: metric
hour-format: 12h
- type: markets
markets:
- symbol: SPY
name: S&P 500
- symbol: BTC-USD
name: Bitcoin
- symbol: NVDA
name: NVIDIA
- symbol: AAPL
name: Apple
- symbol: MSFT
name: Microsoft
- type: releases
cache: 1d
repositories:
- glanceapp/glance
- go-gitea/gitea
- immich-app/immich
- syncthing/syncthing

56
process-compose.yaml Normal file
View file

@ -0,0 +1,56 @@
mcp_server:
host: localhost
port: 3000
transport: sse
version: "0.5"
disable_env_expansion: true
vars:
FOO: 1 # {{.FOO}}
processes:
install:
disabled: true # run `process-compose run install`
command: |
util/wget a69b6424cda4887e84247b1e01dbfb36ae613ac2cb37f19e307889db2cecc39b https://github.com/glanceapp/glance/releases/download/v0.8.4/glance-linux-amd64.tar.gz
paramjob:
command: "echo @{foo}"
description: "parametrized job"
disabled: true # MCP processes must be disabled initially
working_dir: "/var/log"
mcp:
type: tool
arguments:
- name: foo
type: string
description: "example arg"
required: true
#job_$next$next1:
# command: |
# sed -i 's|^ job_| job_$next|g' process-compose.yaml
# process-compose project update -f process-compose.yaml
create_container:
command: |
ID="$RANDOM$RANDOM"
echo "starting $ID"
echo curl --data 'log=https://localhost:8080/process/logs/create_container' -X POST https://home.org/created_container/$ID
disabled: true # run `curl https://loclahost:8080/process/start/create_container`
glance:
command: pkg/glance
availability:
restart: on_failure # other options: "exit_on_failure", "always", "no" (default)
backoff_seconds: 2 # default: 1
max_restarts: 5 # default: 0 (unlimited)
readiness_probe:
http_get:
host: "localhost"
port: 8081
scheme: "http"
period_seconds: 2
timeout_seconds: 5
success_threshold: 1
failure_threshold: 3

30
shell.nix Normal file
View file

@ -0,0 +1,30 @@
{ pkgs ? import <nixos-unstable> {} } :
{
#pkgs = import (builtins.fetchGit {
# name = "nixos-25.05";
# url = "https://github.com/nixos/nixpkgs";
# rev = "11cb3517b3af6af300dd6c055aeda73c9bf52c48";
#}) {};
foo = pkgs.mkShell {
# nativeBuildInputs is usually what you want -- tools you need to run
nativeBuildInputs = with pkgs.buildPackages; [
authbind
process-compose
docker-compose
];
shellHooks = ''
export NIX_SHELL_VPS=1
echo "available commands:"
'';
};
}

17
util/wget Executable file
View file

@ -0,0 +1,17 @@
#!/bin/sh
# downloads an url [+installs to path] [+checks bit-by-bit reproducability]
test -z "$1" && { echo "wget.install [sha256checksum] <url>"; exit 0; }
set -e
test -n "$2" && url="$2" || url="$2"
file=$(basename "$url")
test -n "$OUT" || OUT="pkg"
wget -O "$file" "$url"
sha256sum "$file"
if test -n "$2"; then
echo "$1 $file" | sha256sum --check || { echo "[!] wrong checksum.."; rm $file; exit 1; }
fi
# extract
test -d $OUT || mkdir -p $OUT
mv $file $OUT/. && cd $OUT
echo $file | grep -q '\.zip' && unzip $file && rm $file
echo $file | grep -q '\.tar' && tar -xvf $file && rm $file