Compare commits

..

No commits in common. "42cbd0e54ad12838d6d6a656305741f8a3871aae" and "3e2f9c068485f192a8d361bff89ed5901a9e30cf" have entirely different histories.

17 changed files with 77 additions and 184 deletions

View File

@ -84,8 +84,9 @@ sslcacertfile = /etc/ssl/certs/ca-certificates.crt
### Notes ### Notes
I use Standard Notes to take notes and wrote the tool [standardnotes-fs](https://github.com/tannercollin/standardnotes-fs) I use Standard Notes to take notes and wrote the tool
to mount my notes as a file system to view and edit them as plain text files. [standardnotes-fs](https://github.com/tannercollin/standardnotes-fs) to mount my
notes as a file system to view and edit them as plain text files.
I take weekly backups of the mounted file system on my media server with cron: I take weekly backups of the mounted file system on my media server with cron:
@ -130,7 +131,9 @@ in case Telegram disappears or my account gets banned.
<span class="aside">Saves the messages to a sqlite db</span> <span class="aside">Saves the messages to a sqlite db</span>
Telegram includes a data export feature, but it can't be automated. Instead I Telegram includes a data export feature, but it can't be automated. Instead I
run the deprecated software [telegram-export](https://github.com/expectocode/telegram-export) hourly with cron: run the deprecated software
[telegram-export](https://github.com/expectocode/telegram-export) hourly with
cron:
``` ```
0 * * * * bash -c 'timeout 50m /home/tanner/opt/telegram-export/env/bin/python -m telegram_export' > /var/log/telegramexport.log 2>&1 0 * * * * bash -c 'timeout 50m /home/tanner/opt/telegram-export/env/bin/python -m telegram_export' > /var/log/telegramexport.log 2>&1
@ -141,12 +144,16 @@ Hasn't corrupted the database yet.
### Phone ### Phone
[Signal Messenger](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms&hl=en_CA&gl=US) automatically exports a copy of my text messages database, and [Signal
[Aegis](https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis&hl=en_CA&gl=US) allows me to export an encrypted JSON file of my two-factor authentication Messenger](https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms&hl=en_CA&gl=US)
automatically exports a copy of my text messages database, and
[Aegis](https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis&hl=en_CA&gl=US)
allows me to export an encrypted JSON file of my two-factor authentication
codes. codes.
I mount my phone's internal storage as a file system on my desktop using I mount my phone's internal storage as a file system on my desktop using
[adbfs-rootless](https://github.com/spion/adbfs-rootless). I then rsync the files over to my media server: [adbfs-rootless](https://github.com/spion/adbfs-rootless). I then rsync the
files over to my media server:
``` ```
$ ./adbfs ~/mntphone $ ./adbfs ~/mntphone
@ -174,8 +181,9 @@ All the files will be included in the 1 TB hard drive backup rotations.
### Web Services ### Web Services
Web services that I run like [txt.t0.vc](https://txt.t0.vc) and [QotNews](https://news.t0.vc) are backed up daily, weekly, Web services that I run like [txt.t0.vc](https://txt.t0.vc) and
and monthly depending on how frequently the data changes. [QotNews](https://news.t0.vc) are backed up daily, weekly, and monthly depending
on how frequently the data changes.
I run `rdiff-backup` on the remote server with cron: I run `rdiff-backup` on the remote server with cron:
@ -198,9 +206,11 @@ the `rdiff-backup --server` command for security.
### Protospace ### Protospace
I run a lot of services for [Protospace](https://protospace.ca/), my city's makerspace. I run a lot of services for [Protospace](https://protospace.ca/), my city's
makerspace.
The member portal I wrote called [Spaceport](https://my.protospace.ca/) creates an archive I download daily: The member portal I wrote called [Spaceport](https://my.protospace.ca/) creates
an archive I download daily:
``` ```
40 10 * * * wget --content-disposition \ 40 10 * * * wget --content-disposition \
@ -210,7 +220,8 @@ The member portal I wrote called [Spaceport](https://my.protospace.ca/) creates
https://api.my.protospace.ca/backup/ https://api.my.protospace.ca/backup/
``` ```
The website and [wiki](https://wiki.protospace.ca) that I sysadmin both get backed up weekly: The website and [wiki](https://wiki.protospace.ca) that I sysadmin get
backed up weekly:
``` ```
0 12 * * 1 mysqldump --all-databases > /var/www/dump.sql 0 12 * * 1 mysqldump --all-databases > /var/www/dump.sql
@ -218,7 +229,9 @@ The website and [wiki](https://wiki.protospace.ca) that I sysadmin both get back
20 12 * * 1 rdiff-backup /var/www pshostbak@remotebackup::/mnt/backup/remote/pshostbak/weekly/www/ 20 12 * * 1 rdiff-backup /var/www pshostbak@remotebackup::/mnt/backup/remote/pshostbak/weekly/www/
``` ```
The Protospace [Minecraft server](http://games.protospace.ca:8123/?worldname=world&mapname=flat&zoom=3&x=74&y=64&z=354) I run gets backed up daily: The Protospace [Minecraft
server](http://games.protospace.ca:8123/?worldname=world&mapname=flat&zoom=3&x=74&y=64&z=354)
I run gets backed up daily:
``` ```
00 15 * * * date -Iseconds > /home/tanner/minecraft/backup_check.txt 00 15 * * * date -Iseconds > /home/tanner/minecraft/backup_check.txt
@ -287,11 +300,14 @@ correctly.
## Rotating Hard Drives ## Rotating Hard Drives
I rotate through 2.5" 1 TB hard drives each Saturday when I do a backup. They I rotate through 2.5" 1 TB hard drives each Saturday when I do a backup. They
are quite cheap at [$65 CAD](https://www.memoryexpress.com/Products/MX65194) each so I can have a bunch floating around. are quite cheap at [$65 CAD](https://www.memoryexpress.com/Products/MX65194)
each so I can have a bunch floating around.
I keep one connected to the server, one in my bag, one offsite, one at my I keep one connected to the server, one in my bag, one offsite, one at my
mother's house, and one at my dad's house. Every Saturday I run the script above mother's house, and one at my dad's house. Every Saturday I run the script above
to take a copy and then swap the drive with the one in my bag. It then gets <span class="aside">I go back home about twice per year</span> to take a copy and then swap the drive with the one in my bag. It then gets
<span class="aside">I go back home about twice per year</span>
swapped when I visit my offsite location. Same for when I visit my parents. This swapped when I visit my offsite location. Same for when I visit my parents. This
means that all hard drives eventually get rotated through with new data and means that all hard drives eventually get rotated through with new data and
don't sit too long unpowered. don't sit too long unpowered.

View File

@ -15,15 +15,16 @@ This article explains how I set it up and is targeted towards Linux sysadmins.
## Overview ## Overview
I have a cheap $5 per month virtual server with [Digital Ocean](https://digitalocean.com) that runs I have a cheap $5 per month virtual server with [Digital
Debian GNU/Linux 10. An OpenVPN server is running on this virtual server. Ocean](https://digitalocean.com) that runs Debian GNU/Linux 10. An OpenVPN
server is running on this virtual server.
My media server at home has an OpenVPN client connected to the server and is My media server at home has an OpenVPN client connected to the server and is
assigned a static IP on the VPN network. assigned a static IP on the VPN network.
The virtual server has routing enabled and forwards inbound traffic __from the The virtual server has routing enabled and forwards inbound traffic __from the
internet__ to my media server at home. This allows me to have external HTTP and internet__ to my media server at home. This allows me to have external HTTP and SSH
SSH access. access.
## Server Setup ## Server Setup
@ -40,7 +41,8 @@ $ sudo apt install openvpn ufw
### OpenVPN Server ### OpenVPN Server
These steps roughly follow [this guide](https://wiki.debian.org/OpenVPN#TLS-enabled_VPN). These steps roughly follow [this
guide](https://wiki.debian.org/OpenVPN#TLS-enabled_VPN).
Generate TLS certificates and keys: Generate TLS certificates and keys:
@ -87,8 +89,7 @@ We make a `mediaserver` client because we want to assign a static IP to it. You
need to make a different one for each client you want with a static IP. need to make a different one for each client you want with a static IP.
Also, if you want generic clients that all get dynamic IPs for use on your Also, if you want generic clients that all get dynamic IPs for use on your
laptop, phone, etc. to protect you from public WiFi (like a normal VPN), create laptop, phone, etc. to protect you from public WiFi (like a normal VPN), create only a single extra one:
only a single extra one:
``` ```
$ ./easyrsa build-client-full client nopass # optional $ ./easyrsa build-client-full client nopass # optional
@ -135,8 +136,7 @@ $ sudo mkdir ccd
$ sudo touch ccd/mediaserver $ sudo touch ccd/mediaserver
``` ```
Replace `mediaserver` with whatever client name you used above. Edit it like Replace `mediaserver` with whatever client name you used above. Edit it like so:
so:
<span class="aside">Your home server will be `10.8.0.100`</span> <span class="aside">Your home server will be `10.8.0.100`</span>
@ -221,11 +221,11 @@ COMMIT
Replace `123.123.123.123` with your VPN server's external IP address and `eth0` Replace `123.123.123.123` with your VPN server's external IP address and `eth0`
with the external interface. with the external interface.
This will forward TCP traffic on port 2222 to your home server. If you want to This will forward TCP traffic on port 2222 to your home server. If you want to use
use port 22, then you need to set the VPN SSH server to something else. port 22, then you need to set the VPN SSH server to something else.
A full example of `/etc/ufw/before.rules` with other ports included can be A full example of `/etc/ufw/before.rules` with other ports included can be found
found here: here:
[https://txt.t0.vc/URUG](https://txt.t0.vc/URUG) [https://txt.t0.vc/URUG](https://txt.t0.vc/URUG)
@ -248,8 +248,7 @@ $ sudo apt install openvpn
### Client Configs ### Client Configs
For static IP clients (like your home server), create the config file For static IP clients (like your home server), create the config file `/etc/openvpn/client.conf`:
`/etc/openvpn/client.conf`:
``` ```
client client
@ -289,8 +288,7 @@ $ sudo cat /etc/openvpn/easy-rsa/pki/ca.crt
Also replace `vpn.example.com` with the subdomain you assigned earlier. Also replace `vpn.example.com` with the subdomain you assigned earlier.
For device clients (like your laptop and phone), create the config file For device clients (like your laptop and phone), create the config file `client.ovpn`:
`client.ovpn`:
<span class="aside">`redirect-gateway def1` forces traffic over the VPN</span> <span class="aside">`redirect-gateway def1` forces traffic over the VPN</span>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

View File

@ -1,6 +0,0 @@
Title: Creations
Template: creations
Slug: z
Qot.

View File

@ -1,6 +0,0 @@
Title: Projects
Template: projects
Slug: y
Qot.

View File

@ -0,0 +1,6 @@
Title: Text Files
Template: text-files
Slug: x
Qot.

View File

@ -1,6 +0,0 @@
Title: Writing
Template: writing
Slug: x
Qot.

View File

@ -1,28 +0,0 @@
Title: Wine Crate Coffee Table
Date: 2018-09-12
Category: Creations
Summary: A coffee table made out of wooden wine creates.
Short: 0
My close friend Odai saw a simple coffee table design online that was built out
of four wooden wine crates. They are quite cheap and available at any hardware
store. We each wanted to make one so went and bought eight crates and some
plywood to use as a base.
We went to my local makerspace, Protospace, to build them in the wood shop. We
thought it would be a quick job only taking a few hours, but it turned out to be
a twelve hour job over a couple of days. At least we were in good company!
![the table before staining. four box-like wine crates are on their sides and joined together in a spiral. a messy wood shop is in the background]({static}/images/wine/wine1.jpg)
![the two tables after staining. one face is centred and the contrast between the dark stain and light wood grain shows.]({static}/images/wine/wine2.jpg)
The wine crates were glued and then brad-nailed together. Extra wood was added
under the thin top strips for support. After the glue dried, the brad nails were
painstakingly removed because the ones we used were too long and stuck out.
After being attached to the base, the entire table was sanded and then stained.
We let it dry overnight and returned the following day to add a quick layer of
varnish.
![the table in my living room with blankets inside the wine crates and a plant pot in the centre growing a bonsai tree and a succulent]({static}/images/wine/wine3.jpg)

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # # -*- coding: utf-8 -*- #
from __future__ import unicode_literals from __future__ import unicode_literals
import os
AUTHOR = 'Tanner Collin' AUTHOR = 'Tanner Collin'
SITENAME = 'Tanner Collin' SITENAME = 'Tanner Collin'
@ -56,14 +55,7 @@ CATEGORIES_SAVE_AS = ''
TAGS_SAVE_AS = '' TAGS_SAVE_AS = ''
INDEX_SAVE_AS = 'index.html' INDEX_SAVE_AS = 'index.html'
ARTICLE_URL = '{short}/' ARTICLE_URL = '{date:%d}/'
ARTICLE_SAVE_AS = '{short}/index.html' ARTICLE_SAVE_AS = '{date:%d}/index.html'
PAGE_URL = '{slug}'
PAGE_SAVE_AS = '{slug}/index.html'
def list_text_files():
return sorted(os.listdir('./content/text'))
JINJA_GLOBALS = {'list_text_files': list_text_files}
PROD = False PROD = False

View File

@ -56,7 +56,7 @@ CATEGORIES_SAVE_AS = ''
TAGS_SAVE_AS = '' TAGS_SAVE_AS = ''
INDEX_SAVE_AS = 'index.html' INDEX_SAVE_AS = 'index.html'
ARTICLE_URL = '{short}/' ARTICLE_URL = '{short}'
ARTICLE_SAVE_AS = '{short}/index.html' ARTICLE_SAVE_AS = '{short}/index.html'
PAGE_URL = '{slug}' PAGE_URL = '{slug}'
PAGE_SAVE_AS = '{slug}/index.html' PAGE_SAVE_AS = '{slug}/index.html'

View File

@ -1,21 +0,0 @@
{% extends "base.html" %}
{% block meta %}
{% endblock %}
{% block style %}
{% endblock %}
{% block content %}
Creations
=========
Sometimes I create art or interactive tech.
{% for article in articles if article.category.name == 'Creations' %}
<a href="/{{ article.url }}">{{ article.title }}</a>
{{ article.summary | striptags }}
{% endfor %}
{% endblock %}

View File

@ -1,14 +1,14 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
Hi, I'm Tanner! I like home automation, <a href=d>sensors</a>, bots, Hi, I'm Tanner! I like home automation, bots, privacy,
privacy, Python, Debian, coffee, and makerspaces. Python, Debian, coffee, and makerspaces.
Please sign my <a href=g>Guest Book</a>! Please sign my <a href=g>Guest Book</a>!
Email: site3@tannercollin.com Email: site3@tannercollin.com
Telegram: @tannercollin Telegram: @tannercollin
Resume Resume:
Firmware Engineer at Cabana Blockchain, 2018- Firmware Engineer at Cabana Blockchain, 2018-
Lead Hardware Engineer at Critical Control, 2016-2018 Lead Hardware Engineer at Critical Control, 2016-2018
@ -16,29 +16,26 @@ Electrical Engineer at Opener Aero, 2016-2016
Electrical Engineer Intern at Pason Systems, 2014-2015 Electrical Engineer Intern at Pason Systems, 2014-2015
BSc. Electrical Engineering from University of Calgary BSc. Electrical Engineering from University of Calgary
Projects Projects:
<a href=q>QotNews* <a href=q>QotNews*
<a href=n>Notica* <a href=n>Notica*
<a href=m>Spaceport* <a href=m>Spaceport*
<a href=t>t0txt* <a href=t>t0txt*
<a href=y>[more]</a> <a href=s>standardnotes-fs*</a>
* external link * external link
Creations Creations:
{% for article in articles_page.object_list if article.category.name == 'Creations' %} {% for article in articles_page.object_list if article.category.name == 'Creations' %}
{% if loop.index <= 4 %}
<a href={{ article.url }}>{{ article.title }} <a href={{ article.url }}>{{ article.title }}
{% endif %}
{% endfor %} {% endfor %}
<a href=z>[more]
</a> </a>
Writing Writing:
{% for article in articles_page.object_list if article.category.name == 'Writing' %} {% for article in articles_page.object_list if article.category.name == 'Writing' %}
<a href={{ article.url }}>{{ article.title }} <a href={{ article.url }}>{{ article.title }}
{% endfor %} {% endfor %}
<a href=x>[more] <a href=x>[Text Files]
{% endblock %} {% endblock %}

View File

@ -1,36 +0,0 @@
{% extends "base.html" %}
{% block meta %}
{% endblock %}
{% block style %}
{% endblock %}
{% block content %}
Projects
========
My main hobby is working on software projects. I typically design websites or
build tools that make my life easier.
<a href="https://news.t0.vc/" target="_blank" rel="noreferrer noopener">QotNews*</a> - <a class="source" href="https://git.tannercollin.com/tanner/qotnews" target="_blank" rel="noreferrer noopener">source code*</a>
Hacker News, Reddit, Lobsters, and Tildes articles pre-rendered in reader mode.
Optimized for speed and distraction-free reading.
<a href="https://notica.us" target="_blank" rel="noreferrer noopener">Notica*</a> - <a class="source" href="https://github.com/tannercollin/Notica" target="_blank" rel="noreferrer noopener">source code*</a>
Send browser notifications from your terminal. No installation. No registration.
<a href="https://my.protospace.ca" target="_blank" rel="noreferrer noopener">Spaceport*</a> - <a class="source" href="https://github.com/Protospace/spaceport" target="_blank" rel="noreferrer noopener">source code*</a>
Makerspace members' portal for Calgary Protospace. It tracks membership,
courses, training, access cards, and more.
<a href="https://txt.t0.vc" target="_blank" rel="noreferrer noopener">t0txt*</a> - <a class="source" href="https://github.com/tannercollin/t0txt" target="_blank" rel="noreferrer noopener">source code*</a>
Minimal command line pastebin. Allows you to upload text notes from a bash pipe
or web browser.
<a href="https://github.com/tannercollin/standardnotes-fs" target="_blank" rel="noreferrer noopener">standardnotes-fs*</a>
A filesystem that mounts your Standard Notes account as a directory of text
files that you can edit.
* external link
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block meta %}
{% endblock %}
{% block style %}
{% endblock %}
{% block content %}
<h1>Text Files</h1>
Here are some various text notes that I share with the public.
<hr />
{% for f in list_text_files() %}
<a href="../text/{{ f }}">{{ f }}</a>
{% endfor %}
{% endblock %}

View File

@ -1,28 +0,0 @@
{% extends "base.html" %}
{% block meta %}
{% endblock %}
{% block style %}
{% endblock %}
{% block content %}
Writing
=======
Various articles, mostly about computers.
{% for article in articles if article.category.name == 'Writing' %}
<a href="/{{ article.url }}">{{ article.title }}</a>
{{ article.summary | striptags }}
{% endfor %}
Text Files
----------
Here are some random text notes that I share with the public.
{% for f in list_text_files() %}
<a href="../text/{{ f }}">{{ f }}</a>
{% endfor %}
{% endblock %}