Site Tools


projectinsanity:server_setup

host.pi

Specs

1 x Dedicated Root Server SB32 (hetzner)

  • Intel Core i7-3770
  • 2x HDD SATA 3,0 TB Enterprise
  • 4x RAM 8192 MB DDR3
  • Location: FSN1

Payment

Serverkosten pro Montat: 26,89€ + 5,11€ Steuer: 32,00€

Arne Jonas ST Krischi Schitzu
Juni 18 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40
Juli 18 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40
August 18 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40
September 18 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40
Oktober 18 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40
November 18 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40
Dezember 18 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40 6,40/6,40
Januar 19 0/6,40 6,40/6,40 6,40/6,40 6,40/6,40 0/6,40
Juli 21 (vorausgezahlt) 0/6,40 6,40/6,40 6,40/6,40 0/6,40 0/6,40

Zu überweisen an Jonas

Überblick

Name IP IPv6 Space Last backup
host 10.25.0.1 2a01:4f8:191:327::2 5.5TB pending (picloud)
http 10.25.0.100 2a01:4f8:191:327::10 1TB 10.03.21 (picloud)
http-pub 10.25.0.101 2a01:4f8:191:327::11 500G 24.03.21 (picloud)
mail 10.25.0.102 2a01:4f8:191:327::12 500G 27.01.21 (picloud)
mysql 10.25.0.103 2a01:4f8:191:327::13 100G 28.01.21 (picloud)
playground 10.25.0.104 2a01:4f8:191:327::14 500G 29.03.21 (picloud)
storage 10.25.0.105 2a01:4f8:191:327::15 1TB 28.04.21 (picloud)

Setup

  • IPv4: 144.76.16.40
  • IPv6: 2a01:4f8:191:327::2

Im Rescue system:

installimage -a -n project-insanity -b grub -r yes -l 0 -i root/.oldroot/nfs/images/archlinux-latest-64-minimal.tar.gz -p /boot:ext4:2G,lvm:vg0:all -v vg0:swap:swap:swap:3G,vg0:root:/:btrfs:40G -f yes -s en

systemd-networkd

on the installed host machine, had to change 2a01:4f8:191:327::2/64 to 2a01:4f8:191:327::2/128. Also Address=144.76.16.40 to Address=144.76.16.40/32:

/etc/systemd/networkd/10-enp3s0.network
### Hetzner Online GmbH installimage
[Match]
Name=enp3s0

[Network]
Address=2a01:4f8:191:327::2/128
Gateway=144.76.16.33
Gateway=fe80::1

[Address]
Address=144.76.16.40/32
Peer=144.76.16.33/32
IPForward=ipv4
/etc/systemd/networkd/25-bridge.netdev
[NetDev]
Name=br-internal
Kind=bridge
/etc/systemd/networkd/25-bridge.network
[Match]
Name=br-internal

[Network]
Address=2a01:4f8:191:327::2/64
Address=10.25.0.1/24
ConfigureWithoutCarrier=true

core system

pacman -S mosh tmux htop dmidecode fail2ban openvpn qemu openbsd-netcat openssh easy-rsa fish pacman-contrib
chsh -s $(which fish)
wget https://arch.jensgutermuth.de/iso/2018.06.01/archlinux-2018.06.01-x86_64.iso -P /var/lib/libvirt/images/
chown qemu:qemu /var/lib/libvirt/images/archlinux-2018.06.01-x86_64.iso
useradd -m onny -s /bin/fish
passwd onny
gpasswd -a onny sudo
gpasswd -a onny libvirt
sudo -u onny mkdir /home/onny/.ssh
sudo -u onny vim /home/onny/.ssh/authorized_keys
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/g' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
systemctl enable --now sshd fail2ban systemd-networkd systemd-resolved

dnsmasq settings, ready to listen on wireguard subnet

/etc/dnsmasq.conf
[...]
listen-address=127.0.0.1,10.25.0.1,10.25.40.1

no-resolv

# Google's nameservers, for example
server=8.8.8.8
server=8.8.4.4

systemd resolved dns resolver settings

/etc/systemd/resolved.conf
[...]
[resolve]
DNSStubListener=no
/etc/systemd/resolved.conf.d/dns_over_tls.conf
[Resolve]
DNSOverTLS=opportunistic
/etc/systemd/resolved.conf.d/dnssec.conf
[Resolve]
DNSSEC=true
/etc/systemd/resolved.conf.d/dns_servers.conf
[Resolve]
DNS=2620:fe::fe 9.9.9.9
/etc/hosts
[...]
10.25.0.1 host.pi
10.25.0.100 http.pi
10.25.0.101 http-pub.pi
10.25.0.102 mail.pi
10.25.0.103 mysql.pi
10.25.0.104 playground.pi
10.25.0.105 storage.pi

2a01:4f8:191:327::2 host.pi
2a01:4f8:191:327::10 http.pi
2a01:4f8:191:327::11 http-pub.pi
2a01:4f8:191:327::12 mail.pi
2a01:4f8:191:327::13 mysql.pi
2a01:4f8:191:327::14 playground.pi
2a01:4f8:191:327::15 storage.pi

#vpn clients
10.25.0.200      onny           onny.pi
10.25.0.201      st             st.pi
10.25.0.202      neutrino       neutrino.pi
10.25.0.203      arne           arne.pi

2a01:4f8:191:327::100 onny onny.pi
2a01:4f8:191:327::101 st st.pi
2a01:4f8:191:327::102 neutrino neutrino.pi
2a01:4f8:191:327::103 arne arne.pi

custom pi archlinux repo

/etc/pacman.conf
...
[projectinsanity]
SigLevel = PackageOptional
Server = https://onny.project-insanity.org/archlinux

archlinux auto update

/etc/pacman.conf
...
[projectinsanity]
SigLevel = PackageOptional
Server = https://onny.project-insanity.org/archlinux
/etc/systemd/system/autoupdate.service
[Unit]
Description=Automatic Update
After=network-online.target 

[Service]
Type=simple
ExecStart=/usr/bin/sh -c "/usr/bin/pacman -Syuq --noconfirm --needed --noprogressbar && rm /var/cache/pacman/pkg/*.zst"
TimeoutStopSec=180
KillMode=process
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target
/etc/systemd/system/autoupdate.timer
[Unit]
 Description=Automatic Update when booted up after 5 minutes then check the system for updates every 60 minutes

[Timer]
 OnBootSec=5min
 OnUnitActiveSec=60min
 Unit=autoupdate.service

[Install]
 WantedBy=multi-user.target
systemctl enable --now autoupdate.timer

automatic timed reboot after kernel upgrade

/etc/pacman.d/hooks/linux.hook
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux

[Action]
Description = Enable timer for reboot after kernel upgrade
When = PostTransaction
Exec = /usr/bin/systemctl start kernel-upgrade.timer
/etc/systemd/system/kernel-upgrade.timer
[Unit]
Description=Reboot in the morning after kernel upgrade

[Timer]
OnCalendar=*-*-* 06:00:00
Unit=kernel-upgrade.service

[Install]
WantedBy=multi-user.target
/etc/systemd/system/kernel-upgrade.service
[Unit]
Description=Reboot after kernel upgrade

[Service]
Type=simple
ExecStart=/usr/bin/systemctl reboot

[Install]
WantedBy=multi-user.target

nftables

nftables firewall & routing

/etc/nftables.conf
define TCP_PORT_QUAKEJS_DS = 27960
define TCP_PORT_IMAPS = 993
define TCP_PORT_SMTPS = 587
define TCP_PORT_SMTP = 25
define TCP_PORT_SSH = 22
define TCP_PORT_HTTP = 80
define TCP_PORT_HTTPS = 443
define UDP_PORT_WIREGUARD = 51820
define UDP_PORT_MOSH = 60000-61000
define HOST_HTTP_PI = 10.25.0.100
define HOST_MAIL_PI = 10.25.0.102
define HOST_PLAYGROUND_PI = 10.25.0.104

table inet filter {
	set tcp_accepted {
		type inet_service
		flags interval
		elements = { $TCP_PORT_SSH, $TCP_PORT_HTTP, $TCP_PORT_HTTPS, $TCP_PORT_SMTPS, $TCP_PORT_IMAPS, $TCP_PORT_SMTP, $TCP_PORT_QUAKEJS_DS }
	}

	set udp_accepted {
		type inet_service
		flags interval
		elements = { $UDP_PORT_WIREGUARD, $UDP_PORT_MOSH }
	}

	chain base_checks {
		ct state { established, related } accept
		ct state invalid drop
	}

	chain input {
		type filter hook input priority filter; policy drop;
		jump base_checks
		iifname "lo" accept
		ip protocol icmp icmp type { echo-reply, destination-unreachable, echo-request, time-exceeded, parameter-problem } accept
		ip6 nexthdr ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply, mld-listener-query, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
		tcp dport @tcp_accepted accept
		udp dport @udp_accepted accept
		ip saddr 10.25.0.1/24 accept
		ip saddr 10.25.40.1/24 accept
		reject
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		jump base_checks
		ip daddr 10.25.0.100 ct status dnat accept
		ip saddr {10.25.0.1/24,10.25.40.1/24} accept
		ip daddr {10.25.0.1/24,10.25.40.1/24} accept
	        oif br-internal accept
	        iif br-internal accept
	}

	chain output {
		type filter hook output priority filter; policy accept;
	}
}
table ip nat {
	chain prerouting {
		type nat hook prerouting priority filter; policy accept;

		iif "enp3s0" tcp dport { $TCP_PORT_HTTP, $TCP_PORT_HTTPS } dnat to $HOST_HTTP_PI

		# Forward web traffic to http.pi
		ip daddr { 10.25.0.1/24,144.76.16.40 } tcp dport { $TCP_PORT_HTTP,$TCP_PORT_HTTPS } dnat to $HOST_HTTP_PI

		# Forward mail traffic to mail.pi
		iif "enp3s0" tcp dport { $TCP_PORT_SMTP, $TCP_PORT_SMTPS, $TCP_PORT_IMAPS } dnat to $HOST_MAIL_PI

		iif "enp3s0" tcp dport { $TCP_PORT_QUAKEJS_DS } dnat to $HOST_PLAYGROUND_PI
	}

	chain postrouting {
		type nat hook postrouting priority srcnat; policy accept;
		ip saddr 10.25.0.0/24 oif {"enp3s0", "br-internal"} snat 144.76.16.40
	}
}
nftables.service.d/overwrite.conf
[Unit]
Wants=
Wants=libvirtd.service
Before=
After=libvirtd.service

[Service]
Type=simple
Restart=always
RestartSec=5
pacman -S nftables
systemctl enable --now nftables

libvirtd

libvirt network configuration file

/tmp/net-internal.xml
network connections='6'>
  <name>internal</name>
  <uuid>0a2dff47-afc7-4d27-91b0-5f61a1f5cbaa</uuid>
  <forward mode='bridge'/>
  <bridge name='br-internal'/>
</network>

libvirt qemu hook

pacman -S libvirt virt-install dnsmasq glusterfs
virsh pool-define-as --name 'vg0' --type 'logical' --source-format 'lvm2' --target '/dev/vg0'
virsh pool-autostart vg0
virsh pool-start vg0
virsh net-define /tmp/net-internal.xml
virsh net-start internal
virsh net-autostart internal
systemctl enable --now libvirtd

wireguard

pacman -S wireguard-tools
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey
chmod 600 privatekey
chown root:root privatekey
/etc/systemd/network/99-server.netdev
[NetDev]
Name = wg0
Kind = wireguard
Description = Wireguard

[WireGuard]
ListenPort = 51820
PrivateKey = [PI_SERVER_PRIVKEY]

[WireGuardPeer]
# onny
PublicKey = [ONNY_PUBKEY]
AllowedIPs = 10.25.40.2/32

[WireGuardPeer]
# st
PublicKey = [ST_PUBKEY]
AllowedIPs = 10.25.40.3/32

[WireGuardPeer]
# neutrino
PublicKey = [NEUTRINO_PUBKEY]
AllowedIPs = 10.25.40.4/32

[WireGuardPeer]
# jolla (neutrino)
PublicKey = [JOLLA_PUBKEY]
AllowedIPs = 10.25.40.5/32

[WireGuardPeer]
# picloud (onny)
PublicKey = [PICLOUD_PUBKEY]
AllowedIPs = 10.25.40.6/32
/etc/systemd/network/99-server.network
[Match]
Name = wg0

[Network]
Address = 10.25.40.1/24
DNS=10.25.0.1
DNSSEC=false
IPForward=ipv4

client

pacman -S wireguard-tools
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey
chmod 600 privatekey
chown root:root privatekey
/etc/systemd/network/99-client.netdev
[NetDev]
Name = wg0
Kind = wireguard
Description = Wireguard

[WireGuard]
PrivateKey = [ONNY's PRIVATE KEY]

[WireGuardPeer]
PublicKey = [SERVER PUBLICKEY]
AllowedIPs = 10.25.0.0/16
Endpoint = 2a01:4f8:191:327::2:51820
Endpoint = 144.76.16.40:51820
PersistentKeepalive = 25
/etc/systemd/network/99-client.network
[Match]
Name = wg0

[Network]
Address = 10.25.40.2/16
systemctl restart systemd-networkd

systemd-journal logging server

/etc/systemd/journal-remote.conf
[Remote]
SplitMode=host
/etc/systemd/system/systemd-journal-remote.service
[Unit]
Description=Journal Remote Sink Service
Documentation=man:systemd-journal-remote(8) man:journal-remote.conf(5)
Requires=systemd-journal-remote.socket

[Service]
ExecStart=/lib/systemd/systemd-journal-remote --listen-http=-3 --output=/var/log/journal/remote/
User=systemd-journal-remote
Group=systemd-journal-remote
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
WatchdogSec=3min

[Install]
Also=systemd-journal-remote.socket
mkdir -p /var/log/journal/remote
chown -R systemd-journal-remote:systemd-journal-remote /var/log/journal/remote
pacman -S libmicrohttpd
ufw allow from 10.25.0.0/24 to any proto tcp port 19532
systemctl enable --now systemd-journal-remote

ArchLinux Gastsystem

Erstellen

virt-install --video qxl --channel spicevmc --graphics spice,listen=127.0.0.1 --name=http --vcpus 4 --memory 8048 --disk pool=vg0,size=1000,bus=virtio --cdrom /var/lib/libvirt/images/archlinux-2018.06.01-x86_64.iso --network network:internal,model=virtio --virt-type kvm --autostart --noautoconsole

Löschen

virsh destroy http
virsh undefine http
lvremove /dev/vg0/http

Speicher vergrößern

virsh shutdown http
lvresize -L +20G vg0/http
virsh start http

Auf dem Gastsystem ausführen:

sgdisk -og -a 1024 -n 1:1024:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda
sgdisk -n2:2048:0 -c2:"ArchRoot" -p /dev/vda
shutdown -h now # then start again after that
btrfs filesystem resize max /

Bei neueren Version von libguestfs-tools (>1.16.34) könnte man auch die Partitionstabelle und Dateisystem von dem Host aus resizen und müsste dafür nicht das Gastsystem neustarten.

Backup

Raw backup logical volume to picloud (homeserver onnuex)

lvcreate -s -n playground_snap -L 20G /dev/vg0/playground
dd if=/dev/vg0/playground.img_snap bs=4096 | pv | gpg --batch --passphrase "my_secret_password" --symmetric --compress-algo zlib | ssh picloud@picloud.sexypump.de 'dd of=/mnt/backups/project-insanity/playground_$(date +"%Y-%m-%d").img.gpg bs=4096'
lvremove /dev/vg0/playground_snap

Recover backup

gpg -o /mnt/playground.img -d /mnt/playground.img.gpg

Unfinished backup script:

sas="$1"
password="$2"
 
for vol in `lvs | cut -f3 -d " " | tail -n+2`
	do echo "Backing up $vol"
	lvcreate -s -n "${vol}_snap" -L 20G "/dev/vg0/${vol}"
	pv -cN source "/dev/vg0/${vol}_snap" | gpg --batch --passphrase "${password}" --symmetric --compress-algo zlib | azcopy cp "https://myaccount.blob.core.windows.net/mycontainer/${vol}_$(date +"%Y-%m-%d").img.gpg?${sas}"
	lvremove "/dev/vg0/${vol}_snap"
done

Einrichten

mkfs.btrfs /dev/sda
ifconfig eth0 10.25.0.120 up
route add default gw 10.25.0.1
mount /dev/sda /mnt
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
pacstrap /mnt base base-devel tmux mosh yajl wipe rsync procps neovim lsof strace htop net-tools pkgfile dnsutils iotop aria2 tcpdump nload grub btrfs-progs gptfdisk ntp wget rxvt-unicode-terminfo pwgen mlocate fail2ban pv expac openssh git devtools fish nftables ripgrep bat fd pacman-contrib
genfstab -p /mnt >> /mnt/etc/fstab
arch-chroot /mnt
chsh -s $(which fish)
sed -i 's/^#?SystemMaxUse=.*$/SystemMaxUse=200M/g' /etc/systemd/journald.conf
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/g' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
sed -i 's/^#Color/Color/g' /etc/pacman.conf
mkdir /etc/pacman.d/hooks
ln -s /usr/share/libalpm/hooks/30-systemd-daemon-reload.hook /etc/pacman.d/hooks/
echo "http-pub2" >> /etc/hostname
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
locale-gen
echo 'LANG="en_US.UTF-8"' > /etc/locale.conf
echo "KEYMAP=de" > /etc/vconsole.conf
mkinitcpio -p linux
sed -i '/GRUB_TIMEOUT/s/5/0/' /etc/default/grub
grub-mkconfig -o /boot/grub/grub.cfg
grub-install /dev/sda
passwd
useradd -m onny -s /usr/bin/fish
passwd onny
usermod -a -G sudo onny
sudo -u onny mkdir /home/onny/.ssh
sudo -u onny vim /home/onny/.ssh/authorized_keys
chown -R onny:onny /home/onny
updatedb
pkgfile --update
echo "UserParameter=archlinuxupdates,if [ -d /tmp/pacmandb ]; then fakeroot pacman -Syup --dbpath /tmp/pacmandb | grep "pkg.tar.xz" -c; else mkdir /tmp/pacmandb && ln -s /var/lib/pacman/local /tmp/pacmandb && fakeroot pacman -Syup --dbpath /tmp/pacmandb | grep "pkg.tar.xz" -c; fi" >> /etc/zabbix/zabbix_agentd.conf
sed -i 's/^Server=.*$/Server=http-new.pi/g' /etc/zabbix/zabbix_agentd.conf
systemctl enable --now sshd systemd-networkd nftables fail2ban systemd-resolved
timedatectl set-ntp true
exit
reboot

nftables

/etc/nftables.conf
table inet filter {
        set tcp_accepted {
                type inet_service
                flags interval
                elements = { 22 }
        }

        set udp_accepted {
                type inet_service
                flags interval
                elements = { 60000-61000 }
        }

        chain base_checks {
                ct state { established, related } accept
                ct state invalid drop
        }

        chain input {
                type filter hook input priority filter; policy drop;
                jump base_checks
                iifname "lo" accept
                ip protocol icmp icmp type { echo-reply, destination-unreachable, echo-request, time-exceeded, parameter-problem } accept
                ip6 nexthdr ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply, mld-listener-query, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
                tcp dport @tcp_accepted accept
                udp dport @udp_accepted accept
                reject
        }

        chain forward {
                type filter hook forward priority filter; policy drop;
                jump base_checks
        }

        chain output {
                type filter hook output priority filter; policy accept;
        }
}

systemd-networkd

/etc/systemd/network/ens3.network
[Match]
Name=ens3

[Network]
Address=2a01:4f8:191:327::10/64
Address=10.25.0.100/24
Gateway=10.25.0.1
Gateway=2a01:4f8:191:327::2
DNS=10.25.0.1
DNSSEC=false

LinkLocalAddressing = no
IPv6AcceptRA = no

pacman

project-insanity build server repo

/etc/pacman.conf
[...]

[projectinsanity]
SigLevel = PackageOptional
Server = https://onny.project-insanity.org/archlinux

archlinux auto update

/etc/systemd/system/autoupdate.service
[Unit]
 Description=Automatic Update
 After=network-online.target 

[Service]
 Type=simple
 ExecStart=/usr/bin/pacman -Syuq --noconfirm --needed --noprogressbar 
 TimeoutStopSec=180
 KillMode=process
 KillSignal=SIGINT

[Install]
 WantedBy=multi-user.target
/etc/systemd/system/autoupdate.timer
[Unit]
 Description=Automatic Update when booted up after 5 minutes then check the system for updates every 60 minutes

[Timer]
 OnBootSec=5min
 OnUnitActiveSec=60min
 Unit=autoupdate.service

[Install]
 WantedBy=multi-user.target
systemctl enable --now autoupdate.timer

systemd-journald

systemd logging upload

/etc/systemd/journal-upload.conf
[Upload]
URL=http://10.25.0.1:19532
/etc/systemd/system/systemd-journal-upload.service
[Unit]
Description=Journal Remote Upload Service
Documentation=man:systemd-journal-upload(8)
After=network.target

[Service]
ExecStart=/lib/systemd/systemd-journal-upload --save-state
User=systemd-journal-upload
SupplementaryGroups=systemd-journal
PrivateTmp=yes
PrivateDevices=yes
WatchdogSec=3min

# Add reset/restart options
TimeoutSec=120
Restart=on-failure
RestartSec=2

# Add accounting options
CPUAccounting=true
BlockIOAccounting=true
MemoryAccounting=false
TasksAccounting=true

# If there are many splits up journal files we need a lot of file descriptors to access them all and combine
LimitNOFILE=16384

[Install]
WantedBy=multi-user.target
useradd systemd-journal-upload
mkdir /var/lib/systemd/journal-upload
chown -R systemd-journal-upload:systemd-journal-upload /var/lib/systemd/journal-upload
systemctl enable --now systemd-journal-upload

Maintainance

Update configs

sudo pacdiff

mail.pi

on mail.pi

pacman -S maddy
systemctl enable --now maddy
nft add rule inet filter input position 17 tcp dport smtps accept
nft add rule inet filter input position 17 tcp dport smtp accept
nft add rule inet filter input position 17 tcp dport imaps accept
nft list ruleset > /etc/nftables.conf

on

/etc/maddy/maddy.conf
...
$(hostname) = turbotux.de
...
$(primary_domain) = turbotux.de
...
tls /etc/maddy/certs/$(hostname)/fullchain.pem /etc/maddy/certs/$(hostname)/privkey.pem
...
maddyctl users create postmaster
maddyctl users create onny@turbotux.de

turbotux.de dns record. get dkim key in /var/lib/maddy/dkim-keys/turbotux.de-default.dns

turbotux.de.    A     144.76.16.40
turbotux.de.    AAAA  2a01:4f8:191:327::10
turbotux.de.    MX    10 turbotux.de
turbotux.de.    TXT   "v=spf1 mx -all"
_dmarc.turbotux.de.    TXT    "v=DMARC1; p=none; ruf=postmaster@turbotux.de"
default._domainkey.turbotux.de    TXT   "v=DKIM1; k=ed25519; p=nAcUUozPlhc4VPhp7hZl+owES7j7OlEv0laaDEDBAqg="

forwarding/nat on host.pi

nft add rule inet filter input position 19 tcp dport smtps accept
nft add rule inet filter input position 19 tcp dport smtp accept
nft add rule inet filter input position 19 tcp dport imaps accept
nft add rule ip nat prerouting position 4 iifname "enp3s0" tcp dport imaps dnat to 10.25.0.102
nft add rule ip nat prerouting position 4 iifname "enp3s0" tcp dport smtp dnat to 10.25.0.102
nft add rule ip nat prerouting position 4 iifname "enp3s0" tcp dport smtps dnat to 10.25.0.102
nft list ruleset > /etc/nftables.conf

tls. on mail.pi

chmod +x /var/lib/private
sudo -u maddy ssh-keygen # all default values
cat /var/lib/maddy/.ssh/id_rsa.pub

on http.pi

useradd -m maddy
mkdir /home/maddy/.ssh
vim /home/maddy/.ssh/authorized_keys
setfacl -R -d -m u:maddy:rx /var/lib/caddy/acme/acme-v02.api.letsencrypt.org/sites/t
urbotux.de/turbotux.de.crt /var/lib/caddy/acme/acme-v02.api.letsencrypt.org/sites/turbotux.de/turbotux
.de.key # this does not work so well yet :(

mysql.pi

mariadb

pacman -S mariadb
mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
mysqladmin -u root password 'new-password'
mysql_secure_installation
systemctl enable --now mariadb
nft add rule inet filter input position 17 ip saddr 10.25.0.0/24 tcp dport mysql accept
nft add rule inet filter input position 17 ip6 saddr 2a01:4f8:191:327::0/64 tcp dport mysql accept
nft list ruleset > /etc/nftables.conf
/etc/pacman.d/hooks/40-mariadb.hook
# Restart mariadb service

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = mariadb

[Action]
Description = Restarting mariadb service
When = PostTransaction
Exec = /usr/bin/sh -c "/usr/bin/mysql_upgrade -u root -p'****' && /usr/bin/systemctl restart mariadb"
chmod 600 /etc/pacman.d/hooks/40-mariadb.hook

temporary workaround to get nextcloud to work, see: https://github.com/nextcloud/server/issues/27085

/etc/my.cnf.d/server.cnf
[...]
[server]

innodb_read_only_compressed=0
[...]

postgresql

pacman -S postgresql postgresql-old-upgrade
sudo su - postgres -c "initdb -D /var/lib/postgres/data"
systemctl enable --now postgresql
nft add rule inet filter input position 17 ip saddr 10.25.0.0/24 tcp dport postgresql accept
nft add rule inet filter input position 17 ip6 saddr 2a01:4f8:191:327::0/64 tcp dport postgresql accept
nft list ruleset > /etc/nftables.conf
/var/lib/postgres/data/postgresql.conf
[...]
listen_addresses = '*'
[...]
/var/lib/postgres/data/pg_hba.conf
[...]
host    all             all             10.25.0.0/24            md5
host    all             all             2a01:4f8:191:327::/64           md5
/etc/pacman.d/hooks/postgresql.hook
# Restart postgresql service

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = postgresql

[Action]
Description = Restarting postgresql service
When = PostTransaction
Exec = /usr/bin/systemctl restart postgresql

http.pi

pacman -S caddy dokuwiki gitlab php-fpm php-apcu phpmyadmin wordpress nginx
systemctl enable --now caddy php-fpm
nft add rule inet filter input position 17 tcp dport "{http, https}" accept
nft list ruleset > /etc/nftables.conf
/etc/pacman.d/hooks/php.hook
# Restart php service

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = php
Target = php-fpm

[Action]
Description = Restarting php service
When = PostTransaction
Exec = /usr/bin/systemctl restart php-fpm

custom caddy installation

pacaur -d caddy
~/.cache/pacaur/caddy/PKGBUILD
[...]
#    'http.hugo'
    'http.ipfilter'
#    'http.jekyll'
[...]
cd ~/.cache/pacaur/caddy
makepkg -i --skipinteg
/etc/systemd/system/caddy.service.d/override.conf
[Service]
ProtectHome=false

caddy

pacman -S caddy
gpasswd -a caddy http
/etc/caddy/Caddyfile
import /etc/caddy/conf.d/*
/etc/caddy/conf.d/ausstellung-virtuell.de.conf
www.ausstellung-virtuell.de ausstellung-virtuell.de {

        log {
                output file     /var/log/caddy/ausstellung-virtuell.de.log
                format single_field common_log
        }

    reverse_proxy http://http-pub.pi

}
/etc/caddy/conf.d/blog.project-insanity.org.conf
blog.project-insanity.org {

        root    * /usr/share/webapps/wordpress
        file_server
        log {
                output file     /var/log/caddy/blog.project-insanity.org.log
                format single_field common_log
        }

        php_fastcgi unix//var/run/php-fpm/php-fpm.sock

    @uploads {
          path_regexp path /uploads\/(.*)\.php
        }
        rewrite @uploads /

        @wp-admin {
          path  not ^\/wp-admin/*
        }
        rewrite @wp-admin {path}/index.php?{query}

}
/etc/caddy/conf.d/git.project-insanity.org.conf
git.project-insanity.org {

        log {
                output file     /var/log/caddy/git.project-insanity.org.log
                format single_field common_log
        }

    reverse_proxy unix//run/gitlab/gitlab-workhorse.socket

}
/etc/caddy/conf.d/jhartung.sinewell.de.conf
jhartung.sinewell.de {

        log {
                output file     /var/log/caddy/jhartung.sinewell.de.log
                format single_field common_log
        }

    reverse_proxy https://wrsmtwhrearj2wyg.myfritz.net:46190

}
/etc/caddy/conf.d/nextcloud.project-insanity.org.conf
nextcloud.project-insanity.org {

        root    * /usr/share/webapps/nextcloud
        file_server
        log {
                output file     /var/log/caddy/nextcloud.project-insanity.org.log
                format single_field common_log
        }

        php_fastcgi unix//var/run/php-fpm/php-fpm.sock {
                env front_controller_active true
        }

        header {
                # enable HSTS
                Strict-Transport-Security max-age=31536000;
        }

        redir /.well-known/carddav /remote.php/dav 301
        redir /.well-known/caldav /remote.php/dav 301

        # .htaccess / data / config / ... shouldn't be accessible from outside
        @forbidden {
                path    /.htaccess
                path    /data/*
                path    /config/*
                path    /db_structure
                path    /.xml
                path    /README
                path    /3rdparty/*
                path    /lib/*
                path    /templates/*
                path    /occ
                path    /console.php
        }

        respond @forbidden 404

}
/etc/caddy/conf.d/onny.project-insanity.org.conf
onny.project-insanity.org {

        log {
                output file     /var/log/caddy/onny.project-insanity.org.log
                format single_field common_log
        }

    reverse_proxy http://http-pub.pi

}
/etc/caddy/conf.d/wiki.project-insanity.org.conf
wiki.project-insanity.org {

        root    * /usr/share/webapps/dokuwiki
        file_server
        log {
                output file     /var/log/caddy/wiki.project-insanity.org.log
                format single_field common_log
        }

    encode zstd gzip
        php_fastcgi unix//var/run/php-fpm/php-fpm.sock

    @restrict_files {
      path /data/* /conf/* /bin/* /inc/* /vendor/* /install.php
    }
    respond @restrict_files 404

        @allow_media {
          path_regexp path ^/_media/(.*)$
        }
        rewrite @allow_media /lib/exe/fetch.php?media=/{http.regexp.path.1}

    @allow_detail   {
      path /_detail*
    }
    rewrite @allow_detail /lib/exe/detail.php?media={path}

    @allow_export   {
      path /_export*
      path_regexp export /([^/]+)/(.*)
    }
    rewrite @allow_export /doku.php?do=export_{http.regexp.export.1}&id={http.regexp.export.2}

    try_files {path} {path}/ /doku.php?id={path}&{query}
}
/etc/caddy/conf.d/http.pi.conf
http://http.pi {

        root    * /var/www
        file_server * browse
        log {
                output file     /var/log/caddy/http.pi.log
                format single_field common_log
        }

        php_fastcgi unix//var/run/php-fpm/http.pi_php-fpm.sock
}
/etc/caddy/conf.d/saai.digital
beta.saai.digital {

        log {
                output file     /var/log/caddy/saai.digital.log
                format single_field common_log
        }

    reverse_proxy http://playground.pi:8080

}
/etc/caddy/conf.d/office.project-insanity.org.conf
office.project-insanity.org {

        log {
                output file     /var/log/caddy/office.project-insanity.org.log
                format single_field common_log
        }

    # Routing Onlyoffice Spellchecker
    route /spellchecker/* {
        uri strip_prefix /spellchecker
        reverse_proxy localhost:8081
    }

    # Routing Onlyoffice Documentserver etc.
        @onlyoffice {
          path_regexp path ^/(cache|downloadas|sdkjs|plugins.json|fonts|web-apps|upload|doc|healthcheck|coauthoring|ConvertService.ashx)
        }
        rewrite @onlyoffice /proxy/{uri}
    route /proxy/* {
        uri strip_prefix /proxy/
        reverse_proxy localhost:8000
    }

    # Route to Officepad
    reverse_proxy / http://localhost:8082

}

need to convert

/etc/caddy/conf.d/turbotux.de.conf
www.turbotux.de turbotux.de {
    log /var/log/caddy/turbotux.de_access.log
    errors /var/log/caddy/turbotux.de_errors.log
    gzip
    tls onny@project-insanity.org
    proxy / http://picloud.sexypump.de:8096 {
        websocket
    }
}

php-fpm

cp /etc/php/php-fpm.d/www.conf /etc/php/php-fpm.d/http.pi.conf
/etc/php/php-fpm.d/www.conf
[...]
pm.max_children = 16
[...]
pm.start_servers = 9
[...]
pm.max_spare_servers = 10
[...]
;env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
[...]
/etc/php/php-fpm.d/http.pi.conf
[...]
[http.pi]
[...]
listen = /run/php-fpm/http.pi_php-fpm.sock
[...]
/etc/systemd/system/php-fpm.service.d/overwrite-rw-path.conf
[Service]
ReadWritePaths = /usr/share/webapps/nextcloud/data
ReadWritePaths = /usr/share/webapps/nextcloud/apps
ReadWritePaths = /etc/webapps/nextcloud/config/
ReadWritePaths = /usr/share/webapps/wordpress/wp-content
ReadWritePaths = /usr/share/webapps/invoiceplane/vendor/mpdf/mpdf/tmp
ReadWritePaths = /usr/share/webapps/invoiceplane/uploads/archive
ReadWritePaths = /usr/share/webapps/invoiceplane/uploads/customer_files

wordpress

pacman -S wordpress wp-cli wordpress-plugin-antispam-bee wordpress-plugin-code-syntax-block wordpress-plugin-jetpack-lite wordpress-plugin-lightbox-photoswipe wordpress-plugin-wp-gdpr-compliance wordpress-plugin-wp-statistics wordpress-plugin-co-authors-plus wordpress-theme-geist wordpress-plugin-wp-user-avatar wordpress-plugin-opengraph wordpress-plugin-simple-login-captcha wordpress-plugin-disable-xml-rpc wordpress-plugin-async-javascript wordpress-plugin-breeze wordpress-plugin-webp-converter-for-media
chown -R http:http /usr/share/webapps/wordpress/wp-admin /usr/share/webapps/wordpress/wp-includes
/etc/php/conf.d/wordpress.ini
extension=mysqli
/home/pi_wordpress/wordpress/wp-config.php
define('DB_NAME', '****');
define('DB_USER', '****');
define('DB_PASSWORD', '****');
define('DB_HOST', '****');
[...]
define('AUTH_KEY',         '****');
define('SECURE_AUTH_KEY',  '****');
define('LOGGED_IN_KEY',    '****');
define('NONCE_KEY',        '****');
define('AUTH_SALT',        '****');
define('SECURE_AUTH_SALT', '****');
define('LOGGED_IN_SALT',   '****');
define('NONCE_SALT',       '****');
[...]
define('FORCE_SSL_ADMIN', true);
define('FS_METHOD', 'direct');
define( 'WP_SITEURL','https://blog.project-insanity.org');
define( 'WP_HOME','https://blog.project-insanity.org');
$_SERVER['HTTPS']='on';
define( 'WP_AUTO_UPDATE_CORE', true );
/etc/pacman.d/hooks/wordpress.hook
# Update Wordpress when core or plugins get updated

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = wordpress
Target = wordpress-plugin-*

[Action]
Description = Updating Wordpress installation
When = PostTransaction
Exec = /usr/bin/sh -c "/usr/bin/sudo -u http /usr/bin/bash -c 'wp core update-db --path=/usr/share/webapps/wordpress; wp plugin activate --path=/usr/share/webapps/wordpress antispam-bee code-syntax-block jetpack jetpack-lite lightbox-photoswipe wp-gdpr-compliance wp-statistics co-authors-plus wp-user-avatar opengraph simple-login-captcha disable-xml-rpc async-javascript breeze webp-converter-for-media'"
sudo -u http wp plugin activate --path=/usr/share/webapps/wordpress antispam-bee code-syntax-block jetpack jetpack-lite lightbox-photoswipe wp-gdpr-compliance wp-statistics co-authors-plus wp-user-avatar opengraph simple-login-captcha disable-xml-rpc async-javascript breeze webp-converter-for-media
sudo -u http wp theme activate --path=/usr/share/webapps/wordpress geist

Additional CSS for Geist theme

@media (max-width: 1400px) {
	.single-post .post-content > p:first-child {
		font-size: 1em;
	}
 
	.single-post .post-content > p, ul {
		font-size: 0.8em;
	}
 
	.single-post .post-content > h3 {
		padding-bottom: 0.8em;
	}

Misc settings

  • WP Statistics
    • Settings → privacy: “Hash IP Addresses” (GDPR)
  • Lightbox with PhotoSwipe
    • Enable “Show caption if available”
    • Enable “Get image captions from the database”
    • Spacing between pictures: 12%
  • Settings → Permalinks → Custom structure: /%year%/%monthnum%/%day%/%postname%/
  • Settings → General → 8 posts per page
  • Settings → Discussion → Show avatar
    • Default Avatar → Mytery Man
  • Users → Your Profile → Avatar: Choose picture
  • Dark mode is not enabled by default. To enable this feature go to Appearance > Customize > Dark Mode.

Additional CSS for Ghost theme:

@media (max-width: 1400px) {
	.single-post .post-content > p:first-child {
		font-size: 1em;
	}
 
	.single-post .post-content > p, ul {
		font-size: 0.8em;
	}
 
	.single-post .post-content > h3 {
		padding-bottom: 0.8em;
	}
}
 
.post-full-content h2 {
	margin-bottom: 0.8em;
}

co-authors-plus plugin

template-Anpassung
How to Add Multiple Authors (Co-Authors) for Posts in WordPress

/home/pi_wordpress/wordpress/functions-content.php
if ( function_exists( 'coauthors_posts_links' ) ) {
    coauthors_posts_links();
} else {
    the_author_posts_link();
}

invoiceninja

on mysql.pi

CREATE SCHEMA `ninja` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'ninja'@'http.pi' IDENTIFIED BY '****';
GRANT ALL PRIVILEGES ON `ninja`.* TO 'ninja'@'http.pi';
FLUSH PRIVILEGES;

on http.pi

pacman -S invoiceninja
/etc/php/conf.d/composer.ini
extension=gmp
cd /usr/share/webapps/invoiceninja
sudo chown -R http:http storage public/logo bootstrap
sudo chown http:http .
sudo -u http composer install
/etc/caddy/conf.d/http.pi.conf
http://http.pi/invoiceninja {
        log /var/log/caddy/http.pi_access.log
        errors /var/log/caddy/http.pi_errors.log
        gzip

        tls off
        root /usr/share/webapps/invoiceninja/public
        browse

        rewrite {
                r .*
                ext /
                to /index.php?{query}
        }

        fastcgi / /var/run/php-fpm/http.pi_php-fpm.sock php {
                index index.php index.htm index.html
        }
}
[...]

Settings

  • Localization
    • Currency: Euro
    • Timezone: Berlin
    • Date Format: 31.12.2019
    • Date/Time Format: 31.12.2019 12:00 am
    • 24 Hour Time: Enabled
    • First Day of the Week: Monday
    • First Month of the Year: January

invoiceplane

pacman -S invoiceplane composer grunt-cli
cd /usr/share/webapps/invoiceplane
chown -R http:http .
sudo -u http composer install
sudo -u http npm install
sudo -u http grunt build
cp ipconfig.php.example ipconfig.php
wget "https://git.project-insanity.org/onny/invoiceplane-vtdirektmarketing/-/raw/master/vtdirektmarketing.php" -O /usr/share/webapps/invoiceplane/application/views/invoice_templates/pdf/vtdirektmarketing.php

Visit installation wizard at http://http.pi/invoiceplane/index.php/setup

/usr/share/webapps/invoiceplane/ipconfig.php
[...]
SETUP_COMPLETED=true
DB_HOSTNAME=mysql.pi
DB_USERNAME=invoiceplane
DB_PASSWORD=****
DB_DATABASE=invoiceplane
DISABLE_SETUP=true
/etc/systemd/system/php-fpm.service.d/overwrite-rw-path.conf
[Service]
[...]
ReadWritePaths = /usr/share/webapps/invoiceplane/vendor/mpdf/mpdf/tmp
ReadWritePaths = /usr/share/webapps/invoiceplane/uploads/archive
ReadWritePaths = /usr/share/webapps/invoiceplane/uploads/customer_files

Custom settings

  • Products → Product units
    • Add: Stk., Std.
  • System-Einstellungen → Rechnungen
    • Standard PDF Vorlage: vtdirektmarketing

firefox account server

pacaur -S mozilla-firefox-account-server

podcasttune

not yet stable

dokuwiki

pacman -S dokuwiki dokuwiki-plugin-dw2pdf dokuwiki-template-argon
/etc/webapps/dokuwiki/local.php
<?php
$conf['title'] = 'Project-Insanity';
$conf['userewrite']  = 1;
$conf['template']    = 'argon';
/usr/lib/dokuwiki/plugins/dw2pdf/conf/default.php
[...]
$conf['doublesided']      = 0;
[...]
/usr/lib/dokuwiki/plugins/dw2pdf/tpl/default/style.css
@page {
    margin-left: 100px;
}

[...]

usage: https://wiki.project-insanity.org/onny?do=export_pdf

  • Todo
    • DSGVO complience

gitlab

pacman -S yarn sendmail gitlab
ln -s /usr/bin/vendor_perl/exiftool /usr/bin/exiftool # fix for https://gitlab.com/gitlab-org/gitlab-foss/-/issues/60853

disable backups

/etc/webapps/gitlab/gitlab.yml
[...]
  gitlab:
    ## Web server settings (note: host is the FQDN, do not include http://)
    host: git.project-insanity.org
    port: 443 # Set to 443 if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
    https: true # Set to true if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
[...]
  #backup:
  #  path: "/var/lib/gitlab/backups"   # Relative paths are relative to Rails.root (default: tmp/backups/)

configure database connection

/etc/webapps/gitlab/database.yml
production:
  adapter: postgresql
  encoding: unicode
  database: gitlabhq_production
  pool: 10
  username: gitlab
  password: "****"
  host: mysql.pi

on mysql.pi

sudo -u postgres psql -d template1 -c "CREATE USER gitlab CREATEDB;"
sudo -u postgres psql -d template1 -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
sudo -u postgres psql -d template1 -c "CREATE DATABASE gitlabhq_production OWNER gitlab;"
sudo -u postgres psql -d template1 -c "ALTER USER gitlab WITH SUPERUSER;"

on http.pi

 cd /usr/share/webapps/gitlab
 sudo -u gitlab -H bundle exec rake assets:precompile RAILS_ENV=production
 sudo -u gitlab -H bundle exec rake gitlab:setup RAILS_ENV=production
 systemctl enable --now gitlab-workhorse redis gitlab-puma gitlab-sidekiq gitlab-gitaly

Enable smtp, mail delivery

/etc/webapps/gitlab/smtp_settings.rb
# To enable smtp email delivery for your GitLab instance do the following:
# 1. Rename this file to smtp_settings.rb
# 2. Edit settings inside this file
# 3. Restart GitLab instance
#
# For full list of options and their values see http://api.rubyonrails.org/classes/ActionMailer/Base.html
#
# If you change this file in a Merge Request, please also create a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests
 
if Rails.env.production?
  Rails.application.config.action_mailer.delivery_method = :smtp
 
  ActionMailer::Base.delivery_method = :smtp
  ActionMailer::Base.smtp_settings = {
    address: "mail.pi",
    port: 25,
    user_name: "git@project-insanity.org",
    password: "****",
    domain: "project-insanity.org",
    authentication: :login,
    enable_starttls_auto: false,
    openssl_verify_mode: 'none'
  }
end

further general mail settings

/etc/webapps/gitlab/gitlab.yml
   ## Email settings
    # Uncomment and set to false if you need to disable email sending from GitLab (default: true)
    email_enabled: true
    # Email address used in the "From" field in mails sent by GitLab
    email_from: noreply@project-insanity.org
    email_display_name: GitLab
    email_reply_to: noreply@project-insanity.org
    email_subject_suffix: ''

Auto migrate on pacman update

/etc/pacman.d/hooks/gitlab.hook
# Update Gitlab when core or other Gitlab daemons are touched

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = gitlab
Target = gitlab-*

[Action]
Description = Updating Gitlab installation
When = PostTransaction
Exec = /usr/bin/sh -c "/usr/bin/systemctl restart gitlab-workhorse gitlab-puma gitlab-sidekiq gitlab-gitaly && cd /usr/share/webapps/gitlab && /usr/bin/sudo -u gitlab $(cat /usr/share/webapps/gitlab/environment | xargs) /usr/bin/bash -c 'cd /usr/share/webapps/gitlab; bundle-2.7 exec rake db:migrate'"
/etc/webapps/gitlab/secrets.yml
****
hexdump -v -n 64 -e '1/1 "%02x"' /dev/urandom > /etc/webapps/gitlab/secret
hexdump -v -n 64 -e '1/1 "%02x"' /dev/urandom > /etc/webapps/gitlab-shell/secret
chown root:gitlab /etc/webapps/gitlab/secret /etc/webapps/gitlab-shell/secret
chmod 640 /etc/webapps/gitlab/secret /etc/webapps/gitlab-shell/secret

misc settings:

onlyoffice documentserver

pacman -S npm nodejs rabbitmq redis onlyoffice-documentserver
ln -s /usr/share/libalpm/hooks/onlyoffice-documentserver.hook /etc/pacman.d/hooks/

on mysql.pi

sudo -i -u postgres psql -c "CREATE DATABASE onlyoffice;"
sudo -i -u postgres psql -c "CREATE USER onlyoffice WITH password 'onlyoffice';"
sudo -i -u postgres psql -c "GRANT ALL privileges ON DATABASE onlyoffice TO onlyoffice;"
psql -hmysql.pi -Uonlyoffice -d onlyoffice -f /usr/share/webapps/onlyoffice/documentserver/server/schema/postgresql/createdb.sql
/etc/caddy/conf.d/office.project-insanity.org.conf
office.project-insanity.org {
    log /var/log/caddy/office.project-insanity.org_access.log
    errors /var/log/caddy/office.project-insanity.org_errors.log

    proxy /spellchecker http://localhost:8081 {
        transparent
        websocket
        without /spellchecker
    }

    rewrite {
        r ^/(cache|downloadas|sdkjs|plugins.json|fonts|web-apps|upload|doc)/
        to /proxy/{uri}
    }

    proxy /proxy/ http://localhost:8000 {
        websocket
        transparent
        without /proxy/
    }

    proxy / http://localhost:8082 {
        transparent
    }
}
/etc/webapps/onlyoffice/documentserver/default.json
[...]
                        "sql": {
                                "type": "postgres",
                                "tableChanges": "doc_changes",
                                "tableResult": "task_result",
                                "dbHost": "mysql.pi",
                                "dbPort": 5432,
                                "dbName": "onlyoffice",
                                "dbUser": "onlyoffice",
                                "dbPass": "onlyoffice",
                                "charset": "utf8",
                                "connectionlimit": 10,
                                "max_allowed_packet": 1048575
                        },
[...]
       "SpellChecker": {
                "server": {
                        "port": 8081,
                        "mode": "development"
                }
        }
/etc/hosts
10.25.0.100 nextcloud.project-insanity.org
systemctl enable --now rabbitmq redis onlyoffice-docservice onlyoffice-fileconverter onlyoffice-spellchecker

officepad

/etc/systemd/system/officepad.service
[Unit]
Description=Documentserver integration example

[Service]
User=http
WorkingDirectory=/usr/share/webapps/officepad
ExecStart=/usr/bin/node bin/www

[Install]
WantedBy=basic.target
sudo git clone git clone https://git.project-insanity.org/onny/officepad.git /usr/share/webapps/officepad
sudo chown -R http:http /usr/share/webapps/officepad
systemd daemon-reload
systemctl enable --now officepad
/usr/share/webapps/officepad/config/default.json
[...]
siteUrl": "https://bwsas-prod-oo-02.lsdf.kit.edu/"
[...]

nextcloud

pacman -S php-imagick php-intl nextcloud nextcloud-app-twofactor-gateway nextcloud-app-audioplayer nextcloud-app-polls nextcloud-app-extract nextcloud-app-suspicious-login nextcloud nextcloud-app-mail nextcloud-app-news nextcloud-app-calendar nextcloud-app-contacts nextcloud-app-keeweb nextcloud-app-deck nextcloud-app-onlyoffice nextcloud-app-bookmarks nextcloud-app-notes nextcloud-app-talk nextcloud-integration-github nextcloud-integration-twitter nextcloud-integration-reddit nextcloud-integration-discourse nextcloud-app-radio nextcloud-app-podcast
/etc/php/php-fpm.d/www.conf
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

php performance optimizations

/etc/php/conf.d/nextcloud.ini
memory_limit = 512M

extension=gd
extension=pdo_mysql
extension=apcu
extension=intl
extension=iconv
extension=imagick
extension=bcmath

# Nextcloud recommended performance settings
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1

apc.enable_cli=1
/usr/share/webapps/nextcloud/conf/config.php
<?php
$CONFIG = array (
  'instanceid' => '****',
  'passwordsalt' => '****',
  'datadirectory' => '/usr/share/webapps/nextcloud/data',
  'dbtype' => 'mysql',
  'version' => '19.0.0.12',
  'dbname' => 'nextcloud',
  'dbhost' => 'mysql.pi',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nextcloud',
  'dbpassword' => '****',
  'installed' => true,
  'theme' => '',
  'maintenance' => false,
  'loglevel' => 0,
  'cron_log' => true,
  'maxZipInputSize' => 5145728000,
  'allowZipDownload' => true,
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'allow_local_remote_servers' => true,
  'trusted_domains' => 
  array (
    0 => 'nextcloud.project-insanity.org',
    1 => 'http.pi',
    2 => 'office.project-insanity.org',
  ),
  'secret' => '****',
  'mail_domain' => 'project-insanity.org',
  'mail_smtpmode' => 'php',
  'mail_from_address' => 'nextcloud',
  'trashbin_retention_obligation' => 'auto',
  'updatechecker' => false,
  'has_internet_connection' => false,
  'app.mail.verify-tls-peer' => false,
  'app_install_overwrite' => 
  array (
    0 => 'apporder',
    1 => 'keeweb',
    2 => 'tasks',
    3 => 'weather',
    4 => 'audioplayer',
    5 => 'files_ebookreader',
    6 => 'extract',
    7 => 'polls',
    8 => 'onlyoffice',
    9 => 'drawio',
  ),
);

Due to packaging bug and hardened php-fpm.service file, an unit file overwrite is required:

/etc/systemd/system/php-fpm.service.d/overwrite-rw-path.conf
[Service]
[...]
ReadWritePaths = /usr/share/webapps/nextcloud/data
ReadWritePaths = /usr/share/webapps/nextcloud/apps
ReadWritePaths = /etc/webapps/nextcloud/config/
ReadWritePaths = /usr/share/webapps/wordpress/wp-content

Auto upgrade on pacman update

ln -sv /usr/share/doc/nextcloud/nextcloud.hook /etc/pacman.d/hooks/
/etc/pacman.d/hooks/nextcloud-enable-apps.hook
# Update Nextcloud when core or -apps are touched

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = nextcloud
Target = nextcloud-app-*

[Action]
Description = Updating Nextcloud installation
When = PostTransaction
Exec = /usr/bin/sh -c "/usr/bin/chown -R nextcloud:nextcloud /usr/share/webapps/nextcloud/apps && /usr/bin/sudo -u nextcloud /usr/bin/php /usr/share/webapps/nextcloud/occ app:enable twofactor_gateway audioplayer polls extract suspicious_login mail news calendar contacts keeweb deck onlyoffice bookmarks notes talk integration_github integration_twitter integration_reddit integration_discourse radio podcast"

Nextcloud background job (cron)

[Unit]
Description=Nextcloud cron.php job
 
[Service]
User=nextcloud
ExecStart=/usr/bin/php -f /usr/share/webapps/nextcloud/cron.php
 
[Install]
WantedBy=basic.target
/etc/systemd/system/nextcloudcron.timer
[Unit]
Description=Run Nextcloud cron.php every 15 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Unit=nextcloudcron.service

[Install]
WantedBy=timers.target
systemctl enable --now nextcloudcron.timer

Add additional mimetype for keeweb app

cd /usr/share/webapps/nextcloud
cp resources/config/mimetypemapping.dist.json config/mimetypemapping.json

add kdbx line to json config

/usr/share/webapps/nextcloud/config/mimetypemapping.json
[...]
        "_comment4": "Any changes you make here will be overwritten on an update of Nextcloud",
        "_comment5": "Put any custom mappings in a new file mimetypemapping.json in the config/ folder of Nextcloud",

        "kdbx": ["x-application/kdbx"],
        "3gp": ["video/3gpp"],
        "7z": ["application/x-7z-compressed"],
[...]
occ app:enable twofactor_gateway audioplayer polls extract suspicious_login mail news calendar contacts keeweb deck onlyoffice bookmarks notes talk integration_github integration_twitter integration_reddit integration_discourse radio podcast

mail

disable ssl verification of imap/smpt host

/usr/share/webapps/nextcloud/config/config.php
[...]
  'app.mail.verify-tls-peer' => false,
[...]

twofactor_gateway

disposible phone number registration http://www.getsmscode.com

/etc/webapps/signal-web-gateway/config.yml
[...]
tel: "+1774****"
[...]
cd /usr/share/webapps/nextcloud
sudo -u http ./occ twofactorauth:gateway:configure signal # leave default options (press return)
cd /var/lib/signal-web-gateway
sudo -u signal signal-web-gateway # enter verification
systemctl enable --now signal-web-gateway
  • Activate 2FA in Settings → Security (User)
    • Enter your phone number and press verify

onlyoffice

mantainance

Run file integrity checks

sudo -u http /usr/share/webapps/nextcloud/occ integrity:check-app
sudo -u http /usr/share/webapps/nextcloud/occ integrity:check-core
sudo -u http /usr/share/webapps/nextcloud/occ files:scan --all

phpmyadmin

/etc/webapps/phpmyadmin/config.inc.php
[...]
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'mysql.pi';
$cfg['Servers'][$i]['compress'] = false;
[...]

cockpit

pacman -S cockpit
systemctl enable --now cockpit pmcd
useradd -m cockpit
passwd cockpit
nft add rule inet filter input position 17 ip saddr 10.25.40.0/24 tcp dport 9090 accept
nft add rule inet filter input position 17 ip6 saddr 2a01:4f8:191:327::0/64 tcp dport 9090 accept
nft list ruleset > /etc/nftables.conf
/etc/sudoers
[...]
cockpit ALL=(ALL) ALL
[...]
/etc/pam.d/cockpit
#%PAM-1.0

auth      required  pam_unix.so     try_first_pass nullok
auth      optional  pam_permit.so
auth      required  pam_env.so

account   required  pam_unix.so
account   optional  pam_permit.so
account   required  pam_time.so

password  required  pam_unix.so     try_first_pass nullok sha512 shadow
password  optional  pam_permit.so

session   required  pam_limits.so
session   required  pam_unix.so
session   optional  pam_permit.so

outline

on http.pi

pacman -S outline
/etc/webapps/outline/.env
[...]
SECRET_KEY=****
DATABASE_URL=postgres://outline:outline@mysql.pi:5432/outline
REDIS_URL=redis://localhost:6379
URL=http://playground.pi:3000
FORCE_HTTPS=false

on mysql.pi

sudo -i -u postgres psql -c "CREATE DATABASE outline;"
sudo -i -u postgres psql -c "CREATE USER outline WITH password 'outline';"
sudo -i -u postgres psql -c "GRANT ALL privileges ON DATABASE outline TO outline;"

on http.pi

cd /usr/share/webapps/outline
npm run sequelize:migrate
systemctl enable --now outline

storage.pi

kol ha campus archive radio stream

pacman -S vlc pulseaudio
/etc/systemd/system/106fm_archive_stream.service
[Unit]
Description=160fm.co.il archive radio stream server
After=network-online.target 

[Service]
User=onny
Type=simple
ExecStart=/usr/bin/cvlc -A pulse,none /home/onny/bash-kolhaas-archive/archived --loop --random --sout-keep --sout '#transcode{acodec=opus}:duplicate{dst=display{delay=6000},dst=gather:std{mux=ffmpeg{mux=opus},dst=:8080,access=http},select="novideo"}'
Restart=on-abort

[Install]
WantedBy=multi-user.target
/usr/lib/systemd/system/pulseaudio.service
[Unit]
Description=PulseAudio system server

[Service]
ExecStart=/usr/bin/pulseaudio --system --daemonize=no --disallow-exit --log-target=journal
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target
/usr/share/dbus-1/system.d/pulseaudio.conf
<?xml version="1.0"?> <!--*-nxml-*-->
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
    <policy group="pulse">
        <allow own="org.pulseaudio.Server"/>
    </policy>

    <policy context="default">
        <allow send_destination="org.pulseaudio.Server"/>
        <allow receive_sender="org.pulseaudio.Server"/>
    </policy>
</busconfig>
echo "default-server = /var/run/pulse/native" >> /etc/pulse/client.conf
echo "autospawn = no" >> /etc/pulse/client.conf
systemctl daemon-reload
groupadd --system pulse
groupadd --system pulse-access
useradd --system -g pulse -G audio -d /var/run/pulse -m pulse
gpasswd -a onny audio,pulse-acces
systemctl enable --now pulseaudio 106fm_archive_stream
nft add rule inet filter input position 17 ip saddr 10.25.0.0/24 tcp dport 8080 accept
nft add rule inet filter input position 17 ip6 saddr 2a01:4f8:191:327::0/64 tcp dport 8080 accept
nft list ruleset > /etc/nftables.conf

also added a caddy rule on http.pi for the url: https://blog.project-insanity.org/106fm

bitcoind

pacman -S bitcoin-daemon
systemctl start bitcoind
systemctl enable bitcoind
ufw allow from 10.25.0.0/24 to any port 8333

https://bitcoin.stackexchange.com/a/75312

playground.pi

pacman -S devtools

beta.saai.digital

pacman -S iptables-nft
/etc/nftables.conf
[...]
chain forward {
  type filter hook forward priority security; policy drop;
  mark 1 accept
[...]
table ip filter {
  chain DOCKER-USER {
    mark set 1
  }
}
systemctl enable --now docker

QuakeJS

pacman -S quakejs-git
cd /usr/share/webapps/quakejs
chown -R quakejs:quakejs .
sudo -u quakejs node build/ioq3ded.js +set fs_game baseq3 +set dedicated 2
/etc/conf.d/quakejs
QUAKEJS_DS_PARAMS="+set fs_cdn cdn.quake.turbotux.de +set fs_game baseq3 +set dedicated 1 +exec server.cfg"
/usr/share/webapps/quakejs/base/baseq3/server.cfg
seta sv_hostname "Project-Insanity.org QuakeJS"
seta sv_maxclients 12
seta g_motd "Welcome to PI Quake 3 battleground"
seta g_quadfactor 3
seta g_gametype 0
seta timelimit 15
seta fraglimit 25
seta g_weaponrespawn 3
seta g_inactivity 3000
seta g_forcerespawn 0
seta rconpassword "CHANGE_ME"
set d1 "map q3dm17 ; set nextmap vstr d2"
set d2 "map q3tourney3 ; set nextmap vstr d3"
set d3 "map q3tourney1 ; set nextmap vstr d1"
vstr d1
/etc/webapps/quakejs/web.json
{ 
        "content": "cdn.quake.turbotux.de",
        "port": 8081
}
systemctl enable --now quakejs-ds quakejs quakejs-cdn

PI ArchLinux Repository

build and install auruitls from source

cd /tmp
curl "https://aur.archlinux.org/cgit/aur.git/snapshot/aurutils.tar.gz" | tar xz
cd aurutils
gpg --recv-keys DBE7D3DD8C81D58D0A13D0E76BC26A17B9B7018A 
makepkg -i
pacman --root=/var/lib/aurbuild/x86_64/root -S git
pacman --root=/var/lib/aurbuild/x86_64/root -S python2-setuptools # workaround for zeronet -> python-pyelliptic
pacman --root=/var/lib/aurbuild/x86_64/root -S wayland # workaround for dmenu-wayland-git
sudo /usr/share/devtools/pacman-extra.conf /etc/aurutils/pacman-projectinsanity.conf

configure custom repository

/etc/pacman.conf
[...]
Include = /etc/pacman.d/projectinsanity
/etc/pacman.d/projectinsanity
[options]
CacheDir = /var/cache/pacman/pkgwf
CacheDir = /var/cache/pacman/projectinsanity
CleanMethod = KeepCurrent

[aur]
SigLevel = Optional TrustAll
Server = file:///var/cache/pacman/projectinsanity
/etc/suders
[...]
aur ALL = NOPASSWD: SETENV: /usr/bin/makechrootpkg
aur ALL = NOPASSWD: /usr/bin/arch-nspawn
[...]
sudo useradd -m aur
sudo install -d /var/cache/pacman/projectinsanity -o aur
sudo repo-add /var/cache/pacman/projectinsanity/projectinsanity.db.tar
sudo chown -R aur:aur /var/cache/pacman/projectinsanity
sudo -u aur gpg --recv-keys 6BC26A17B9B7018A
sudo -u aur gpg --recv-keys 1D1F0DC78F173680
/etc/systemd/system/aurupdate.service
[Unit]
 Description=Automatic update AUR repository.
 After=network-online.target 

[Service]
 Type=simple
 User=aur
 ExecStart=/usr/bin/pi-archlinuxrepo-update.sh
 TimeoutStopSec=180
 KillMode=process
 KillSignal=SIGINT

[Install]
 WantedBy=multi-user.target
/usr/bin/pi-archlinuxrepo-update.sh
#!/bin/bash
for package in $(pacman -Sql projectinsanity) 
do
  aur sync --no-view -c $package
done
/etc/systemd/system/aurupdate.timer
[Unit]
 Description=Automatic update AUR repository when booted up after 5 minutes then check for updates every 60 minutes.

[Timer]
 OnBootSec=5min
 OnUnitActiveSec=120min
 Unit=aurupdate.service

[Install]
 WantedBy=multi-user.target
systemctl enable --now aurupdate.timer
sudo -u aur gpg --recv-keys 2A349DD577D586A5
sudo -u aur aur sync -d projectinsanity -c librewolf pkgbuild-introspection tor-browser-en r128gain split2flac id3ted redshift-wlr-gamma-control-git krop wcalc anbox-git ocenaudio-bin smloadr soulseekqt aurutils downgrade maddy wp-cli wordpress-plugin-antispam-bee wordpress-plugin-code-syntax-block wordpress-plugin-jetpack-lite wordpress-plugin-lightbox-photoswipe wordpress-plugin-wp-gdpr-compliance wordpress-plugin-wp-statistics jellyfin onlyoffice-documentserver nextcloud-app-twofactor-gateway nextcloud-app-audioplayer nextcloud-app-polls nextcloud-app-extract nextcloud-app-suspicious-login nextcloud-app-keeweb nextcloud-app-radio nextcloud-app-onlyoffice fdroidserver android-sdk android-sdk-build-tools gplaycli vlc-bittorrent qlcplus signal-web-gateway-git invoiceninja invoiceplane python-gspread-git etcher zeronet teamviewer scrcpy ttyd wdisplays-git dmenu-wayland-git python-soundcard python-soundfile pacaur archivemount micro python-rpi.gpio python-pad4pi python-pulse-control python-rplcd python-vlc python-mpv pmbootstrap wordpress-theme-geist linux-libre opensnitch-git powerpill osmctools tilemaker nextcloud-app-talk xerox-phaser-6000-6010 dokuwiki-plugin-captcha dokuwiki-plugin-dw2pdf dokuwiki-template-argon nextcloud-integration-github nextcloud-integration-twitter nextcloud-integration-reddit nextcloud-integration-discourse wordpress-plugin-opengraph nextcloud-app-podcast wordpress-plugin-simple-login-captcha wordpress-plugin-disable-xml-rpc wordpress-plugin-async-javascript wordpress-plugin-breeze wordpress-plugin-webp-converter-for-media
pacman -S caddy
gpasswd -a caddy http
systemctl enable --now caddy
nft add rule inet filter input position 17 ip saddr 10.25.0.0/24 tcp dport http accept
nft add rule inet filter input position 17 ip6 saddr 2a01:4f8:191:327::0/64 tcp dport http accept
nft list ruleset > /etc/nftables.conf

caddy configuration

/etc/caddy/Caddyfile import conf.d/*.conf

/etc/caddy/conf.d/onny.project-insanity.org.conf
http://onny.project-insanity.org {

        log {
                output file     /var/log/caddy/onny.project-insanity.org.log
                format single_field common_log
        }

    handle /archlinux {
        redir https://onny.project-insanity.org/archlinux/
    }

    handle /archlinux/* {
        root * /var/cache/pacman/projectinsanity
        uri strip_prefix /archlinux
            file_server browse
    }

}
systemctl restart caddy

caddy configuration on http-pub.pi:

/etc/caddy/conf.d/onny.project-insanity.org.conf
[...]
    proxy /archlinux playground.pi {
        transparent
    }
[...]
systemctl restart caddy

http-pub.pi

pacman -S caddy php-fpm
systemctl enable --now caddy php-fpm
nft add rule inet filter input position 17 ip saddr 10.25.0.0/24 tcp dport http accept
nft add rule inet filter input position 17 ip6 saddr 2a01:4f8:191:327::0/64 tcp dport http accept
nft list ruleset > /etc/nftables.conf
/etc/pacman.d/hooks/php.hook
# Restart php service

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = php
Target = php-fpm

[Action]
Description = Restarting php service
When = PostTransaction
Exec = /usr/bin/systemctl restart php-fpm

custom caddy installation

pacaur -d caddy
~/.cache/pacaur/caddy/PKGBUILD
[...]
#    'http.expires'
    'http.filemanager'
#    'http.filter'
[...]
cd ~/.cache/pacaur/caddy
makepkg -i --skipinteg

caddy

pacman -S caddy
gpasswd -a caddy http
/etc/caddy/Caddyfile
import /etc/caddy/conf.d/*
/etc/caddy/conf.d/ausstellung-virtuell.de.conf
http://ausstellung-virtuell.de {
    redir https://www.ausstellung-virtuell.de{uri}
}

http://www.ausstellung-virtuell.de {

        root    * /var/www/ausstellung-virtuell.de
        file_server
        log {
                output file     /var/log/caddy/ausstellung-virtuell.de.log
                format single_field common_log
        }

        php_fastcgi unix//var/run/php-fpm/ausstellung-virtuell.de_php-fpm.sock

        @mainpage {
          path_regexp path ^/([^.]+)$
        }
        rewrite @mainpage /index.php?page={http.regexp.path.1}
}
/etc/caddy/conf.d/onny.project-insanity.org.conf
http://onny.project-insanity.org {

        reverse_proxy /archlinux* playground.pi:80
        
        root    * /var/www/onny.project-insanity.org
        file_server
        log {
                output file     /var/log/caddy/onny.project-insanity.org.log
                format single_field common_log
        }

        php_fastcgi unix//var/run/php-fpm/onny.project-insanity.org_php-fpm.sock

}
/etc/systemd/system/caddy.service.d/overwride.conf
[Service]
ProtectHome=false
LimitNOFILE=infinity
LimitNPROC=infinity
systemctl daemon-reload
systemctl restart caddy

Overwrite php-fpm.service configuration, allow access to home directories:

php-fpm.service.d/overwrite.conf
[Service]
ProtectHome=false

wordpress

/etc/php/conf.d/wordpress.ini
extension=mysqli

upload_max_filesize = 64M
post_max_size = 64M

uwsgi

pacman -S uwsgi-plugin-python python-bottle
mkdir /etc/uwsgi/systemd
/etc/systemd/system/uwsgi-private@.service
[Unit]
Description=uWSGI service unit
After=syslog.target

[Service]
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini
Type=notify
SuccessExitStatus=15 17 29 30
NotifyAccess=all
KillSignal=SIGQUIT
PrivateDevices=yes
PrivateTmp=yes
ProtectSystem=full
CapabilityBoundingSet=CAP_SETGID CAP_SETUID
ReadWriteDirectories=${rw_directory}
ProtectHome=yes
NoNewPrivileges=yes
EnvironmentFile=/etc/uwsgi/systemd/%i.conf

[Install]
WantedBy=multi-user.target
/etc/systemd/system/uwsgi-private@.socket
[Unit]
Description=Socket for uWSGI %I

[Socket]
# Change this to your uwsgi application port or unix socket location
ListenStream=/run/uwsgi/%I.sock

[Install]
WantedBy=sockets.target

getmetadata

pacman -S python-requests
/etc/uwsgi/getmetadata.ini
[uwsgi]
http-socket = /run/uwsgi/%n.sock
uid = http
gid = http
chdir = /usr/share/webapps/getmetadata
master = true
plugins = python
file = streammetadata-api.py
/etc/uwsgi/systemd/getmetadata.conf
rw_directory="/usr/share/webapps/getmetadata"
systemctl enable uwsgi-private@getmetadata
systemctl start uwsgi-private@getmetadata

biolaedle-etiketten-generator

pacman -S python-pandas python-reportlab python-xlrd python-bottle
/etc/uwsgi/biolaedle-etiketten-generator.ini
[uwsgi]
http-socket = /run/uwsgi/%n.sock
uid = http
gid = http
chdir = /usr/share/webapps/biolaedle-etiketten-generator
master = true
plugins = python
file = label.py
systemctl enable --now uwsgi@biolaedle\\x2detiketten\\x2dgenerator

feeds

pacman -S python-feedparser python-beautifulsoup4 python-pyrss2gen python-dateutil python-lxml
/etc/uwsgi/feeds.ini
[uwsgi]
http-socket = /run/uwsgi/%n.sock
uid = http
gid = http
chdir = /usr/share/webapps/feeds
master = true
plugins = python
file = app.py
/etc/uwsgi/systemd/feeds.conf
rw_directory="/usr/share/webapps/feeds"
systemctl enable uwsgi-private@feeds
systemctl start uwsgi-private@feeds

pishare

pacman -S nodejs
/etc/uwsgi/pishare.ini
[uwsgi] 
httpsocket = /run/uwsgi/%n.sock
uid = http
gid = http
chdir = /usr/share/webapps/pishare
master = true
threads = true
plugins = python
file = pishare.py
lazy-apps = true
systenmctl enable --now uwsgi@pishare

arch-upstream

pacman -S python-progressbar python-jinja
ln -s /usr/share/webapps/arch-upstream /var/www/onny.sexypump.de/
/etc/systemd/system/arch-upstream.service
[Unit]
Description=Arch-Upstream

[Service]
Type=simp
User=http
Group=http
PrivateDevices=yes
PrivateTmp=yes
ProtectSystem=full
CapabilityBoundingSet=
ReadWriteDirectories=/usr/share/webapps/arch-upstream
ProtectHome=yes
NoNewPrivileges=yes
WorkingDirectory=/usr/share/webapps/arch-upstream
ExecStart=/usr/share/webapps/arch-upstream/main.py
/etc/systemd/system/arch-upstream.timer
[Unit]
Description=Run arch-upstream every 12 hours

[Timer]
# Time to wait after booting before we run first time
OnBootSec=10min
# Time between running each consecutive time
OnUnitActiveSec=12h
Unit=arch-upstream.service

[Install]
WantedBy=multi-user.target
systemctl enable arch-upstream.timer
systemctl start arch-upstream.timer

fdroid repo gplay mirror

http-pub.pi

enable multilib

/etc/pacman.conf
[...]
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist

# An example of a custom package repository.  See the pacman manpage for
# tips on creating your own repositories.
[...]
pacman -S fdroidserver android-sdk android-sdk-build-tools gplaycli
cd www
mkdir fdroid
cd fdroid
env ANDROID_HOME=/opt/android-sdk fdroid init
www/fdroid/config.py
[...]
repo_url = "https://onny.project-insanity.org/fdroid/repo"
repo_name = "Project-Insanity F-Droid repo"
repo_icon = "fdroid-icon.png"
repo_description = "This is a private F-Droid repository for the PI-crew :)"
[...]
env ANDROID_HOME=/opt/android-sdk fdroid update --create-metadata
mkdir ~/.config/gplaycli
~/.config/gplaycli/gplaycli.conf
[Credentials]
gmail_address=****@gmail.com
gmail_password=****
token=False
~/.config/gplaycli/apk.list
org.thoughtcrime.securesms
de.nextbike
com.spotify.music
com.mobiledirection.GPSRepairFix
com.melodis.midomiMusicIdentifier.freemium
com.whatsapp
de.hafas.android.db
de.regiorad.stuttgart
com.ebay.mobile
com.ebay.kleinanzeigen
com.comuto
org.jellyfin.mobile
com.bandcamp.android
com.cubic.cumo.android.kvv
com.moovel.kvv
com.supercell.boombeach
com.wahoofitness.boltcompanion
io.voiapp.voi
de.sdvrz.ihb.mobile.secureapp.sparda.produktion
com.valvesoftware.android.steam.community
com.aspiro.tidal
com.google.android.inputmethod.latin
deezer.android.app
org.mozilla.firefox
com.myunibo
de.thomastreyer.beonbike
de.gls.pure
de.gls.pure
org.lichess.mobileapp
com.zhiliaoapp.musically
com.lynxspa.prontotreno
/etc/systemd/system/gplaycli.service
 
[Unit]
Description=Gplaycli automatic APK mirror
After=network-online.target 

[Service]
Type=simple
User=onny
ExecStart=/usr/bin/sh -c "rm -f /home/onny/.cache/gplaycli/token && /usr/bin/gplaycli -v -dc shamu --file /home/onny/.config/gplaycli/apk.list --folder /home/onny/www/fdroid/repo/ -c /home/onny/.config/gplaycli/gplaycli.conf && cd /home/onny/www/fdroid && env ANDROID_HOME=/opt/android-sdk fdroid update --create-metadata"
TimeoutStopSec=180
KillMode=process
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target
/etc/systemd/system/gplaycli.timer
[Unit]
Description=Gplaycli automatic APK mirror

[Timer]
OnBootSec=5min
OnUnitActiveSec=12h
Unit=gplaycli.service

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl --now enable gplaycli.timer

Notes:

  • Manually put Threema apk into repo folder

public hosting

Create user for hosting site

useradd -m example
mkdir /home/example/www
ln -s /home/example/www /var/www/example.de
chmod +x /home/example

Copy php-fpm profile

cp /etc/php/php-fpm.d/sexypump.de.conf /etc/php/php-fpm.d/example.com

Replace all occurences from the domain (sexypump.de) and the user (sexypump) with your domain and user. Now restart php-fpm:

systemctl restart php-fpm

Create nginx webserver configuration:

/etc/nginx/sites-available/example.de
server {
    server_name example.de www.example.de;
    access_log /var/log/nginx/example.de.access.log;
    error_log /var/log/nginx/example.de.error.log;
    root /var/www/example.de/wordpress/;

    location / {
        index index.php index.htm index.html;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/var/run/php-fpm/example.de_php.sock;
        fastcgi_index index.php;
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_intercept_errors on;
    }
}

Enable webserver configuration:

ln -s /etc/nginx/sites-available/example.de /etc/nginx/sites-enabled/
systemctl restart nginx

Enable SSL caddy proxy on http.pi. Edit as user caddy and append following part:

/opt/caddy/Caddyfile
www.example.de example.de {
        log /var/log/caddy/example.de_access.log
        gzip
        tls crux@project-insanity.org
        proxy / http://http-pub.pi:80 {
                header_upstream Host {host}
                header_upstream X-Real-IP {remote}
                header_upstream X-Forwarded-Proto {scheme}
                header_downstream -Server ""
        }      
} 

Restart caddy process after that. Depending on the permissions of your webroot, you can run:

sudo gpasswd -a example http

Mysql database creation on mysql.pi:

CREATE DATABASE IF NOT EXISTS sexypump;
GRANT ALL PRIVILEGES ON sexypump.* TO 'sexypump'@'http-pub' IDENTIFIED BY '****';
FLUSH PRIVILEGES;
/etc/conf.d/ballisticc.de.ini
upload_max_filesize = 1000M
post_max_size = 1000M

podcast feeds

sudo cp /home/onny/www/laboumdeluxe/laboumdeluxe_* /etc/systemd/system/
sudo cp /home/onny/www/bounce/bounce_* /etc/systemd/system/
systemctl enable --now bounce_feed.timer laboumdeluxe_feed.timer kampus_hakatze_feed.timer
projectinsanity/server_setup.txt · Last modified: 2022/08/12 20:20 by 10.25.0.100