Import original docs
This commit is contained in:
parent
018c9f763e
commit
fdbd56938c
|
@ -0,0 +1,3 @@
|
|||
# Docs
|
||||
|
||||
The core documentation on how to setup an SBC as a lolipop cloud
|
|
@ -0,0 +1,3 @@
|
|||
# Armbian
|
||||
|
||||
Setup an SBC as a lolipop router and private LAN
|
|
@ -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.
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
|
@ -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/
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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.
|
|
@ -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
|
|
@ -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.
|
|
@ -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/)
|
|
@ -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.
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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```
|
|
@ -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
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
|
@ -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"
|
||||
|
||||
```
|
|
@ -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
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -0,0 +1,3 @@
|
|||
# Hardware
|
||||
|
||||
Setup additional hardware with an SBC
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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
|
||||
|
||||
```
|
|
@ -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/
|
|
@ -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.
|
|
@ -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
|
||||
|
||||
```
|
||||
|
Reference in New Issue