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 pending (picloud)
http-pub 10.25.0.101 2a01:4f8:191:327::11 500G 15.06.19 (picloud)
mail 10.25.0.102 2a01:4f8:191:327::12 500G 15.06.19 (picloud)
mysql 10.25.0.103 2a01:4f8:191:327::13 100G 16.06.19 (picloud)
playground 10.25.0.104 2a01:4f8:191:327::14 500G 18.06.19 (picloud)
storage 10.25.0.105 2a01:4f8:191:327::15 1TB syncing (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
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

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 autoupdate.timer
systemctl start autoupdate.timer

nftables firewall & routing

/etc/nftables.conf
flush ruleset

table inet filter {
    set tcp_accepted {
        type inet_service; flags interval;
        elements = {
            http, https, ssh,
        }
    }
    set udp_accepted {
        type inet_service; flags interval;
        elements = {
            60000-61000, # mosh
	    51820
        }
    }

    chain base_checks {
        # allow established/related connections
        ct state {established, related} accept

        # early drop of invalid connections
        ct state invalid drop
    }
    chain input {
        type filter hook input priority 0; policy drop;

        jump base_checks

        # allow from loopback
        iifname lo accept

        # allow icmp
        ip protocol icmp icmp type { echo-request, echo-reply, time-exceeded, parameter-problem, destination-unreachable } accept
        ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, time-exceeded, parameter-problem, destination-unreachable, packet-too-big, nd-router-advert, nd-router-solicit, nd-neighbor-solicit, nd-neighbor-advert, mld-listener-query } accept

        # allow ports
        ip saddr 10.25.40.0/24 tcp dport 8096 accept
        ip saddr 10.25.40.0/24 tcp dport 2222 accept
        ip6 saddr 2a01:4f8:191:327::/64 tcp dport 8096 accept
        ip6 saddr 2a01:4f8:191:327::/64 tcp dport 2222 accept
        ip saddr 10.25.0.0/24 tcp dport 8096 accept
        ip saddr 10.25.0.0/24 tcp dport 2222 accept        
        tcp dport @tcp_accepted accept
        udp dport @udp_accepted accept

	iif {br-internal,wg0} tcp dport domain accept
	iif {br-internal,wg0} udp dport domain accept

        # everything else
        reject with icmpx type port-unreachable
    }
    chain forward {
        type filter hook forward priority 0; policy drop;

        jump base_checks

        # Allow coming out of the vpn
        #ip saddr 192.168.87.0/24 iifname tun0 accept

        # Allow connecting to home_srv.
        ip daddr 10.25.0.100 ct status dnat accept

	oif br-internal accept
	iif br-internal accept
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

table ip nat {
    chain prerouting {
        type nat hook prerouting priority 0;

        iifname enp3s0 tcp dport http dnat 10.25.0.100
        iifname enp3s0 tcp dport https dnat 10.25.0.100
    }
    chain postrouting {
        type nat hook postrouting priority 100;

	oifname enp3s0 masquerade
    }
}
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-arch
mkdir /etc/wireguard
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 = [SERVER PRIVATE KEY]

[WireGuardPeer]
# onny 10.25.40.2
PublicKey = [ONNY's PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
# st-think 10.25.40.3
PublicKey = [ST-THINK's PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
# neutrino 10.25.40.4
PublicKey = [NEUTRINO's PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
# arne 10.25.40.5
PublicKey = [ARNE's PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
# st-rpi-gravograf 10.25.40.6
PublicKey = [ST-RPI-GRAVOGRAF PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
# st-rpi-home 10.25.40.7
PublicKey = [ST-RPI-HOME PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
# st-1 10.25.40.8
PublicKey = [ST-1 PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
# st-2 10.25.40.9
PublicKey = [ST-2 PUBLIC KEY]
AllowedIPs = 10.25.40.0/24
/etc/systemd/network/99-server.network
[Match]
Name = wg0

[Link]
MTUBytes=1500

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

client

pacman -S wireguard-arch
mkdir /etc/wireguard
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

[Link]
MTUBytes=1500

[Network]
Address = 10.25.40.2/32
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 --vnc --name=http --vcpus 4 --memory 8048 --disk pool=vg0,size=1000 --cdrom /var/lib/libvirt/images/archlinux-2018.06.01-x86_64.iso --network network:internal --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 vim 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 fd devtools fish nftables
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
sudo -u onny curl "https://aur.archlinux.org/cgit/aur.git/snapshot/aurutils.tar.gz" | tar xz -C /tmp/
chown -R onny:onny /tmp/aurutils /home/onny
tmux
cd /tmp/aurutils
sudo -u onny makepkg -i --skipinteg
sudo -u aur aurutils -c zabbix-agent linux-libre
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 zabbix-agentd 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

aur setup

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

[aur]
SigLevel = Optional TrustAll
Server = file:///var/cache/pacman/aur
/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/aur -o aur
sudo repo-add /var/cache/pacman/aur/aur.db.tar
sudo chown -R aur:aur /var/cache/pacman/aur
sudo -u aur gpg --recv-keys 6BC26A17B9B7018A
/etc/systemd/system/aurupdate.service
[Unit]
 Description=Automatic update AUR repository.
 After=network-online.target 

[Service]
 Type=simple
 User=aur
 ExecStart=/usr/bin/aur sync --no-view -cu
 TimeoutStopSec=180
 KillMode=process
 KillSignal=SIGINT

[Install]
 WantedBy=multi-user.target
/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=60min
 Unit=aurupdate.service

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

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

mail.pi

  • domain with mx record
  • spf record, eg. v=spf1 a mx ip4:144.76.16.40 ~all
aur sync -c maddy-git
systemctl start maddy # create empty sql database file
systemctl stop maddy
sudo -u maddy imapsql-ctl --driver sqlite3 --dsn /var/lib/maddy/all.db users create cypherpunk@sexypump.de
/etc/maddy/maddy.conf
# Location of TLS certificate and private key. Global directive is used for all
# endpoints.
tls /etc/maddy/cert.pem /etc/maddy/privkey.pem

# hostname is the identifier of this mail server.
# It is recommended to set it to the domain that resolves to the IP of this
# server.
hostname mail.sexypump.de

# Domain that will be used in From field in auto-generated messages.
# (notably, notifications about failed deliveries)
autogenerated_msg_domain mail.sexypump.de

# auth_domains directive allows users to log in using 'user@example.org' as a
# username in addition to just 'user'.
auth_domains mail.sexypump.de

# Create and initialize sql module, it provides simple authentication and
# storage backend using one database for everything.
sql local_mailboxes local_authdb {
    driver sqlite3
    dsn /var/lib/maddy/all.db
}

smtp smtp://0.0.0.0:25 {
    check {
        # Verify that hostname in EHLO/HELO resolves to the source IP. Fail if it is not.
        require_matching_ehlo

        # Verify that domain in MAIL FROM does have a MX record.
        require_mx_record
    }

    # All messages for the recipients at example.org should be
    # delivered to local mailboxes.
    destination sexypump.de {
        deliver_to local_mailboxes
    }

    # Other recipients are rejected because we are not an open relay.
    default_destination {
        reject 550 5.1.1 "User not local"
    }
}

submission smtps://0.0.0.0:465 smtp://0.0.0.0:587 {
    # Use sql module for authentication.
    auth local_authdb

    # All messages for the recipients at example.org should be
    # delivered to local mailboxes directly.
    destination cypherpunk@sexypump.de {
        deliver_to local_mailboxes
    }

    # Remaining recipients are scheduled for remote delivery.
    default_destination {
        deliver_to remote_queue
    }
}

queue remote_queue {
    # Try to deliver message up to 8 tries. Note that this counter is not per
    # recipient, but for entire message.
    max_tries 8

    # Try to deliver up to 16 messages concurrently.
    workers 16

    # Send messages to remote MTA discovered using DNS MX records.
    target remote

    # This is how bounce messages (aka DSNs) will be routed.
    # The syntax is same as smtp/submission directives.
    bounce {
        destination sexypump.de {
            deliver_to local_mailboxes
        }
        default_destination {
            reject 550 5.0.0 "Refusing to send DSNs to non-local addresses"
        }
    }
}

# Configuration for remote delivery module (none for now, just create a
# configuration block for use with 'target' above).
remote { }

imap imaps://0.0.0.0:993 {
    auth local_authdb
    storage local_mailboxes
}
systemctl enable --now maddy
nft add rule inet filter input position 17 tcp dport submission 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

forwarding/nat on host.pi

nft add rule inet filter input position 19 tcp dport submission 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 submission dnat to 10.25.0.102
nft list ruleset > /etc/nftables.conf

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

postgresql

pacman -S postgresql
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

http.pi

sudo -u aur aur sync -c caddy
pacman -S caddy dokuwiki gitlab php-fpm php-apcu phpmyadmin wordpress nginx roundcubemail
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

/etc/caddy/caddy.conf.d/archbox.icu.conf
www.archbox.icu archbox.icu {
        log /var/log/caddy/archbox.icu_access.log
        gzip
        tls onny@project-insanity.org
        proxy / http://playground.pi {
                websocket
        }      
} 
/etc/caddy/caddy.conf.d/ausstellung-virtuell.de.conf
www.ausstellung-virtuell.de ausstellung-virtuell.de {
        log /var/log/caddy/ausstellung-virtuell.de_access.log
        gzip
        tls onny@project-insanity.org
        proxy / http://http-pub.pi {
                transparent
        }
} 
/etc/caddy/caddy.conf.d/ausstellung-virtuell.de.conf
www.xn--bioldle-8wa.de xn--bioldle-8wa.de {
        log /var/log/caddy/biolädle.de_access.log
        gzip
        tls onny@project-insanity.org
        proxy / http://http-pub.pi {
                transparent
        }      
} 
/etc/caddy/caddy.conf.d/blog.project-insanity.org.conf
blog.project-insanity.org/106fm {
        log /var/log/caddy/project-insanity.org_access.log
        errors /var/log/caddy/project-insanity.org_errors.log

        gzip
        tls onny@project-insanity.org

        header / {
                Content-Type "application/ogg"
        }

        proxy / http://storage.pi:8080 {
                transparent
        }      
}

blog.project-insanity.org {
        log /var/log/caddy/project-insanity.org_access.log
        gzip
        tls onny@project-insanity.org

        root /usr/share/webapps/wordpress
        fastcgi / /var/run/php-fpm/php-fpm.sock php {
                read_timeout 1000s
                send_timeout 1000s
        }

        rewrite {
                if {path} not_match ^\/wp-admin
                to {path} {path}/ /index.php?{query}
        }
}
/etc/caddy/caddy.conf.d/einfach-abhängen.de.conf
xn--einfach-abhngen-blb.de www.xn--einfach-abhngen-blb.de {
        log /var/log/caddy/einfach-abhängen.de_access.log
        gzip
        tls onny@project-insanity.org
        proxy / http://http-pub.pi {
                transparent
        }      
} 
/etc/caddy/caddy.conf.d/git.project-insanity.org.conf
git.project-insanity.org {
    log /var/log/caddy/git.project-insanity.org_access.log
    errors /var/log/caddy/git.project-insanity.org_errors.log

    rewrite {
        if_op or

        if {>User-Agent} has SemrushBot
        if {>User-Agent} has MJ12Bot
        if {>User-Agent} has DotBot
        if {>User-Agent} has AhrefsBot

        to /bad-robot
    }

    status 403 /bad-robot

    proxy / unix:/run/gitlab/gitlab-workhorse.socket {
        fail_timeout 300s
        max_fails 100
        transparent
    }
}
/etc/caddy/caddy.conf.d/http.pi.conf
http://http.pi {
        log /var/log/caddy/http.pi_access.log
        errors /var/log/caddy/http.pi_errors.log
        gzip

        tls off
        root /var/www
        browse

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

        #ipfilter / {
        #       rule allow
        #       ip 10.25.0.0/24 2a01:4f8:191:327::/64
        #}
}
/etc/caddy/caddy.conf.d/jhartung.sinewell.de.conf
jhartung.sinewell.de {
    log /var/log/caddy/jhartung.sinewell.de_access.log
    errors /var/log/caddy/jhartung.sinewell.de_errors.log
    gzip
    tls onny@project-insanity.org
    proxy / https://****.myfritz.net:46190
}
/etc/caddy/caddy.conf.d/lit-eratur.de.conf
www.lit-eratur.de lit-eratur.de {
        log /var/log/caddy/lit-eratur.de_access.log
        gzip
        tls onny@project-insanity.org
        proxy / http://http-pub.pi {
                transparent
        }      
} 
/etc/caddy/caddy.conf.d/music-id.xyz.conf
www.music-id.xyz music-id.xyz {
        log /var/log/caddy/music-id.xyz_access.log
        errors /var/log/caddy/music-id.xyz_errors.log
        gzip
        tls onny@project-insanity.org
        proxy / http://playground.pi:8080 {
                transparent
        }      
} 
/etc/caddy/caddy.conf.d/nextcloud.project-insanity.org.conf
nextcloud.project-insanity.org {

        root   /usr/share/webapps/nextcloud
        log    /var/log/caddy/nextcloud.project-insanity.org_access.log
        errors /var/log/caddy/nextcloud.project-insanity.org_errors.log

        tls onny@project-insanity.org {
                curves X25519 p256 p384 p521
        }

        fastcgi / /var/run/php-fpm/php-fpm.sock php {
                env PATH /bin
        }

        header / {
                 Strict-Transport-Security         "max-age=15768000;"
        }

        # checks for images
        rewrite {
                ext .svg .gif .png .html .ttf .woff .ico .jpg .jpeg
                r ^/index.php/(.+)$
                to /{1} /index.php?{1}
        }

        rewrite {
                r ^/\.well-known/host-meta$
                to /public.php?service=host-meta&{query}
        }
        rewrite {
                r ^/\.well-known/host-meta\.json$
                to /public.php?service=host-meta-json&{query}
        }
        rewrite {
                r ^/\.well-known/webfinger$
                to /public.php?service=webfinger&{query}
        }

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

        # client support (e.g. os x calendar / contacts)
        redir /.well-known/carddav /remote.php/carddav 301
        redir /.well-known/caldav /remote.php/caldav 301

        # remove trailing / as it causes errors with php-fpm
        rewrite {
                r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)(\/?)$
                to /remote.php/{1}
        }

        rewrite {
                r ^/remote.php/(webdav|caldav|carddav|dav)/(.+?)(\/?)(\/?)$
                to /remote.php/{1}/{2}
        }

        rewrite {
                r ^/public.php/(dav|webdav|caldav|carddav)(\/?)(\/?)$
                to /public.php/{1}
        }

        rewrite {
                r ^/public.php/(dav|webdav|caldav|carddav)/(.+)(\/?)(\/?)$
                to /public.php/{1}/{2}
        }

        # .htaccess / data / config / ... shouldn't be accessible from outside
        status 403 {
                /.htaccess
                /data
                /config
                /db_structure
                /.xml
                /README
        }

}
/etc/caddy/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
        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/caddy/caddy.conf.d/onny.project-insanity.org.conf
onny.project-insanity.org {
        log /var/log/caddy/onny.project-insanity.org_access.log
        gzip
        tls onny@project-insanity.org
        proxy / http://http-pub.pi {
                websocket
                transparent
        }
} 
/etc/caddy/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
    }
}
/etc/caddy/caddy.conf.d/wiki.project-insanity.org.conf
wiki.project-insanity.org {
        log /var/log/caddy/wiki.project-insanity.org_access.log
        root /usr/share/webapps/dokuwiki
        gzip
        tls onny@project-insanity.org

        fastcgi / /var/run/php-fpm/php-fpm.sock php {
          index doku.php
        }

        internal /forbidden

        rewrite {
          r /(data/|conf/|bin/|inc/|install.php)
          to /forbidden
        }
        rewrite /_media {
          to /lib/exe/fetch.php?media={path}&{query}
        }
        rewrite /_detail {
          to /lib/exe/detail.php?media={path}&{query}
        }
        rewrite /_export {
          r /([^/]+)/(.*)
          to /doku.php?do=export_{1}&id={2}
        }
        rewrite {
          if {path} not_match /lib/.*
          if {path} not_match /forbidden
          r /(.*)
          to {uri} /doku.php?id={1}&{query}
        }
}
/etc/caddy/caddy.conf.d/zirkel.fun.conf
nextcloud.zirkel.fun {

        root   /usr/share/webapps/nextcloud
        log /var/log/caddy/nextcloud.sexypump.de_access.log
        errors /var/log/caddy/nextcloud.sexypump.de_errors.log

        fastcgi / /var/run/php-fpm/php-fpm.sock php {
          env PATH /bin
        }

        # checks for images
        rewrite {
                ext .svg .gif .png .html .ttf .woff .ico .jpg .jpeg
                r ^/index.php/(.+)$
                to /{1} /index.php?{1}
        }

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

        # client support (e.g. os x calendar / contacts)
        redir /.well-known/carddav /remote.php/carddav 301
        redir /.well-known/caldav /remote.php/caldav 301

        # remove trailing / as it causes errors with php-fpm
        rewrite {
                r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)(\/?)$
                to /remote.php/{1}
        }

        rewrite {
                r ^/remote.php/(webdav|caldav|carddav|dav)/(.+?)(\/?)(\/?)$
                to /remote.php/{1}/{2}
        }

        rewrite {
                r ^/public.php/(dav|webdav|caldav|carddav)(\/?)(\/?)$
                to /public.php/{1}
        }

        rewrite {
                r ^/public.php/(dav|webdav|caldav|carddav)/(.+)(\/?)(\/?)$
                to /public.php/{1}/{2}
        }

        # .htaccess / data / config / ... shouldn't be accessible from outside
        status 403 {
                /.htaccess
                /data
                /config
                /db_structure
                /.xml
                /README
        }

        header / Strict-Transport-Security "max-age=31536000;"

}

www.zirkel.fun zirkel.fun {
        log /var/log/caddy/zirkel.fun_access.log
        gzip
        tls onny@project-insanity.org
        proxy / http://http-pub.pi {
                transparent
        }      
} 

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
[...]

wordpress

sudo -u aur aur sync -c wp-cli wordpress-plugin-antispam-bee wordpress-plugin-code-syntax-block wordpress-plugin-jetpack-lite wordpress-plugin-lightbox-photoswipe wordpress-plugin-wp-gdpr wordpress-plugin-wp-statistics
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 wordpress-plugin-wp-statistics
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 );
sudo -u http wp plugin activate antispam-bee code-syntax-block jetpack jetpack-lite lightbox-photoswipe wp-gdpr-core wp-statistics --path=/usr/share/webapps/wordpress

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

invoiceplane

pacaur -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

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

firefox sync server

pacaur -S mozilla-firefox-sync-server uwsgi-plugin-python2
/etc/webapps/mozilla-firefox-sync-server/syncserver.ini
public_url = https://sync.project-insanity.org
sqluri = pymysql://ffsync:****@mysql.pi/firefox_sync
#sqluri = sqlite:////var/lib/mozilla-firefox-sync-server/syncserver.db
/etc/uwsgi/mozilla-firefox-sync-server.ini
[uwsgi]
http-socket = /run/uwsgi/%n.sock
uid = http
gid = http
chdir = /usr/share/webapps/mozilla-firefox-sync-server
master = true
plugins = python2
file = syncserver.wsgi
systemctl restart uwsgi@mozilla\\x2dfirefox\\x2dsync\\x2dserver caddy
systemctl enable uwsgi@mozilla\\x2dfirefox\\x2dsync\\x2dserver caddy

firefox account server

pacaur -S mozilla-firefox-account-server

podcasttune

not yet stable

dokuwiki

/etc/webapps/dokuwiki/local.php
<?php
$conf['title'] = 'Project-Insanity';
$conf['userewrite']  = 1;

dw2pdf plugin

wget "https://github.com/splitbrain/dokuwiki-plugin-dw2pdf/tarball/master" -O /tmp/dw2pdf.tar.gz
cd /tmp
tar xvf dw2pdf.tar.gz
mv splitbrain* /var/lib/dokuwiki/plugins/dw2pdf
/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

sudo -u aur aur sync -cu gitlab
pacman -S yarn sendmail

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;"

on http.pi

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

Enable smtp, mail delivery

/usr/share/webapps/gitlab/config/initializers/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-unicorn gitlab-sidekiq gitlab-gitaly && /usr/bin/sudo -u gitlab /usr/bin/bash -c 'cd /usr/share/webapps/gitlab; bundle-2.5 exec rake db:migrate RAILS_ENV=production'"
/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

debugging:

sudo su - gitlab -s /bin/sh -c "cd '/usr/share/webapps/gitlab'; EXECJS_RUNTIME=Disabled bundle-2.5 exec rake db:migrate RAILS_ENV=production"
sudo su - gitlab -s /bin/sh -c "cd '/usr/share/webapps/gitlab'; EXECJS_RUNTIME=Disabled bundle-2.5 exec rake gitlab:assets:clean gitlab:assets:compile cache:clear RAILS_ENV=production"
sudo su - gitlab -s /bin/sh -c "cd '/usr/share/webapps/gitlab'; EXECJS_RUNTIME=Disabled bundle-2.5 exec rake gitlab:env:info RAILS_ENV=production"
sudo su - gitlab -s /bin/sh -c "cd '/usr/share/webapps/gitlab'; EXECJS_RUNTIME=Disabled bundle-2.5 exec rake gitlab:check RAILS_ENV=production"

onlyoffice documentserver

sudo -u aur aur sync -cu 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/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

integration example

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

[Service]
User=http
WorkingDirectory=/usr/share/webapps/onlyoffice-integration-example
ExecStart=/usr/bin/node bin/www

[Install]
WantedBy=basic.target
cd /usr/share/webapps
sudo git clone https://github.com/ONLYOFFICE/document-server-integration.git
sudo chown -R http:http document-server-integration /srv/http
cd document-server-integration
sudo -u http make
systemctl enable --now onlyoffice-integration-example

nextcloud

sudo -u aur aur sync -c 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
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-tasks nextcloud-app-calendar nextcloud-app-contacts nextcloud-app-keeweb nextcloud-app-radio nextcloud-app-deck nextcloud-app-onlyoffice nextcloud-app-bookmarks
/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

# 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
/usr/share/webapps/nextcloud/conf/config.php
<?php
$CONFIG = array (
  'instanceid' => '****',
  'passwordsalt' => '****',
  'datadirectory' => '/usr/share/webapps/nextcloud/data',
  'dbtype' => 'mysql',
  'version' => '13.0.2.1',
  'dbname' => 'nextcloud',
  'dbhost' => 'mysql.pi',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nextcloud',
  'dbpassword' => '****',
  'installed' => true,
  'theme' => '',
  'maintenance' => false,
  'loglevel' => 2,
  'cron_log' => true,
  'maxZipInputSize' => 5145728000,
  'allowZipDownload' => true,
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'trusted_domains' => 
  array (
    0 => 'nextcloud.project-insanity.org',
    1 => 'http-new.pi',
    2 => 'office.project-insanity.org',
    3 => 'onny.project-insanity.org',
  ),
  'secret' => '****',
  'mail_domain' => 'project-insanity.org',
  'mail_smtpmode' => 'php',
  'mail_from_address' => 'nextcloud',
  'trashbin_retention_obligation' => 'auto',
  'overwrite.cli.url' => 'https://nextcloud.project-insanity.org',
  'htaccess.RewriteBase' => '/',
);

Auto upgrade on pacman update

/etc/pacman.d/hooks/nextcloud.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/runuser -u http -- /usr/bin/php /usr/share/webapps/nextcloud/occ upgrade

Nextcloud background job (cron)

[Unit]
Description=Nextcloud cron.php job
 
[Service]
User=http
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"],
[...]
sudo -u http /usr/share/webapps/nextcloud/occ app:enable twofactor_gateway audioplayer polls extract suspicious_login mail news tasks calendar contacts keeweb radio deck onlyoffice bookmarks

two factor configuration

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)

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;
[...]

roundcubemail

/etc/webapps/roundcubemail/config/config.inc.php
[...]
$config['db_dsnw'] = 'mysql://roundcubemail:****@mysql.pi/roundcubemail';
$config['default_host'] = 'tls://mail.pi';
$config['smtp_server'] = 'tls://mail.pi';
$config['smtp_port'] = 587;
$config['imap_conn_options'] = array(
  'ssl'         => array(
     'verify_peer'  => false,
     'verify_peer_name' => false,
   ),
);
$config['smtp_conn_options'] = array(
  'ssl'         => array(
     'verify_peer'  => false,
     'verify_peer_name' => false,
   ),
);

todo:

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

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

http-pub.pi

sudo -u aur aur sync -cu caddy
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

/etc/caddy/caddy.conf.d/ausstellung-virtuell.de.conf
http://ausstellung-virtuell.de {
    redir https://www.ausstellung-virtuell.de
}

http://www.ausstellung-virtuell.de {
    log /var/log/caddy/ausstellung-virtuell.de_access.log
    errors /var/log/caddy/ausstellung-virtuell.de_errors.log

    gzip

    root /var/www/ausstellung-virtuell.de

    rewrite {
        r ^/(.+)$
        to /{1} /index.php?page={1}
    }

    fastcgi / /var/run/php-fpm/ausstellung-virtuell.de_php-fpm.sock php {
        index index.php
    }
}
/etc/caddy/caddy.conf.d/biolädle.de.conf
http://biolädle.de http://www.biolädle.de http://www.xn--bioldle-8wa.de http://xn--bioldle-8wa.de {
    log /var/log/caddy/biolädle.de_access.log
    errors /var/log/caddy/biolädle.de_errors.log
    tls off
    gzip

    root /var/www/biolädle.de

    proxy /etiketten unix:/run/uwsgi/biolaedle-etiketten-generator.sock {
        transparent
    }
    proxy /lagerhaltung unix:/run/uwsgi/biolaedle-lagerhaltung.sock {
        transparent
    }

    rewrite {
        if {path} not_match ^\/etiketten
        if {path} not_match ^\/lagerhaltung
        if {path} not_match ^\/wp-admin
        to {path} {path}/ /index.php?{query}
    }

    fastcgi / /var/run/php-fpm/biolädle.de_php-fpm.sock php {
        env HTTPS 1
        index index.php
    }
}
/etc/caddy/caddy.conf.d/einfach-abhängen.de.conf
http://einfach-abhängen.de http://www.einfach-abhängen.de http://xn--einfach-abhngen-blb.de http://www.xn--einfach-abhngen-blb.de {
    log /var/log/caddy/einfach-abhängen.de_access.log
    errors /var/log/caddy/einfach-abhängen.de_errors.log
    tls off
    gzip

    root /var/www/einfach-abhängen.de

    rewrite {
        if {path} not_match ^\/wp-admin
        to {path} {path}/ /index.php?{query}
    }

    fastcgi / /var/run/php-fpm/einfach-abhängen.de_php-fpm.sock php {
        env HTTPS 1
        index index.php
    }

}
/etc/caddy/caddy.conf.d/lit-eratur.de.conf
http://lit-eratur.de http://www.lit-eratur.de {
    log /var/log/caddy/lit-eratur.de_access.log
    errors /var/log/caddy/lit-eratur.de_errors.log
    tls off
    gzip

    root /var/www/lit-eratur.de

    proxy / unix:/run/uwsgi/literatur.sock {
        transparent
    }
}
/etc/caddy/caddy.conf.d/onny.project-insanity.org.conf
http://onny.project-insanity.org/arch-upstream/ {
    log /var/log/caddy/onny.project-insanity.org_access.log
    errors /var/log/caddy/onny.project-insanity.org_errors.log
    tls off
    gzip

    index index.html index.htm upstream.html

    root /usr/share/webapps/arch-upstream
}

http://onny.project-insanity.org {
    log /var/log/caddy/onny.project-insanity.org_access.log
    errors /var/log/caddy/onny.project-insanity.org_errors.log
    tls off
    gzip

    index index.html index.htm upstream.html

    fastcgi / /var/run/php-fpm/onny.project-insanity.org_php-fpm.sock php {
        index index.php
    }

    redir /arch-upstream /arch-upstream/
    
    root /var/www/onny.project-insanity.org

    header /files/kampus_hakatze.xml {
        Content-Type "application/rss+xml; charset=utf-8"
    }

    header /bounce/feed.xml {
        Content-Type "application/rss+xml; charset=utf-8"
    }

    header /laboumdeluxe/feed.xml {
        Content-Type "application/rss+xml; charset=utf-8"
    }

    header /getmetadata {
        Access-Control-Allow-Origin  *
    }

    proxy /getmetadata unix:/run/uwsgi/getmetadata.sock {
        transparent
    }
    proxy /feeds unix:/run/uwsgi/feeds.sock {
        transparent
    }
    proxy /pishare unix:/run/uwsgi/pishare.sock {
        transparent
    }
}
/etc/caddy/caddy.conf.d/zirkel.fun.conf
http://retro.zirkel.fun {
    log /var/log/caddy/zirkel.fun_access.log
    errors /var/log/caddy/zirkel.fun_errors.log
    tls off
    gzip

    root /var/www/zirkel.fun/retro
}

http://zirkel.fun http://www.zirkel.fun {
    log /var/log/caddy/zirkel.fun_access.log
    errors /var/log/caddy/zirkel.fun_errors.log
    tls off
    gzip

    root /var/www/zirkel.fun/root

    rewrite {
        if {path} not_match ^\/wp-admin
        to {path} {path}/ /index.php?{query}
    }
    
    fastcgi / /var/run/php-fpm/zirkel.fun_php-fpm.sock php {
        env HTTPS 1
    }
}
/etc/systemd/system/caddy.service.d/overwride.conf
[Service]
ProtectHome=false
LimitNOFILE=infinity
LimitNPROC=infinity
systemctl daemon-reload
systemctl restart caddy

wordpress

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

upload_max_filesize = 64M
post_max_size = 64M

roundcubemail

pacman -S roundcubemail imagemagick
/etc/webapps/roundcubemail/config/config.inc.php
$config['db_dsnw'] = 'mysql://roundcubemail:****@mysql.pi/roundcubemail';
$config['default_host'] = 'tls://mail.pi';
$config['smtp_server'] = 'tls://mail.pi';
$config['smtp_port'] = 587;
$config['imap_conn_options'] = array(
  'ssl'         => array(
     'verify_peer'  => false,
     'verify_peer_name' => false,
   ),
);
$config['smtp_conn_options'] = array(
  'ssl'         => array(
     'verify_peer'  => false,
     'verify_peer_name' => false,
   ),
);
/etc/php/conf.d/roundcubemail.ini
extension=iconv
extension=pdo_mysql
extension=gd
extension=exif
date.timezone = "UTC"

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

pacaur -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

pacaur -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.
[...]
sudo -u aur aur sync -c fdroidserver android-sdk android-sdk-build-tools gplaycli
pacman -Sy 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]
token=True
token_url=https://matlink.fr/token/email/gsfid

[Cache]
token=~/.cache/gplaycli/token
~/.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
/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/ && 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

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: 2019/09/11 09:11 by 2a02:8071:3eba:0:466d:57ff:fe22:1dfc