kemonine
/
lollipopcloud
Archived
1
0
Fork 0

Import original docs

This commit is contained in:
KemoNine 2018-06-07 22:33:45 -04:00
parent 018c9f763e
commit fdbd56938c
No known key found for this signature in database
GPG Key ID: 331B7E1107F99137
38 changed files with 4134 additions and 0 deletions

3
README.orig.md Normal file
View File

@ -0,0 +1,3 @@
# Docs
The core documentation on how to setup an SBC as a lolipop cloud

3
armbian/README.md Normal file
View File

@ -0,0 +1,3 @@
# Armbian
Setup an SBC as a lolipop router and private LAN

47
armbian/base_setup.md Normal file
View File

@ -0,0 +1,47 @@
# Base Setup
Fundamental setup after first boot/reboot.
## Pro Tip
```sudo -sHu root``` is a handy trick when doing a lot of administrative stuff at the command line
## Upgrade Packages
``` bash
apt update
apt upgrade
systemctl reboot
```
## DISABLE Automatic Update Downloads
*Note: this is to save bandwidth, time, etc when travelling*
### /etc/apt/apt.conf.d/02periodic
Change ```APT::Periodic::Enable "1";``` to ```APT::Periodic::Enable "0";```
### /etc/apt/apt.conf.d/20auto-upgrades
Change ```APT::Periodic::Update-Package-Lists "1";``` to ```APT::Periodic::Update-Package-Lists "0";```
Change ```APT::Periodic::Unattended-Upgrade "1";``` to ```APT::Periodic::Unattended-Upgrade "0";```
## Tweak OpenSSH Config
Edit ```/etc/ssh/sshd_config```
Make sure the following are set and/or adjusted.
- ```PermitRootLogin no```
Restart the service
```systemctl restart sshd```
## Networking
See ```network_manager.md``` for details on getting online after running the above commands for how to get online and configure routing.

88
armbian/borg.md Normal file
View File

@ -0,0 +1,88 @@
# Borg Backups
The BETTER backup solution.
**BE MINDFUL OF RUNNING BORG. IT CAN CAUSE PROBLEMS WITH DISK IOPS AND RAM USAGE. BEST USED WHEN THE MACHINE IS KNOWN TO BE IDLE!!!**
## Inspiration / Further Reading
- [https://borgbackup.readthedocs.io/en/stable/installation.html#from-source](https://borgbackup.readthedocs.io/en/stable/installation.html#from-source)
## Install
Note this is built using sources (kinda). May take awhile on most arm boards.
``` bash
# install build dependencies
apt update
apt install python-setuptools python3-setuptools \
python3 python3-dev python3-pip python-virtualenv \
libssl-dev openssl \
libacl1-dev libacl1 \
build-essential \
libfuse-dev fuse pkg-config
pip3 install borgbackup[fuse]
```
## Upgrades
Per the docs
> To upgrade Borg to a new version later, run the following after activating your virtual environment:
```pip install -U borgbackup[fuse]```
## Initialize Backup Repo
*Note: assumes you have a ```/tank``` on external disk*
``` bash
cd /tank/backup
borg init --encryption none . # No crypto/auth for speed (see docs for more infos)
```
## Backup Script
Setup a backup script that backs up everything (**note the excludes**) to the initialized repository.
Run ```/root/borg_backup.sh``` any time you want to take a backup.
``` bash
cat > /root/borg_backup.sh <<EOF
#!/bin/sh
REPOSITORY=/tank/backup
# Backup all of /home and /var/www except a few
# excluded directories
/usr/local/bin/borg create -v --progress --stats -C lzma,3 \\
\$REPOSITORY::backup-\`date +%Y-%m-%d-%H%M\` \\
/ \\
--exclude /run \\
--exclude /snapshots \\
--exclude /tank \\
--exclude /scratch \\
--exclude /swap \\
--exclude /proc \\
--exclude /sys \\
--exclude /var/lib/schroot/mount \\
--exclude /var/lib/lxcfs \\
--exclude /var/lib/docker \\
--exclude /mnt
# Use the 'prune' subcommand to maintain 7 daily, 4 weekly
# and 6 monthly archives.
/usr/local/bin/borg prune -v --list \$REPOSITORY \\
--keep-daily=7 \\
--keep-weekly=4 \\
--keep-monthly=6
EOF
chmod a+x /root/borg_backup.sh
```

98
armbian/caddy.md Normal file
View File

@ -0,0 +1,98 @@
# Web Service Proxy (caddy)
Simple and efficient go based proxy server and static web host. TLS and more supported out of the box. Supports all kinds of arch's and you probably want to just use this as it's the simplest approach and leanest.
## SSL Certs
This assumes you've run the [Let's Encrypt](lets_encrypt.md) process to get your certificates setup properly.
## Inspiration / Sources
- [https://caddyserver.com/](https://caddyserver.com/)
- [https://github.com/lucaslorentz/caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy)
## Docker Integration
Please note the Docker plugin is for a *swarm* which is *not* setup in these docs. It does **NOT** apply to this build.
## Install
``` bash
mkdir /var/log/caddy
mkdir -p /etc/caddy/services
chown www-data /var/log/caddy /etc/caddy
cat > /root/update_caddy.sh <<EOF
curl https://getcaddy.com | bash -s personal http.cache,http.cgi,http.cors,http.expires,http.filemanager,http.ipfilter,http.locale,http.realip,http.upload,net
EOF
chmod a+x /root/update_caddy.sh
/root/update_caddy.sh
```
## Configure
Setup a basic config for all services provided by the SBC. Pi Hole, NextCloud, Syncthing UIs all behind a SSL/TLS capable proxy.
``` bash
cat > /etc/caddy/Caddyfile <<EOF
# Individual configs are in their own files
import /etc/caddy/services/*.conf
EOF
```
## Adjust firewall to allow caddy on internal network(s)
``` bash
firewall-cmd --permanent --zone=internal --add-service http --add-service https
firewall-cmd --permanent --zone=trusted --add-service http --add-service https
firewall-cmd --reload
```
## Grant access to SSL certificates
``` bash
apt install acl
setfacl -m www-data:rx /var/acme.sh/
setfacl -m www-data:rx /var/acme.sh/domain.tld
setfacl -m www-data:r /var/acme.sh/domain.tld/fullchain.cer
setfacl -m www-data:r /var/acme.sh/domain.tld/domain.tld.cer
setfacl -m www-data:r /var/acme.sh/domain.tld/domain.tld.key
mkdir /etc/ssl/caddy
chown www-data /etc/ssl/caddy
```
## Run via systemd
``` bash
wget -O /etc/systemd/system/caddy.service https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service
chown root:root /etc/systemd/system/caddy.service
chmod 644 /etc/systemd/system/caddy.service
systemctl daemon-reload
systemctl enable caddy.service
```
## Update Caddy
To update Caddy, run the script that was setup during install : ```/root/update_caddy.sh```. That's it, you'll download the latest version and update in-place. Simple.
## Update unbound
*Serve the IP address of the proxy for the services with web interfaces*
``` bash
cat > /etc/unbound/local_zone/caddy.conf <<EOF
local-data: "domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 domain.tld"
EOF
```

52
armbian/chrony.md Normal file
View File

@ -0,0 +1,52 @@
# Chrony
Setup alternative ntp that does well with systems that may or may not always be online.
## Inspiration / Further Reading
- [https://wiki.archlinux.org/index.php/Chrony](https://wiki.archlinux.org/index.php/Chrony)
- [https://insights.ubuntu.com/2018/04/09/ubuntu-bionic-using-chrony-to-configure-ntp](https://insights.ubuntu.com/2018/04/09/ubuntu-bionic-using-chrony-to-configure-ntp)
- [http://manpages.ubuntu.com/manpages/trusty/man5/chrony.conf.5.html](http://manpages.ubuntu.com/manpages/trusty/man5/chrony.conf.5.html)
## Install
``` bash
apt update
apt install chrony
systemctl enable chrony # Enable service
systemctl start chrony # Start service
chronyc activity # Verify install successful
systemctl disable ntp.service # Disable std ntpd (replaced by chrony)
```
## Configuration
``` bash
cat >> /etc/chrony/chrony.conf <<EOF
allow 172.16.16.0/24
allow 172.17.17.0/24
allow 172.18.18.0/24
allow 172.30.0.0/16
# Allow large clock adjustments (you want this as there is no RTC on most SBCs)
makestep 1 -1
EOF
```
Run ```systemctl restart chrony``` to pickup the changes.
## Allow NTP access via internal/trusted networks
``` bash
firewall-cmd --permanent --zone=internal --add-service ntp
firewall-cmd --permanent --zone=trusted --add-service ntp
firewall-cmd --reload
firewall-cmd --info-zone internal
firewall-cmd --info-zone trusted
```

46
armbian/cockpit.md Normal file
View File

@ -0,0 +1,46 @@
# Cockpit
This is **OPTIONAL** but can provide some helpful tools/insights while in the field.
Notably Cockpit includes a terminal via a web browser. Perfect for on-the-go tuning of network settings and/or disaster recovery.
Further reading: [http://cockpit-project.org/running](http://cockpit-project.org/running)
## Install
``` bash
#add-apt-repository ppa:cockpit-project/cockpit
apt update
apt install cockpit cockpit-doc \
cockpit-docker cockpit-networkmanager \
cockpit-dashboard cockpit-system \
cockpit-storaged cockpit-packagekit
systemctl enable cockpit
systemctl start cockpit
```
## Config
Leave the defaults (*including SSL certificate*). This is here to save you on the fly or when not near a 'full' computer. Defaults are a good thing at times.
## Allow internal access
If you already setup firewalld, run the following to allow access from the *INTERNAL* network only.
``` bash
firewall-cmd --permanent --zone=internal --add-port=9090/tcp
firewall-cmd --reload
```
## Grant Admin User(s) Access to Docker
``` bash
usermod -aG docker [admin_user]
systemctl restart docker
```

103
armbian/docker.md Normal file
View File

@ -0,0 +1,103 @@
# Docker
Containerized services for easy deployment and updates.
## Inspiration / Further Reading
- [https://docs.docker.com/install/](https://docs.docker.com/install/)
- [https://docs.docker.com/install/linux/docker-ce/ubuntu/](https://docs.docker.com/install/linux/docker-ce/ubuntu/)
- [https://blog.alexellis.io/get-started-with-docker-on-64-bit-arm/](https://blog.alexellis.io/get-started-with-docker-on-64-bit-arm/)
## Pre Flight Setup
``` bash
apt remove docker docker-engine docker.io
apt install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```
### Arm (32bit / armv7)
``` bash
add-apt-repository \
"deb [arch=armhf] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
```
### Arm (64bit)
``` bash
add-apt-repository \
"deb [arch=arm64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
```
## Install
``` bash
apt update
apt install docker-ce
systemctl enable docker
```
## Adjust Storage
**OPTIONAL**
If you have an external USB storage device always connected, you may want to move the contents of ```/var/lib/docker``` to somewhere on the external storage and use a symlink in place. This will help with churn on the internal micro-sd card and extend its life.
## Create Container Script Dir
For the containers detailed here, you'll want a dedicated directory for keeping the scripts/outputs.
```mkdir /root/docker```
## Configure Docker Default Bridge
Ensure the default Docker bridge doesn't conflict with existing networks.
``` bash
cat >> /etc/docker/daemon.json <<EOF
{
"bip": "10.30.0.1/16"
}
EOF
systemctl restart docker
```
## Setup Custom Network for Services
``` bash
docker network create \
--subnet=172.30.0.1/16 \
docker-private
```
## Trust Docker Private LAN
``` bash
nmcli connection show # Look for uuid of new docker bridge
nmcli connection modify [uuid] connection.zone trusted
systemctl restart NetworkManager docker firewalld
firewall-cmd --info-zone trusted
```

View File

@ -0,0 +1,36 @@
https://github.com/docker/distribution
https://github.com/docker/docker.github.io/blob/master/registry/deploying.md
https://stackoverflow.com/questions/24309526/how-to-change-the-docker-image-installation-directory
Prereq : Docker installed
Prereq : Docker config
/etc/docker/daemon.json
graph: /tank/docker/graph
docker info | grep "Docker Root Dir"
docker pull ubuntu:16.04 # pull from hub
docker tag ubuntu:16.04 localhost:5000/my-ubuntu # tag for registry
docker push localhost:5000/my-ubuntu # push to registry
docker image remove ubuntu:16.04 # nuke local cache
docker image remove localhost:5000/my-ubuntu # nuke local cached
docker pull localhost:5000/my-ubuntu # pull from registry
docker run --name registry \
--restart unless-stopped \\
-p 5000:5000 \
-e TZ=UTC \\
-e DEBUG=1 \\
-e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v /path/data:/var/lib/registry
-v /path/certs:/certs
-v /path/auth:/auth
registry/registry:$tag

20
armbian/elasticbeats.md Normal file
View File

@ -0,0 +1,20 @@
https://www.elastic.co/products/beats/filebeat
https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-installation.html
https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-configuration.html
docker pull docker.elastic.co/beats/filebeat:6.2.4
docker run --name filebeat --restart unless-stopped --net docker-private --ip 172.30.11.11 -e TZ=UTC -e DEBUG=1 docker.elastic.co/beats/filebeat:6.2.4
This can't be accomplished just yet but it looks promising for the future
https://github.com/elastic/beats-docker/tree/6.2
https://discuss.elastic.co/t/how-to-install-filebeat-on-a-arm-based-sbc-eg-raspberry-pi-3/103670/2
https://github.com/elastic/beats/tree/master/dev-tools/packer
https://s3-us-west-2.amazonaws.com/beats-package-snapshots/index.html?prefix=filebeat/
https://s3-us-west-2.amazonaws.com/beats-package-snapshots/index.html?prefix=metricbeat/

142
armbian/firewalld.md Normal file
View File

@ -0,0 +1,142 @@
# FirewallD
AKA : firewall and routing. Let's make this a firewall/router!
## Inspiration / Further Reading
- [http://www.firewalld.org/](http://www.firewalld.org/)
- [http://www.firewalld.org/documentation/howto/add-a-service.html](http://www.firewalld.org/documentation/howto/add-a-service.html)
- [http://www.firewalld.org/documentation/howto/reload-firewalld.html](http://www.firewalld.org/documentation/howto/reload-firewalld.html)
- [https://www.certdepot.net/rhel7-get-started-firewalld/](https://www.certdepot.net/rhel7-get-started-firewalld/)
- [https://fedoramagazine.org/build-network-router-firewall-fedora-22-systemd-networkd/](https://fedoramagazine.org/build-network-router-firewall-fedora-22-systemd-networkd/)
- [https://www.centos.org/forums/viewtopic.php?f=50&t=53819#p227743](https://www.centos.org/forums/viewtopic.php?f=50&t=53819#p227743)
## Configure sysctl for routing purposes
*Note: This was borrowed from the standard OpenWRT ```sysctl.conf```*
``` bash
# Setup NAT/Forwarding/Routing sysctl config
cat > /etc/sysctl.d/20-routing.conf <<EOF
net.ipv4.conf.default.arp_ignore=1
net.ipv4.conf.all.arp_ignore=1
net.ipv4.ip_forward=1
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.igmp_max_memberships=100
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_keepalive_time=120
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_timestamps=1
net.ipv4.tcp_sack=1
net.ipv4.tcp_dsack=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1
EOF
# Apply configuration
sysctl -p
```
## Setup FirewallD
``` bash
apt update
apt install firewalld
systemctl enable firewalld
systemctl start firewalld
```
## Verify Fundamentals
Run ```firewall-cmd --get-default-zone``` and make sure it returns ```public```.
If not run:
``` bash
firewall-cmd --set-default-zone=public
firewall-cmd --runtime-to-permanent
firewall-cmd --reload
```
## Allow internal access to ssh
``` bash
# Remove ssh from public zone
firewall-cmd --permanent --zone=public --remove-service=ssh
# Add ssh to internal zone
firewall-cmd --permanent --zone=internal --add-service ssh
# Reload rules
firewall-cmd --reload
# Verify rules
firewall-cmd --zone=public --list-all
firewall-cmd --zone=internal --list-all
```
## Useful Commands
- ```firewall-cmd --state```
- ```firewall-cmd --runtime-to-permanent```
- ```firewall-cmd --reload```
- ```firewall-cmd --get-default-zone```
- ```firewall-cmd --get-active-zones```
- ```firewall-cmd --get-zones```
- ```firewall-cmd --info-zone=[aZone]```
- ```firewall-cmd --permanent --zone=[aZone] --list-all```
- ```firewall-cmd --get-zone-of-interface=[iface]```
- ```firewall-cmd --get-log-denied```
- ```firewall-cmd --set-log-denied all```
## Tweak NetworkManager Connection Zones
``` bash
# Adjust interfaces from NetworkManager setup
firewall-cmd --permanent --zone=internal --change-interface=[wifi adapter for hot spots]
firewall-cmd --reload
nmcli connection modify wifi-ap-24 connection.zone internal
nmcli connection modify wifi-ap-50 connection.zone internal
nmcli connection modify mgmt connection.zone internal
# Verify zone configs
firewall-cmd --get-active-zones
```
## Turn on Routing
``` bash
firewall-cmd --permanent --zone=public --add-masquerade # Add NAT stuff for ipv4
firewall-cmd --permanent --query-masquerade # Make sure it's actually on
firewall-cmd --permanent --zone=internal --add-source=172.16.16.0/24
firewall-cmd --permanent --zone=internal --add-source=172.17.17.0/24
firewall-cmd --permanent --zone=internal --add-source=172.18.18.0/24
firewall-cmd --permanent --zone=internal --add-service dns --add-service dhcp
firewall-cmd --reload
```
## Other Useful Commands
Odds and ends for setting up services and the like. You can probably ignore this section. Breadcrumbs for the author really.
``` bash
firewall-cmd --permanent --zone=trusted --add-source=192.168.2.0/24
firewall-cmd --zone=internal --add-service=ssh --permanent
firewall-cmd --zone=internal --add-service={ssh,http,https,dns}
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-forward-port=port=22:proto=tcp:toport=3753:toaddr=10.0.0.1
```

35
armbian/first_boot.md Normal file
View File

@ -0,0 +1,35 @@
# First Boot
Basic setup and configuration that's necessary to get under way.
## Adjust root password + Create First User
When you login to Armbian as root the first time you'll be prompted to set a root password and create the first user.
Follow the prompts and create an administrative user (armbian/ubuntu/admin/etc as the name) that will be used as your primary 'admin' login.
The rest of this guide assumes you'll be logged in as the admin user and will be using sudo to run all commands.
## Mirror Docs
Just in case you need reference material while offline or on a bad network link, mirror these docs to the root filesystem.
```git clone https://gitlab.com/kemonine/lolipop_lan_cloud.git /root/lolipop_lan_cloud```
## Disable root login
This will **EXPIRE** the root password. If you run this you can **NOT** login as root!!! Use with care if you're not used to sudo and/or want to retain root login for some reason.
``` bash
passwd -l root
```
## Cleanup fstab
Edit ```/etc/fstab``` and remove the ```commit=600``` block from the root filesystem definition.
## Reboot
This is necessary for the armbian setup to finish resizing the filesystem stored on the sd card.

33
armbian/gogs.md Normal file
View File

@ -0,0 +1,33 @@
# Gogs
Self hosted git repos, issue tracking and more. Think GitHub/GitLab but self hosted and lean.
## Inspiration / Further Reading
- [https://discuss.gogs.io/t/how-to-backup-restore-and-migrate/991](https://discuss.gogs.io/t/how-to-backup-restore-and-migrate/991)
- [https://blog.meinside.pe.kr/Gogs-on-Raspberry-Pi/](https://blog.meinside.pe.kr/Gogs-on-Raspberry-Pi/)
## Build/Install/Update/Run Scripts
Setup a generic script that'll auto update Gogs, build a container and launch it. You should only run this script at first launch and/or when you're looking for updates.
```FIXME : Update with wget/sed from repo```
## Run Gogs
Simply execute ```/root/docker/gogs/gogs.sh``` to update/run Gogs.
## Serving Via Caddy
```FIXME : Update with wget/sed from repo```
## Update Unbound
```FIXME : Update with wget/sed from repo```
## First Run / Finalize Setup
- Navigate to ```http://gogs-insecure.domain.tld:3000```
- Follow on-screen prompts for finalizing setup
- Be sure to specify an admin user
- Login to ```https://gogs.domain.tld``` and enjoy

60
armbian/incron.md Normal file
View File

@ -0,0 +1,60 @@
# Incron
A 'cron' daemon that watches the filesystem for changes and performs actions. This is used to auto-apply config for Caddy and Unbound.
This is here mainly to facilitate auto-reloads of Caddy/Unbound during setup and over time. This is especially helpful if using acme.sh for Let's Encrypt certificates as they are regularly updated and once updated need a restart of the Caddy service. This config takes care of that situation as well as updated DNS records in Unbound.
## Inspiration / Sources
- [https://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/](https://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/)
## Install
``` bash
apt update
apt install incron
systemctl enable incron
systemctl start incron
```
## Configure
### Unbound
``` bash
cat > /etc/incron.d/unbound.conf <<EOF
/etc/unbound/local_zone IN_CREATE,IN_ATTRIB,IN_MODIFY,IN_DELETE unbound-control reload
EOF
```
### Caddy
``` bash
cat > /etc/incron.d/caddy.conf <<EOF
/etc/caddy/services IN_CREATE,IN_ATTRIB,IN_MODIFY,IN_DELETE killall -USR1 caddy
EOF
```
### Acme.sh Certificate Updates
``` bash
cat > /etc/incron.d/acme-sh.conf <<EOF
/var/acme.sh/domain.tld IN_CREATE,IN_ATTRIB,IN_MODIFY,IN_DELETE killall -USR1 caddy
EOF
```
### Post Configure
``` bash
systemctl restart incron
```

177
armbian/lets_encrypt.md Normal file
View File

@ -0,0 +1,177 @@
# Let's Encrypt
Use [acme.sh](https://github.com/Neilpang/acme.sh/) for wholly self-contained Let's Encrypt certificates. This assumes CloudFlare DNS is used for authentication.
*Note: You probably want to use a DNS provider/API so you don't have to expose a service to the outside world*
*NOTE: You may want to use a filesystem on a USB disk instead of /var for the volumes setup in the below Docker command(s) to help reduce writes to the micro sd card*
## Dependencies
``` bash
apt update
apt install jq
```
## Prep
Grab the acme.sh Dockerfile and update it to work with arm (32 or 64).
``` bash
mkdir -p /root/docker/acme.sh
cd /root/docker/acme.sh
wget https://raw.githubusercontent.com/Neilpang/acme.sh/master/Dockerfile
sed -i '1s/^/ARG ALPINE=alpine:3.6\n/' Dockerfile
sed -i '/FROM/c\FROM $ALPINE' Dockerfile
mkdir /var/acme.sh
chmod 700 /var/acme.sh
```
## Setup / Run
Setup a basic update/run script with the adjusted upstream Dockerfile
``` bash
cat > /root/docker/acme.sh/acme.sh <<EOF
#!/bin/bash
LATEST=\`docker images --no-trunc acme.sh/acme.sh | awk '{print \$2}' | sort -r | head -n1\`
RELEASE=\`curl -s https://api.github.com/repos/Neilpang/acme.sh/releases/latest | jq -r .tag_name\`
if [ \$RELEASE == \$LATEST ]
then
echo "Already up to date"
fi
ARCH=\`arch\`
ALPINE=""
# Cleanup arch here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
ARCH="arm64"
ALPINE="arm64v8/alpine"
else
echo "32bit arm"
ARCH="arm"
ALPINE="arm32v6/alpine"
fi
echo "Build parms"
echo " \${RELEASE}"
echo " \${ARCH}"
echo " \${ALPINE}"
echo "Running build"
docker build \\
--network host \\
--build-arg ALPINE=\$ALPINE \\
--file /root/docker/acme.sh/Dockerfile \\
--tag acme_sh/acme_sh:\$RELEASE \\
.
echo "Running with latest release"
# Cleanup existing container
docker stop acme_sh
docker rm acme_sh
# Re-run/create container with latest image
# daemon (for cron auto renews)
docker run -itd \\
-v "/var/acme.sh":/acme.sh \\
--net=host \\
--restart unless-stopped \\
--name=acme_sh \\
acme_sh/acme_sh:\$RELEASE daemon
EOF
chmod a+x /root/docker/acme.sh/acme.sh
```
## First Run
Run ```cd /root/docker/acme.sh && /root/docker/acme.sh/acme.sh``` to get the container online. The following commands will get your Let's Encrypt certificates created.
*Note: The above script(s) setup the container to auto-run for auto-renew purposes. If you think you'll miss your renew window, force update the certs*
## Get Help
``` bash
docker exec acme.sh --help
```
## Renewals...
If you're going to be on the go, you may want to force rewewal of your scripts ahead of any travel or longer periods of time away from the internet. The author recommends a simple script at ```/root/update_certs.sh``` or similar that calls the necessary command(s) from below.
## Register a Let's Encrypt Account
Only do this **ONCE**
``` bash
docker exec acme.sh \
--register-account \
--staging
```
## Issue Cert (CloudFlare DNS API)
``` bash
docker exec \
-e CF_Email='[your cloudflare email]' \
-e CF_Key='[your cloudflare api key]' \
acme.sh \
--issue \
--cert-file /acme.sh/domain.tld/domain.tld.crt \
--dns dns_cf \
-d domain.tld \
-d pi-hole-gui.domain.tld \
-d syncthing-gui.domain.tld \
-d nextcloud.domain.tld \
--staging
```
## Force Renew All Certs (CloudFlare DNS API)
``` bash
docker exec \
-e CF_Email='[your cloudflare email]' \
-e CF_Key='[your cloudflare api key]' \
acme.sh \
--renew-all \
--force \
--dns dns_cf \
--staging
```
## Revoke Cert
``` bash
docker exec acme.sh \
--revoke \
-d domain.tld \
-d pi-hole-gui.domain.tld \
-d syncthing-gui.domain.tld \
-d nextcloud.domain.tld \
--staging
```

95
armbian/modem_manager.md Normal file
View File

@ -0,0 +1,95 @@
# Modem Manager
Setup an LTE/3G modem. You'll need to adapt this information to your specific modem(s) but overall the process is sound.
## Inspiration / Further Reading
- [https://www.freedesktop.org/software/ModemManager/man/1.0.0/mmcli.8.html](https://www.freedesktop.org/software/ModemManager/man/1.0.0/mmcli.8.html)
- [https://superuser.com/questions/1228477/linux-gsm-nmcli-working-with-two-gsm-modems-and-connections](https://superuser.com/questions/1228477/linux-gsm-nmcli-working-with-two-gsm-modems-and-connections)
- [https://unix.stackexchange.com/questions/113975/configure-gsm-connection-using-nmcli](https://unix.stackexchange.com/questions/113975/configure-gsm-connection-using-nmcli)
- [http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=836](http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=836)
- [https://wiki.openwrt.org/doc/recipes/3gdongle](https://wiki.openwrt.org/doc/recipes/3gdongle)
- [http://www.draisberghof.de/usb_modeswitch/#download](http://www.draisberghof.de/usb_modeswitch/#download)
- [http://www.draisberghof.de/usb_modeswitch/#install](http://www.draisberghof.de/usb_modeswitch/#install)
- [http://www.draisberghof.de/usb_modeswitch/#install](http://www.draisberghof.de/usb_modeswitch/#install)
- [https://forums.linuxmint.com/viewtopic.php?f=53&t=119342](https://forums.linuxmint.com/viewtopic.php?f=53&t=119342)
- [https://bostonenginerd.com/posts/getting-the-t-mobile-jet-huawei-366-usb-modem-to-work-in-linux/](https://bostonenginerd.com/posts/getting-the-t-mobile-jet-huawei-366-usb-modem-to-work-in-linux/)
- [https://github.com/Robpol86/robpol86.com/blob/master/docs/raspberry_pi_project_fi.rst](https://github.com/Robpol86/robpol86.com/blob/master/docs/raspberry_pi_project_fi.rst)
## On The Go Help
If you're ever in need of help on the go, ```man mmcli``` has a lot of good info as does ```mmcli --help```.
## Initial Setup
The steps below are for getting USB mode switch working which is necessary for some Huawei modems. This example is for a Huawei 366 modem. You'll need to adjust your setup accordingly.
``` bash
apt update
apt install usb-modeswitch usb-modeswitch-data
cd /etc/usb_modeswitch.d
tar -xzf /usr/share/usb_modeswitch/configPack.tar.gz
lsusb # note modem ids
# Huawei e366
usb_modeswitch --default-vendor 12d1 --default-product 1446 -c /etc/usb_modeswitch.d/12d1\:1446
lsusb # verify the modem ids changed (may take a moment to mode switch)
```
## Modem Manager Setup / Preflight
``` bash
apt update
apt install modemmanager # Install
systemctl enable ModemManager # Enable the service
systemctl start ModemManager # Start the service
mmcli --scan-modems # Scan for modems (this can take a few minutes)
mmcli --list-modems # List the modems modem manager sees
mmcli --modem 0 # Get details of first modem
```
## Setup Auto Mode Switch
This should be setup by the ```usb_modeswitch``` package for you. Reboot and then run ```lspci``` to ensure it's 100%.
## Useful mmcli Commands / Switches
- ```mmcli --monitor-modems```
- ```mmcli --enable```
- ```mmcli --disable```
- ```mmcli --monitor-state```
- ```--set-power-state-on```
- ```--set-power-state-low```
- ```--set-power-state-off```
## Add connection to NetworkManager
``` bash
# Ensure things work
mmcli --modem 0 --enable
mmcli --modem 0 --list-bearers
mmcli --modem 0 --3gpp-scan --timeout=30
# Simple connection (this does no good in production)
mmcli --modem 0 --simple-connect="pin=1234,apn=internet"
# Setup persistent connection via NetworkManager
nmcli c add con-name "wan-wwan-1" type gsm ifname "*" apn "internet"
```
## Location Related Commands
``` bash
mmcli --modem 0 --location-status
mmcli --modem 0 --location-enable-3gpp
mmcli --modem 0 --location-enable-gps-nmea
mmcli --modem 0 --location-enable-gps-raw
mmcli --modem 0 --location-get
```

76
armbian/monitoring.md Normal file
View File

@ -0,0 +1,76 @@
# Monitoring
Track resource utilization over time.
**BE MINDFUL OF RUNNING THIS. IT CAN CAUSE PROBLEMS WITH DISK IOPS AND RAM USAGE. BEST ONLY USED IF NEEDED OR YOU'RE TROUBLESHOOTING.**
## cadvisor
[cadvisor (link)](https://github.com/google/cadvisor) has been recommended for monitoring Docker container resource usage. Could be useful.
Untested by the Author.
## Munin
Simple, efficient, old school, well supported. Start here.
Further reading : [http://munin-monitoring.org/](http://munin-monitoring.org/)
### Install
``` bash
apt update
apt install munin munin-node \
munin-plugins-core munin-plugins-extra \
libcgi-fast-perl
vim /etc/munin/munin.conf
vim /etc/munin/munin-node.conf
vim /etc/munin/plugin-conf.d/*
munin-node-configure --suggest 2>&1 | less
munin-node-configure --shell 2>&1 | less
systemcl restart munin-node
systemctl enable munin-node
```
### Serving Output Via Caddy
``` bash
cat > /etc/caddy/services/munin.conf <<EOF
# Munin - Static web resources
domain.tld:80/static domain.tld:443/static {
redir 301 {
if {scheme} is http
/ https://domain.tld{uri}
}
root /etc/munin/static
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
}
# Munin - main site/cgi's
domain.tld:80 domain.tld:443 {
redir 301 {
if {scheme} is http
/ https://domain.tld{uri}
}
log /var/log/caddy/test.kemonine.info.log
# Setup CGI rendering scripts
cgi /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph
cgi /munin-cgi/munin-cgi-html /usr/lib/munin/cgi/munin-cgi-html
# Set path to generated HTML via cron/systemd processes
root /var/cache/munin/www
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
}
EOF
```

241
armbian/network_manager.md Normal file
View File

@ -0,0 +1,241 @@
# Network Manager
```TODO : INCOMPLETE```
Setup overall networking. This is focused on ethernet/WiFi as an internet connection.
## Inspiration / Further Reading
- [https://developer.gnome.org/NetworkManager/stable/NetworkManager.html](https://developer.gnome.org/NetworkManager/stable/NetworkManager.html)
- [https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html](https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html)
- [https://developer.gnome.org/NetworkManager/stable/nmcli.html](https://developer.gnome.org/NetworkManager/stable/nmcli.html)
- [https://developer.gnome.org/NetworkManager/stable/nmcli-examples.html](https://developer.gnome.org/NetworkManager/stable/nmcli-examples.html)
## Overview
Setup the base NetworkManager config/networking. This will help with making the Internet side of networking more dynamic and responsive to devices being added/removed.
The author assumes LAN/Ethernet > WiFi > 3G/LTE for connection priority. (*Note: NetworkManager assumes this too*)
## Install / Enable
``` bash
apt update
# Install additional deps
apt install ebtables ipset
# Install + add-ons
apt install network-manager \
network-manager-openvpn network-manager-pptp
systemctl enable NetworkManager # Enable the service
systemctl start NetworkManager # Start the service
```
## Disable Stock Networking
Edit ```/etc/network/interfaces``` and make sure eth0 directives aren't present.
Reboot after above cleanup of interfaces file.
## ProTip
```nmtui``` can be used for an ncurses graphical interface for NetworkManager
## Set Hostname
``` bash
nmcli general hostname [hostname] # Additional parm sets hostname
systemctl reboot # Reboot to pickup the change
```
## Get Status
Some commands that help getting the status of NetworkManager
- ```nmcli networking connectivity```
- ```nmcli monitor```
- ```nmcli device monitor```
- ```nmcli connection monitor```
## Enable / Disable ALL
Handy if you want to shut down *all* networking for some reason
```nmcli networking on|off```
## Radio Control
Control WiFi / GSM radios
### Wifi
```nmcli radio wifi [on|off]```
### 3G/LTE
```nmcli radio wwan [on|off]```
## Connection / Device Related
Some useful commands for adjusting connection/device status
- ```nmcli connection reload # Reload any changes / updates (this isn't automagic by default)```
- ```nmcli connection show --active```
- ```nmcli connection up [id]```
- ```nmcli connection down [id]```
- ```nmcli device status```
- ```nmcli device show [ifname]```
- ```nmcli device connect [ifname]```
- ```nmcli device disconnect [ifname]```
## Disable Orange Pi Zero Internal WiFi
If you're using an Orange Pi Zero, the internal WiFi adapter is unstable at best. The following will disable the adapter.
``` bash
nmcli device status # Verify the internal WiFi is shwoing as wlan0
nmcli device disconnect wlan0 # Run this if it shows as connected
nmcli device set wlan0 autoconnect no
```
## Setup Networks
Some configuration via ```nmcli``` for various networks/interfaces/devices that may or may not be in use at any given moment. These commands just make NetworkManager aware of the overall topology and connections. Routing, firewall and more is setup later.
*Note: Add autoconnect false if you don't want the connection auto started if a device is present*
### Clear Existing
Run ```nmcli connection show``` to get a list of active network connections. We will want to remove all of these.
Run ```nmcli connection del [UUID]``` for each UUID listed in the previous commands output.
### Management Ethernet
*Note: It's assumed the on-board ethernet adapter will be used for management and an EXTERNAL USB Ethernet adapter used for WAN (if needed)*
``` bash
# Management via usb ethernet adapter
# includes network sharing
nmcli connection add save yes \
type ethernet \
con-name mgmt \
ifname eth0 \
-- \
ipv4.method shared \
ipv4.addr 172.16.16.16/24 \
ipv6.method ignore
nmcli device set eth0 autoconnect yes
```
### WiFi 2.4ghz Access Point
*Note: You can use ```802-11-wireless.channel #``` in the below command to force a channel to be used*
``` bash
# Get the ifname of the wifi adapter with `nmcli dev show`
# HostAP mode (2.4ghz / wireless access point)
# includes network sharing
nmcli connection add save yes \
type wifi \
con-name wifi-ap-24 \
ifname [wifi iface] \
ssid 24.lolipop.domain.tld \
-- \
ipv4.method shared \
ipv4.addresses 172.17.17.17/24 \
ipv6.method ignore \
802-11-wireless.mode ap \
802-11-wireless.band bg \
802-11-wireless.channel 11 \
802-11-wireless-security.key-mgmt wpa-psk \
802-11-wireless-security.proto rsn \
802-11-wireless-security.psk MyPassword
```
### WiFi 5ghz Access Point
*Note: You can use ```802-11-wireless.channel #``` in the below command to force a channel to be used*
``` bash
# Get the ifname of the wifi adapter with `nmcli dev show`
# HostAP mode (5ghz / wireless access point)
# includes network sharing
nmcli connection add save yes \
type wifi \
con-name wifi-ap-50 \
ifname [wifi iface] \
ssid 50.lolipop.domain.tld \
-- \
ipv4.method shared \
ipv4.addresses 172.18.18.18/24 \
ipv6.method ignore \
802-11-wireless.mode ap \
802-11-wireless.band a \
802-11-wireless.channel 40 \
802-11-wireless-security.key-mgmt wpa-psk \
802-11-wireless-security.proto rsn \
802-11-wireless-security.psk MyPassword
```
### WAN - Ethernet (External USB Adapter)
*Note: It's assumed you'll be using a USB Ethernet adapter for WAN if needed. This matches the overall use of USB devices that are plugged/unplugged as necessary for WAN needs*
``` bash
# WAN via ethernet cable
nmcli connection add save yes \
type ethernet \
con-name wan-eth \
ifname eth1 \
-- \
ipv4.method auto \
ipv6.method auto
nmcli device set eth1 autoconnect yes
```
### WAN - WiFi Bridge
``` bash
# Get list of access points in the area
nmcli dev wifi list
# Get the ifname of the client wifi adapter with `nmcli dev show`
# WAN via Client mode (wireless bridge)
# Note the ASK flag so you're prompted to enter user/pass type infos
nmcli connection add save yes \
type wifi \
con-name wan-wifi \
ifname [wifi iface] \
ssid [ssidFromAbove] \
-- \
wifi-sec.key-mgmt wpa-psk \
wifi-sec.psk [wpaPassword]
nmcli device set [wifi iface] autoconnect yes
```
### WAN - GSM (3G/LTE)
See [Modem Manager](modem_manager.md) for details on integrating a 3G/LTE modem into the networking setup.
## Auto Config
Once the above is setup Network Manager should handle the auto configuration of your WAN/LAN/Modems/etc for you.

262
armbian/nextcloud.md Normal file
View File

@ -0,0 +1,262 @@
# NextCloud
NextCloud in a container. A simple PHP-FPM deployment. You'll need the Web Server container setup to get access. This just gives a very basic, non-web-server version of NextCloud.
*NOTE: You may want to use a filesystem on a USB disk instead of /var for the volumes setup in the below Docker command(s) to help reduce writes to the micro sd card*
## Inspiration / Sources
- [https://github.com/nextcloud/docker](https://github.com/nextcloud/docker)
- [https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion)
- [https://hub.docker.com/_/nextcloud/](https://hub.docker.com/_/nextcloud/)
- [https://hub.docker.com/r/arm64v8/nextcloud/](https://hub.docker.com/r/arm64v8/nextcloud/)
- [https://hub.docker.com/r/arm32v5/nextcloud/](https://hub.docker.com/r/arm32v5/nextcloud/)
- [https://hub.docker.com/r/arm32v7/nextcloud/](https://hub.docker.com/r/arm32v7/nextcloud/)
## Install / Update / Run Script
Setup a generic script that'll auto update NextCloud, build a container and launch it. You should only run this script at first launch and/or when you're looking for updates.
``` bash
mkdir /var/nextcloud
chown www-data /var/nextcloud
cat > /root/docker/nextcloud.sh <<EOF
#!/bin/bash
ARCH=\`arch\`
UPSTREAM="arm32v7/nextcloud:stable"
# Cleanup arch/container image here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
UPSTREAM="arm64v8/nextcloud:stable"
else
echo "32bit arm"
UPSTREAM="arm32v7/nextcloud:stable"
fi
echo "Updating"
docker pull \$UPSTREAM
echo "Running with latest release"
# Cleanup existing container
docker stop nextcloud
docker rm nextcloud
##########
# For postgresql instead of sqlite run the following commands
#docker exec -it postgres psql -U postgres
#create role nextcloud nocreatedb nocreaterole login PASSWORD 'password';
#create database nextcloud owner=nextcloud encoding=UTF8;
# Setup using the above database/username/role and ip of 172.30.12.12
##########
# Re-run/create container with latest image
docker run \\
--name nextcloud \\
--restart unless-stopped \\
--net docker-private \\
--ip 172.30.7.7 \\
-e TZ=UTC \\
-e DEBUG=1 \\
-v /var/nextcloud:/var/www/html \\
\$UPSTREAM
EOF
chmod a+x /root/docker/nextcloud.sh
```
## Run NextCloud
Simply execute ```/root/docker/nextcloud.sh``` to update/run NextCloud.
## Update Unbound
``` bash
cat > /etc/unbound/local_zone/nextcloud.conf <<EOF
local-data: "nextcloud-insecure A 172.30.7.7"
local-data-ptr: "172.30.7.7 nextcloud-insecure"
local-data: "nextcloud-insecure.domain.tld A 172.30.7.7"
local-data-ptr: "172.30.7.7 nextcloud-insecure.domain.tld"
local-data: "nextcloud A 172.30.0.1"
local-data: "nextcloud.domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 nextcloud"
local-data-ptr: "172.30.0.1 nextcloud.domain.tld"
EOF
```
## Serving Via Caddy
``` bash
cat > /etc/caddy/services/nextcloud.conf <<EOF
# Nextcloud proxy
nextcloud:80, nextcloud:443, nextcloud.domain.tld:80, nextcloud.domain.tld:443 {
redir 301 {
if {scheme} is http
/ https://nextcloud.domain.tld{uri}
}
log /var/log/caddy/nextcloud.log
proxy / 172.30.7.7:80 {
transparent
}
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
header / {
# Enable HTTP Strict Transport Security (HSTS) to force clients to always
# connect via HTTPS (do not use if only testing)
Strict-Transport-Security "max-age=15552000;"
# Enable cross-site filter (XSS) and tell browser to block detected attacks
X-XSS-Protection "1; mode=block"
# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type
X-Content-Type-Options "nosniff"
# Disallow the site to be rendered within a frame (clickjacking protection)
X-Frame-Options "DENY"
}
}
EOF
```
## First Run / Finalize Setup
- Navigate to ```http://nextcloud-insecure.domain.tld```
- Follow on-screen prompts for finalizing the NextCloud setup
- Login as Admin
## Post Install
### Update/Install/Enable Apps
#### Enabled Apps
- Update any apps that are showing as out of date
#### Disabled apps
- Enable Auditing / Logging app
- Enable Default encryption module
- Enable external storage support
- Enable PDF Viewer
#### Customization
- Install External sites app
#### Files
- Install Group folders app
#### Office & Text
- Enable Calendar app
- Enable Contacts app
- Enable Notes app
- Enable Tasks app
#### Organization
- Install Annoucement center app
- Enable bookmarks app
#### Security
- Enable brute force settings app
- Enable restrict login to IP addresses app
- Enable Two Factor TOTP Provider app
- Enable Two Factor U2F app
- Enable Two Factory Yubikey
#### Social & communication
- Enable circles app
#### Tools
- Enable Impersonate app
### Basic Setup
#### Adjust default view
If you'd like to see the activities view as your default view in NextCloud, edit ```/var/nextcloud/config/config.php``` and add ```'defaultapp' => 'activity',``` to the file.
#### Add Cronjob
In the settings change from ```Ajax``` for scheduled jobs to ```Cron``` and run the following commands on your device.
This will lessen the page loads and keep the cron job constrained to a reasonable duration.
``` bash
cat > /etc/systemd/system/nextcloudcron.service <<EOF
[Unit]
Description=Nextcloud cron.php job
[Service]
User=roo
ExecStart=/usr/bin/docker exec --user www-data nextcloud php /var/www/html/cron.php
[Install]
WantedBy=basic.target
EOF
cat > /etc/systemd/system/nextcloudcron.timer <<EOF
[Unit]
Description=Run Nextcloud cron.php every 90 minutes
[Timer]
OnBootSec=10min
OnUnitActiveSec=90min
Unit=nextcloudcron.service
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl start nextcloudcron.timer
systemctl enable nextcloudcron.timer
```
#### Adjust Sharing settings
- Disable ```Allow public uploads```
- Disable ```Allow users on this server to send shares to other servers```
- Disable ```Send password by mail```
#### Adjust Security settings
Recommended Settings (Up to you)
- Minimal Length : 12
- Forbid common passwords
- Enforce upper and lower case characters
- Enforce numeric characters
### Setup Apps
- Setup file encryption : [https://docs.nextcloud.com/server/13/admin_manual/configuration_files/encryption_configuration.html](https://docs.nextcloud.com/server/13/admin_manual/configuration_files/encryption_configuration.html)
- Setup external sites app as appropriate
- Setup remaining apps from above
### Configure groups (as appropriate)
- Create group for standard users
- Create group folder for the new group (non-syncthing dumping ground for sync)
- Setup shared contacts list for new group
- Setup shared calendar for new group

173
armbian/pi_hole.md Normal file
View File

@ -0,0 +1,173 @@
# Pi Hole
Ad blocking at the DNS level. Save yourself that precious transfer while on the go.
This was chosen as it's designed to run on a Raspberry Pi and... this project is all about that kind of hardware.
*NOTE: You may want to use a filesystem on a USB disk instead of /var for the volumes setup in the below Docker command(s) to help reduce writes to the micro sd card*
## Inspiration / Further Reading
- [https://hub.docker.com/r/diginc/pi-hole/](https://hub.docker.com/r/diginc/pi-hole/)
- [https://hub.docker.com/r/diginc/pi-hole-multiarch/tags/](https://hub.docker.com/r/diginc/pi-hole-multiarch/tags/)
- [https://github.com/diginc/docker-pi-hole/blob/master/README.md](https://github.com/diginc/docker-pi-hole/blob/master/README.md)
- [https://www.bentasker.co.uk/documentation/linux/279-unbound-adding-custom-dns-records](https://www.bentasker.co.uk/documentation/linux/279-unbound-adding-custom-dns-records)
## Update Unbound
### Setup unbound to listen on the Docker LAN so it can be the upstream of Pi Hole
Add a 2nd ```interface``` line to ```/etc/unbound/unbound.conf```
```interface: 172.30.0.1```
Restart unbound with ```systemctl restart unbound```
## Setup Unbound to start *after* Docker
*See [here (link)](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-Managing_Services_with_systemd-Unit_Files#brid-Managing_Services_with_systemd-Extending_Unit_Config) for more details.*
This is mainly here to ensure that unbound starts *after* the Docker network comes up as it's configured to listen on the Docker network. It'll fail to load/restart if the bind address isn't present when it is started.
``` bash
mkdir -p /etc/systemd/system/unbound.service.d
cat > /etc/systemd/system/unbound.service.d/10-after-docker.conf <<EOF
[Unit]
Requires=docker.service
After=docker.service
Restart=always
RestartSec=10
EOF
systemctl daemon-reload
```
## Setup Initial Run & Update Script
A simple update script that will pull the latest Pi Hole Docker image, configure it for auto-run, etc. Note the settings under the ```docker run``` command. You need/want to tweak them lightly.
Full docs on run time parms can be found in the Pi Hole [docs (link)](https://github.com/diginc/docker-pi-hole/blob/master/README.md).
``` bash
mkdir /var/pihole /var/pihole/data /var/pihole/dnsmasq.d
cat > /root/docker/pi-hole.sh <<EOF
#!/bin/bash
ARCH=\`arch\`
UPSTREAM=""
# Cleanup arch/container image here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
UPSTREAM="diginc/pi-hole-multiarch:debian_aarch64"
else
echo "32bit arm"
UPSTREAM="diginc/pi-hole-multiarch:debian_armhf"
fi
echo "Updating"
docker pull \$UPSTREAM
# Cleanup existing container
docker stop pi-hole
docker rm pi-hole
# Re-run/create container with latest image
docker run \\
--name pi-hole \\
--restart unless-stopped \\
--memory=128m \\
--net docker-private \\
--ip 172.30.5.5 \\
-e ServerIP=172.30.5.5 \\
-e DNS1=172.30.0.1 \\
-e TZ=UTC \\
-e WEBPASSWORD=[adecentpassword] \\
-e DEBUG=1 \\
-v /var/pihole/data:/etc/pihole \\
-v /var/pihole/dnsmasq.d:/etc/dnsmasq.d \\
\$UPSTREAM
EOF
chmod a+x /root/docker/pi-hole.sh
```
## Run Pi Hole
Simply execute ```/root/docker/pi-hole.sh``` to update/run Pi Hole.
## Update LAN(s) to Use Pi Hole
*Note: Do NOT update the WAN connections to use Pi Hole. The only 'thing' using the WAN dns (unbound) should be the main board which should not be affected by ads. This also simplifies troubleshooting and failure modes (the board won't need working Docker/Pi Hole to fix problems with Docker/Pi Hole).*
``` bash
# Ensure *ALL* shared connections use pi hole (creative trick with NetworkManager)
cat > /etc/NetworkManager/dnsmasq-shared.d/pi-hole.conf <<EOF
server=172.30.5.5
EOF
# Bounce LAN's to pickup changes
nmcli con down mgmt && nmcli con up mgmt
nmcli con down wifi-ap-50 && nmcli con up wifi-ap-50
nmcli con down wifi-ap-24 && nmcli con up wifi-ap-24
```
## Update Unbound
``` bash
cat > /etc/unbound/local_zone/pi-hole.conf <<EOF
local-data: "pi-hole A 172.30.5.5"
local-data-ptr: "172.30.5.5 pi-hole"
local-data: "pi-hole.domain.tld A 172.30.5.5"
local-data-ptr: "172.30.5.5 pi-hole.domain.tld"
local-data-ptr: "172.30.0.1 pi-hole-gui"
local-data-ptr: "172.30.0.1 pi-hole-gui.domain.tld"
local-data: "pi-hole-gui A 172.30.0.1"
local-data: "pi-hole-gui.domain.tld A 172.30.0.1"
EOF
```
## Serving Via Caddy
``` bash
cat > /etc/caddy/services/pi-hole.conf <<EOF
# Pi Hole proxy
# This is only so good
# Pi Hole assumes everything is http. Bump it over to http instead of https, because Pi Hole is stupid at life
pi-hole-gui:80, pi-hole-gui:443, pi-hole-gui.domain.tld:80 pi-hole-gui.domain.tld:443 {
redir 301 {
if {scheme} is https
/ http://pi-hole-gui.domain.tld{uri}
}
log /var/log/caddy/pi-hole.log
proxy / 172.30.5.5:80 {
transparent
}
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
}
EOF
```
## Admin Interface
Once the container is online you can get to the Pi Hole admin interface at ```http://pi-hole.domain.tld/admin```.
## First Run Config
Upon first run Pi Hole will be using a Google DNS server as a secondary to the locally hosted Unbound instance. You'll likely want to disable this functionality.

237
armbian/pia.md Normal file
View File

@ -0,0 +1,237 @@
# Private Internet Access (PIA)
```TODO : INCOMPLETE```
This is a **VERY** advanced topic with some creative tricks to simplify getting the config added to NetworkManager. You're on your own.
The author *strongly* recommends reading through this and adapting to other services well ahead of any real need(s).
## Inspiration / Sources
- [http://blog.deadlypenguin.com/blog/2017/04/24/vpn-auto-connect-command-line/](http://blog.deadlypenguin.com/blog/2017/04/24/vpn-auto-connect-command-line/)
- [https://forums.linuxmint.com/viewtopic.php?t=97187](https://forums.linuxmint.com/viewtopic.php?t=97187)
- [https://unix.stackexchange.com/questions/301845/scripting-a-way-to-quickly-import-ovpn-files-to-networkmanager-on-ubuntu](https://unix.stackexchange.com/questions/301845/scripting-a-way-to-quickly-import-ovpn-files-to-networkmanager-on-ubuntu)
- [https://www.privateinternetaccess.com/pages/client-support/](https://www.privateinternetaccess.com/pages/client-support/)
## Pep Work
Download PIA OpenVPN advanced configs, drop them in a good place on the filesystem and script import.
All files can be found Under ```Advanced OpenVPN SSL Restrictive Configurations``` on the main PIA website.
### Download PIA OpenVPN Template Files
``` bash
mkdir -p /etc/pia
cd /etc/pia
mkdir openvpn-strong
cd openvpn-strong
wget https://www.privateinternetaccess.com/openvpn/openvpn-strong.zip
unzip openvpn-strong.zip
cd ..
mkdir openvpn-strong-tcp
cd openvpn-strong-tcp
wget https://www.privateinternetaccess.com/openvpn/openvpn-strong-tcp.zip
unzip openvpn-strong-tcp.zip
cd ..
```
### Add OpenVPN To Network Manager
``` bash
# NetworkManager Gnome is *required* to get a missing library on xenial
# OMIT Gnome item if you can get away with it...
apt update
apt install network-manager-openvpn network-manager-openvpn-gnome
```
### Cleanup Files for Import
The cipher lines in the templates provided by PIA won't work 100% correctly on import. These commands will clean them up for import.
``` bash
cd /etc/pia
cd openvpn-strong
sed -i 's/aes-256-cbc/AES-256-CBC/g' *.ovpn
sed -i 's/sha256/SHA256/g' *.ovpn
sed -i 's_crl.rsa.4096.pem_/etc/pia/openvpn-strong/crl.rsa.4096.pem_g' *.ovpn
sed -i 's_ca.rsa.4096.crt_/etc/pia/openvpn-strong/ca.rsa.4096.crt_g' *.ovpn
cd ..
cd openvpn-strong-tcp
sed -i 's/aes-256-cbc/AES-256-CBC/g' *.ovpn
sed -i 's/sha256/SHA256/g' *.ovpn
sed -i 's_crl.rsa.4096.pem_/etc/pia/openvpn-strong-tcp/crl.rsa.4096.pem_g' *.ovpn
sed -i 's_ca.rsa.4096.crt_/etc/pia/openvpn-strong-tcp/ca.rsa.4096.crt_g' *.ovpn
cd ..
```
## Import / Setup
### Manual Import
Import the cleaned up, provided OpenVPN profiles. This will require intervention on your part after the profile is created in NetworkManager to ensure it can connect properly.
*Note: this assumes UDP profiles, tweak for the ```openvpn-strong-tcp``` directory if desired or necessary*
#### Initial Import / Edit
``` bash
nmcli connection import type openvpn file /etc/pia/openvpn-strong/[con_name].ovpn
nmcli con show
vim /etc/NetworkManager/system-connections/[con_name]
```
#### Adjustments/Necessary Verification
``` bash
id=PIA - [con_name]
[vpn]
auth=SHA256
cipher=AES-256-CBC
password-flags=0
user-name=[your_username]
[vpn-secrets]
password=[your_password]
```
#### Update Profiles in NetworkManager
``` bash
# Reload For Changes
nmcli connection reload [uuid_from_above]
# Connect
nmcli con up [uuid_from_above]
```
### Scripted Import
Some automated imports based on how the ```ovpn``` files are normally imported via ```nmcli```
*Note: this assumes UDP profiles, you'll need to tweak this as you see fit for TCP*
#### Install ```uuidgen```
``` bash
apt update
apt install uuid-runtime
```
#### Create List of VPN Endpoints
``` bash
cat > /etc/pia/server_list.txt << EOF
us-west.privateinternetaccess.com=PIA - USA (West)
us-east.privateinternetaccess.com=PIA - USA (East)
us-midwest.privateinternetaccess.com=PIA - USA (Midwest)
aus.privateinternetaccess.com=PIA - Australia (Sydney)
austria.privateinternetaccess.com=PIA - Austria
belgium.privateinternetaccess.com=PIA - Belgium
ca-toronto.privateinternetaccess.com=PIA - Canada (Toronto) (East)
ca-vancouver.privateinternetaccess.com=PIA - Canada (Vancouver) (West)
fi.privateinternetaccess.com=PIA - Finland
france.privateinternetaccess.com=PIA - France
germany.privateinternetaccess.com=PIA - Germany
hk.privateinternetaccess.com=PIA - Hong Kong
in.privateinternetaccess.com=PIA - India
japan.privateinternetaccess.com=PIA - Japan
mexico.privateinternetaccess.com=PIA - Mexico
nl.privateinternetaccess.com=PIA - Netherlands
no.privateinternetaccess.com=PIA - Norway
sg.privateinternetaccess.com=PIA - Singapore
spain.privateinternetaccess.com=PIA - Spain
sweden.privateinternetaccess.com=PIA - Sweden
swiss.privateinternetaccess.com=PIA - Switzerland
turkey.privateinternetaccess.com=PIA - Turkey
uk-london.privateinternetaccess.com=PIA - UK (London)
brazil.privateinternetaccess.com=PIA - Brazil
EOF
```
#### Setup NeworkManager Profiles
Some fancy bash tricks to get the full list of NetworkManager PIA connections imported in one copy/paste.
*Note: You'll need to fill in ```[your_username]``` and ```[your_password]``` before running this block of commands.
``` bash
export PIA_USER="[your_username]"
export PIA_PASSWORD="[your_password]"
while read line;
do
desc=$(echo $line | cut -f2 -d'=')
dns=$(echo $line | cut -f1 -d'=')
file="/etc/NetworkManager/system-connections/$desc"
cat > "$file" <<EOF
[connection]
id=$desc
uuid=`uuidgen`
type=vpn
permissions=
secondaries=
[vpn]
connection-type=password
auth=SHA256
password-flags=0
remote=${dns}:1197
cipher=AES-256-CBC
comp-lzo=yes
reneg-seconds=0
remote-cert-tls=server
ca=/etc/pia/openvpn-strong/ca.rsa.4096.crt
dev=tun
service-type=org.freedesktop.NetworkManager.openvpn
username=${PIA_USER}
[vpn-secrets]
password=${PIA_PASSWORD}
[ipv4]
dns-search=
method=auto
[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto
EOF
chmod 600 "$file"
done < /etc/pia/server_list.txt
systemctl restart NetworkManager
nmcli con show
```
## Testing VPN (Post Setup)
Go to each link below and verify you're safe.
- [https://www.privateinternetaccess.com/pages/whats-my-ip/](https://www.privateinternetaccess.com/pages/whats-my-ip/)
- [http://dnsleak.com/](http://dnsleak.com/)
- [http://ipv6leak.com/](http://ipv6leak.com/)
- [http://emailipleak.com/](http://emailipleak.com/)

55
armbian/postgres.md Normal file
View File

@ -0,0 +1,55 @@
# Postgresql
A database for all those awesome services you'll be running.
## Install / Update / Run Script
Setup a generic script that'll auto update , build a container and launch it. You should only run this script at first launch and/or when you're looking for updates.
``` bash
mkdir -p /var/postgres/data
cat > /root/docker/postgres.sh << EOF
#!/bin/bash
VERSION=""
ARCH=\`arch\`
# Cleanup arch/container image here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
VERSION="arm64v8/postgres:latest"
else
echo "32bit arm"
VERSION="arm32v7/postgres:latest"
fi
docker pull \$VERSION
# Cleanup existing container
docker stop postgres
docker rm postgres
# Re-run/create container with latest image
docker run \\
--name postgres \\
--restart unless-stopped \\
--net docker-private \\
--ip 172.30.12.12 \\
-e TZ=UTC \\
-e DEBUG=1 \\
-e POSTGRES_PASSWORD=test1234 \\
-v /var/postgres/data:/var/lib/postgresql/data \\
\$VERSION
EOF
chmod a+x /root/docker/postgres.sh
```
## Run Postgres
Simply execute ```/root/docker/postgres.sh``` to update/run Postgres.

112
armbian/searx.md Normal file
View File

@ -0,0 +1,112 @@
# Searx
Self hosted metasearch. Prevent profiling by major search engines
## Inspiration / Further Reading
- [https://asciimoo.github.io/searx/](https://asciimoo.github.io/searx/)
- [https://github.com/asciimoo/morty](https://github.com/asciimoo/morty)
- [https://asciimoo.github.io/searx/user/own-instance.html](https://asciimoo.github.io/searx/user/own-instance.html)
## Install / Update / Run Script
Setup a generic script that'll auto update Searx, build a container and launch it. You should only run this script at first launch and/or when you're looking for updates.
``` bash
mkdir -p /var/searx
chown root:root /var/searx
mkdir -p /root/docker/searx
git clone https://github.com/asciimoo/searx.git /root/docker/searx/src
cat > /root/docker/searx/searx.sh << EOF
#!/bin/bash
cd /root/docker/searx/src
git checkout Dockerfile
git fetch
LATESTTAG=\`git describe --abbrev=0 --tags\`
git checkout \$LATESTTAG
ARCH=\`arch\`
# Cleanup arch/container image here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
sed -i 's_alpine:3.5_arm64v8/alpine:3.5_g' Dockerfile
else
echo "32bit arm"
sed -i 's_alpine:3.5_arm32v6/alpine:3.5_g' Dockerfile
fi
docker build \\
--file ./Dockerfile \\
--tag searx/searx:\$LATESTTAG \\
.
# Cleanup existing container
docker stop searx
docker rm searx
# Re-run/create container with latest image
docker run \\
--name searx \\
--restart unless-stopped \\
--net docker-private \\
--ip 172.30.8.8 \\
-e TZ=UTC \\
-e DEBUG=1 \\
-e BASE_URL=searx.domain.tld \\
searx/searx:\$LATESTTAG
EOF
chmod a+x /root/docker/searx/searx.sh
```
## Run Searx
Simply execute ```/root/docker/searx/searx.sh``` to update/run Gogs.
## Serving Via Caddy
``` bash
cat > /etc/caddy/services/searx.conf <<EOF
# Searx proxy
searx:80, searx:443, searx.domain.tld:80, searx.domain.tld:443 {
redir 301 {
if {scheme} is http
/ https://searx.domain.tld{uri}
}
log /var/log/caddy/searx.log
proxy / 172.30.8.8:8888 {
transparent
}
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
}
EOF
```
## Update Unbound
``` bash
cat > /etc/unbound/local_zone/searx.conf <<EOF
local-data: "searx-insecure A 172.30.8.8"
local-data-ptr: "172.30.8.8 searx-insecure"
local-data: "searx-insecure.domain.tld A 172.30.8.8"
local-data-ptr: "172.30.8.8 searx-insecure.domain.tld"
local-data: "searx A 172.30.0.1"
local-data-ptr: "172.30.0.1 searx"
local-data: "searx.domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 searx.domain.tld"
EOF
```

169
armbian/syncthing.md Normal file
View File

@ -0,0 +1,169 @@
# Syncthing
A very simple way to setup/run Syncthing in a container. This approach will also update to the latest syncthing releases if available.
## Inspiration / Sources
- [https://github.com/syncthing/syncthing/releases](https://github.com/syncthing/syncthing/releases)
- [https://docs.syncthing.net/users/autostart.html#linux](https://docs.syncthing.net/users/autostart.html#linux)
## Dependencies
We need one utility to ensure we can find the latest releases. Install it.
``` bash
apt update
apt install jq
```
## Preflight Configuration
Setup basic config / storage areas ahead of install
```bash
mkdir -p /var/syncthing/.config/syncthing
groupadd syncthing
useradd -s /usr/sbin/nologin -d /var/syncthing -g syncthing syncthing
cat > /var/syncthing/.config/syncthing/config.xml <<EOF
<configuration version="28">
<options>
<globalAnnounceEnabled>false</globalAnnounceEnabled>
<localAnnounceEnabled>true</localAnnounceEnabled>
<relaysEnabled>false</relaysEnabled>
<natEnabled>false</natEnabled>
<minHomeDiskFree unit="%">10</minHomeDiskFree>
<defaultFolderPath>/tank/syncthing</defaultFolderPath>
</options>
</configuration>
EOF
chown syncthing -R /var/syncthing
chgrp syncthing -R /var/syncthing
```
## Install Syncthing
Grab the latest release of syncthing, drop it in place, setup system service.
``` bash
RELEASE=`curl -s https://api.github.com/repos/syncthing/syncthing/releases/latest | jq -r .tag_name`
ARCH=`arch`
if [ $ARCH == "aarch64" ]
then
ARCH="arm64"
else
ARCH="arm"
fi
gpg --keyserver keyserver.ubuntu.com --recv-key D26E6ED000654A3E
mkdir -p /tmp/syncthing
cd /tmp/syncthing
curl -sLO https://github.com/syncthing/syncthing/releases/download/${RELEASE}/syncthing-linux-${ARCH}-${RELEASE}.tar.gz
curl -sLO https://github.com/syncthing/syncthing/releases/download/${RELEASE}/sha256sum.txt.asc
gpg --verify sha256sum.txt.asc
grep syncthing-linux-${ARCH} sha256sum.txt.asc | sha256sum
tar -zxf syncthing-linux-${ARCH}-${RELEASE}.tar.gz
mv syncthing-linux-${ARCH}-${RELEASE}/syncthing /usr/bin/syncthing
chmod a+x /usr/bin/syncthing
mv syncthing-linux-${ARCH}-${RELEASE}/etc/linux-systemd/system/syncthing@.service /etc/systemd/system
systemctl daemon-reload
cd ~
rm -rf /tmp/syncthing
```
## Adjust firewall to allow syncthing on internal network(s)
``` bash
firewall-cmd --permanent --zone=internal --add-port 22000/tcp --add-port 21027/udp
# Allow GUI from docker containers (it'll be proxied by the main web proxy container for ssl purposes)
firewall-cmd --permanent --zone=trusted --add-port 22000/tcp --add-port 21027/udp --add-port 8384/tcp
firewall-cmd --reload
```
## Run Syncthing Via systemd Service
``` bash
systemctl enable syncthing@syncthing.service
systemctl start syncthing@syncthing.service
```
## Setup Update Script
Syncthing has an auto update mechanism. Script it so it can be run at any point to get updates.
``` bash
cat > /root/update_syncthing.sh <<EOF
/usr/bin/syncthing -upgrade-check
/usr/bin/syncthing -upgrade
EOF
chmod a+x /root/update_syncthing.sh
```
## Update Unbound
``` bash
cat > /etc/unbound/local_zone/syncthing.conf <<EOF
local-data: "syncthing A 172.30.0.1"
local-data-ptr: "172.30.0.1 synching"
local-data: "syncthing.domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 synching.domain.tld"
local-data: "syncthing-gui A 172.30.0.1"
local-data: "syncthing-gui.domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 syncthing-gui"
local-data-ptr: "172.30.0.1 syncthing-gui.domain.tld"
EOF
```
## Serving Via Caddy
``` bash
cat > /etc/caddy/services/syncthing.conf <<EOF
# Syncthing proxy
syncthing-gui:80, syncthing-gui:443, syncthing-gui.domain.tld:80, syncthing-gui.domain.tld:443 {
redir 301 {
if {scheme} is http
/ https://syncthing-gui.domain.tld{uri}
}
log /var/log/caddy/syncthing.log
proxy / 127.0.0.1:8384 {
transparent
header_upstream Host 127.0.0.1 # Reset the transparent proxy host so requests aren't blocked by syncthing
}
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
}
EOF
```
## Admin Interface
Once the container is online you can get to the admin interface at ```http://syncthing.domain.tld:8384```.
## Finish Configuration via GUI
- ssh router with 8384 port forward
- Open the admin interface in your browser
- Configure ```/tank/syncthing/global``` as default shared folder
- *IF* you have a ```/tank``` available
- Set ```Minimum disk space``` to ```10%```
- Disable ```Anonymous usage reporting```
- Setup a ```GUI Authentication User``` and ```GUI Authentication Password```

108
armbian/ttrss.md Normal file
View File

@ -0,0 +1,108 @@
# TT-RSS
Self hosted RSS reader a la Google Reader
## Inspiration / Further Reading
- [https://hub.docker.com/r/linuxserver/tt-rss/](https://hub.docker.com/r/linuxserver/tt-rss/)
## Install / Update / Run Script
Setup a generic script that'll auto update TT-RSS, build a container and launch it. You should only run this script at first launch and/or when you're looking for updates.
``` bash
mkdir -p /var/ttrss
docker exec -it postgres psql -U postgres
create role ttrss nocreatedb nocreaterole login PASSWORD 'password';
create database ttrss owner=ttrss encoding=UTF8;
cat > /root/docker/ttrss.sh << EOF
#!/bin/bash
ARCH=\`arch\`
HUBIMAGE=""
# Cleanup arch/container image here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
HUBIMAGE="lsioarmhf/tt-rss-aarch64:latest"
else
echo "32bit arm"
HUBIMAGE="lsioarmhf/tt-rss:latest"
fi
# Cleanup existing container
docker stop ttrss
docker rm ttrss
# Re-run/create container with latest image
docker run \\
--name ttrss \\
--restart unless-stopped \\
--net docker-private \\
--ip 172.30.13.13 \\
-e TZ=UTC \\
-e DEBUG=1 \\
-v /var/ttrss:/config \\
\$HUBIMAGE
EOF
chmod a+x /root/docker/ttrss.sh
```
## Run TT-RSS
Simply execute ```/root/docker/ttrss.sh``` to update/run TT-RSS.
## Serving Via Caddy
``` bash
cat > /etc/caddy/services/ttrss.conf <<EOF
# TT-RSS proxy
ttrss:80, ttrss:443, ttrss.domain.tld:80, ttrss.domain.tld:443 {
redir 301 {
if {scheme} is http
/ https://ttrss.domain.tld{uri}
}
log /var/log/caddy/ttrss.log
proxy / 172.30.13.13:80 {
transparent
}
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
}
EOF
```
## Update Unbound
``` bash
cat > /etc/unbound/local_zone/ttrss.conf <<EOF
local-data: "ttrss-insecure A 172.30.13.13"
local-data-ptr: "172.30.13.13 ttrss-insecure"
local-data: "ttrss-insecure.domain.tld A 172.30.13.13"
local-data-ptr: "172.30.13.13 ttrss-insecure.domain.tld"
local-data: "ttrss A 172.30.0.1"
local-data-ptr: "172.30.0.1 ttrss"
local-data: "ttrss.domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 ttrss.domain.tld"
EOF
```
## First Run / Finalize Setup
- Navigate to ```http://ttrss-insecure.domain.tld```
- Follow on-screen prompts for finalizing setup
- Use the above psql username/password/database during the install phase
- Use 172.30.12.12 as the postgresql hostname
- Login and enjoy
- The default account is admin/password

184
armbian/turtl.md Normal file
View File

@ -0,0 +1,184 @@
# Turtl
Self hosted Evernote/OneNote. Take some notes already.
## Inspiration / Further Reading
- [https://github.com/turtl/server](https://github.com/turtl/server)
- [https://turtlapp.com/docs/server/](https://turtlapp.com/docs/server/)
- [https://turtlapp.com/](https://turtlapp.com/)
## Prep
``` bash
mkdir -p /var/turtl/plugins
mkdir -p /root/docker/turtl
git clone https://github.com/turtl/server.git /root/docker/turtl/src
docker exec -it postgres psql -U postgres
create role turtl nocreatedb nocreaterole login PASSWORD 'password';
create database turtl owner=turtl encoding=UTF8;
cat > /root/docker/turtl/src/config/config.yaml <<EOF
---
server:
port: 8181
db:
host: '172.30.12.12'
port: 5432
database: 'turtl'
user: 'turtl'
password: 'password'
pool: 24
loglevel: 'debug'
app:
# ALWAYS false in production. Always.
# Set to 'I UNDERSTAND THIS VIOLATES THE PRIVACY OF MY USERS' to enable
enable_bookmarker_proxy: false
# no trailing slash
api_url: 'http://172.30.10.10:8181'
www_url: 'https://172.30.10.10'
emails:
admin: 'admin@turtlapp.com'
info: 'Turtl <info@turtlapp.com>'
invites: 'invites@turtlapp.com'
# TODO: replace this with a long, unique value. seriously. write down a dream
# you had, or the short story you came up with during your creative writing
# class in your freshmen year of college. have fun with it.
secure_hash_salt: "Plaque is a figment of the liberal media and the dental industry to scare you into buying useless appliances and pastes. Now, I've read the arguments on both sides and I haven't found any evidence yet to support the need to brush your teeth. Ever."
sync:
# how many sync records can a client send at a time? it's a good idea to have
# a limit here, lest a rogue client flood the server with sync items
max_bulk_sync_records: 32
plugins:
plugin_location: '/var/www/turtl/server/plugins'
analytics:
enabled: false
email:
enabled: false
premium:
enabled: false
uploads:
# if set to a path, files will be uploaded to the local filesystem instead of
# S3. otherwise, set to false
local: '/var/www/turtl/server/public/uploads'
# if true, downloading local files will be proxied through the turtl server.
# this avoids needing to set up any CORS config in your favorite webserver,
# but may slightly affect performance on high-demand servers.
local_proxy: true
# if local_proxy is false, this is should be the url path the uploaded files
# are publicly available on
url: 'http://api.turtl.dev/uploads'
s3:
token: 'IHADAPETSNAKEBUTHEDIEDNOOOOO'
secret: ''
bucket: ''
endpoint: 'https://s3.amazonaws.com'
EOF
```
## Install / Setup
``` bash
cat > /root/docker/turtl/turtl.sh <<EOF
cd /root/docker/turtl/src
git checkout Dockerfile
git pull
VERSION="HEAD"
ARCH=\`arch\`
# Cleanup arch/container image here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
sed -i 's_node:8.9.4-alpine_arm64v8/node:8.9.4-alpine_g' Dockerfile
else
echo "32bit arm"
sed -i 's_node:8.9.4-alpine_arm32v7/node:8.9.4-alpine_g' Dockerfile
fi
sed -i 's_config/config.yaml.default_config/config.yaml_g' Dockerfile
docker build \\
--network docker-private \\
--file ./Dockerfile \\
--tag turtl/turtl:\$VERSION \\
.
# Cleanup existing container
docker stop turtl
docker rm turtl
# Re-run/create container with latest image
docker run \\
--name turtl \\
--restart unless-stopped \\
--net docker-private \\
--ip 172.30.10.10 \\
-e TZ=UTC \\
-e DEBUG=1 \\
-v /var/turtl:/var/www/turtl/server \\
turtl/turtl:\$VERSION
EOF
chmod a+x /root/docker/turtl/turtl.sh
```
## Run Turtl
Simply execute ```/root/docker/turtl/turtl.sh``` to update/run Turtl.
## Serving Via Caddy
``` bash
cat > /etc/caddy/services/turtl.conf <<EOF
# Turtl proxy
turtl:80, turtl:443, turtl.domain.tld:80, turtl.domain.tld:443 {
redir 301 {
if {scheme} is http
/ https://turtl.domain.tld{uri}
}
log /var/log/caddy/turtl.log
proxy / 172.30.9.9:80 {
transparent
}
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/fullchain.cer /var/acme.sh/domain.tld/domain.tld.key
}
EOF
```
## Update Unbound
``` bash
cat > /etc/unbound/local_zone/turtl.conf <<EOF
local-data: "turtl-insecure A 172.30.10.10"
local-data-ptr: "172.30.10.10 turtl-insecure"
local-data: "turtl-insecure.domain.tld A 172.30.10.10"
local-data-ptr: "172.30.10.10 turtl-insecure.domain.tld"
local-data: "turtl A 172.30.0.1"
local-data-ptr: "172.30.0.1 turtl"
local-data: "turtl.domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 turtl.domain.tld"
EOF
```

19
armbian/ui.md Normal file
View File

@ -0,0 +1,19 @@
Adafruit kit
Connection online/offline
Access point band selection
Modem manager
Poweroff
Reboot
Python
bluetooth serial console for simple UI to manage things
mimics adafruit kit for overall ui
build underpinnings the same for boh adafruit approach and bt console
https://www.freedesktop.org/software/ModemManager/api/latest/
https://wiki.gnome.org/Projects/NetworkManager/Developers
https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/dbus
https://cgit.freedesktop.org/ModemManager/ModemManager/tree/examples/modem-watcher-python/ModemWatcher.py

135
armbian/unbound.md Normal file
View File

@ -0,0 +1,135 @@
# Unbound
Caching DNS that uses the roots instead of ISP/other DNS servers
## Inspiration / Further Reading
- [https://wiki.archlinux.org/index.php/Unbound](https://wiki.archlinux.org/index.php/Unbound)
## Install / Base Setup
``` bash
apt update
apt install unbound unbound-host
mkdir /etc/unbound/local_zone
curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
cat > /etc/unbound/root.key <<EOF
. IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
EOF
chown unbound /etc/unbound
cat > /etc/unbound/unbound.conf <<EOF
server:
interface: 127.0.0.1
port: 53
hide-identity: yes
hide-version: yes
num-threads: 1
root-hints: "/etc/unbound/root.hints"
cache-min-ttl: 60
logfile: /var/log/unbound
use-syslog: yes
do-ip4: yes
#do-ip6: no
do-udp: yes
do-tcp: yes
domain-insecure: * # Comment this out if you have a proper RTC
verbosity: 1
minimal-responses: yes
prefetch: yes
rrset-roundrobin: yes
use-caps-for-id: yes
harden-glue: yes
harden-dnssec-stripped: yes
auto-trust-anchor-file: "/etc/unbound/root.key"
val-clean-additional: yes
private-domain: "[domain.tld]"
private-address: 192.168.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8
access-control: 172.30.0.0/16 allow
access-control: 172.16.16.0/24 allow
access-control: 172.17.17.0/24 allow
access-control: 172.18.18.0/24 allow
include: /etc/unbound/local_zone/*.conf
EOF
systemctl enable unbound
systemctl start unbound
unbound-host -C /etc/unbound/unbound.conf -v sigok.verteiltesysteme.net
unbound-host -C /etc/unbound/unbound.conf -v sigfail.verteiltesysteme.net
cat > /etc/systemd/system/roothints.service <<EOF
[Unit]
Description=Update root hints for unbound
After=network.target
[Service]
ExecStart=/usr/bin/curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
EOF
cat > /etc/systemd/system/roothints.timer <<EOF
[Unit]
Description=Run root.hints monthly
[Timer]
OnCalendar=monthly
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable roothints.timer
systemctl start roothints.timer
```
## Adjust NetworkManager Config
Edit ```/etc/NetworkManager/NetworkManager.conf```
Change the ```dns=``` line to be ```dns=127.0.0.1```
## Setup all WAN connections to use this for dns cache
### WiFi
``` bash
nmcli con modify wan-wifi \
ipv4.ignore-auto-dns yes \
ipv6.ignore-auto-dns yes
nmcli con modify wan-wifi \
ipv4.dns "127.0.0.1"
```
### Ethernet
``` bash
nmcli con modify wan-eth \
ipv4.ignore-auto-dns yes \
ipv6.ignore-auto-dns yes
nmcli con modify wan-eth \
ipv4.dns "127.0.0.1"
```
### USB 3G/LTE
``` bash
nmcli con modify wan-wwan-1 \
ipv4.ignore-auto-dns yes \
ipv6.ignore-auto-dns yes
nmcli con modify wan-wwan-1 \
ipv4.dns "127.0.0.1"
```

110
armbian/vpn_ac.md Normal file
View File

@ -0,0 +1,110 @@
# vpn.ac
```TODO : INCOMPLETE / NOT VERIFIED```
This is a **VERY** advanced topic with some creative tricks to simplify getting the config added to NetworkManager. You're on your own.
The author *strongly* recommends reading through this and adapting to other services well ahead of any real need(s).
## Inspiration / Sources
This is an adaptation of the [PIA](pia.md) setup but for vpn.ac instead.
- [https://vpn.ac/ovpn](https://vpn.ac/ovpn)
## Pep Work
Download OpenVPN configs, drop them in a good place on the filesystem and script import.
### Download OpenVPN Template Files
``` bash
mkdir -p /etc/vpn.ac
cd /etc/vpn.ac
mkdir openvpn-strong
cd openvpn-strong
wget https://vpn.ac/ovpn/AES-256-UDP.zip
unzip AES-256-UDP.zip
cd ..
wget https://vpn.ac/ovpn/ca.crt
```
### Add OpenVPN To Network Manager
``` bash
# NetworkManager Gnome is *required* to get a missing library on xenial
# OMIT Gnome item if you can get away with it...
apt update
apt install network-manager-openvpn network-manager-openvpn-gnome
```
## Import / Setup
### Manual Import
Import the cleaned up, provided OpenVPN profiles. This will require intervention on your part after the profile is created in NetworkManager to ensure it can connect properly.
#### Initial Import / Edit
``` bash
nmcli connection import type openvpn file /etc/vpn.ac/openvpn-strong/AES-256-UDP/[con_name].ovpn
nmcli con show
vim /etc/NetworkManager/system-connections/[con_name]
```
#### Adjustments/Necessary Verification
``` bash
id=vpn.ac - [con_name]
[vpn]
password-flags=0
user-name=[your_username]
[vpn-secrets]
password=[your_password]
```
#### Update Profiles in NetworkManager
``` bash
# Reload For Changes
nmcli connection reload [uuid_from_above]
# Connect
nmcli con up [uuid_from_above]
```
## Suggested Files For import
```TODO : Verify this is a reasonable subset```
- australia_sydney-aes256-udp.ovpn
- canada_toronto-aes256-udp.ovpn
- canada_vancouver-aes256-udp.ovpn
- finland-aes256-udp.ovpn
- france-aes256-udp.ovpn
- germany-aes256-udp.ovpn
- hong-kong_tseung-kwan-o-aes256-udp.ovpn
- luxembourg-aes256-udp.ovpn
- mexico-aes256-udp.ovpn
- netherlands_amsterdam-1-aes256-udp.ovpn
- norway-aes256-udp.ovpn
- singapore-aes256-udp.ovpn
- spain-aes256-udp.ovpn
- sweden-aes256-udp.ovpn
- switzerland-aes256-udp.ovpn
- uk_london-aes256-udp.ovpn
- us-central_chicago-aes256-udp.ovpn
- us-east_new-york-aes256-udp.ovpn
- us-west_seattle-aes256-udp.ovpn

288
armbian/vpn_autoconnect.md Normal file
View File

@ -0,0 +1,288 @@
# VPN Autoconnect (Connect VPN automatically)
Some basic setup for auto-connecting a *specific* VPN connection. You'll need/want other tricks to switch out your VPN connection. This is mainly to set a default so no matter what you're using a VPN, even if it's not the 'ideal' one initially.
## Inspiration / Further Reading
- [https://developer.gnome.org/NetworkManager/stable/NetworkManager.html](https://developer.gnome.org/NetworkManager/stable/NetworkManager.html)
- [https://wiki.gnome.org/Projects/NetworkManager/Developers](https://wiki.gnome.org/Projects/NetworkManager/Developers)
- [https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/dbus](https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/dbus)
- [https://wiki.archlinux.org/index.php/NetworkManager#Use_dispatcher_to_automatically_toggle_Wi-Fi_depending_on_LAN_cable_being_plugged_in](https://wiki.archlinux.org/index.php/NetworkManager#Use_dispatcher_to_automatically_toggle_Wi-Fi_depending_on_LAN_cable_being_plugged_in)
- [http://sysadminsjourney.com/content/2008/12/18/use-networkmanager-launch-scripts-based-network-location/](http://sysadminsjourney.com/content/2008/12/18/use-networkmanager-launch-scripts-based-network-location/)
- [https://gist.github.com/domenkozar/1547663](https://gist.github.com/domenkozar/1547663)
## Setup the default VPN connection
``` bash
# Get UUID for PIA endpoint you want as a default
nmcli con show
mkdir /etc/autovpn
# Setup the default so it can be used via autovpn script (see below)
echo "[uuid]" > /etc/autovpn/default
```
## Setup Docker networks to exclude
``` bash
# Get network names of ALL docker connections
nmcli con show
echo "[name1],[name2]" > /etc/autovpn/exclude
```
## Setup script that will auto activate VPN
This will auto-activate whenever NetworkManager says that the network is in a state of ```Connected-Global```. It may take a few minutes to get the whole network online/activated.
Put the below script at ```/etc/autovpn/autovpn.py```
``` python
#!/usr/bin/env python3
"""
Copyright 2011 Domen Kozar. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY DOMEN KOZAR ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DOMEN KOZAR OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of DOMEN KOZAR.
USAGE
=====
1) clone gist somewhere (eg. /home/user/autovpn/)
2) add to /etc/rc.local: python /home/user/autovpn/autovpn.py "myvpn" 'Auto homenetwork,Auto worknetwork' >> /var/log/autovpn.log&
3) reboot :-)
CHANGELOG
=========
0.2 (28.01.2012)
----------------
* feature: use logging module
* bug: script would fail if there was no active connection
0.1 (01.01.2012)
----------------
* bug: compatible with NM 0.9, dropped support for 0.8
* feature: specify networks that vpn is not autoconnected
KNOWN ISSUES
============
* it will always use first active network connection
"""
import sys
import logging
from dbus.mainloop.glib import DBusGMainLoop
import dbus
from gi.repository import GObject as gobject
logger = logging.getLogger(__name__)
logging.basicConfig(
level=logging.INFO,
filename='/var/log/autovpn.log',
filemode='a',
)
class AutoVPN(object):
"""Solves two jobs, tested with NetworkManager 0.9.x:
* if VPN connection is not disconnected by user himself, reconnect (configurable max_attempts)
* on new active network connection, activate VPN
:param vpn_name: Name of VPN connection that will be used for autovpn
:param ignore_networks: Comma separated network names in NM that will not force VPN usage
:param max_attempts: Maximum number of attempts of reconnection VPN session on failures
:param delay: Miliseconds to wait before reconnecting VPN
"""
def __init__(self, vpn_name, ignore_networks='', max_attempts=5, delay=5000):
self.vpn_name = vpn_name
self.max_attempts = max_attempts
self.delay = delay
self.failed_attempts = 0
self.bus = dbus.SystemBus()
self.ignore_networks = filter(None, ignore_networks.split(','))
self.activate_vpn() # Auto connect at startup (Listen for StateChanged going forward)
self.get_network_manager().connect_to_signal("StateChanged", self.onNetworkStateChanged)
logger.info("Maintaining connection for %s, reattempting up to %d times with %d ms between retries", vpn_name, max_attempts, delay)
def onNetworkStateChanged(self, state):
"""Handles network status changes and activates the VPN on established connection."""
logger.debug("Network state changed: %d", state)
if state == 70:
self.activate_vpn()
def onVpnStateChanged(self, state, reason):
"""Handles different VPN status changes and eventually reconnects the VPN."""
# vpn connected or user disconnected manually?
if state == 5 or (state == 7 and reason == 2):
self.failed_attempts = 0
if state == 5:
logger.info("VPN %s connected", self.vpn_name)
else:
logger.info("User disconnected manually")
return
# connection failed or unknown?
elif state in [6, 7]:
# reconnect if we haven't reached max_attempts
if not self.max_attempts or self.failed_attempts < self.max_attempts:
logger.info("Connection failed, attempting to reconnect")
self.failed_attempts += 1
gobject.timeout_add(self.delay, self.activate_vpn)
else:
logger.info("Connection failed, exceeded %d max attempts.", self.max_attempts)
self.failed_attempts = 0
def get_network_manager(self):
"""Gets the network manager dbus interface."""
logger.debug("Getting NetworkManager DBUS interface")
proxy = self.bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')
return dbus.Interface(proxy, 'org.freedesktop.NetworkManager')
def get_vpn_interface(self, name):
'Gets the VPN connection interface with the specified name.'
logger.debug("Getting %s VPN connection DBUS interface", name)
proxy = self.bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager/Settings')
iface = dbus.Interface(proxy, 'org.freedesktop.NetworkManager.Settings')
connections = iface.ListConnections()
for connection in connections:
proxy = self.bus.get_object('org.freedesktop.NetworkManager', connection)
iface = dbus.Interface(proxy, 'org.freedesktop.NetworkManager.Settings.Connection')
con_settings = iface.GetSettings()['connection']
if con_settings['type'] == 'vpn' and con_settings['uuid'] == name:
logger.debug("Got %s interface", name)
return iface
logger.error("Unable to acquire %s VPN interface. Does it exist?", name)
return None
def get_active_connection(self):
"""Gets the dbus interface of the first active
network connection or returns None.
"""
logger.debug("Getting active network connection")
proxy = self.bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')
iface = dbus.Interface(proxy, 'org.freedesktop.DBus.Properties')
active_connections = iface.Get('org.freedesktop.NetworkManager', 'ActiveConnections')
if len(active_connections) == 0:
logger.info("No active connections found")
return None
logger.info("Found %d active connection(s)", len(active_connections))
return active_connections[0]
def activate_vpn(self):
"""Activates the vpn connection."""
logger.info("Activating %s VPN connection", self.vpn_name)
vpn_con = self.get_vpn_interface(self.vpn_name)
active_con = self.get_active_connection()
if active_con is None:
return
# check if we have to ignore vpn
proxy = self.bus.get_object('org.freedesktop.NetworkManager', active_con)
con = dbus.Interface(proxy, 'org.freedesktop.DBus.Properties').Get('org.freedesktop.NetworkManager.Connection.Active', 'Connection')
proxy = self.bus.get_object('org.freedesktop.NetworkManager', con)
settings = dbus.Interface(proxy, 'org.freedesktop.NetworkManager.Settings.Connection').GetSettings()
if settings['connection']['id'] in self.ignore_networks:
logger.info("Ignored network connection %s based on settings", settings['connection']['id'])
return
# activate vpn and watch for reconnects
if vpn_con and active_con:
try:
new_con = self.get_network_manager().ActivateConnection(
vpn_con,
dbus.ObjectPath("/"),
active_con,
)
proxy = self.bus.get_object('org.freedesktop.NetworkManager', new_con)
iface = dbus.Interface(proxy, 'org.freedesktop.NetworkManager.VPN.Connection')
iface.connect_to_signal('VpnStateChanged', self.onVpnStateChanged)
logger.info("VPN %s should be active (soon)", self.vpn_name)
except dbus.exceptions.DBusException:
# Ignore dbus connections (in case VPN already active when this script runs)
# TODO: Do this handling better; maybe check active/inactive status above and bail if already active?
pass
if __name__ == '__main__':
if len(sys.argv) < 2:
print('usage: autovpn VPN_CONNECTION_NAME <COMMA SEPARATED NAMES OF IGNORABLE NETWORKS>')
print('-> activates vpn if any network connection is active')
print('-> and reconnects VPN on failure')
sys.exit(0)
# set up the main loop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
# TODO: argparse
if len(sys.argv) > 2:
AutoVPN(sys.argv[1], sys.argv[2])
else:
AutoVPN(sys.argv[1])
loop.run()
```
## Setup Script
``` bash
# Set permissions as required by NetworkManager
chown root:root /etc/autovpn/autovpn.py
chmod 0700 /etc/autovpn/autovpn.py
```
## Setup the script as a systemd service
``` bash
cat > /etc/systemd/system/autovpn.service <<EOF
[Unit]
Description=Autovpn - Ensure your VPN connection is always online
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
ExecStart=/etc/autovpn/autovpn.py `cat /etc/autovpn/default` `cat /etc/autovpn/exclude`
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable autovpn
systemctl restart autovpn
```

152
armbian/wallabag.md Normal file
View File

@ -0,0 +1,152 @@
# Wallabag
Self hosted Read It Later / Pocket service. Read the net while offline.
## Inspiration / Further Reading
- [https://hub.docker.com/r/wallabag/wallabag/~/dockerfile/](https://hub.docker.com/r/wallabag/wallabag/~/dockerfile/)
- [https://github.com/wallabag/wallabag](https://github.com/wallabag/wallabag)
## Prep
``` bash
mkdir -p /var/wallabag/var /var/wallabag/data /var/wallabag/assets /var/wallabag/cache
mkdir -p /root/docker/wallabag
git clone https://gitlab.com/kemonine/wallabag-in-a-can.git /root/docker/wallabag/src
```
## Install / Setup
``` bash
cat > /root/docker/wallabag/wallabag.sh <<EOF
cd /root/docker/wallabag/src
git pull
VERSION=\`curl -s https://api.github.com/repos/wallabag/wallabag/releases/latest | jq -r .tag_name\`
ARCH=\`arch\`
# Cleanup arch/container image here
if [ \$ARCH == "aarch64" ]
then
echo "64bit arm"
ALPINE="arm64v8/alpine:latest"
else
echo "32bit arm"
ALPINE="arm32v6/alpine:latest"
fi
docker build \\
--network docker-private \\
--file ./Dockerfile \\
--build-arg ALPINE=\$ALPINE \\
--build-arg VERSION=\$VERSION \\
--tag wallabag/wallabag:\$VERSION \\
.
# Cleanup existing container
docker stop wallabag
docker rm wallabag
SECRET=\`dd if=/dev/urandom bs=128 count=1 | base64\`
SECRET=\`echo $SECRET | tr --delete '\n' | tr --delete ' '\`
##########
# For postgresql instead of sqlite run the following commands
#docker exec -it postgres psql -U postgres
#create role wallabag nocreatedb nocreaterole login PASSWORD 'password';
#create database wallabag owner=wallabag encoding=UTF8;
# Setup the below using the above database/username/role and ip of 172.30.12.12
# You'll also need to use pdo_pgsql instead of pdo_sqlite in the below env variables
##########
# Re-run/create container with latest image
docker run \\
--name wallabag \\
--restart unless-stopped \\
--net docker-private \\
--ip 172.30.9.9 \\
-e TZ=UTC \\
-e DEBUG=1 \\
-e SYMFONY__ENV__DATABASE_DRIVER=pdo_sqlite \\
-e SYMFONY__ENV__DATABASE_HOST=127.0.0.1 \\
-e SYMFONY__ENV__DATABASE_PORT=null \\
-e SYMFONY__ENV__DATABASE_PATH=/wallabag/data/db/wallabag.sqlite \\
-e SYMFONY__ENV__DATABASE_NAME=wallabag \\
-e SYMFONY__ENV__DATABASE_USER=null \\
-e SYMFONY__ENV__DATABASE_PASSWORD=null \\
-e SYMFONY__ENV__SECRET="\$SECRET" \\
-e SYMFONY__ENV__DOMAIN_NAME="https://wallabag.domain.tld" \\
-v /var/wallabag/var:/wallabag/var \\
-v /var/wallabag/data:/wallabag/data \\
-v /var/wallabag/assets:/wallabag/assets \\
-v /var/wallabag/cache:/wallabag/cache \\
wallabag/wallabag:\$VERSION
EOF
chmod a+x /root/docker/wallabag/wallabag.sh
```
## Run Wallabag
Simply execute ```/root/docker/wallabag/wallabag.sh``` to update/run Wallabag.
## Post Install
Run the below command just after container creation to finalize installation
It creates ```wallabag/wallabag``` user/pass combo as the admin
``` bash
docker exec -it wallabag /bin/sh -c "mkdir -p /wallabag/data/db && touch /wallabag/data/db/wallabag.sqlite && php bin/console wallabag:install --no-interaction && chown -R nobody /wallabag/data /wallabag/cache /wallabag/assets /wallabag/var"
```
## Serving Via Caddy
``` bash
cat > /etc/caddy/services/wallabag.conf <<EOF
# Wallabag proxy
wallabag:80, wallabag:443, wallabag.domain.tld:80, wallabag.domain.tld:443 {
redir 301 {
if {scheme} is http
/ https://wallabag.domain.tld{uri}
}
log /var/log/caddy/wallabag.log
proxy / 172.30.9.9:80 {
transparent
}
# Use acme.sh Let's Encrypt SSL cert setup
tls /var/acme.sh/domain.tld/domain.tld.cer /var/acme.sh/domain.tld/domain.tld.key
}
EOF
```
## Update Unbound
``` bash
cat > /etc/unbound/local_zone/wallabag.conf <<EOF
local-data: "wallabag-insecure A 172.30.9.9"
local-data-ptr: "172.30.9.9 wallabag-insecure"
local-data: "wallabag-insecure.domain.tld A 172.30.9.9"
local-data-ptr: "172.30.9.9 wallabag-insecure.domain.tld"
local-data: "wallabag A 172.30.0.1"
local-data-ptr: "172.30.0.1 wallabag"
local-data: "wallabag.domain.tld A 172.30.0.1"
local-data-ptr: "172.30.0.1 wallabag.domain.tld"
EOF
```

3
hardware/README.md Normal file
View File

@ -0,0 +1,3 @@
# Hardware
Setup additional hardware with an SBC

View File

@ -0,0 +1,130 @@
# Bluetooth Serial Console
Setup a cheap, simple bluetooth adapter as a serial console.
**THIS IS VERY ADVANCED. YOU PROBABLY DON'T WANT TO DO THIS UNLESS YOU'RE WILLING TO PLAY WITH HARDWARE**
## Inspiration / Further Reading
- [https://www.sparkfun.com/products/12576](https://www.sparkfun.com/products/12576)
- [https://learn.sparkfun.com/tutorials/using-the-bluesmirf](https://learn.sparkfun.com/tutorials/using-the-bluesmirf)
- [https://cdn.sparkfun.com/assets/1/e/e/5/d/5217b297757b7fd3748b4567.pdf](https://cdn.sparkfun.com/assets/1/e/e/5/d/5217b297757b7fd3748b4567.pdf)
- [https://www.sparkfun.com/datasheets/Wireless/Bluetooth/rn-42-ds.pdf](https://www.sparkfun.com/datasheets/Wireless/Bluetooth/rn-42-ds.pdf)
- [https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal)
- [https://play.google.com/store/apps/details?id=com.ucconnect.ucbtadapter_hex](https://play.google.com/store/apps/details?id=com.ucconnect.ucbtadapter_hex)
- [https://blog.miguelgrinberg.com/post/a-cheap-bluetooth-serial-port-for-your-raspberry-pi](https://blog.miguelgrinberg.com/post/a-cheap-bluetooth-serial-port-for-your-raspberry-pi)
- [https://linux-sunxi.org/Xunlong_Orange_Pi_Zero](https://linux-sunxi.org/Xunlong_Orange_Pi_Zero)
- [https://unix.stackexchange.com/questions/378359/how-to-use-uart-pins-on-orange-pi-zero](https://unix.stackexchange.com/questions/378359/how-to-use-uart-pins-on-orange-pi-zero)
## Hardware
This document assumes the Sparkfun Bluetooth Mate Silver [(link)](https://www.sparkfun.com/products/12576) is used for the bluetooth serial console.
## Android Apps
Connect to your device on the go
- [https://f-droid.org/packages/ru.sash0k.bluetooth_terminal/](https://f-droid.org/packages/ru.sash0k.bluetooth_terminal/)
- [https://play.google.com/store/apps/details?id=ru.sash0k.bluetooth_terminal](https://play.google.com/store/apps/details?id=ru.sash0k.bluetooth_terminal)
- [https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal)
## Hardware Connection
Connect the Bluetooth Mate Silver to the Orange Pi Zero UART 1 or 2 on expansion header.
*Note: use UART1 if possible. It's more likely to be present already*
| BT Mate Silver Pin | UART 1 Pin | UART 2 Pin |
| ------------------ | :--------: | :--------: |
| CTS | N/A | 15 |
| RTS | N/A | 22 |
| Rx | 8 | 13 |
| Tx | 10 | 11 |
| VCC | 1 | 1 |
| GND | 9 | 9 |
## Setup Orange Pi UART
Edit ```/boot/armbianEnv.txt``` and add ```uart1``` to the ```overlays``` line.
Reboot after applying the changes
## Configure Bluetooth Mate Silver
``` bash
minicom -s
```
The below commands should be run to configure the Bluetooth Mate Silver. You'll need to adapt these to your needs.
``` text
$$$ # Enter command mode
V # Display firmware version
D # Displays current config
SF,1 # Restore to factory defaults
ST,0 # Disable remote configuration
SR,Z # Erase any stored addresses
SU,115K # Set BT serial speed
SA,4 # Force entering a pin code to connect
SE,1 # Turn on crypo if firmware below 5.40 (on by default otherwise)
SM,<value> # sets the mode (6 pairing)
SN,<string(max 20 chars)> # Set device name
SP,1234 # Set pin code (up to 20 alphanumeric)
SY,0000 # Set a lower antenna power mode (0 in this case, FFF4 for -12, FFF8 for -8, FFFC for -4)
S|,0A03 # Cycle on for 3 seconds and off for 10 seconds (adjust per how fiddly your bt is to connect)
R,1 # Reboot device
--- # Exit command mode
```
## Enable New Serial tty
Start / enable a new serial tty with the following
``` bash
# Adjust the default serial-getty config for the BT device/oPi
cat > /etc/systemd/system/serial-getty@ttyS1.service <<EOF
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Serial Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
BindsTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes
[Service]
ExecStart=-/sbin/agetty 115200 %I $TERM
Type=idle
Restart=always
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=no
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=no
[Install]
WantedBy=getty.target
EOF
ln -s /etc/systemd/system/serial-getty@ttyS1.service /etc/systemd/system/getty.target.wants
systemctl start serial-getty@ttyS1
systemctl enable serial-getty@ttyS1
```

136
hardware/gps.md Normal file
View File

@ -0,0 +1,136 @@
# GPS
Location fun. Tracking, logging, etc
## Inspiration / Further Reading
- [https://github.com/wadda/gps3](https://github.com/wadda/gps3)
- [https://learn.adafruit.com/adafruit-ultimate-gps-on-the-raspberry-pi?view=all](https://learn.adafruit.com/adafruit-ultimate-gps-on-the-raspberry-pi?view=all)
- [https://learn.adafruit.com/assets/3715](https://learn.adafruit.com/assets/3715)
- [https://learn.adafruit.com/adafruit-ultimate-gps?view=all](https://learn.adafruit.com/adafruit-ultimate-gps?view=all)
- [https://stackoverflow.com/questions/16989153/saving-gps-data-as-gpx](https://stackoverflow.com/questions/16989153/saving-gps-data-as-gpx)
- [http://www.catb.org/gpsd/gpspipe.html](http://www.catb.org/gpsd/gpspipe.html)
- [http://www.catb.org/gpsd/gpsd-time-service-howto.html#_feeding_chrony_from_gpsd](http://www.catb.org/gpsd/gpsd-time-service-howto.html#_feeding_chrony_from_gpsd)
- [http://thomasloughlin.com/gpspipe-gps-client/](http://thomasloughlin.com/gpspipe-gps-client/)
## Hardware
The author chose the [Adafruit Ultimate GPS Breakout (link)](https://www.adafruit.com/product/746) for this guide. YMMV with other boards.
## Setup
``` bash
armbian-config # enable hardware uarts
apt install gpsd gpsd-clients python-gps gpsbabel # necessary software
systemctl stop gpsd # stop gpsd to help with testin
gpsd -n -N -D 2 /dev/ttyS2 # run gpsd by hand
cgps -s # run a cli client to verify it works
```
Setup necessary ```gpsd``` defaults (daemon that provides location data to programs).
Edit ```/etc/default/gpsd```
- Add ```/dev/ttyS2``` to ```DEVICES```
- Add ```-n``` to ```GPSD_OPTIONS```
## Chrony
Add GPS as a time source to chrony
``` bash
cat >> /etc/chrony/chrony.conf <<EOF
# set larger delay to allow the NMEA source to overlap with
# the other sources and avoid the falseticker status
refclock SHM 0 refid GPS precision 1e-1 offset 0.9999 delay 0.2
refclock SOCK /var/run/gpsd.sock refid PPS
EOF
systemctl restart chrony
cgps # look for ```Status: 3D FIX```
chronyc sources # Should see GPS and SOC1 with times for recent samples
```
## GPX Tracks
### NextCloud
**GpxPod** for NextCloud is a good viewer for GPX track recordings
### Tracking
```gpspipe -r -d -l -o /tmp/xxx.nmea``` will record the raw GPS data from the module. Can be used for tracking.
### GPX Files
You can convert raw ```nmea``` data from ```gpspipe``` using ```gpsbabel```
Examples
- ```gpsbabel -t -r -w -i nmea -f /tmp/xxx.nmea -o gpx -F xxx.gpx```
- ```gpsbabel -t -i nmea -f /tmp/xxx.nmea -x track,pack,split=5m,title="LOG # %Y%m%d-%H%M" -o gpx -F out.gpx```
## Automatic Logging
The Python program used here is in the ```scripts``` directory.
``` bash
mkdir -p /tank/gps_data
chown -R gpsd:root /tank/gps_data
# put gpslog.py at /usr/local/bin
cat > /etc/systemd/system/gps-logger.service <<EOF
[Unit]
Description=Simple gps logger
After=gpsd.service gpsd.socket
[Service]
User=gpsd
ExecStart=/usr/local/bin/gpslog.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable gps-logger
systemctl start gps-logger
```
## Setup Auto GPX Track Creation/Upload
A handy trick for auto-converting your GPS log data as well as uploading it to NextCloud. The Python program used here is in the ```scripts``` directory.
``` bash
cat > /etc/systemd/system/gpsconvert.service <<EOF
[Unit]
Description=Merge GPS logs and upload to NextCloud
After=gps-logger
[Service]
ExecStart=/usr/local/bin/gpsconvert.py
EOF
cat > /etc/systemd/system/gpsconvert.timer <<EOF
[Unit]
Description=Run GPS log merge
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable gpsconvert.timer
systemctl start gpsconvert.timer
```

146
hardware/rtc.md Normal file
View File

@ -0,0 +1,146 @@
# RTC (Real Time Clock)
Setup a good time source. The built in RTC for Allwinner chips lacks a battery on the Orange Pi boards and has a higher drain than others. Go with the others for the better power use
## Inspiration / Further Reading
- [https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi?view=all](https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi?view=all)
- [https://www.raspberrypi.org/forums/viewtopic.php?t=20619](https://www.raspberrypi.org/forums/viewtopic.php?t=20619)
- [https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/](https://www.raspberrypi-spy.co.uk/2015/05/adding-a-ds3231-real-time-clock-to-the-raspberry-pi/)
- [https://unix.stackexchange.com/questions/246605/how-can-the-link-target-of-dev-rtc-be-changed](https://unix.stackexchange.com/questions/246605/how-can-the-link-target-of-dev-rtc-be-changed)
- [https://www.raspberrypi.org/forums/viewtopic.php?t=85683](https://www.raspberrypi.org/forums/viewtopic.php?t=85683)
## Clocks
### Suggestions
- Use cheapest for ultra portable builds
- Use most accurate for mostly permanent builds (RV/similar)
- Use most common rarely used (unless you have good reason, don't)
### Hardware
- [DS1307 (most common | Link)](https://www.adafruit.com/product/3296)
- [PCF8523 (cheapest | Link)](https://www.adafruit.com/product/3295)
- [DS3231 (most accurate | Link](https://www.adafruit.com/product/3013)
### Key Note
This guide assumes the PCF8523. You'll need to adjust lightly for the DS3231 or DS1307.
## Initial Setup
``` bash
armbian-config # enable i2c busses
systemctl reboot # reboot to enable bus(es)
apt install i2c-tools # install tools
i2cdetect -l # check to ensure busses are present
i2cdetect -y 0 # 0 for orange pi zero ; 1 for recent pi's
modprobe rtc-pcf8523 # load the proper rtc module (adafruit cheap model)
echo pcf8523 0x68 > /sys/class/i2c-adapter/i2c-0/new_device # setup device so it's seen
dmesg | grep rtc # verify the kernel sees the rtc
ls /dev/rtc* # should have rtc1
hwclock -f /dev/rtc1 --systohc -D --noadjfile --utc # set / init the rtc
hwclock -r -f /dev/rtc1 # read the value from the rtc
hwclock -w -f /dev/rtc1 # write the current time to the rtc
apt remove --purge fake-hwclock # purge the fake hwclock as we have a real one now
```
## Udev Rules
``` bash
# setup udev rule to setup the new rtc as the primary for the board
# `udevadm info -a -p /sys/class/rtc/rtc1` gets the details for the below entries
cat > /etc/udev/rules.d/99-rtc1.rules <<EOF
KERNEL=="rtc1", SUBSYSTEM=="rtc", DRIVER=="", ATTR{name}=="rtc-pcf8523 0-0068", SYMLINK="rtc", MODE="0666"
EOF
```
## Internal RTC Adjustments
A systemd service to ensure the internal RTC is 'close' to the real time w/o battery.
``` bash
# Set the internal RTC on shutdown to match ntpified time
cat > /etc/systemd/system/rtc0-shutdown-fix.service <<EOF
[Unit]
Description=Set sunxi internal RTC on shutdown
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
[Service]
Type=oneshot
ExecStart=/sbin/hwclock --systohc -D --noadjfile --utc -f /dev/rtc0
[Install]
WantedBy=halt.target reboot.target shutdown.target
EOF
systemctl daemon-reload
systemctl enable rtc0-shutdown-fix
# Trick for getting the early boot time 'close'
cat > /etc/systemd/system/rtc0-online.service <<EOF
[Unit]
Description=Set system clock to rtc0
DefaultDependencies=no
Before=time-sync.target
[Service]
Type=oneshot
ExecStart=/sbin/hwclock -s -f /dev/rtc0
[Install]
WantedBy=time-sync.target
EOF
systemctl daemon-reload
systemctl enable rtc0-online
```
## External RTC On Boot
A systemd unit that brings the external RTC online during boot
``` bash
cat > /etc/systemd/system/rtc1-online.service <<EOF
[Unit]
Description=Setup rtc1 as primary clock
DefaultDependencies=no
Before=time-sync.target
After=rtc0-online.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c '/sbin/modprobe rtc_pcf8523 \
&& echo pcf8523 0x68 > /sys/class/i2c-adapter/i2c-0/new_device \
&& /sbin/hwclock -s -f /dev/rtc1'
[Install]
WantedBy=time-sync.target
After=rtc0-online
EOF
systemctl daemon-reload
systemctl
```
## Misc Notes
``` bash
date # Wait for this to get sync'd via whatever ntp you're doing
hwclock -r -f /dev/rtc1 # Verify this isn't right
hwclock -w -f /dev/rtc1 # Write ntp system time -> rtc
hwclock -r -f /dev/rtc1 # Verify the write worked
ls -l /dev/rtc* # Check rtc dev node is present
hwclock -r -f /dev/rtc1 # read time from external rtc
hwclock -r -f /dev/rtc0 # read time from internal rtc
```

106
hardware_notes.md Normal file
View File

@ -0,0 +1,106 @@
# Hardware Notes
Various notes and tidbits that may deserve consideration.
## USB Storage
If you're going to run services like NextCloud, Syncthing and/or Samba you will want to consider what kind of USB disk to use. I'd recommend a [Sandisk Cruzer Fit (link)](https://www.sandisk.com/home/usb-flash/cruzer-fit) or [Sandisk Ultra Fit (link)](https://www.sandisk.com/home/usb-flash/ultra-fit-usb) or similar, low power flash drive. Full hard disks that aren't SSD's tend to be power hungry and can cause problems with SBCs.
## WiFi
- The author has had decent luck with the [ASUS USB-N13 (link)](https://www.asus.com/us/Networking/USB-N13/) adapter in client mode. Be minful of your 2.4ghz channel setup. If this adapter and your AP share a channel in 2.4ghz this adapter *will* drop packets and/or suffer disconnections
- Sometimes a reboot is necessary to get authentication to work properly after initial setup
- The author has **NOT** tested AP mode
- The author has had very good luck with the [ASUS USB-N53 (link)](https://www.asus.com/us/Networking/USBN53/) in AP mode. *Both* 2.4ghz and 5ghz can used for AP mode at the same time.
- The author has **NOT** tested client mode
- The author has had decent luck with the TP-Link N150 USB WiFi adapter in client mode
- The author could not get the TP-Link N300 USB WiFi adapter to work in client mode
## Single Board Computers (SBC)
### Orange Pi Zero
The Orange Pi Zero has buggy WiFi and will **NOT** work for production purposes. However, the rest of the device is functional. Please note the WiFi chip in the Orange Pi Zero is "junk" (per the driver devs) and is unlikely to ever be supported fully.
You'll need/want a USB hub and USB WiFi adapter for this device.
### Pine64
- The 'Euler Bus' has dedicated ```DC IN``` and ```GND``` pins. If you run into power problems, consider these headers for powering the board.
- [Pinout reference (link)](http://files.pine64.org/doc/Pine%20A64%20Schematic/Pine%20A64%20Pin%20Assignment%20160119.pdf)
### Raspberry Pi
The Raspberry Pi devices are notorious for power problems. Especially lack of power for USB devices. You'll want to do a little additional research to ensure you have a good power supply.
## Expansion / Hardware Ideas
### WiFi Antennas
- [https://www.mouser.com/ProductDetail/?qs=%2fv8iy7V9uiwj65CKT%2f%252b6tQ%3d%3d](https://www.mouser.com/ProductDetail/?qs=%2fv8iy7V9uiwj65CKT%2f%252b6tQ%3d%3d)
- [https://www.mouser.com/ProductDetail/?qs=G9o9YCnxvoZVoyw0A06Ktg%3d%3d](https://www.mouser.com/ProductDetail/?qs=G9o9YCnxvoZVoyw0A06Ktg%3d%3d)
- [https://www.mouser.com/ProductDetail/?qs=WUa1z%2fNV9%252b2lzv2ZS%2f50GQ%3d%3d](https://www.mouser.com/ProductDetail/?qs=WUa1z%2fNV9%252b2lzv2ZS%2f50GQ%3d%3d)
- [https://www.mouser.com/ProductDetail/?qs=RuW%2fu%252bNMQmv6yDroBT8RNQ%3d%3d](https://www.mouser.com/ProductDetail/?qs=RuW%2fu%252bNMQmv6yDroBT8RNQ%3d%3d)
- [https://www.mouser.com/ProductDetail/Antenova/SR4W030-100?qs=sGAEpiMZZMuBTKBKvsBmlN73K%2f2BcYXln6YUd9YVZ3FLX3OerI69PA%3d%3d](https://www.mouser.com/ProductDetail/Antenova/SR4W030-100?qs=sGAEpiMZZMuBTKBKvsBmlN73K%2f2BcYXln6YUd9YVZ3FLX3OerI69PA%3d%3d)
- [https://www.mouser.com/ProductDetail/Antenova/SRF2W021-100?qs=sGAEpiMZZMuBTKBKvsBmlMeP1Lut7uca61hspfdOxQexT8ZJsKeXqw%3d%3d](https://www.mouser.com/ProductDetail/Antenova/SRF2W021-100?qs=sGAEpiMZZMuBTKBKvsBmlMeP1Lut7uca61hspfdOxQexT8ZJsKeXqw%3d%3d)
### Power / LiPo Batteries
- [SparkFun mosfet power control (link)](https://www.sparkfun.com/products/12959)
- [Pimoroni On/Off shim (link)](https://www.adafruit.com/product/3581)
- [SparkFun Charger/Booster (link)](https://learn.sparkfun.com/tutorials/sparkfun-5v1a-lipo-chargerbooster-hookup-guide)
- [Power Meter](https://www.sparkfun.com/products/14331)
- [Pimoroni LiPo shim (link)](https://www.adafruit.com/product/3196)
### Storage
- [Ableconn mSATA Hat (link)](https://www.amazon.com/dp/B00WQJ8BH2)
- [Ableconn nvme Hat (link)](https://www.amazon.com/dp/B01LZ0LCTU)
### Displays
- [Waveshare 4.2 inch e-ink display (link)](https://www.waveshare.com/product/modules/oleds-lcds/e-paper/4.2inch-e-paper-module.htm?___SID=U)
- [Waveshare 2.9 inch e-ink display (link)](https://www.waveshare.com/product/modules/oleds-lcds/e-paper/2.9inch-e-paper-module.htm?___SID=U)
- [Pimoroni e-ink hat (link)](https://www.adafruit.com/product/3743)
### Input
- [Waveshare touch keypad (link)](https://www.waveshare.com/product/RPi-Touch-Keypad.htm)
- [Pimoroni touch button hat (link)](https://www.adafruit.com/product/3472)
- [Pimoroni push button shim (link)](https://www.adafruit.com/product/3582)
- [Adafruit display+button hat (link)](https://www.adafruit.com/product/3531)
- [Adafruit joystick+button hat (link)](https://www.adafruit.com/product/3464)
- [Pimoroni display+button hat (link)](https://www.adafruit.com/product/2694)
### Cell Data
- [LTE rPi Shield (link)](http://sixfab.com/product/raspberry-pi-3g-4glte-base-shield-v2/)
- [LTE/4G pciE (link)](http://sixfab.com/product/quectel-ec25-mini-pcle-4glte-module/)
- [3G pciE (link)](http://sixfab.com/product/quectel-uc20-mini-pcle-3g-module/)
### Misc
- [SparkFun TTL serial usb adapter (link)](https://www.sparkfun.com/products/14050)
- [Adafruit TTL serial usb adapter (link)](https://www.adafruit.com/product/3309)
- [SparkFun Bluetooth Mate Silver (link)](https://www.sparkfun.com/products/12576)
- [Adafruit GPS (link)](https://www.adafruit.com/product/746)
- [Pimoroni mini hat extender (link)](https://www.adafruit.com/product/3182)
- [Pimoroni hat extender (link)](https://www.adafruit.com/product/3742)
## 3d Printed Cases
- Pine64 [(source)](https://www.thingiverse.com/thing:1831345) : ```3d_printer_sources/Pine_A64_Two-Parts_case.zip```
- Orange Pi Zero [Plus] Base [(source)](https://www.thingiverse.com/thing:2776831) : ```3d_printer_sources/Orange_Pi_Zero_-_Minimal_Mount.zip```
- Orange Pi Zero [Plus] Case [(source)](https://www.thingiverse.com/thing:1939780) : ```3d_printer_sources/Orange_Pi_Zero_Case.zip```
- Orange Pi Zero [Plus] + Expansion Board Case [(source)](https://www.thingiverse.com/thing:2353879) : ```3d_printer_sources/Orange_Pi_Zero_+_Expansion_Board_Case.zip```
- Orange Pi Zero [Plus] + NAS Board Case [(source)](https://www.thingiverse.com/thing:2122451) : ```3d_printer_sources/Orange_Pi_Zero_NAS_Board_Case.zip```
- Orange Pi PC Case (External Mounts) [(source)](https://www.thingiverse.com/thing:2239240) : ```3d_printer_sources/Orange_PI_PC_Case_with_External_mounts_+_M5_mount.zip```
- Orange Pi PC NAS Case [(source)](https://www.thingiverse.com/thing:2468854) : ```3d_printer_sources/Orange_PI_PC_NAS_Case.zip```
- Orange Pi One Case [(source)](https://www.thingiverse.com/thing:1447933) : ```3d_printer_sources/OrangePi_One_Case.zip```
- Orange Pi One NAS Case [(source)](https://www.thingiverse.com/thing:2790266) : ```3d_printer_sources/Orange_Pi_One_NAS_Case.zip```
- Orange Pi Zero NAS Case (minimal) [(source)](https://www.thingiverse.com/thing:2740032) : ```3d_printer_sources/Orange_Pi_Zero_NAS_minimal.zip```
- Orange Pi Zero 2+ H5 Case [(source)](https://www.thingiverse.com/thing:2797865) : ```3d_printer_sources/Orange_Pi_Zero_2+_H5_Case.zip```
- Orange Pi Zero 2 Case [(source)](https://www.thingiverse.com/thing:2626323) : ```3d_printer_sources/Orange_Pi_Zero_2_Case.zip```
- Orange Pi Plus 2E Case [(source)](https://www.thingiverse.com/thing:2251219) : ```3d_printer_sources/Orange_Pi_plus_2e_case.zip```
- Orange Pi Plus 2E Case (alt) [(source)](https://www.thingiverse.com/thing:1916113) : ```3d_printer_sources/Orange_Pi_Plus_2E_case_2.zip```
- Orange Pi Zero Plus2 H3 Case [(source)](https://www.thingiverse.com/thing:2802598) : ```3d_printer_sources/

46
preflight.md Normal file
View File

@ -0,0 +1,46 @@
# Preflight
Some things you may or may not want to consider ahead of time
## Hardware
- Orange Pi R1
- Orange Pi Zero Plus
- Pine64 Plus
- (see [hardware notes](hardware_notes.md) for additional considerations)
- Orange Pi Zero
- (see [hardware notes](hardware_notes.md) for additional considerations)
- Raspberry Pi
- (see [hardware notes](hardware_notes.md) for additional considerations)
### Offical Support
Be sure to check OpenWRT/Armbian for your chosen router/boards support status. A number are going to be officially supported while others will have development snapshots avilable.
## Domain
If you want to have an 'official' domain for your device, it's possible and this documentation will cover some of the setup.
### Registrars
A couple of good registrars for registering a domain
- [http://namecheap.com/](http://namecheap.com/)
- [https://uniregistry.com/](https://uniregistry.com/)
### TLDs (Top Level Domains)
Some good TLDs for a lolipop device
- .zone
- .host
- .travel
- .link
- .online
- .net
- .tech
- .club
### Domain Preflight
In your chosen registrar you'll need to setup API access if you want to use Let's Encrypt for SSL certificates (recommended). Check with your registrar for necessary information on setup.

208
virtualization.md Normal file
View File

@ -0,0 +1,208 @@
# Virtualization
Some notes on setting up Docker build hosts using emulation. Specifically using qemu to setup arm32v7 and arm64v8 environments for Docker builds.
Handy if you need are using an SBC that's too 'small' for building searx/gogs but *can* run the final Docker image.
## Inspiration / Further Reading
- [https://resin.io/blog/building-arm-containers-on-any-x86-machine-even-dockerhub/](https://resin.io/blog/building-arm-containers-on-any-x86-machine-even-dockerhub/)
- [https://github.com/petrosagg/armv7hf-python-dockerhub/blob/master/Dockerfile](https://github.com/petrosagg/armv7hf-python-dockerhub/blob/master/Dockerfile)
- [https://github.com/ViViDboarder/docker-rpi-homebridge/blob/master/Dockerfile](https://github.com/ViViDboarder/docker-rpi-homebridge/blob/master/Dockerfile)
- This BREAKS when not cross building so you can't easily run docker build / up on a docker file w/ these in it
- [https://wiki.qemu.org/Documentation/Platforms/ARM](https://wiki.qemu.org/Documentation/Platforms/ARM)
- [https://translatedcode.wordpress.com/2016/11/03/installing-debian-on-qemus-32-bit-arm-virt-board/](https://translatedcode.wordpress.com/2016/11/03/installing-debian-on-qemus-32-bit-arm-virt-board/)
- [https://translatedcode.wordpress.com/2017/07/24/installing-debian-on-qemus-64-bit-arm-virt-board/](https://translatedcode.wordpress.com/2017/07/24/installing-debian-on-qemus-64-bit-arm-virt-board/)
- [https://www.raymii.org/s/articles/virt-install_introduction_and_copy_paste_distro_install_commands.html](https://www.raymii.org/s/articles/virt-install_introduction_and_copy_paste_distro_install_commands.html)
- [http://ftp.nl.debian.org/debian/dists/stretch/main/](http://ftp.nl.debian.org/debian/dists/stretch/main/)
- [https://www.collabora.com/news-and-blog/blog/2017/06/20/debian-armhf-vm-on-arm64-server/](https://www.collabora.com/news-and-blog/blog/2017/06/20/debian-armhf-vm-on-arm64-server/)
- [http://blog.system76.com/post/139138591598/howto-qemu-w-ubuntu-xenial-host-uefi-guest](http://blog.system76.com/post/139138591598/howto-qemu-w-ubuntu-xenial-host-uefi-guest)
## Minor notes
- Use arm64 for arm64v8
- Use armhf for arm32v
## Prep
``` bash
apt install qemu-system-arm libguestfs-tools qemu-efi qemu-efi-aarch64 qemu-efi-arm
```
## Plain QEMU
These processes will let you bootstrap a virtual machine for later import into libvirt management engines.
### 64bit arm v8
``` bash
# Probably should have this in a dedicated dir, no?
mkdir arm64v8
cd arm64v8
# Pull installer
wget http://ports.ubuntu.com/ubuntu-ports/dists/xenial/main/installer-arm64/current/images/netboot/mini.iso
mv mini.iso net-install.iso
# Create storage for VM
qemu-img create -f qcow2 arm64v8-xenial.qcow2 16G
# Prep EFI boot
cp /usr/share/AAVMF/AAVMF_VARS.fd AAVMF_VARS.fd
# Install
# WARNING: YOU MUST TWEAK THE GRUB KERNEL CONSOLE LINE TO HAVE 'console=ttyAMA0' IMMEDIATELY FOLLOWING THE KERNEL IMAGE OR YOU WON'T GET OUTPUT
# NOTE: Use CTRL-H for backspace and CTRL-X to boot
# NOTE: virtio-blk-device and virtio-net-device are necessary as the mini.iso (renamed to net-install.iso) doesn't support PCI (fixed post-install)
qemu-system-aarch64 -M virt -m 2048 -smp 4 -cpu cortex-a53 \
-drive if=pflash,format=raw,readonly,file=/usr/share/AAVMF/AAVMF_CODE.fd \
-drive if=pflash,format=raw,file=AAVMF_VARS.fd \
-cdrom net-install.iso \
-drive if=none,file=arm64v8-xenial.qcow2,format=qcow2,id=hd \
-device virtio-blk-device,drive=hd \
-netdev user,id=arm0 -device virtio-net-device,netdev=arm0 \
-nographic -no-reboot
# Backup base install (just in case)
cp arm64v8-xenial.qcow2 arm64v8-xenial-base-install.qcow2
# Run the VM with the necessary parms/infos
qemu-system-aarch64 -M virt -m 2048 -smp 4 -cpu cortex-a53 \
-drive if=pflash,format=raw,readonly,file=/usr/share/AAVMF/AAVMF_CODE.fd \
-drive if=pflash,format=raw,file=AAVMF_VARS.fd \
-drive if=none,file=arm64v8-xenial.qcow2,format=qcow2,id=hd \
-device virtio-blk-device,drive=hd \
-netdev user,id=arm0 -device virtio-net-device,netdev=arm0 \
-nographic -no-reboot
```
### 32bit arm v7
``` bash
# Probably should have this in a dedicated dir, no?
mkdir arm32v7
cd arm32v7
# Get netbook kernel/initrd
wget -O installer-vmlinuz http://ports.ubuntu.com/ubuntu-ports/dists/xenial/main/installer-armhf/current/images/generic-lpae/netboot/vmlinuz
wget -O installer-initrd.gz http://ports.ubuntu.com/ubuntu-ports/dists/xenial/main/installer-armhf/current/images/generic-lpae/netboot/initrd.gz
# Create storage for VM
qemu-img create -f qcow2 arm32v7-xenial.qcow2 16G
# Prep EFI boot
cp /usr/share/AAVMF/AAVMF32_VARS.fd AAVMF32_VARS.fd
# Install
qemu-system-arm -M virt -m 2048 -smp 4 -cpu cortex-a15 \
-kernel installer-vmlinuz \
-initrd installer-initrd.gz \
-drive if=none,file=arm32v7-xenial.qcow2,format=qcow2,id=hd \
-device virtio-blk-pci,drive=hd \
-netdev user,id=arm0 -device virtio-net-pci,netdev=arm0 \
-nographic -no-reboot
# Backup base install (just in case)
cp arm32v7-xenial.qcow2 arm32v7-xenial-base-install.qcow2
# Copy vmlinuz/initrd from root filesystem for final boot
virt-filesystems -a arm32v7-xenial.qcow2
virt-ls -a arm32v7-xenial.qcow2 /boot/
virt-copy-out -a arm32v7-xenial.qcow2 /boot/vmlinuz-4.4.0-127-generic-lpae /boot/initrd.img-4.4.0-127-generic-lpae .
# Boot!
qemu-system-arm -M virt -m 2048 -smp 4 -cpu cortex-a15 \
-kernel vmlinuz-4.4.0-127-generic-lpae \
-initrd initrd.img-4.4.0-127-generic-lpae \
-drive if=none,file=arm32v7-xenial.qcow2,format=qcow2,id=hd \
-device virtio-blk-pci,drive=hd \
-netdev user,id=arm0 -device virtio-net-pci,netdev=arm0 \
-nographic -no-reboot
```
## virsh/virt-install
This section is very much a work in progress. Based on further research / reading you'll need to bootstrap the VM with raw qemu and then import to virsh.
``` bash
virt-install --name ubuntu-16.04-arm64v8 \
--import \
--virt-type qemu \
--arch aarch64 \
--machine virt \
--memory 2048 \
--vcpus 4 \
--noacpi \
--os-type linux \
--os-variant ubuntu16.04 \
--disk path=template-ubuntu-16.04-arm64v8.qcow2,size=25,bus=virtio \
--network default \
--graphics none \
```
## Useful virsh commands
For post install usage
``` bash
virsh list --all # List all VMs
virsh dumpxml --domain VM_NAME # Dump the XML for the VM
virsh destroy --domain VM_NAME # Force shutdown VM
virsh undefine --domain VM_NAME # Remove/Delete VM
virsh console VM_NAME
virsh edit VM_NAME
rm DISK_IMAGE_PATH
```
## First Boot
``` bash
vim /etc/default/grub
update-grub
apt update && apt install sudo vim tmux screen wget curl htop git nano rsync iotop nload unzip
ufw allow ssh
ufw enable
```
## rclone
``` bash
curl https://rclone.org/install.sh | sudo bash
```
## Docker
``` bash
apt remove docker docker-engine docker.io
apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common
echo "deb [arch=arm64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
echo "deb [arch=armhf] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
apt update
apt install docker-ce python3 python3-pip
pip3 install docker-compose
poweroff
```
## Export Docker Container Images
``` bash
for repo in `docker image ls --format "{{.Repository}}"`; do
outfile=`echo $repo | sed 's+/+_+g'`
echo "$repo -> $outfile"
docker save -o ${outfile}.tar $repo
done
```