This commit is contained in:
Joel Beckmeyer 2021-01-29 00:00:00 -05:00
commit c4dae0f4bb
76 changed files with 5207 additions and 0 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "themes/no-js-hugo-theme"]
path = themes/no-js-hugo-theme
url = https://github.com/stevenengler/no-js-hugo-theme.git

6
archetypes/default.md Normal file
View File

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

37
config.toml Normal file
View File

@ -0,0 +1,37 @@
baseURL = "https://beckmeyer.us/"
languageCode = 'en-us'
title = "Joel Beckmeyer's Homepage"
theme = "no-js-hugo-theme"
[author]
name = "Joel Beckmeyer"
email = "joel@beckmeyer.us"
[menu]
[[menu.main]]
name = "Git"
identifier = "Gitea"
url = "https://git.beckmeyer.us/TnSb"
weight = 400
[[menu.main]]
name = "GitHub"
identifier = "GitHub"
url = "https://github.com/TinfoilSubmarine"
weight = 500
[markup]
[markup.highlight]
codeFences = true
noClasses = false
[markup.tableOfContents]
startLevel = 1
endLevel = 6
[params]
# footer text at the bottom of every page
footerText = "Have any questions? Let me know on [Matrix](https://matrix.to/#/@joel:thebeckmeyers.xyz), or start a discussion on [Fediverse](https://social.beckmeyer.us/TinfoilSubmarine)!"
# enable the table of content on pages with more than this many words
# (negative to disable)
# (can be overridden per-page by setting the 'toc' front matter parameter)
#tocWordThreshold = 1000 # default <unset>

12
content/_index.md Normal file
View File

@ -0,0 +1,12 @@
---
title: Home
menu:
main:
weight: 100
---
# Welcome!
You can find me on the [Fediverse](https://social.beckmeyer.us/TinfoilSubmarine) and [Matrix](https://matrix.to/#/@joel:thebeckmeyers.xyz).
[What is the Fediverse?](https://pleroma.social/blog/2021/01/13/the-big-pleroma-and-fediverse-faq/)

11
content/contact.md Normal file
View File

@ -0,0 +1,11 @@
---
title: Contact
draft: false
menu:
main:
weight: 200
---
Joel Beckmeyer\
Matrix: [@joel:thebeckmeyers.xyz](https://matrix.to/#/@joel:thebeckmeyers.xyz)\
Fediverse: [@TinfoilSubmarine@social.beckmeyer.us](https://social.beckmeyer.us/TinfoilSubmarine)

6
content/posts/_index.md Normal file
View File

@ -0,0 +1,6 @@
---
title: Blog
menu:
main:
weight: 300
---

35
content/posts/better.md Normal file
View File

@ -0,0 +1,35 @@
---
title: "Better?"
tags: ["poetry"]
date: 2021-04-03T22:15:44-04:00
draft: false
---
There are many that say
(and I tend to agree)
that free software is the best there could be.
But please don't mistake
using software that's free
as a right to superiority.
There are many that go
from day to day living
and don't give a thought to what they are using.
Are they worse for this?
Are you better for caring?
Sometimes the truth can be quite baring.
That not every human
in present circumstance
is able or willing to take a chance.
'Cause that's what it is,
taking a chance and going
into the unknown with fear, and knowing
that what you might find,
may not truly be better.
But instead simply different;
and still made by a stranger.

View File

@ -0,0 +1,33 @@
---
title: "Consistency"
tags: ["FOSS"]
date: 2021-04-04T00:00:00-05:00
draft: false
---
I've seen a lot of talk about this stuff:
- "Check out my FOSS project (hosted on Github)"
- "Wayland is a great innovation and boon to the community! Also, there are very few tools/alternatives available yet for your favorite X11 tool!"
- "We love open source! Also, we develop the most popular proprietary operating system!"
- "Do as I say, not as I do."
We love to poke fun at and expose this kind of stuff, which is all fine and
dandy. I think it's an interesting (and important) part of our humanity that
this kind of thing bugs us so much. Think about that last point, which at least
in my experience, is something I *loved* to fault authorities for.
Hypocrisy is fun and also infuriating to uncover in others, but how often do
we do a "consistency check" on ourselves? Is what we are saying evidenced by
the rest of our actions?
That's a hard look sometimes. I know it is for me, since I'm **very** quick
to judge others, but don't often think about how I fail at my own principles.
Example: As a FOSS advocate, it's nearly natural to assume that everything will
be better and easier with more people using FOSS. When evidence seems to point
to the contrary (e.g. fighting with Matrix/Element to get it working for my
family and friends), I don't own up to the fact that it isn't easier, and that
is an actual problem.
If we truly want to build a welcoming and wholesome community, let's be careful
to do a consistency check to make sure nothing smells foul.

View File

@ -0,0 +1,6 @@
---
title: "Disruptive Technologies"
date: 2021-01-27T10:01:12-05:00
draft: true
---

View File

@ -0,0 +1,12 @@
---
title: "Federation"
date: 2021-03-24T08:17:39-04:00
draft: true
---
First, federation was non-existent. There was no need for federation with
so few computers and no widespread network to support.
Then, federation was necessary. No one had the resources to run a centralized
everything for all users. So we created a way to communicate between computers.
After that, federation was

138
content/posts/hello_doas.md Normal file
View File

@ -0,0 +1,138 @@
---
title: "Hello doas"
tags: ["Linux"]
date: 2021-01-30T15:15:55-05:00
draft: false
---
Today, I switched my workstation from `sudo` to `doas`. I'm running Void Linux,
and the process was fairly easy.
First, I needed to figure out how to remove `sudo` (yes, I realize I could have
installed `doas` first, then removed `sudo`, but I decided to do it the hard way.)
As it turns out, the [advanced usage section of the XBPS manual](https://docs.voidlinux.org/xbps/advanced-usage.html#ignoring-packages) details how to use the `ignorepkg` entry in xbps.d with nothing
other than this exact use case! I created the file `/etc/xbps.d/20-ignorepkg-sudo.conf` with contents
```
ignorepkg=sudo
```
and then ran `sudo xbps-remove sudo` (an ironic command).
After that, because I was stupid and removed `sudo` before I had set up `doas`,
I had to use plain-old `su` to change to the root user and run `xi opendoas`. I also
configured `doas` in `/etc/doas.conf` with the following:
```
# see doas.conf(5) for configuration details
permit nopass keepenv :admin
```
I ran `groupadd admin`, `usermod -aG admin joel`, and then logged out so that my
user account would see the new group perms.
And just like that, I can now run `doas xbps-install ...` and all of my other commands,
just substituting `doas` for `sudo`.
The one thing I immediately missed was `sudoedit`. Before I accidentally tried
to use `sudo` for the first time, I had already accidentally tried to run `sudoedit`
*at least* 5 times. I had to fix this. I saw a discussion on Reddit where [one user
suggested](https://www.reddit.com/r/linux/comments/l6y7nv/is_doas_a_good_alternative_to_sudo/gl4hs42?utm_source=share&utm_medium=web2x&context=3) writing a script to replace the `sudoedit` functionality.
I quickly starting hacking together something like that. I started with:
```
#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/tmp_file
$EDITOR /tmp/doasedit/tmp_file
```
And quickly ran into my first road-block. The script is going to have to change
the permissions of that file before the user can edit it. But if the script changes
the permissions, how can I restore it to the original location with the right
permissions? `cp /tmp/doasedit/tmp_file $1` won't work. I thought about just using
cat to overwrite the file contents in-place (`cat /tmp/doasedit/tmp_file > $1`).
That *could* create some issues if a program has the file open. Instead, a better option
is to create two copies of the file--one for editing, and one for preserving file
attributes:
```
#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $1 /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1>/dev/null
doas mv -f /tmp/doasedit/file $1
rm -rf /tmp/doasedit
```
Of course, the issue with this is that it only works with absolute paths.
I want to make it work for relative paths as well. I'm going to take advantage
of `realpath`, which is part of the `coreutils` package from Void. As a bonus, this
will also take care of the edge case where the given file is a symlink (IIRC,
`sudoedit` didn't follow symlinks, so I may be diverging here):
```
#!/bin/sh
mkdir -p /tmp/doasedit
srcfile="$(realpath $1)"
doas cp $srcfile /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $srcfile /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1>/dev/null
doas mv -f /tmp/doasedit/file $srcfile
rm -rf /tmp/doasedit
```
At this point, it works...okay-ish. It can only be used in one instance currently
since I hard-coded `/tmp/doasedit/file` and `/tmp/doasedit/edit`, but that's easily fixed:
```
#!/bin/sh
destfile_pfx="$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32)"
while [ -d "/tmp/doasedit/$destfile_pfx" ]; do
destfile_pfx="$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32)"
done
mkdir -p /tmp/doasedit/$destfile_pfx
srcfile="$(realpath $1)"
doas cp $srcfile /tmp/doasedit/$destfile_pfx/edit
doas chown -R $USER:$USER /tmp/doasedit/$destfile_pfx/edit
doas cp $srcfile /tmp/doasedit/$destfile_pfx/file
$EDITOR /tmp/doasedit/$destfile_pfx/edit
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1>/dev/null
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
rm -rf /tmp/doasedit/$destfile_pfx
```
At this point, the only thing missing is the check to see if the file was actually
edited:
```
...
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1>/dev/null
if cmp -s "/tmp/doasedit/$destfile_pfx/file" "$srcfile"; then
echo "Skipping write; no changes."
else
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
fi
...
```
I put this in a [repo on GitHub](https://github.com/AluminumTank/doasedit) if
anyone is interested. I know that a major
weakness of this script is the number of times it calls `doas`, which could
break flows where password is required every time `doas` is run.

View File

@ -0,0 +1,44 @@
---
title: "Moving Back To OpenSSL"
tags: ["Linux"]
date: 2021-03-22T11:00:00-04:00
draft: false
---
Void Linux [recently announced](https://voidlinux.org/news/2021/02/OpenSSL.html)
that they were going to move back to OpenSSL after originally [switching to
LibreSSL in 2014](https://voidlinux.org/news/2014/08/LibreSSL-by-default.html).
It seems that there are a lot of things at play here.
It seems that the main focus of the recent announcement is on the maintainability
and other difficulties of not using the *one true SSL/TLS library*. To me,
this pragmatically makes sense. However, every time something like this happens
I get this lingering feeling of worry...
Microsoft moving their default browser from their own implementation to
Chromium, and other browsers following suit.
Linux distributions moving *en masse* to **systemd**.
Distributed email being slowly crushed and killed by Google with GMail.
And many other examples that aren't immediately coming to mind.
I think it's great that OpenSSL as a project has made a comeback from the
Heartbleed fiasco, and that it is apparently more actively developed nowadays,
but the fact that we are even at the point of moving back to OpenSSL due to
difficulties with building software is worrying. To me, it looks like a
symptom of software becoming too entrenched and dependent on a single piece
of software.
This kind of accusation coming from anyone is going to be hypocritical, since
we all depend on Linux, X11, Wayland, systemd, or some common piece of software
that we take for granted and don't lose sleep over. However, I think what's
categorically different about this one is that an alternative was adopted,
worked on, but eventually "failed" (at least for Void, but also possibly for
Linux as well).
I don't know what the fix for this specific issue would be. I'm not nearly
familiar enough with SSL/TLS or how you would develop software to be agnostic
of dependencies like this. But I think in order to honor principles like
the Unix philosophy, the KISS principle, and countless others, we need to
figure out a way to be more modular for dependency issues like this.

View File

@ -0,0 +1,110 @@
---
title: "OpenWRT + Unbound + adblock"
tags: ["Linux"]
date: 2021-02-05T19:03:15-05:00
draft: false
---
I decided to do some work on my Linksys WRT32X running OpenWRT to make it a
little more useful.
[Unbound](https://nlnetlabs.nl/projects/unbound/about/) is a DNS
resolver which I like because it's recursive, meaning it directly queries the
root servers instead of relying on existing DNS servers run by Google,
Cloudflare, your ISP, or the like. I already have it running on several of my
servers and computers, but I figured it would be great if everything on my
network can use Unbound and be, well, *unbound* from all of those intermediary
DNS servers.
Luckily, OpenWRT already has Unbound packaged, and also has a useful LuCI app
that goes with it (LuCI is the graphical web interface that comes with OpenWRT).
All I had to do was install `luci-app-unbound`, which pulls in all of the
necessary dependencies to run unbound.
![LuCI: Software](/luci_software.png)
![LuCI: Install](/luci_install.png)
After that finished installing, I
refreshed LuCI/OpenWRT and went to "Services" on the top, and there it is!
![LuCI: Services -> Recursive DNS](/luci_services.png)
At this point, you'll have to get your hands dirty. You can either dig through
some LuCI menus or SSH in and make some edits. For reference, I'm using
["Parallel dnsmasq"](https://github.com/openwrt/packages/blob/openwrt-19.07/net/unbound/files/README.md#parallel-dnsmasq) section from the README for unbound in the OpenWRT packages (which
has a lot of other useful information as well!). Essentially, I made the edits
to `/etc/config/unbound` and `/etc/config/dhcp` after SSH'ing in. However, you
can make the same edits through LuCI.
For the `/etc/config/unbound` edits, you can make the edits to the file in
LuCI directly at "Services -> Recursive DNS -> Files -> Edit: UCI":
![LuCI: Edit /etc/config/unbound](/unbound_config.png)
For the `/etc/config/dhcp` edits, you can make the edits by finding the same
fields under "Network -> DHCP and DNS":
![LuCI: Edit DHCP and DNS Settings](/dhcp_config.png)
However, the field names are different from the lines in the config, so they
would need to be researched to determine which fields in LuCI map to which
lines in `/etc/config/dhcp`.
At this point (or maybe after restarting unbound and dnsmasq, which is a lot
easier using SSH and `/etc/init.d ... restart` as well), OpenWRT should now
be using unbound for resolving all DNS lookups, while dnsmasq is only used for
DHCP-DNS.
Bonus: you can also enable a nice status dashboard in LuCI under
"Services -> Recursive DNS -> Status", but this requires installing several more
software packages: `unbound-control` and `unbound-control-setup`. You will also
need to change a line in `/etc/config/unbound`:
```
...
option unbound_control '0'
...
```
becomes
```
...
option unbound_control '1'
...
```
A word of warning: there is another section on "Unbound and odhcpd" which
tries to cut out dnsmasq completely. However, when I tried to set this up,
I got myself into a lot of trouble (had to reset OpenWRT, re-install any extra
software packages, and restore configuration from backup). It is also possible that if you mess up
the configuration for the "Parallel dnsmasq" method, you could end up in a
similar error state and have to start over. Please be careful when doing this
and don't change anything you're not supposed to.
Now, moving on to adblock, which should be **much** simpler to setup. First,
install `luci-app-adblock` and refresh. Navigate to "Services -> Adblock":
![Services -> Adblock](/adblock.png)
Check the settings at the bottom. The only thing you need to get going is
to go to the "Blocklist Sources" tab and choose your blocklists.
![Adblock: Blacklist sources](/adblock_blocklist.png)
The
[adblock readme](https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md)
has some more info on what each list is. After that,
make sure "Enabled" is checked under the "General Settings" tab:
![Adblock: enable](/adblock_enable.png)
and click the "Refresh" button above:
![Adblock: refresh](/adblock_refresh.png)
Then you're good to go; adblock should work out of the box with unbound; cheers!
ADDENDUM: Another word of warning: once you've setup adblock, it will download
the blocklists, merge them into a single file at `/var/lib/unbound/adb_list.overall`,
and try to restart unbound. I recommend not trying to view/interact with adblock
or unbound during this restart, which can take anywhere from 30 seconds - 2 minutes.
Just leave them alone in LuCI for a little bit...

View File

@ -0,0 +1,6 @@
---
title: "Repressive Filters"
date: 2021-01-31T17:07:19-05:00
draft: true
---

View File

@ -0,0 +1,43 @@
---
title: "The Generation Ship Problem"
tags: ["Volatile Mediums"]
date: 2021-03-19T15:00:00-04:00
draft: false
---
After talking about the hardware and software problems of
digital permanence, I'm struck by a classical Sci-Fi
motif with a conundrum: the **Generation Ship**; a ship
outfitted with all of the technology, infrastructure, and
storage to support lightyear-scale human travel.
But what about that technology on the ship? If we build
one of these ships, we need to accomplish one of several
things in regards to information storage:
### 1. Innovate to the point where the lifetime of the storage devices is able to support lightyear scale travel.
That's a tall order, given where we are right now with
physical storage devices. As I mentioned in one of my
previous posts, the average lifetime of physical storage
devices is less than 100 years, no matter if it is a hard
drive, solid-state drive, etc.
### 2. Provide the facility to create new storage devices to replace the failing old ones.
Again, in my mind a tall order, since it would require
facilities on the ship to create storage devices. The
problem of having materials is at least solvable by just
sending the ship with all of the materials it needs in
advance.
### 3. Provide the facility to revitalize storage devices.
One of the main reasons I'm even thinking about this is
because I'm an individual with limited resources.
Accordingly, I think about things in terms of
broken/working, on/off, etc. With enough resources, there
is a much larger chance of being able to repair, re-purpose,
and otherwise revitalize storage devices, increasing their
lifetime. E.g., if the only failure in the hard drive is the
control circuit, that is an "easy enough" repair.
I like to toy with the idea of a generation ship a lot in
my head, but I think it's really fun to think about the
technical possibilities and needs of a ship like this.

View File

@ -0,0 +1,116 @@
---
title: "Volatile Formats"
tags: ["Volatile Mediums"]
date: 2021-03-18T14:24:00-04:00
draft: false
---
*Note: This is a continuation of the thoughts I started
thinking about in my [Volatile Mediums](https://beckmeyer.us/posts/volatile_mediums/) blog post.*
The next level up from physical mediums for data storage
is the *way* that the data is stored. In the digital age,
we have a plethora of formats for storing information.
For me, one of the most interesting areas of information
storage is the analog-digital space.
The fundamental problem of storing audio, video, and other
replications of the physical world is that there is so much
information that we can collect with sensors
(think microphones, video cameras, etc.). It would be great
if we could go get the best camera and microphone out there,
record whatever people record these days, and have that
exact physical experience "played back" for us on a screen
and speaker/headphones.
Unfortunately, there are several problems with this. Among
those is the actual design of the sensor. It takes a lot of
careful thought, engineering, and the like to create a truly
good microphone or camera. And after all of that, this sensor
will cost something. Hopefully, that cost will correspond to
the actual technical ability of that sensor! In any case,
not everyone can have the best camera or microphone due to
any number of constraints, not just those listed above.
The second problem is the sampling issue. The sensor will
create some sort of output that can then be measured, or
**sampled**, by an ADC (analog-to-digital converter). The
very word "sample" belies what this nearly magical box is
doing: it is only looking at certain portions or timestamps
of the analog signal. Granted, the time between samples
can be very small (e.g. 44.1 kHz is a fairly common sample
rate for audio), but there is still some loss of signal.
Once the ADC creates these samples, it converts them into
a digital format (something that can be stored on a
CD, hard drive, thumb drive, etc.).
The third problem is the encoding issue. The ADC creates all
of these samples, but we need to start thinking about storage
limitations. Storing the raw output of a sensor can take a
lot of space: an average album length (40 minutes) could
easily take 400MB of space! Now, again, the physical storage
space is moving in the upward direction to combat this, but
storing isn't the only problem. One prime issue is internet
bandwidth.
The solution to this is compression, like a ZIP file. It
makes big files smaller by doing some fancy math tricks
that can be reversed by a computer to reconstruct the
original file. However, for audio/video files, another level
of compression exists which actually gets rid of some of the
information in the original file to save more space. This
is called "lossy" compression, as opposed to "lossless"
compression.
Great! We've found a way to save more space. The problem
with lossy compression is that we have to decide which
information to throw away. Usually, this is frequencies
that the average human ear/eye can't perceive. But, let's
just say that some compression is a bit too "greedy" when it
comes to saving space and starts to cut into the band of
frequencies that can be perceived. Also note that
the design of these compression algorithms is an artform
and takes lots of careful consideration.
The final problem I want to mention is the codec problem.
There are many different codecs available today, and for
each and every one of them to be useful, you need to have a
way to decode each and every one of them. Unfortunately,
this is sometimes very difficult.
It could be a licensing
issue, where you don't have the correct software installed
or purchased to actually decode that file on your computer.
Or it could be a physical constraints issue, where your
computer isn't powerful enough to decode the file at a fast
enough rate for you to view it without stuttering,
buffering, etc.
Third, it could be a personal preference. Some people
have much more sensitive eyes/ears and need to have formats
that are more **transparent**, meaning that the lossy file
is perceptually identical to the source it was encoded from.
With all of these issues at play, I think there are several
key points to make:
### 1. Codecs need to be freely available for widespread use with no strings attached.
Can't stress this one enough: we need to make sure we are
doing everything possible to not let our information die
when a corporation or individual makes a decision that
impacts the "who, what, where, when, and how" of their codec
usage.
### 2. Lossless compression is good, but it is not the only thing we need.
We need to remember that not everyone has the ability to use
lossless codecs, whether that be because of internet
bandwidth limitations, storage limitation, or the like.
Instead, we need to continue to innovate in the lossy
compression space to narrow the perceptual gap between lossy
and lossless more and more.
### 3. A codec should never become obsolete.
This one may sound weird, but the fact is, if we're talking
about long-term storage of information, we can't let codecs
die, since there may come a day where we need a codec to
decode great-grandpa's album that never made it big.

View File

@ -0,0 +1,46 @@
---
title: "Volatile Mediums"
tags: ["Volatile Mediums"]
date: 2021-01-29T23:36:00-05:00
draft: false
---
I've recently been thinking a lot about storage mediums [1] -- especially in the long-term.
Technology has made a lot of progress. Digital storage mediums started out only being
able to store [224KB on a tape drive](https://en.wikipedia.org/wiki/Tape_drive)
for an average lifetime of [*up to* 30 years](https://blog.storagecraft.com/data-storage-lifespan/).
Now, we can store terrabytes of data on hard drives and solid-state drives. However,
no one ever really answered the question about long-term storage.
(Note: the following is based off an assumption that the storage medium is only
being used to make backups or archive data. The device itself could be unplugged and stored
when no backup is in progress.)
Even though *theoretically* hard drives could store data for 20+ years, random bit flips, drive
failure, etc. all make hard drives too volatile of an option. As always, of course
redundancy takes away some of these issues.
SSDs are in an even worse position: they cost significantly more than hard drives
per TB right now, and last I heard, there were still issues with bit fade when
unpowered.
CD/DVD is sounding a lot better, but there are some serious issues here too.
Variable quality directly impacts the storage lifetime. Physically storing the
discs is a lot more risky since the disc itself doesn't have as much built-in
protection as a hard drive or SSD has. You'll need a much larger quantity to
store the terrabytes of data that you can easily dump on one hard drive. And finally, life
expectancy is still fairly low -- while manufacturers of recordable discs (the 'R' in CD-R, DVD-R, etc.)
claim life expectancies of 100-200 (!) years under optimal conditions, others are *slightly* more conservative,
[giving an estimate of 30 years](https://www.clir.org/pubs/reports/pub121/sec4/).
Oh, and remember how I mentioned this is for recordable discs? That means they're single write.
The random access (RW - CD-RW, DVD-RW, etc.) discs have even lower life expectancies.
All in all, humanity has not gotten very far with the digital storage medium.
All of these life expectancies have an inconsequential variance when we zoom out
to the century view of history.
[1] And no, I'm not talking about the kind you pay to see your dead great-great-aunt to figure out if
you're actually related to George Washington.
*This is intended to be the beginning of a learning series/personal study on the issues surrounding
information preservation, digital permanence, and their related issues.*

3
deploy Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
hugo
rsync -avz --delete public/ epoch:/srv/www/

BIN
public/adblock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
public/adblock_enable.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
public/adblock_refresh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Categories &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/categories/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Categories</h1>
</div>
<article class="all-list">
<div class="title-list">
<h3><a href="/contact/">Contact</a></h3>
<div class="title-list-date">
</div>
</div>
<div class="body-list">
<p></p>
<p>
Joel Beckmeyer
Matrix: @joel:thebeckmeyers.xyz
Fediverse: @TinfoilSubmarine@social.beckmeyer.us
</p>
</div>
</article>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Categories on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/categories/</link>
<description>Recent content in Categories on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster><atom:link href="https://beckmeyer.us/categories/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

58
public/contact/index.html Normal file
View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Contact &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Contact</h1>
<div class="title-header-date">
</div>
</div>
<p>Joel Beckmeyer<br>
Matrix: <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">@joel:thebeckmeyers.xyz</a><br>
Fediverse: <a href="https://social.beckmeyer.us/TinfoilSubmarine">@TinfoilSubmarine@social.beckmeyer.us</a></p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

604
public/css/styles.css Normal file
View File

@ -0,0 +1,604 @@
h1 { font-size: 1.50em; }
h2 { font-size: 1.40em; }
h3 { font-size: 1.20em; }
h4 { font-size: 1.00em; }
h5 { font-size: 0.85em; }
h6 { font-size: 0.75em; }
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
text-decoration: none;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.5em;
}
@media (hover: hover) {
/* For devices which support hover, hide the heading URL fragment
link/icon until the mouse hovers over the heading */
h1:hover .heading-anchor,
h2:hover .heading-anchor,
h3:hover .heading-anchor,
h4:hover .heading-anchor,
h5:hover .heading-anchor,
h6:hover .heading-anchor {
visibility: visible;
}
h1 .heading-anchor,
h2 .heading-anchor,
h3 .heading-anchor,
h4 .heading-anchor,
h5 .heading-anchor,
h6 .heading-anchor {
visibility: hidden;
}
}
.heading-anchor {
color: grey;
margin-left: 0.5em;
font-size: 0.75em;
}
.heading-anchor:hover {
text-decoration: none;
}
.heading-anchor img {
height: 1em;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.dont-show {
display: none;
}
/* Improvements to Hugo Chroma syntax highlighting */
.highlight {
margin-top: 1em;
margin-bottom: 1em;
/* set the tab size for browsers that support it */
tab-size: 4;
-moz-tab-size: 4;
/* needed for the iPhone so that the two columns (line numbers and code) don't have different font sizes */
-webkit-text-size-adjust: 100%;
}
.highlight > * {
padding: 0.5em;
border-width: 2px;
border-style: solid;
}
.highlight pre {
margin: 0px;
overflow-x: auto;
word-wrap: normal;
}
.highlight td.lntd pre {
/* needed to fix an iPhone scrolling bug */
overflow-x: hidden;
}
.highlight td.lntd:last-child {
/* needed until this bug is fixed: https://github.com/alecthomas/chroma/issues/225 */
width: 100%;
}
/* Improvements to inline code blocks */
code {
font-size: 98%;
}
:not(pre) > code {
/* inline code elements */
background-color: rgba(25, 25, 25, 0.05);
border-radius: 5px;
font-size: 80%;
padding-top: 0.2em;
padding-bottom: 0.2em;
padding-left: 0.4em;
padding-right: 0.4em;
}
/* Formatting for "notice" shortcodes */
.notice {
margin: 1.5em 0;
width: 70%;
margin-left: auto;
margin-right: auto;
background-color: #E9E9E9;
}
@media only screen and (max-width: 500pt) {
.notice {
width: 100%;
}
}
.notice > hr {
display: none; /* only want the child hr elements to appear if css is disabled */
}
.notice .notice-title {
margin: 0;
padding: 0.4em;
line-height: 1em;
background-color: #D5D5D5;
}
.notice .notice-title span {
vertical-align: -10%; /* we don't want the font descender space to be centered as well */
}
.notice .notice-title .notice-title-icon {
display: inline-block;
vertical-align: middle;
margin-left: 0.15em;
margin-right: 0.25em;
height: 0.85em;
}
.notice .notice-body {
padding: 0.6em;
}
.notice .notice-body p:first-child {
margin-top: 0;
}
.notice .notice-body p {
margin: 0.8em 0;
}
/* ************************ */
blockquote {
color: #404040;
border-left: 0.25em solid #CCC;
padding-left: 0.5em;
margin-left: 1.5em;
}
.title-header {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
.title-header > h1{
margin-top: 0;
margin-bottom: 0.3em;
}
.title-header-date {
color: rgb(90, 90, 90);
font-size: 80%;
}
.title-list > h2, .title-list > h3, .title-list > h4, .title-list > h5, .title-list > h6{
margin-bottom: 0.1em;
}
.body-list p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.title-list-date {
color: rgb(90, 90, 90);
font-size: 80%;
}
.table-of-contents {
border-width: 2px;
border-style: solid;
padding: 1em;
margin-bottom: 2em;
font-size: 0.9em;
}
.table-of-contents nav > ul {
/* only the most-parent ul element */
margin-bottom: 0;
}
.table-of-contents ul {
list-style: none;
padding-left: 0;
}
.table-of-contents li {
margin-top: 0.5em;
}
.table-of-contents ul ul {
list-style: none;
padding-left: 1.0em;
}
.table-of-contents-title {
font-size: 1.2em;
font-weight: bold;
}
.section-list {
padding-left: 0;
}
.section-list li {
display: inline-block;
margin-right: 0.5em;
}
.section-list li:last-child {
margin-right: 0em;
}
.section-list li > * {
background-color: rgba(25, 25, 25, 0.05);
border-radius: 5px;
font-size: 90%;
padding-top: 0.2em;
padding-bottom: 0.2em;
padding-left: 0.4em;
padding-right: 0.4em;
}
.links {
font-size: 120%;
list-style-type: none;
line-height: 1;
padding: 0;
margin: 0;
margin-top: 9pt;
display: flex;
flex-direction: row;
flex-wrap: wrap;
overflow: hidden;
-webkit-overflow-scrolling: touch; /* this needs to go here for some reason */
}
.links li {
margin-right: 1em;
}
.links li > * {
display:inline-block;
}
.links li:last-child {
margin-right: 0;
}
.links a {
text-decoration: none;
color: inherit;
}
.links a:hover {
color: #505050;
}
.overlay {
position: fixed;
visibility: hidden;
opacity: 0;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
z-index: 2;
}
.header-right {
position: absolute;
top: 0;
right: 0;
display: flex;
}
.header-right * {
margin-left: 1em;
}
.header-right *:first-child {
margin-left: 0;
}
.clickable-header-label {
cursor: pointer;
}
.clickable-header-label * {
height: 1em;
width: auto; /* to override the <img width="__"> attribute when css is supported */
}
#show-hide-menu-label {
display: none;
}
body {
font-size: 13pt;
font-family: Lato, Arial, Helvetica, "Liberation Sans", sans-serif;
line-height: 1.45;
margin: 0;
}
.title {
font-weight: bold;
font-size: 140%;
line-height: 1em;
}
.title a {
text-decoration: none;
color: inherit;
}
.header {
background-color: lightgray;
background-size: 100%;
background-position: bottom;
display: inline-block;
z-index: 1; /* this prevents images with css filters from appearing above the header when in portrait mode */
width: 100%;
}
.header-content {
margin: 15pt;
position: relative; /* so that "position:absolute" works for the menu label */
}
.body {
display: inline-block;
width: 100%;
}
.body-content {
margin: 15pt;
word-wrap: break-word;
}
/* Image/Figure formatting */
.body-content :not(figure) img {
/* regular image elements should be inline elements */
max-width: 100%;
max-height: 60vw; /* if the image is really tall, we don't want the width to be 100% */
}
.body-content figure {
margin-left: auto;
margin-right: auto;
max-width: 70%;
}
.body-content figure img {
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 0.5em;
max-width: 100%;
max-height: 40vw; /* if the image is really tall, we don't want the width to be 70% */
}
.body-content figure:not(.color-adapting-image) img {
/* if the image is designed to adapt to the theme, then don't use a background */
background-color: rgb(255, 255, 255); /* images with transparent backgrounds typically assume a light background */
}
.body-content figure figcaption {
font-size: 90%;
line-height: 1.5em;
padding-bottom: 0.3em;
border-bottom: 2px solid lightgray;
}
.body-content figure figcaption * {
margin: 0;
}
@media only screen and (orientation: portrait) {
.body-content :not(figure) img,
.body-content figure img {
/* need to target both so that they're more specific */
max-height: 100vw;
}
}
@media only screen and (max-width: 400pt) {
.body-content figure {
max-width: 100%;
}
.body-content figure figcaption {
margin-left: 5%;
margin-right: 5%;
}
}
/* ************************ */
.main {
width: 700pt; /* make sure to also change this in the media query */
margin: 0 auto;
margin-top: 10pt;
margin-bottom: 10pt;
box-sizing: border-box;
box-shadow: 0 0 10px rgba(50, 50, 50, .17);
}
.footer {
text-align: center;
font-size: 80%;
}
@media only screen and (orientation: portrait) {
.header {
top: 0;
position: sticky;
position: -webkit-sticky; /* needed for iOS */
box-shadow: 0 0 1em rgba(30, 30, 30, .3);
}
.body-content :target::before {
/* When linking to tags with 'id's (example:
'website.com/post/#heading'), make them
appear lower down the page so that they
don't appear under the sticky header set
above.
See: https://stackoverflow.com/a/24298427
Note that this causes the cursor text
selection of the target to behave
undesirably.
*/
content: '';
display: block;
height: 3em;
margin-top: -3em;
visibility: hidden;
pointer-events: none;
}
}
@media only screen and (max-width: 700pt) {
.main {
width: 100%;
margin-top: 0;
margin-bottom: 0;
}
body {
font-size: 12pt;
background-color: white;
}
}
@media only screen and (max-width: 400pt) {
.header-right {
height: 100%;
align-items: center;
}
.clickable-header-label {
display: inline-flex;
}
.clickable-header-label * {
vertical-align: middle;
}
#show-hide-menu-label {
display: inherit;
}
.show-hide-menu-input:checked ~ .main .links {
visibility: visible;
opacity: 1;
right: 0;
transition: all 0.3s;
}
.show-hide-menu-input:checked ~ .main .overlay {
visibility: visible;
opacity: 1;
transition: opacity 0.3s;
}
.links {
display: block;
visibility: hidden;
opacity: 0;
overflow-y: scroll;
position: fixed;
top: 0;
bottom: 0;
right: -100px; /* start to the right for the transition */
min-width: 75%;
z-index: 3;
background-color: rgb(247, 247, 247);
padding: 10pt;
margin: 0;
}
.links li {
margin-right: 0;
border-bottom: solid 1px gray;
}
.links li > * {
box-sizing: border-box;
width: 100%;
padding: 13px;
}
.links li:first-child {
border-top: solid 1px gray;
margin-top: 0px;
}
.header-content {
margin: 8pt 10pt;
}
.body-content {
margin: 10pt;
}
.title a {
vertical-align: -10%; /* we don't want the font descender space to be centered as well */
}
}
@media print {
body {
background-color: initial !important;
}
.main {
margin-top: 0;
margin-bottom: 0;
width: 100%;
box-shadow: none !important;
}
.header {
background-color: initial !important;
background-image: none !important;
}
.header-content {
margin: 0;
}
.body-content {
margin: 0;
}
.header-right {
display: none;
}
.links {
display: none;
}
}

View File

@ -0,0 +1,64 @@
/* Background */ .chroma { color: #d0d0d0; background-color: #1a1a1a }
/* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; }
/* LineHighlight */ .chroma .hl { display: block; width: 100%; background-color: #404040 }
/* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; }
/* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; }
/* Keyword */ .chroma .k { color: #6ab825; font-weight: bold }
/* KeywordConstant */ .chroma .kc { color: #6ab825; font-weight: bold }
/* KeywordDeclaration */ .chroma .kd { color: #6ab825; font-weight: bold }
/* KeywordNamespace */ .chroma .kn { color: #6ab825; font-weight: bold }
/* KeywordPseudo */ .chroma .kp { color: #6ab825 }
/* KeywordReserved */ .chroma .kr { color: #6ab825; font-weight: bold }
/* KeywordType */ .chroma .kt { color: #6ab825; font-weight: bold }
/* NameAttribute */ .chroma .na { color: #bbbbbb }
/* NameBuiltin */ .chroma .nb { color: #24909d }
/* NameClass */ .chroma .nc { color: #447fcf }
/* NameConstant */ .chroma .no { color: #447fcf }
/* NameDecorator */ .chroma .nd { color: #ffa500 }
/* NameException */ .chroma .ne { color: #bbbbbb }
/* NameFunction */ .chroma .nf { color: #447fcf }
/* NameNamespace */ .chroma .nn { color: #447fcf }
/* NameTag */ .chroma .nt { color: #6ab825; font-weight: bold }
/* NameVariable */ .chroma .nv { color: #447fcf }
/* LiteralString */ .chroma .s { color: #ed9d13 }
/* LiteralStringAffix */ .chroma .sa { color: #ed9d13 }
/* LiteralStringBacktick */ .chroma .sb { color: #ed9d13 }
/* LiteralStringChar */ .chroma .sc { color: #ed9d13 }
/* LiteralStringDelimiter */ .chroma .dl { color: #ed9d13 }
/* LiteralStringDoc */ .chroma .sd { color: #ed9d13 }
/* LiteralStringDouble */ .chroma .s2 { color: #ed9d13 }
/* LiteralStringEscape */ .chroma .se { color: #ed9d13 }
/* LiteralStringHeredoc */ .chroma .sh { color: #ed9d13 }
/* LiteralStringInterpol */ .chroma .si { color: #ed9d13 }
/* LiteralStringOther */ .chroma .sx { color: #ffa500 }
/* LiteralStringRegex */ .chroma .sr { color: #ed9d13 }
/* LiteralStringSingle */ .chroma .s1 { color: #ed9d13 }
/* LiteralStringSymbol */ .chroma .ss { color: #ed9d13 }
/* LiteralNumber */ .chroma .m { color: #3677a9 }
/* LiteralNumberBin */ .chroma .mb { color: #3677a9 }
/* LiteralNumberFloat */ .chroma .mf { color: #3677a9 }
/* LiteralNumberHex */ .chroma .mh { color: #3677a9 }
/* LiteralNumberInteger */ .chroma .mi { color: #3677a9 }
/* LiteralNumberIntegerLong */ .chroma .il { color: #3677a9 }
/* LiteralNumberOct */ .chroma .mo { color: #3677a9 }
/* OperatorWord */ .chroma .ow { color: #6ab825; font-weight: bold }
/* Comment */ .chroma .c { color: #999999; font-style: italic }
/* CommentHashbang */ .chroma .ch { color: #999999; font-style: italic }
/* CommentMultiline */ .chroma .cm { color: #999999; font-style: italic }
/* CommentSingle */ .chroma .c1 { color: #999999; font-style: italic }
/* CommentSpecial */ .chroma .cs { color: #e50808; background-color: #520000; font-weight: bold }
/* CommentPreproc */ .chroma .cp { color: #cd2828; font-weight: bold }
/* CommentPreprocFile */ .chroma .cpf { color: #cd2828; font-weight: bold }
/* GenericDeleted */ .chroma .gd { color: #d22323 }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericError */ .chroma .gr { color: #d22323 }
/* GenericHeading */ .chroma .gh { color: #ffffff; font-weight: bold }
/* GenericInserted */ .chroma .gi { color: #589819 }
/* GenericOutput */ .chroma .go { color: #cccccc }
/* GenericPrompt */ .chroma .gp { color: #aaaaaa }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { color: #ffffff }
/* GenericTraceback */ .chroma .gt { color: #d22323 }
/* TextWhitespace */ .chroma .w { color: #666666 }

112
public/css/themes/dark.css Normal file
View File

@ -0,0 +1,112 @@
@import url("dark-chroma.css");
a {
color: #A1A1EA;
}
.highlight > * {
border-color: #505050;
}
:not(pre) > code {
/* inline code elements */
background-color: rgba(90, 90, 90, 0.25);
}
a > code {
background-color: rgba(65, 65, 170, 0.3);
}
.section-list li > * {
background-color: rgba(90, 90, 90, 0.25);
}
.section-list li > a {
background-color: rgba(65, 65, 170, 0.3);
}
body {
color: rgb(210, 210, 210);
background-color: rgb(27, 27, 27);
}
blockquote {
color: rgb(170, 170, 170);
border-left: 0.25em solid #444;
}
img.color-adapting-image,
figure.color-adapting-image img {
filter: invert(85%) hue-rotate(180deg);
/* hue rotate trick from: https://medium.com/@mwichary/dark-theme-in-a-day-3518dde2955a */
}
.header {
background-color: rgb(40, 40, 40); /* still want a background color before the image loads */
background-image: url(../../images/header-bg-dark.jpg);
}
.main {
background-color: rgb(14, 14, 14);
box-shadow: none;
}
.footer {
color: rgb(160, 160, 160);
}
.title-header-date {
color: rgb(150, 150, 150);
}
.title-list-date {
color: rgb(150, 150, 150);
}
.table-of-contents {
border-color: #505050;
background-color: #1A1A1A;
}
.notice {
border-width: 2px;
border-style: solid;
border-top: 0;
}
.notice .notice-title .notice-title-icon {
filter: invert(80%);
}
.notice.note {
background-color: #001320;
border-color: #00487B;
}
.notice.note .notice-title {
background-color: #00487B;
}
.notice.tip {
background-color: #132000;
border-color: #105600;
}
.notice.tip .notice-title {
background-color: #105600;
}
.notice.warning {
background-color: #200000;
border-color: #700000;
}
.notice.warning .notice-title {
background-color: #700000;
}
@media only screen and (max-width: 400pt) {
.links {
background-color: rgb(30, 30, 30);
}
}

View File

@ -0,0 +1,70 @@
/* Background */ .chroma { color: #272822; background-color: #fafafa }
/* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; }
/* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #e1e1e1 }
/* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; }
/* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; }
/* Keyword */ .chroma .k { color: #00a8c8 }
/* KeywordConstant */ .chroma .kc { color: #00a8c8 }
/* KeywordDeclaration */ .chroma .kd { color: #00a8c8 }
/* KeywordNamespace */ .chroma .kn { color: #f92672 }
/* KeywordPseudo */ .chroma .kp { color: #00a8c8 }
/* KeywordReserved */ .chroma .kr { color: #00a8c8 }
/* KeywordType */ .chroma .kt { color: #00a8c8 }
/* Name */ .chroma .n { color: #111111 }
/* NameAttribute */ .chroma .na { color: #75af00 }
/* NameBuiltin */ .chroma .nb { color: #111111 }
/* NameBuiltinPseudo */ .chroma .bp { color: #111111 }
/* NameClass */ .chroma .nc { color: #75af00 }
/* NameConstant */ .chroma .no { color: #00a8c8 }
/* NameDecorator */ .chroma .nd { color: #75af00 }
/* NameEntity */ .chroma .ni { color: #111111 }
/* NameException */ .chroma .ne { color: #75af00 }
/* NameFunction */ .chroma .nf { color: #75af00 }
/* NameFunctionMagic */ .chroma .fm { color: #111111 }
/* NameLabel */ .chroma .nl { color: #111111 }
/* NameNamespace */ .chroma .nn { color: #111111 }
/* NameOther */ .chroma .nx { color: #75af00 }
/* NameProperty */ .chroma .py { color: #111111 }
/* NameTag */ .chroma .nt { color: #f92672 }
/* NameVariable */ .chroma .nv { color: #111111 }
/* NameVariableClass */ .chroma .vc { color: #111111 }
/* NameVariableGlobal */ .chroma .vg { color: #111111 }
/* NameVariableInstance */ .chroma .vi { color: #111111 }
/* NameVariableMagic */ .chroma .vm { color: #111111 }
/* Literal */ .chroma .l { color: #ae81ff }
/* LiteralDate */ .chroma .ld { color: #d88200 }
/* LiteralString */ .chroma .s { color: #d88200 }
/* LiteralStringAffix */ .chroma .sa { color: #d88200 }
/* LiteralStringBacktick */ .chroma .sb { color: #d88200 }
/* LiteralStringChar */ .chroma .sc { color: #d88200 }
/* LiteralStringDelimiter */ .chroma .dl { color: #d88200 }
/* LiteralStringDoc */ .chroma .sd { color: #d88200 }
/* LiteralStringDouble */ .chroma .s2 { color: #d88200 }
/* LiteralStringEscape */ .chroma .se { color: #8045ff }
/* LiteralStringHeredoc */ .chroma .sh { color: #d88200 }
/* LiteralStringInterpol */ .chroma .si { color: #d88200 }
/* LiteralStringOther */ .chroma .sx { color: #d88200 }
/* LiteralStringRegex */ .chroma .sr { color: #d88200 }
/* LiteralStringSingle */ .chroma .s1 { color: #d88200 }
/* LiteralStringSymbol */ .chroma .ss { color: #d88200 }
/* LiteralNumber */ .chroma .m { color: #ae81ff }
/* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
/* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
/* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
/* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
/* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
/* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
/* Operator */ .chroma .o { color: #f92672 }
/* OperatorWord */ .chroma .ow { color: #f92672 }
/* Punctuation */ .chroma .p { color: #111111 }
/* Comment */ .chroma .c { color: #75715e }
/* CommentHashbang */ .chroma .ch { color: #75715e }
/* CommentMultiline */ .chroma .cm { color: #75715e }
/* CommentSingle */ .chroma .c1 { color: #75715e }
/* CommentSpecial */ .chroma .cs { color: #75715e }
/* CommentPreproc */ .chroma .cp { color: #75715e }
/* CommentPreprocFile */ .chroma .cpf { color: #75715e }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericStrong */ .chroma .gs { font-weight: bold }

View File

@ -0,0 +1,85 @@
@import url("light-chroma.css");
a {
color: #0000A0;
}
.highlight > * {
border-color: #E0E0E0;
}
:not(pre) > code {
/* inline code elements */
background-color: rgba(25, 25, 25, 0.05);
}
a > code {
background-color: rgba(15, 15, 150, 0.05);
}
.section-list li > * {
background-color: rgba(25, 25, 25, 0.05);
}
.section-list li > a {
background-color: rgba(15, 15, 150, 0.05);
}
body {
color: #232629;
background-color: rgb(247, 247, 247);
}
blockquote {
color: #404040;
border-left: 0.25em solid #CCC;
}
.main {
background-color: white;
}
.footer {
color: #383838;
}
.table-of-contents {
border-color: #E0E0E0;
background-color: #FAFAFA;
}
.notice {
color: #404040;
}
.notice .notice-title {
color: white;
}
.notice .notice-title .notice-title-icon {
filter: invert(1);
}
.notice.note {
background-color: #E7F2FA;
}
.notice.note .notice-title {
background-color: #6AB0DE;
}
.notice.tip {
background-color: #e6f9e6;
}
.notice.tip .notice-title {
background-color: #77c577;
}
.notice.warning {
background-color: #fae2e2;
}
.notice.warning .notice-title {
background-color: #df6f6c;
}

BIN
public/dhcp_config.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36.329693mm"
height="36.329624mm"
viewBox="0 0 36.329693 36.329624"
version="1.1"
id="svg1143"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="chain-link.svg">
<defs
id="defs1137" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="41.183747"
inkscape:cy="-1.0638373"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata1140">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-106.18932,-64.144405)">
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:15.11811066;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
mask="none"
d="m 499.69727,242.43555 c -5.63871,0 -11.27655,2.12809 -15.53321,6.38476 L 467.125,265.85742 c -8.23333,8.23336 -8.50042,21.63554 -0.80859,30.20899 l 10.73437,-10.73438 c -1.97467,-2.71509 -1.72344,-6.29608 0.76563,-8.78515 l 17.03711,-17.03711 c 2.77595,-2.77592 6.91155,-2.77594 9.6875,0 l 17.0371,17.03711 c 2.77592,2.7759 2.77592,6.91158 0,9.6875 l -17.0371,17.03906 c -2.48897,2.48893 -6.06818,2.73797 -8.78321,0.76367 l -10.73828,10.73633 c 8.57338,7.69283 21.97725,7.42317 30.21094,-0.81055 l 17.03906,-17.03711 c 8.51335,-8.51334 8.51331,-22.55504 0,-31.06836 l -17.03906,-17.03711 c -4.25666,-4.25667 -9.8945,-6.38476 -15.5332,-6.38476 z"
transform="scale(0.26458333)"
id="rect917"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:15.11811066;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
mask="none"
d="m 440.30078,301.83008 c -5.6387,0 -11.27655,2.1281 -15.5332,6.38476 l -17.03711,17.03907 c -8.51335,8.51333 -8.51335,22.55306 0,31.0664 l 17.03711,17.03907 c 8.51331,8.5133 22.55501,8.51334 31.06836,0 l 17.03711,-17.03907 c 8.23369,-8.23371 8.50337,-21.63755 0.81054,-30.21093 l -10.73632,10.73828 c 1.9743,2.71502 1.72525,6.29426 -0.76368,8.7832 l -17.03906,17.03711 c -2.77591,2.77592 -6.91159,2.7759 -9.6875,0 l -17.03711,-17.03711 c -2.77595,-2.77593 -2.77595,-6.91158 0,-9.6875 l 17.03711,-17.03711 c 2.48932,-2.48932 6.06998,-2.74094 8.78516,-0.76563 l 10.73437,-10.73437 c -4.14095,-3.71513 -9.40796,-5.57617 -14.67578,-5.57617 z"
transform="scale(0.26458333)"
id="rect919"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 119.41373,87.24996 9.88087,-9.88087"
id="path860-2"
inkscape:connector-curvature="0"
mask="none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.441597mm"
height="18.441597mm"
viewBox="0 0 18.441597 18.441597"
version="1.1"
id="svg8"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="exclamation.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="23.53253"
inkscape:cy="-1.8454934"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-95.779202,-139.2792)">
<path
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.66666698;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 34.849609 0 A 34.850262 34.850262 0 0 0 0 34.849609 A 34.850262 34.850262 0 0 0 34.849609 69.701172 A 34.850262 34.850262 0 0 0 69.701172 34.849609 A 34.850262 34.850262 0 0 0 34.849609 0 z M 33.720703 11.71875 L 36.048828 11.71875 C 37.266264 11.71875 38.268886 12.159718 39.056641 13.042969 C 39.939916 13.902333 40.333777 14.940767 40.238281 16.158203 L 39.126953 37.607422 C 39.055344 38.729387 38.625645 39.660384 37.837891 40.400391 C 37.002388 41.140422 36.024309 41.509766 34.902344 41.509766 C 33.756517 41.509766 32.76519 41.140422 31.929688 40.400391 C 31.165795 39.660384 30.736121 38.729387 30.640625 37.607422 L 29.53125 16.158203 C 29.483502 14.940767 29.877388 13.902333 30.712891 13.042969 C 31.500645 12.159718 32.503242 11.71875 33.720703 11.71875 z M 34.902344 45.771484 C 36.644958 45.723862 38.077253 46.308055 39.199219 47.525391 C 40.416655 48.718965 41.000848 50.164484 40.953125 51.859375 C 41.000747 53.554241 40.416554 54.986537 39.199219 56.15625 C 38.077253 57.373686 36.644958 57.982422 34.902344 57.982422 C 33.231339 57.982422 31.787774 57.373686 30.570312 56.15625 C 29.352876 54.986537 28.744141 53.554241 28.744141 51.859375 C 28.744141 50.18837 29.352876 48.742852 30.570312 47.525391 C 31.787774 46.307954 33.231339 45.723762 34.902344 45.771484 z "
id="path815"
transform="matrix(0.26458333,0,0,0.26458333,95.779202,139.2792)" />
<g
aria-label="!"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:19.40277863px;line-height:1.25;font-family:Dyuthi;-inkscape-font-specification:'Dyuthi, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
id="text819" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="119.0113345192303 189.00247805341664 83.99999999999997 65.28000000000006" width="80" height="61.28"><defs><path d="M194.37 190C197.48 190 200.01 192.53 200.01 195.65C200.01 196.77 200.01 194.52 200.01 195.65C200.01 198.76 197.48 201.29 194.37 201.29C179.5 201.29 140.53 201.29 125.65 201.29C122.54 201.29 120.01 198.76 120.01 195.65C120.01 194.52 120.01 196.77 120.01 195.65C120.01 192.53 122.54 190 125.65 190C140.53 190 179.5 190 194.37 190Z" id="eNJsZ8Kg3"></path><path d="M194.37 215C197.48 215 200.01 217.53 200.01 220.64C200.01 221.77 200.01 219.51 200.01 220.64C200.01 223.76 197.48 226.29 194.37 226.29C179.5 226.29 140.53 226.29 125.65 226.29C122.54 226.29 120.01 223.76 120.01 220.64C120.01 219.51 120.01 221.77 120.01 220.64C120.01 217.53 122.54 215 125.65 215C140.53 215 179.5 215 194.37 215Z" id="a2DqdC3JRN"></path><path d="M194.37 240C197.48 240 200.01 242.52 200.01 245.64C200.01 246.77 200.01 244.51 200.01 245.64C200.01 248.76 197.48 251.28 194.37 251.28C179.5 251.28 140.53 251.28 125.65 251.28C122.54 251.28 120.01 248.76 120.01 245.64C120.01 244.51 120.01 246.77 120.01 245.64C120.01 242.52 122.54 240 125.65 240C140.53 240 179.5 240 194.37 240Z" id="aVsnnO02n"></path></defs><g><g><use xlink:href="#eNJsZ8Kg3" opacity="1" fill="#000000" fill-opacity="1"></use></g><g><use xlink:href="#a2DqdC3JRN" opacity="1" fill="#000000" fill-opacity="1"></use></g><g><use xlink:href="#aVsnnO02n" opacity="1" fill="#000000" fill-opacity="1"></use></g></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="13.509594mm"
height="14.165941mm"
viewBox="0 0 13.509594 14.165941"
version="1.1"
id="svg8"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="theme-switcher-moon.svg">
<defs
id="defs2">
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refX="1"
id="Arrow2Lstart"
style="overflow:visible"
inkscape:isstock="true"
refY="-0.1">
<path
id="path4819"
style="fill:#00000f;fill-opacity:1;fill-rule:evenodd;stroke:#00000f;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(0.3,0,0,0.3,0.3,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refX="1"
id="Arrow2Lstart-7"
style="overflow:visible"
inkscape:isstock="true"
refY="-0.1">
<path
id="path4819-9"
style="fill:#00000f;fill-opacity:1;fill-rule:evenodd;stroke:#00000f;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(0.3,0,0,0.3,0.3,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-122.68578"
inkscape:cy="-34.841124"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-133.69591,-59.597941)">
<path
style="opacity:0.98000004;vector-effect:none;fill:none;fill-opacity:1;stroke:#00000f;stroke-width:1.05833328;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 140.12254,60.12711 a 6.5537713,6.5537713 0 0 0 -0.13087,0.0046 5.6606021,5.6606021 0 0 1 1.69862,4.035792 5.6606021,5.6606021 0 0 1 -5.66076,5.660761 5.6606021,5.6606021 0 0 1 -1.8045,-0.301188 6.5537713,6.5537713 0 0 0 5.89751,3.707641 6.5537713,6.5537713 0 0 0 6.5538,-6.553803 6.5537713,6.5537713 0 0 0 -6.5538,-6.553805 z"
id="path817-2-9-2"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="20.008001mm"
height="20.292175mm"
viewBox="0 0 20.008001 20.292174"
version="1.1"
id="svg8"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="theme-switcher-sun.svg">
<defs
id="defs2">
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refX="1"
id="Arrow2Lstart"
style="overflow:visible"
inkscape:isstock="true"
refY="-0.1">
<path
id="path4819"
style="fill:#00000f;fill-opacity:1;fill-rule:evenodd;stroke:#00000f;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(0.3,0,0,0.3,0.3,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refX="1"
id="Arrow2Lstart-7"
style="overflow:visible"
inkscape:isstock="true"
refY="-0.1">
<path
id="path4819-9"
style="fill:#00000f;fill-opacity:1;fill-rule:evenodd;stroke:#00000f;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(0.3,0,0,0.3,0.3,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-81.16043"
inkscape:cy="-22.76665"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-96.115683,-56.666412)">
<circle
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#00000f;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path817"
cx="105.83332"
cy="66.8125"
r="5.1500478" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 113.09949,72.909536 110.72812,70.91972"
id="path823"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 107.48045,76.153702 106.9429,73.105129"
id="path823-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 101.09069,75.027017 1.5478,-2.680871"
id="path823-3-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 96.92007,70.056669 2.908914,-1.058761"
id="path823-3-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 96.920061,63.568331 2.908915,1.058759"
id="path823-3-5"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 101.09068,58.597987 1.5478,2.680871"
id="path823-3-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 107.48043,57.471296 -0.53754,3.048574"
id="path823-3-56"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 113.09949,60.715466 -2.37136,1.989816"
id="path823-3-5-2"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.58749998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 115.31863,66.812497 h -3.0956"
id="path823-3-3-9"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

113
public/index.html Normal file
View File

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta name="generator" content="Hugo 0.101.0" />
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<h1 id="welcome">Welcome!</h1>
<p>You can find me on the <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a> and <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>.</p>
<p><a href="https://pleroma.social/blog/2021/01/13/the-big-pleroma-and-fediverse-faq/">What is the Fediverse?</a></p>
<h2>Recent Posts</h2>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/consistency/">Consistency</a></h3>
<div class="title-list-date">
<time>Sunday, April 4, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
I&rsquo;ve seen a lot of talk about this stuff:
&ldquo;Check out my FOSS project (hosted on Github)&rdquo; &ldquo;Wayland is a great innovation and boon to the community! Also, there are very few tools/alternatives available yet for your favorite X11 tool!&rdquo; &ldquo;We love open source! Also, we develop the most popular proprietary operating system!&rdquo; &ldquo;Do as I say, not as I do.&rdquo; We love to poke fun at and expose this kind of stuff, which is all fine and dandy.
</p>
<a href="/posts/consistency/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/better/">Better?</a></h3>
<div class="title-list-date">
<time>Saturday, April 3, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
There are many that say
(and I tend to agree)
that free software is the best there could be.
But please don&rsquo;t mistake
using software that&rsquo;s free
as a right to superiority.
There are many that go
from day to day living
and don&rsquo;t give a thought to what they are using.
Are they worse for this?
Are you better for caring?
Sometimes the truth can be quite baring.
That not every human
</p>
<a href="/posts/better/">Read More…</a>
</div>
</article>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

505
public/index.xml Normal file
View File

@ -0,0 +1,505 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Home on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/</link>
<description>Recent content in Home on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster>
<lastBuildDate>Sun, 04 Apr 2021 00:00:00 -0500</lastBuildDate><atom:link href="https://beckmeyer.us/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Consistency</title>
<link>https://beckmeyer.us/posts/consistency/</link>
<pubDate>Sun, 04 Apr 2021 00:00:00 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/consistency/</guid>
<description>&lt;p&gt;I&amp;rsquo;ve seen a lot of talk about this stuff:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Check out my FOSS project (hosted on Github)&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Wayland is a great innovation and boon to the community! Also, there are very few tools/alternatives available yet for your favorite X11 tool!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;We love open source! Also, we develop the most popular proprietary operating system!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Do as I say, not as I do.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We love to poke fun at and expose this kind of stuff, which is all fine and
dandy. I think it&amp;rsquo;s an interesting (and important) part of our humanity that
this kind of thing bugs us so much. Think about that last point, which at least
in my experience, is something I &lt;em&gt;loved&lt;/em&gt; to fault authorities for.&lt;/p&gt;
&lt;p&gt;Hypocrisy is fun and also infuriating to uncover in others, but how often do
we do a &amp;ldquo;consistency check&amp;rdquo; on ourselves? Is what we are saying evidenced by
the rest of our actions?&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a hard look sometimes. I know it is for me, since I&amp;rsquo;m &lt;strong&gt;very&lt;/strong&gt; quick
to judge others, but don&amp;rsquo;t often think about how I fail at my own principles.&lt;/p&gt;
&lt;p&gt;Example: As a FOSS advocate, it&amp;rsquo;s nearly natural to assume that everything will
be better and easier with more people using FOSS. When evidence seems to point
to the contrary (e.g. fighting with Matrix/Element to get it working for my
family and friends), I don&amp;rsquo;t own up to the fact that it isn&amp;rsquo;t easier, and that
is an actual problem.&lt;/p&gt;
&lt;p&gt;If we truly want to build a welcoming and wholesome community, let&amp;rsquo;s be careful
to do a consistency check to make sure nothing smells foul.&lt;/p&gt;
</description>
</item>
<item>
<title>Better?</title>
<link>https://beckmeyer.us/posts/better/</link>
<pubDate>Sat, 03 Apr 2021 22:15:44 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/better/</guid>
<description>&lt;p&gt;There are many that say&lt;br&gt;
(and I tend to agree)&lt;br&gt;
that free software is the best there could be.&lt;/p&gt;
&lt;p&gt;But please don&amp;rsquo;t mistake&lt;br&gt;
using software that&amp;rsquo;s free&lt;br&gt;
as a right to superiority.&lt;/p&gt;
&lt;p&gt;There are many that go&lt;br&gt;
from day to day living&lt;br&gt;
and don&amp;rsquo;t give a thought to what they are using.&lt;/p&gt;
&lt;p&gt;Are they worse for this?&lt;br&gt;
Are you better for caring?&lt;br&gt;
Sometimes the truth can be quite baring.&lt;/p&gt;
&lt;p&gt;That not every human&lt;br&gt;
in present circumstance&lt;br&gt;
is able or willing to take a chance.&lt;/p&gt;
&lt;p&gt;&amp;lsquo;Cause that&amp;rsquo;s what it is,&lt;br&gt;
taking a chance and going&lt;br&gt;
into the unknown with fear, and knowing&lt;/p&gt;
&lt;p&gt;that what you might find,&lt;br&gt;
may not truly be better.&lt;/p&gt;
&lt;p&gt;But instead simply different;&lt;br&gt;
and still made by a stranger.&lt;/p&gt;
</description>
</item>
<item>
<title>Moving Back To OpenSSL</title>
<link>https://beckmeyer.us/posts/moving_back_to_openssl/</link>
<pubDate>Mon, 22 Mar 2021 11:00:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/moving_back_to_openssl/</guid>
<description>&lt;p&gt;Void Linux &lt;a href=&#34;https://voidlinux.org/news/2021/02/OpenSSL.html&#34;&gt;recently announced&lt;/a&gt;
that they were going to move back to OpenSSL after originally &lt;a href=&#34;https://voidlinux.org/news/2014/08/LibreSSL-by-default.html&#34;&gt;switching to
LibreSSL in 2014&lt;/a&gt;.
It seems that there are a lot of things at play here.&lt;/p&gt;
&lt;p&gt;It seems that the main focus of the recent announcement is on the maintainability
and other difficulties of not using the &lt;em&gt;one true SSL/TLS library&lt;/em&gt;. To me,
this pragmatically makes sense. However, every time something like this happens
I get this lingering feeling of worry&amp;hellip;&lt;/p&gt;
&lt;p&gt;Microsoft moving their default browser from their own implementation to
Chromium, and other browsers following suit.&lt;/p&gt;
&lt;p&gt;Linux distributions moving &lt;em&gt;en masse&lt;/em&gt; to &lt;strong&gt;systemd&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Distributed email being slowly crushed and killed by Google with GMail.&lt;/p&gt;
&lt;p&gt;And many other examples that aren&amp;rsquo;t immediately coming to mind.&lt;/p&gt;
&lt;p&gt;I think it&amp;rsquo;s great that OpenSSL as a project has made a comeback from the
Heartbleed fiasco, and that it is apparently more actively developed nowadays,
but the fact that we are even at the point of moving back to OpenSSL due to
difficulties with building software is worrying. To me, it looks like a
symptom of software becoming too entrenched and dependent on a single piece
of software.&lt;/p&gt;
&lt;p&gt;This kind of accusation coming from anyone is going to be hypocritical, since
we all depend on Linux, X11, Wayland, systemd, or some common piece of software
that we take for granted and don&amp;rsquo;t lose sleep over. However, I think what&amp;rsquo;s
categorically different about this one is that an alternative was adopted,
worked on, but eventually &amp;ldquo;failed&amp;rdquo; (at least for Void, but also possibly for
Linux as well).&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know what the fix for this specific issue would be. I&amp;rsquo;m not nearly
familiar enough with SSL/TLS or how you would develop software to be agnostic
of dependencies like this. But I think in order to honor principles like
the Unix philosophy, the KISS principle, and countless others, we need to
figure out a way to be more modular for dependency issues like this.&lt;/p&gt;
</description>
</item>
<item>
<title>The Generation Ship Problem</title>
<link>https://beckmeyer.us/posts/the_generation_ship_problem/</link>
<pubDate>Fri, 19 Mar 2021 15:00:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/the_generation_ship_problem/</guid>
<description>&lt;p&gt;After talking about the hardware and software problems of
digital permanence, I&amp;rsquo;m struck by a classical Sci-Fi
motif with a conundrum: the &lt;strong&gt;Generation Ship&lt;/strong&gt;; a ship
outfitted with all of the technology, infrastructure, and
storage to support lightyear-scale human travel.&lt;/p&gt;
&lt;p&gt;But what about that technology on the ship? If we build
one of these ships, we need to accomplish one of several
things in regards to information storage:&lt;/p&gt;
&lt;h3 id=&#34;1-innovate-to-the-point-where-the-lifetime-of-the-storage-devices-is-able-to-support-lightyear-scale-travel&#34;&gt;1. Innovate to the point where the lifetime of the storage devices is able to support lightyear scale travel.&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s a tall order, given where we are right now with
physical storage devices. As I mentioned in one of my
previous posts, the average lifetime of physical storage
devices is less than 100 years, no matter if it is a hard
drive, solid-state drive, etc.&lt;/p&gt;
&lt;h3 id=&#34;2-provide-the-facility-to-create-new-storage-devices-to-replace-the-failing-old-ones&#34;&gt;2. Provide the facility to create new storage devices to replace the failing old ones.&lt;/h3&gt;
&lt;p&gt;Again, in my mind a tall order, since it would require
facilities on the ship to create storage devices. The
problem of having materials is at least solvable by just
sending the ship with all of the materials it needs in
advance.&lt;/p&gt;
&lt;h3 id=&#34;3-provide-the-facility-to-revitalize-storage-devices&#34;&gt;3. Provide the facility to revitalize storage devices.&lt;/h3&gt;
&lt;p&gt;One of the main reasons I&amp;rsquo;m even thinking about this is
because I&amp;rsquo;m an individual with limited resources.
Accordingly, I think about things in terms of
broken/working, on/off, etc. With enough resources, there
is a much larger chance of being able to repair, re-purpose,
and otherwise revitalize storage devices, increasing their
lifetime. E.g., if the only failure in the hard drive is the
control circuit, that is an &amp;ldquo;easy enough&amp;rdquo; repair.&lt;/p&gt;
&lt;p&gt;I like to toy with the idea of a generation ship a lot in
my head, but I think it&amp;rsquo;s really fun to think about the
technical possibilities and needs of a ship like this.&lt;/p&gt;
</description>
</item>
<item>
<title>Volatile Formats</title>
<link>https://beckmeyer.us/posts/volatile_formats/</link>
<pubDate>Thu, 18 Mar 2021 14:24:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/volatile_formats/</guid>
<description>&lt;p&gt;&lt;em&gt;Note: This is a continuation of the thoughts I started
thinking about in my &lt;a href=&#34;https://beckmeyer.us/posts/volatile_mediums/&#34;&gt;Volatile Mediums&lt;/a&gt; blog post.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The next level up from physical mediums for data storage
is the &lt;em&gt;way&lt;/em&gt; that the data is stored. In the digital age,
we have a plethora of formats for storing information.
For me, one of the most interesting areas of information
storage is the analog-digital space.&lt;/p&gt;
&lt;p&gt;The fundamental problem of storing audio, video, and other
replications of the physical world is that there is so much
information that we can collect with sensors
(think microphones, video cameras, etc.). It would be great
if we could go get the best camera and microphone out there,
record whatever people record these days, and have that
exact physical experience &amp;ldquo;played back&amp;rdquo; for us on a screen
and speaker/headphones.&lt;/p&gt;
&lt;p&gt;Unfortunately, there are several problems with this. Among
those is the actual design of the sensor. It takes a lot of
careful thought, engineering, and the like to create a truly
good microphone or camera. And after all of that, this sensor
will cost something. Hopefully, that cost will correspond to
the actual technical ability of that sensor! In any case,
not everyone can have the best camera or microphone due to
any number of constraints, not just those listed above.&lt;/p&gt;
&lt;p&gt;The second problem is the sampling issue. The sensor will
create some sort of output that can then be measured, or
&lt;strong&gt;sampled&lt;/strong&gt;, by an ADC (analog-to-digital converter). The
very word &amp;ldquo;sample&amp;rdquo; belies what this nearly magical box is
doing: it is only looking at certain portions or timestamps
of the analog signal. Granted, the time between samples
can be very small (e.g. 44.1 kHz is a fairly common sample
rate for audio), but there is still some loss of signal.
Once the ADC creates these samples, it converts them into
a digital format (something that can be stored on a
CD, hard drive, thumb drive, etc.).&lt;/p&gt;
&lt;p&gt;The third problem is the encoding issue. The ADC creates all
of these samples, but we need to start thinking about storage
limitations. Storing the raw output of a sensor can take a
lot of space: an average album length (40 minutes) could
easily take 400MB of space! Now, again, the physical storage
space is moving in the upward direction to combat this, but
storing isn&amp;rsquo;t the only problem. One prime issue is internet
bandwidth.&lt;/p&gt;
&lt;p&gt;The solution to this is compression, like a ZIP file. It
makes big files smaller by doing some fancy math tricks
that can be reversed by a computer to reconstruct the
original file. However, for audio/video files, another level
of compression exists which actually gets rid of some of the
information in the original file to save more space. This
is called &amp;ldquo;lossy&amp;rdquo; compression, as opposed to &amp;ldquo;lossless&amp;rdquo;
compression.&lt;/p&gt;
&lt;p&gt;Great! We&amp;rsquo;ve found a way to save more space. The problem
with lossy compression is that we have to decide which
information to throw away. Usually, this is frequencies
that the average human ear/eye can&amp;rsquo;t perceive. But, let&amp;rsquo;s
just say that some compression is a bit too &amp;ldquo;greedy&amp;rdquo; when it
comes to saving space and starts to cut into the band of
frequencies that can be perceived. Also note that
the design of these compression algorithms is an artform
and takes lots of careful consideration.&lt;/p&gt;
&lt;p&gt;The final problem I want to mention is the codec problem.
There are many different codecs available today, and for
each and every one of them to be useful, you need to have a
way to decode each and every one of them. Unfortunately,
this is sometimes very difficult.&lt;/p&gt;
&lt;p&gt;It could be a licensing
issue, where you don&amp;rsquo;t have the correct software installed
or purchased to actually decode that file on your computer.&lt;/p&gt;
&lt;p&gt;Or it could be a physical constraints issue, where your
computer isn&amp;rsquo;t powerful enough to decode the file at a fast
enough rate for you to view it without stuttering,
buffering, etc.&lt;/p&gt;
&lt;p&gt;Third, it could be a personal preference. Some people
have much more sensitive eyes/ears and need to have formats
that are more &lt;strong&gt;transparent&lt;/strong&gt;, meaning that the lossy file
is perceptually identical to the source it was encoded from.&lt;/p&gt;
&lt;p&gt;With all of these issues at play, I think there are several
key points to make:&lt;/p&gt;
&lt;h3 id=&#34;1-codecs-need-to-be-freely-available-for-widespread-use-with-no-strings-attached&#34;&gt;1. Codecs need to be freely available for widespread use with no strings attached.&lt;/h3&gt;
&lt;p&gt;Can&amp;rsquo;t stress this one enough: we need to make sure we are
doing everything possible to not let our information die
when a corporation or individual makes a decision that
impacts the &amp;ldquo;who, what, where, when, and how&amp;rdquo; of their codec
usage.&lt;/p&gt;
&lt;h3 id=&#34;2-lossless-compression-is-good-but-it-is-not-the-only-thing-we-need&#34;&gt;2. Lossless compression is good, but it is not the only thing we need.&lt;/h3&gt;
&lt;p&gt;We need to remember that not everyone has the ability to use
lossless codecs, whether that be because of internet
bandwidth limitations, storage limitation, or the like.
Instead, we need to continue to innovate in the lossy
compression space to narrow the perceptual gap between lossy
and lossless more and more.&lt;/p&gt;
&lt;h3 id=&#34;3-a-codec-should-never-become-obsolete&#34;&gt;3. A codec should never become obsolete.&lt;/h3&gt;
&lt;p&gt;This one may sound weird, but the fact is, if we&amp;rsquo;re talking
about long-term storage of information, we can&amp;rsquo;t let codecs
die, since there may come a day where we need a codec to
decode great-grandpa&amp;rsquo;s album that never made it big.&lt;/p&gt;
</description>
</item>
<item>
<title>OpenWRT &#43; Unbound &#43; adblock</title>
<link>https://beckmeyer.us/posts/openwrt_plus_unbound/</link>
<pubDate>Fri, 05 Feb 2021 19:03:15 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/openwrt_plus_unbound/</guid>
<description>&lt;p&gt;I decided to do some work on my Linksys WRT32X running OpenWRT to make it a
little more useful.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://nlnetlabs.nl/projects/unbound/about/&#34;&gt;Unbound&lt;/a&gt; is a DNS
resolver which I like because it&amp;rsquo;s recursive, meaning it directly queries the
root servers instead of relying on existing DNS servers run by Google,
Cloudflare, your ISP, or the like. I already have it running on several of my
servers and computers, but I figured it would be great if everything on my
network can use Unbound and be, well, &lt;em&gt;unbound&lt;/em&gt; from all of those intermediary
DNS servers.&lt;/p&gt;
&lt;p&gt;Luckily, OpenWRT already has Unbound packaged, and also has a useful LuCI app
that goes with it (LuCI is the graphical web interface that comes with OpenWRT).
All I had to do was install &lt;code&gt;luci-app-unbound&lt;/code&gt;, which pulls in all of the
necessary dependencies to run unbound.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_software.png&#34; alt=&#34;LuCI: Software&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_install.png&#34; alt=&#34;LuCI: Install&#34;&gt;&lt;/p&gt;
&lt;p&gt;After that finished installing, I
refreshed LuCI/OpenWRT and went to &amp;ldquo;Services&amp;rdquo; on the top, and there it is!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_services.png&#34; alt=&#34;LuCI: Services -&amp;gt; Recursive DNS&#34;&gt;&lt;/p&gt;
&lt;p&gt;At this point, you&amp;rsquo;ll have to get your hands dirty. You can either dig through
some LuCI menus or SSH in and make some edits. For reference, I&amp;rsquo;m using
&lt;a href=&#34;https://github.com/openwrt/packages/blob/openwrt-19.07/net/unbound/files/README.md#parallel-dnsmasq&#34;&gt;&amp;ldquo;Parallel dnsmasq&amp;rdquo;&lt;/a&gt; section from the README for unbound in the OpenWRT packages (which
has a lot of other useful information as well!). Essentially, I made the edits
to &lt;code&gt;/etc/config/unbound&lt;/code&gt; and &lt;code&gt;/etc/config/dhcp&lt;/code&gt; after SSH&amp;rsquo;ing in. However, you
can make the same edits through LuCI.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;/etc/config/unbound&lt;/code&gt; edits, you can make the edits to the file in
LuCI directly at &amp;ldquo;Services -&amp;gt; Recursive DNS -&amp;gt; Files -&amp;gt; Edit: UCI&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/unbound_config.png&#34; alt=&#34;LuCI: Edit /etc/config/unbound&#34;&gt;&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;/etc/config/dhcp&lt;/code&gt; edits, you can make the edits by finding the same
fields under &amp;ldquo;Network -&amp;gt; DHCP and DNS&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/dhcp_config.png&#34; alt=&#34;LuCI: Edit DHCP and DNS Settings&#34;&gt;&lt;/p&gt;
&lt;p&gt;However, the field names are different from the lines in the config, so they
would need to be researched to determine which fields in LuCI map to which
lines in &lt;code&gt;/etc/config/dhcp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At this point (or maybe after restarting unbound and dnsmasq, which is a lot
easier using SSH and &lt;code&gt;/etc/init.d ... restart&lt;/code&gt; as well), OpenWRT should now
be using unbound for resolving all DNS lookups, while dnsmasq is only used for
DHCP-DNS.&lt;/p&gt;
&lt;p&gt;Bonus: you can also enable a nice status dashboard in LuCI under
&amp;ldquo;Services -&amp;gt; Recursive DNS -&amp;gt; Status&amp;rdquo;, but this requires installing several more
software packages: &lt;code&gt;unbound-control&lt;/code&gt; and &lt;code&gt;unbound-control-setup&lt;/code&gt;. You will also
need to change a line in &lt;code&gt;/etc/config/unbound&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
option unbound_control &amp;#39;0&amp;#39;
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;becomes&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
option unbound_control &amp;#39;1&amp;#39;
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A word of warning: there is another section on &amp;ldquo;Unbound and odhcpd&amp;rdquo; which
tries to cut out dnsmasq completely. However, when I tried to set this up,
I got myself into a lot of trouble (had to reset OpenWRT, re-install any extra
software packages, and restore configuration from backup). It is also possible that if you mess up
the configuration for the &amp;ldquo;Parallel dnsmasq&amp;rdquo; method, you could end up in a
similar error state and have to start over. Please be careful when doing this
and don&amp;rsquo;t change anything you&amp;rsquo;re not supposed to.&lt;/p&gt;
&lt;p&gt;Now, moving on to adblock, which should be &lt;strong&gt;much&lt;/strong&gt; simpler to setup. First,
install &lt;code&gt;luci-app-adblock&lt;/code&gt; and refresh. Navigate to &amp;ldquo;Services -&amp;gt; Adblock&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock.png&#34; alt=&#34;Services -&amp;gt; Adblock&#34;&gt;&lt;/p&gt;
&lt;p&gt;Check the settings at the bottom. The only thing you need to get going is
to go to the &amp;ldquo;Blocklist Sources&amp;rdquo; tab and choose your blocklists.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_blocklist.png&#34; alt=&#34;Adblock: Blacklist sources&#34;&gt;&lt;/p&gt;
&lt;p&gt;The
&lt;a href=&#34;https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md&#34;&gt;adblock readme&lt;/a&gt;
has some more info on what each list is. After that,
make sure &amp;ldquo;Enabled&amp;rdquo; is checked under the &amp;ldquo;General Settings&amp;rdquo; tab:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_enable.png&#34; alt=&#34;Adblock: enable&#34;&gt;&lt;/p&gt;
&lt;p&gt;and click the &amp;ldquo;Refresh&amp;rdquo; button above:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_refresh.png&#34; alt=&#34;Adblock: refresh&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then you&amp;rsquo;re good to go; adblock should work out of the box with unbound; cheers!&lt;/p&gt;
&lt;p&gt;ADDENDUM: Another word of warning: once you&amp;rsquo;ve setup adblock, it will download
the blocklists, merge them into a single file at &lt;code&gt;/var/lib/unbound/adb_list.overall&lt;/code&gt;,
and try to restart unbound. I recommend not trying to view/interact with adblock
or unbound during this restart, which can take anywhere from 30 seconds - 2 minutes.
Just leave them alone in LuCI for a little bit&amp;hellip;&lt;/p&gt;
</description>
</item>
<item>
<title>Hello doas</title>
<link>https://beckmeyer.us/posts/hello_doas/</link>
<pubDate>Sat, 30 Jan 2021 15:15:55 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/hello_doas/</guid>
<description>&lt;p&gt;Today, I switched my workstation from &lt;code&gt;sudo&lt;/code&gt; to &lt;code&gt;doas&lt;/code&gt;. I&amp;rsquo;m running Void Linux,
and the process was fairly easy.&lt;/p&gt;
&lt;p&gt;First, I needed to figure out how to remove &lt;code&gt;sudo&lt;/code&gt; (yes, I realize I could have
installed &lt;code&gt;doas&lt;/code&gt; first, then removed &lt;code&gt;sudo&lt;/code&gt;, but I decided to do it the hard way.)
As it turns out, the &lt;a href=&#34;https://docs.voidlinux.org/xbps/advanced-usage.html#ignoring-packages&#34;&gt;advanced usage section of the XBPS manual&lt;/a&gt; details how to use the &lt;code&gt;ignorepkg&lt;/code&gt; entry in xbps.d with nothing
other than this exact use case! I created the file &lt;code&gt;/etc/xbps.d/20-ignorepkg-sudo.conf&lt;/code&gt; with contents&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ignorepkg=sudo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then ran &lt;code&gt;sudo xbps-remove sudo&lt;/code&gt; (an ironic command).&lt;/p&gt;
&lt;p&gt;After that, because I was stupid and removed &lt;code&gt;sudo&lt;/code&gt; before I had set up &lt;code&gt;doas&lt;/code&gt;,
I had to use plain-old &lt;code&gt;su&lt;/code&gt; to change to the root user and run &lt;code&gt;xi opendoas&lt;/code&gt;. I also
configured &lt;code&gt;doas&lt;/code&gt; in &lt;code&gt;/etc/doas.conf&lt;/code&gt; with the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# see doas.conf(5) for configuration details
permit nopass keepenv :admin
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I ran &lt;code&gt;groupadd admin&lt;/code&gt;, &lt;code&gt;usermod -aG admin joel&lt;/code&gt;, and then logged out so that my
user account would see the new group perms.&lt;/p&gt;
&lt;p&gt;And just like that, I can now run &lt;code&gt;doas xbps-install ...&lt;/code&gt; and all of my other commands,
just substituting &lt;code&gt;doas&lt;/code&gt; for &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The one thing I immediately missed was &lt;code&gt;sudoedit&lt;/code&gt;. Before I accidentally tried
to use &lt;code&gt;sudo&lt;/code&gt; for the first time, I had already accidentally tried to run &lt;code&gt;sudoedit&lt;/code&gt;
&lt;em&gt;at least&lt;/em&gt; 5 times. I had to fix this. I saw a discussion on Reddit where &lt;a href=&#34;https://www.reddit.com/r/linux/comments/l6y7nv/is_doas_a_good_alternative_to_sudo/gl4hs42?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3&#34;&gt;one user
suggested&lt;/a&gt; writing a script to replace the &lt;code&gt;sudoedit&lt;/code&gt; functionality.
I quickly starting hacking together something like that. I started with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/tmp_file
$EDITOR /tmp/doasedit/tmp_file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And quickly ran into my first road-block. The script is going to have to change
the permissions of that file before the user can edit it. But if the script changes
the permissions, how can I restore it to the original location with the right
permissions? &lt;code&gt;cp /tmp/doasedit/tmp_file $1&lt;/code&gt; won&amp;rsquo;t work. I thought about just using
cat to overwrite the file contents in-place (&lt;code&gt;cat /tmp/doasedit/tmp_file &amp;gt; $1&lt;/code&gt;).
That &lt;em&gt;could&lt;/em&gt; create some issues if a program has the file open. Instead, a better option
is to create two copies of the file&amp;ndash;one for editing, and one for preserving file
attributes:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $1 /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/file $1
rm -rf /tmp/doasedit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, the issue with this is that it only works with absolute paths.
I want to make it work for relative paths as well. I&amp;rsquo;m going to take advantage
of &lt;code&gt;realpath&lt;/code&gt;, which is part of the &lt;code&gt;coreutils&lt;/code&gt; package from Void. As a bonus, this
will also take care of the edge case where the given file is a symlink (IIRC,
&lt;code&gt;sudoedit&lt;/code&gt; didn&amp;rsquo;t follow symlinks, so I may be diverging here):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
srcfile=&amp;#34;$(realpath $1)&amp;#34;
doas cp $srcfile /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $srcfile /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/file $srcfile
rm -rf /tmp/doasedit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point, it works&amp;hellip;okay-ish. It can only be used in one instance currently
since I hard-coded &lt;code&gt;/tmp/doasedit/file&lt;/code&gt; and &lt;code&gt;/tmp/doasedit/edit&lt;/code&gt;, but that&amp;rsquo;s easily fixed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
destfile_pfx=&amp;#34;$(cat /dev/urandom | tr -cd &amp;#39;a-f0-9&amp;#39; | head -c 32)&amp;#34;
while [ -d &amp;#34;/tmp/doasedit/$destfile_pfx&amp;#34; ]; do
destfile_pfx=&amp;#34;$(cat /dev/urandom | tr -cd &amp;#39;a-f0-9&amp;#39; | head -c 32)&amp;#34;
done
mkdir -p /tmp/doasedit/$destfile_pfx
srcfile=&amp;#34;$(realpath $1)&amp;#34;
doas cp $srcfile /tmp/doasedit/$destfile_pfx/edit
doas chown -R $USER:$USER /tmp/doasedit/$destfile_pfx/edit
doas cp $srcfile /tmp/doasedit/$destfile_pfx/file
$EDITOR /tmp/doasedit/$destfile_pfx/edit
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
rm -rf /tmp/doasedit/$destfile_pfx
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point, the only thing missing is the check to see if the file was actually
edited:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&amp;gt;/dev/null
if cmp -s &amp;#34;/tmp/doasedit/$destfile_pfx/file&amp;#34; &amp;#34;$srcfile&amp;#34;; then
echo &amp;#34;Skipping write; no changes.&amp;#34;
else
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
fi
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I put this in a &lt;a href=&#34;https://github.com/AluminumTank/doasedit&#34;&gt;repo on GitHub&lt;/a&gt; if
anyone is interested. I know that a major
weakness of this script is the number of times it calls &lt;code&gt;doas&lt;/code&gt;, which could
break flows where password is required every time &lt;code&gt;doas&lt;/code&gt; is run.&lt;/p&gt;
</description>
</item>
<item>
<title>Volatile Mediums</title>
<link>https://beckmeyer.us/posts/volatile_mediums/</link>
<pubDate>Fri, 29 Jan 2021 23:36:00 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/volatile_mediums/</guid>
<description>&lt;p&gt;I&amp;rsquo;ve recently been thinking a lot about storage mediums [1] &amp;ndash; especially in the long-term.&lt;/p&gt;
&lt;p&gt;Technology has made a lot of progress. Digital storage mediums started out only being
able to store &lt;a href=&#34;https://en.wikipedia.org/wiki/Tape_drive&#34;&gt;224KB on a tape drive&lt;/a&gt;
for an average lifetime of &lt;a href=&#34;https://blog.storagecraft.com/data-storage-lifespan/&#34;&gt;&lt;em&gt;up to&lt;/em&gt; 30 years&lt;/a&gt;.
Now, we can store terrabytes of data on hard drives and solid-state drives. However,
no one ever really answered the question about long-term storage.&lt;/p&gt;
&lt;p&gt;(Note: the following is based off an assumption that the storage medium is only
being used to make backups or archive data. The device itself could be unplugged and stored
when no backup is in progress.)&lt;/p&gt;
&lt;p&gt;Even though &lt;em&gt;theoretically&lt;/em&gt; hard drives could store data for 20+ years, random bit flips, drive
failure, etc. all make hard drives too volatile of an option. As always, of course
redundancy takes away some of these issues.&lt;/p&gt;
&lt;p&gt;SSDs are in an even worse position: they cost significantly more than hard drives
per TB right now, and last I heard, there were still issues with bit fade when
unpowered.&lt;/p&gt;
&lt;p&gt;CD/DVD is sounding a lot better, but there are some serious issues here too.
Variable quality directly impacts the storage lifetime. Physically storing the
discs is a lot more risky since the disc itself doesn&amp;rsquo;t have as much built-in
protection as a hard drive or SSD has. You&amp;rsquo;ll need a much larger quantity to
store the terrabytes of data that you can easily dump on one hard drive. And finally, life
expectancy is still fairly low &amp;ndash; while manufacturers of recordable discs (the &amp;lsquo;R&amp;rsquo; in CD-R, DVD-R, etc.)
claim life expectancies of 100-200 (!) years under optimal conditions, others are &lt;em&gt;slightly&lt;/em&gt; more conservative,
&lt;a href=&#34;https://www.clir.org/pubs/reports/pub121/sec4/&#34;&gt;giving an estimate of 30 years&lt;/a&gt;.
Oh, and remember how I mentioned this is for recordable discs? That means they&amp;rsquo;re single write.
The random access (RW - CD-RW, DVD-RW, etc.) discs have even lower life expectancies.&lt;/p&gt;
&lt;p&gt;All in all, humanity has not gotten very far with the digital storage medium.
All of these life expectancies have an inconsequential variance when we zoom out
to the century view of history.&lt;/p&gt;
&lt;p&gt;[1] And no, I&amp;rsquo;m not talking about the kind you pay to see your dead great-great-aunt to figure out if
you&amp;rsquo;re actually related to George Washington.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is intended to be the beginning of a learning series/personal study on the issues surrounding
information preservation, digital permanence, and their related issues.&lt;/em&gt;&lt;/p&gt;
</description>
</item>
<item>
<title>Contact</title>
<link>https://beckmeyer.us/contact/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/contact/</guid>
<description>&lt;p&gt;Joel Beckmeyer&lt;br&gt;
Matrix: &lt;a href=&#34;https://matrix.to/#/@joel:thebeckmeyers.xyz&#34;&gt;@joel:thebeckmeyers.xyz&lt;/a&gt;&lt;br&gt;
Fediverse: &lt;a href=&#34;https://social.beckmeyer.us/TinfoilSubmarine&#34;&gt;@TinfoilSubmarine@social.beckmeyer.us&lt;/a&gt;&lt;/p&gt;
</description>
</item>
</channel>
</rss>

View File

@ -0,0 +1,40 @@
// in Firefox we need to add a new css style with document.write rather than modifying the href
// of the existing one, otherwise the screen will flash white while loading on dark themes
var theme_css_elem = document.getElementById('theme_css');
var js_url = document.currentScript.src; // example: http://example.com/myhugo/js/theme-switcher.js
if(localStorage.getItem('theme') === 'dark'){
var clone = theme_css_elem.cloneNode(false);
clone.href = new URL("../css/themes/dark.css", js_url);
theme_css_elem.remove();
document.write(clone.outerHTML);
}else if(localStorage.getItem('theme') === 'light'){
var clone = theme_css_elem.cloneNode(false);
clone.href = new URL("../css/themes/light.css", js_url);
theme_css_elem.remove();
document.write(clone.outerHTML);
}
window.addEventListener("load", function(event){update_toggle_button();}, false);
function update_toggle_button(){
var elem = document.getElementById('theme_css');
var button = document.getElementById('change-theme-button');
button.style.display = "";
if(elem.href.endsWith('light.css')){
button.getElementsByTagName('img')[0].src = new URL('../images/theme-switcher-moon.svg', js_url);
}else if(elem.href.endsWith('dark.css')){
button.getElementsByTagName('img')[0].src = new URL('../images/theme-switcher-sun.svg', js_url);
}
}
function toggle_theme(){
var elem = document.getElementById('theme_css');
if(elem.href.endsWith('light.css')){
elem.href = new URL("../css/themes/dark.css", js_url);
localStorage.setItem('theme', 'dark');
}else if(elem.href.endsWith('dark.css')){
elem.href = new URL("../css/themes/light.css", js_url);
localStorage.setItem('theme', 'light');
}
update_toggle_button();
}

BIN
public/luci_install.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
public/luci_services.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
public/luci_software.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Better? &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Better?</h1>
<div class="title-header-date">
<time>Saturday, April 3, 2021</time>
</div>
</div>
<p>There are many that say<br>
(and I tend to agree)<br>
that free software is the best there could be.</p>
<p>But please don&rsquo;t mistake<br>
using software that&rsquo;s free<br>
as a right to superiority.</p>
<p>There are many that go<br>
from day to day living<br>
and don&rsquo;t give a thought to what they are using.</p>
<p>Are they worse for this?<br>
Are you better for caring?<br>
Sometimes the truth can be quite baring.</p>
<p>That not every human<br>
in present circumstance<br>
is able or willing to take a chance.</p>
<p>&lsquo;Cause that&rsquo;s what it is,<br>
taking a chance and going<br>
into the unknown with fear, and knowing</p>
<p>that what you might find,<br>
may not truly be better.</p>
<p>But instead simply different;<br>
and still made by a stranger.</p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Consistency &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Consistency</h1>
<div class="title-header-date">
<time>Sunday, April 4, 2021</time>
</div>
</div>
<p>I&rsquo;ve seen a lot of talk about this stuff:</p>
<ul>
<li>&ldquo;Check out my FOSS project (hosted on Github)&rdquo;</li>
<li>&ldquo;Wayland is a great innovation and boon to the community! Also, there are very few tools/alternatives available yet for your favorite X11 tool!&rdquo;</li>
<li>&ldquo;We love open source! Also, we develop the most popular proprietary operating system!&rdquo;</li>
<li>&ldquo;Do as I say, not as I do.&rdquo;</li>
</ul>
<p>We love to poke fun at and expose this kind of stuff, which is all fine and
dandy. I think it&rsquo;s an interesting (and important) part of our humanity that
this kind of thing bugs us so much. Think about that last point, which at least
in my experience, is something I <em>loved</em> to fault authorities for.</p>
<p>Hypocrisy is fun and also infuriating to uncover in others, but how often do
we do a &ldquo;consistency check&rdquo; on ourselves? Is what we are saying evidenced by
the rest of our actions?</p>
<p>That&rsquo;s a hard look sometimes. I know it is for me, since I&rsquo;m <strong>very</strong> quick
to judge others, but don&rsquo;t often think about how I fail at my own principles.</p>
<p>Example: As a FOSS advocate, it&rsquo;s nearly natural to assume that everything will
be better and easier with more people using FOSS. When evidence seems to point
to the contrary (e.g. fighting with Matrix/Element to get it working for my
family and friends), I don&rsquo;t own up to the fact that it isn&rsquo;t easier, and that
is an actual problem.</p>
<p>If we truly want to build a welcoming and wholesome community, let&rsquo;s be careful
to do a consistency check to make sure nothing smells foul.</p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,156 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Hello doas &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Hello doas</h1>
<div class="title-header-date">
<time>Saturday, January 30, 2021</time>
</div>
</div>
<p>Today, I switched my workstation from <code>sudo</code> to <code>doas</code>. I&rsquo;m running Void Linux,
and the process was fairly easy.</p>
<p>First, I needed to figure out how to remove <code>sudo</code> (yes, I realize I could have
installed <code>doas</code> first, then removed <code>sudo</code>, but I decided to do it the hard way.)
As it turns out, the <a href="https://docs.voidlinux.org/xbps/advanced-usage.html#ignoring-packages">advanced usage section of the XBPS manual</a> details how to use the <code>ignorepkg</code> entry in xbps.d with nothing
other than this exact use case! I created the file <code>/etc/xbps.d/20-ignorepkg-sudo.conf</code> with contents</p>
<pre tabindex="0"><code>ignorepkg=sudo
</code></pre><p>and then ran <code>sudo xbps-remove sudo</code> (an ironic command).</p>
<p>After that, because I was stupid and removed <code>sudo</code> before I had set up <code>doas</code>,
I had to use plain-old <code>su</code> to change to the root user and run <code>xi opendoas</code>. I also
configured <code>doas</code> in <code>/etc/doas.conf</code> with the following:</p>
<pre tabindex="0"><code># see doas.conf(5) for configuration details
permit nopass keepenv :admin
</code></pre><p>I ran <code>groupadd admin</code>, <code>usermod -aG admin joel</code>, and then logged out so that my
user account would see the new group perms.</p>
<p>And just like that, I can now run <code>doas xbps-install ...</code> and all of my other commands,
just substituting <code>doas</code> for <code>sudo</code>.</p>
<p>The one thing I immediately missed was <code>sudoedit</code>. Before I accidentally tried
to use <code>sudo</code> for the first time, I had already accidentally tried to run <code>sudoedit</code>
<em>at least</em> 5 times. I had to fix this. I saw a discussion on Reddit where <a href="https://www.reddit.com/r/linux/comments/l6y7nv/is_doas_a_good_alternative_to_sudo/gl4hs42?utm_source=share&amp;utm_medium=web2x&amp;context=3">one user
suggested</a> writing a script to replace the <code>sudoedit</code> functionality.
I quickly starting hacking together something like that. I started with:</p>
<pre tabindex="0"><code>#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/tmp_file
$EDITOR /tmp/doasedit/tmp_file
</code></pre><p>And quickly ran into my first road-block. The script is going to have to change
the permissions of that file before the user can edit it. But if the script changes
the permissions, how can I restore it to the original location with the right
permissions? <code>cp /tmp/doasedit/tmp_file $1</code> won&rsquo;t work. I thought about just using
cat to overwrite the file contents in-place (<code>cat /tmp/doasedit/tmp_file &gt; $1</code>).
That <em>could</em> create some issues if a program has the file open. Instead, a better option
is to create two copies of the file&ndash;one for editing, and one for preserving file
attributes:</p>
<pre tabindex="0"><code>#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $1 /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&gt;/dev/null
doas mv -f /tmp/doasedit/file $1
rm -rf /tmp/doasedit
</code></pre><p>Of course, the issue with this is that it only works with absolute paths.
I want to make it work for relative paths as well. I&rsquo;m going to take advantage
of <code>realpath</code>, which is part of the <code>coreutils</code> package from Void. As a bonus, this
will also take care of the edge case where the given file is a symlink (IIRC,
<code>sudoedit</code> didn&rsquo;t follow symlinks, so I may be diverging here):</p>
<pre tabindex="0"><code>#!/bin/sh
mkdir -p /tmp/doasedit
srcfile=&#34;$(realpath $1)&#34;
doas cp $srcfile /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $srcfile /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&gt;/dev/null
doas mv -f /tmp/doasedit/file $srcfile
rm -rf /tmp/doasedit
</code></pre><p>At this point, it works&hellip;okay-ish. It can only be used in one instance currently
since I hard-coded <code>/tmp/doasedit/file</code> and <code>/tmp/doasedit/edit</code>, but that&rsquo;s easily fixed:</p>
<pre tabindex="0"><code>#!/bin/sh
destfile_pfx=&#34;$(cat /dev/urandom | tr -cd &#39;a-f0-9&#39; | head -c 32)&#34;
while [ -d &#34;/tmp/doasedit/$destfile_pfx&#34; ]; do
destfile_pfx=&#34;$(cat /dev/urandom | tr -cd &#39;a-f0-9&#39; | head -c 32)&#34;
done
mkdir -p /tmp/doasedit/$destfile_pfx
srcfile=&#34;$(realpath $1)&#34;
doas cp $srcfile /tmp/doasedit/$destfile_pfx/edit
doas chown -R $USER:$USER /tmp/doasedit/$destfile_pfx/edit
doas cp $srcfile /tmp/doasedit/$destfile_pfx/file
$EDITOR /tmp/doasedit/$destfile_pfx/edit
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&gt;/dev/null
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
rm -rf /tmp/doasedit/$destfile_pfx
</code></pre><p>At this point, the only thing missing is the check to see if the file was actually
edited:</p>
<pre tabindex="0"><code>...
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&gt;/dev/null
if cmp -s &#34;/tmp/doasedit/$destfile_pfx/file&#34; &#34;$srcfile&#34;; then
echo &#34;Skipping write; no changes.&#34;
else
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
fi
...
</code></pre><p>I put this in a <a href="https://github.com/AluminumTank/doasedit">repo on GitHub</a> if
anyone is interested. I know that a major
weakness of this script is the number of times it calls <code>doas</code>, which could
break flows where password is required every time <code>doas</code> is run.</p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

194
public/posts/index.html Normal file
View File

@ -0,0 +1,194 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Posts &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/posts/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Posts</h1>
</div>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/consistency/">Consistency</a></h3>
<div class="title-list-date">
<time>Sunday, April 4, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
I&rsquo;ve seen a lot of talk about this stuff:
&ldquo;Check out my FOSS project (hosted on Github)&rdquo; &ldquo;Wayland is a great innovation and boon to the community! Also, there are very few tools/alternatives available yet for your favorite X11 tool!&rdquo; &ldquo;We love open source! Also, we develop the most popular proprietary operating system!&rdquo; &ldquo;Do as I say, not as I do.&rdquo; We love to poke fun at and expose this kind of stuff, which is all fine and dandy.
</p>
<a href="/posts/consistency/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/better/">Better?</a></h3>
<div class="title-list-date">
<time>Saturday, April 3, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
There are many that say
(and I tend to agree)
that free software is the best there could be.
But please don&rsquo;t mistake
using software that&rsquo;s free
as a right to superiority.
There are many that go
from day to day living
and don&rsquo;t give a thought to what they are using.
Are they worse for this?
Are you better for caring?
Sometimes the truth can be quite baring.
That not every human
</p>
<a href="/posts/better/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/moving_back_to_openssl/">Moving Back To OpenSSL</a></h3>
<div class="title-list-date">
<time>Monday, March 22, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
Void Linux recently announced that they were going to move back to OpenSSL after originally switching to LibreSSL in 2014. It seems that there are a lot of things at play here.
It seems that the main focus of the recent announcement is on the maintainability and other difficulties of not using the one true SSL/TLS library. To me, this pragmatically makes sense. However, every time something like this happens I get this lingering feeling of worry&hellip;
</p>
<a href="/posts/moving_back_to_openssl/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/the_generation_ship_problem/">The Generation Ship Problem</a></h3>
<div class="title-list-date">
<time>Friday, March 19, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
After talking about the hardware and software problems of digital permanence, I&rsquo;m struck by a classical Sci-Fi motif with a conundrum: the Generation Ship; a ship outfitted with all of the technology, infrastructure, and storage to support lightyear-scale human travel.
But what about that technology on the ship? If we build one of these ships, we need to accomplish one of several things in regards to information storage:
1. Innovate to the point where the lifetime of the storage devices is able to support lightyear scale travel.
</p>
<a href="/posts/the_generation_ship_problem/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/volatile_formats/">Volatile Formats</a></h3>
<div class="title-list-date">
<time>Thursday, March 18, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
Note: This is a continuation of the thoughts I started thinking about in my Volatile Mediums blog post.
The next level up from physical mediums for data storage is the way that the data is stored. In the digital age, we have a plethora of formats for storing information. For me, one of the most interesting areas of information storage is the analog-digital space.
The fundamental problem of storing audio, video, and other replications of the physical world is that there is so much information that we can collect with sensors (think microphones, video cameras, etc.
</p>
<a href="/posts/volatile_formats/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/openwrt_plus_unbound/">OpenWRT &#43; Unbound &#43; adblock</a></h3>
<div class="title-list-date">
<time>Friday, February 5, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
I decided to do some work on my Linksys WRT32X running OpenWRT to make it a little more useful.
Unbound is a DNS resolver which I like because it&rsquo;s recursive, meaning it directly queries the root servers instead of relying on existing DNS servers run by Google, Cloudflare, your ISP, or the like. I already have it running on several of my servers and computers, but I figured it would be great if everything on my network can use Unbound and be, well, unbound from all of those intermediary DNS servers.
</p>
<a href="/posts/openwrt_plus_unbound/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/hello_doas/">Hello doas</a></h3>
<div class="title-list-date">
<time>Saturday, January 30, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
Today, I switched my workstation from sudo to doas. I&rsquo;m running Void Linux, and the process was fairly easy.
First, I needed to figure out how to remove sudo (yes, I realize I could have installed doas first, then removed sudo, but I decided to do it the hard way.) As it turns out, the advanced usage section of the XBPS manual details how to use the ignorepkg entry in xbps.
</p>
<a href="/posts/hello_doas/">Read More…</a>
</div>
</article>
<article class="all-list">
<div class="title-list">
<h3><a href="/posts/volatile_mediums/">Volatile Mediums</a></h3>
<div class="title-list-date">
<time>Friday, January 29, 2021</time>
</div>
</div>
<div class="body-list">
<p></p>
<p>
I&rsquo;ve recently been thinking a lot about storage mediums [1] &ndash; especially in the long-term.
Technology has made a lot of progress. Digital storage mediums started out only being able to store 224KB on a tape drive for an average lifetime of up to 30 years. Now, we can store terrabytes of data on hard drives and solid-state drives. However, no one ever really answered the question about long-term storage.
</p>
<a href="/posts/volatile_mediums/">Read More…</a>
</div>
</article>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

493
public/posts/index.xml Normal file
View File

@ -0,0 +1,493 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Posts on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/posts/</link>
<description>Recent content in Posts on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster>
<lastBuildDate>Sun, 04 Apr 2021 00:00:00 -0500</lastBuildDate><atom:link href="https://beckmeyer.us/posts/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Consistency</title>
<link>https://beckmeyer.us/posts/consistency/</link>
<pubDate>Sun, 04 Apr 2021 00:00:00 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/consistency/</guid>
<description>&lt;p&gt;I&amp;rsquo;ve seen a lot of talk about this stuff:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Check out my FOSS project (hosted on Github)&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Wayland is a great innovation and boon to the community! Also, there are very few tools/alternatives available yet for your favorite X11 tool!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;We love open source! Also, we develop the most popular proprietary operating system!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Do as I say, not as I do.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We love to poke fun at and expose this kind of stuff, which is all fine and
dandy. I think it&amp;rsquo;s an interesting (and important) part of our humanity that
this kind of thing bugs us so much. Think about that last point, which at least
in my experience, is something I &lt;em&gt;loved&lt;/em&gt; to fault authorities for.&lt;/p&gt;
&lt;p&gt;Hypocrisy is fun and also infuriating to uncover in others, but how often do
we do a &amp;ldquo;consistency check&amp;rdquo; on ourselves? Is what we are saying evidenced by
the rest of our actions?&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a hard look sometimes. I know it is for me, since I&amp;rsquo;m &lt;strong&gt;very&lt;/strong&gt; quick
to judge others, but don&amp;rsquo;t often think about how I fail at my own principles.&lt;/p&gt;
&lt;p&gt;Example: As a FOSS advocate, it&amp;rsquo;s nearly natural to assume that everything will
be better and easier with more people using FOSS. When evidence seems to point
to the contrary (e.g. fighting with Matrix/Element to get it working for my
family and friends), I don&amp;rsquo;t own up to the fact that it isn&amp;rsquo;t easier, and that
is an actual problem.&lt;/p&gt;
&lt;p&gt;If we truly want to build a welcoming and wholesome community, let&amp;rsquo;s be careful
to do a consistency check to make sure nothing smells foul.&lt;/p&gt;
</description>
</item>
<item>
<title>Better?</title>
<link>https://beckmeyer.us/posts/better/</link>
<pubDate>Sat, 03 Apr 2021 22:15:44 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/better/</guid>
<description>&lt;p&gt;There are many that say&lt;br&gt;
(and I tend to agree)&lt;br&gt;
that free software is the best there could be.&lt;/p&gt;
&lt;p&gt;But please don&amp;rsquo;t mistake&lt;br&gt;
using software that&amp;rsquo;s free&lt;br&gt;
as a right to superiority.&lt;/p&gt;
&lt;p&gt;There are many that go&lt;br&gt;
from day to day living&lt;br&gt;
and don&amp;rsquo;t give a thought to what they are using.&lt;/p&gt;
&lt;p&gt;Are they worse for this?&lt;br&gt;
Are you better for caring?&lt;br&gt;
Sometimes the truth can be quite baring.&lt;/p&gt;
&lt;p&gt;That not every human&lt;br&gt;
in present circumstance&lt;br&gt;
is able or willing to take a chance.&lt;/p&gt;
&lt;p&gt;&amp;lsquo;Cause that&amp;rsquo;s what it is,&lt;br&gt;
taking a chance and going&lt;br&gt;
into the unknown with fear, and knowing&lt;/p&gt;
&lt;p&gt;that what you might find,&lt;br&gt;
may not truly be better.&lt;/p&gt;
&lt;p&gt;But instead simply different;&lt;br&gt;
and still made by a stranger.&lt;/p&gt;
</description>
</item>
<item>
<title>Moving Back To OpenSSL</title>
<link>https://beckmeyer.us/posts/moving_back_to_openssl/</link>
<pubDate>Mon, 22 Mar 2021 11:00:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/moving_back_to_openssl/</guid>
<description>&lt;p&gt;Void Linux &lt;a href=&#34;https://voidlinux.org/news/2021/02/OpenSSL.html&#34;&gt;recently announced&lt;/a&gt;
that they were going to move back to OpenSSL after originally &lt;a href=&#34;https://voidlinux.org/news/2014/08/LibreSSL-by-default.html&#34;&gt;switching to
LibreSSL in 2014&lt;/a&gt;.
It seems that there are a lot of things at play here.&lt;/p&gt;
&lt;p&gt;It seems that the main focus of the recent announcement is on the maintainability
and other difficulties of not using the &lt;em&gt;one true SSL/TLS library&lt;/em&gt;. To me,
this pragmatically makes sense. However, every time something like this happens
I get this lingering feeling of worry&amp;hellip;&lt;/p&gt;
&lt;p&gt;Microsoft moving their default browser from their own implementation to
Chromium, and other browsers following suit.&lt;/p&gt;
&lt;p&gt;Linux distributions moving &lt;em&gt;en masse&lt;/em&gt; to &lt;strong&gt;systemd&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Distributed email being slowly crushed and killed by Google with GMail.&lt;/p&gt;
&lt;p&gt;And many other examples that aren&amp;rsquo;t immediately coming to mind.&lt;/p&gt;
&lt;p&gt;I think it&amp;rsquo;s great that OpenSSL as a project has made a comeback from the
Heartbleed fiasco, and that it is apparently more actively developed nowadays,
but the fact that we are even at the point of moving back to OpenSSL due to
difficulties with building software is worrying. To me, it looks like a
symptom of software becoming too entrenched and dependent on a single piece
of software.&lt;/p&gt;
&lt;p&gt;This kind of accusation coming from anyone is going to be hypocritical, since
we all depend on Linux, X11, Wayland, systemd, or some common piece of software
that we take for granted and don&amp;rsquo;t lose sleep over. However, I think what&amp;rsquo;s
categorically different about this one is that an alternative was adopted,
worked on, but eventually &amp;ldquo;failed&amp;rdquo; (at least for Void, but also possibly for
Linux as well).&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know what the fix for this specific issue would be. I&amp;rsquo;m not nearly
familiar enough with SSL/TLS or how you would develop software to be agnostic
of dependencies like this. But I think in order to honor principles like
the Unix philosophy, the KISS principle, and countless others, we need to
figure out a way to be more modular for dependency issues like this.&lt;/p&gt;
</description>
</item>
<item>
<title>The Generation Ship Problem</title>
<link>https://beckmeyer.us/posts/the_generation_ship_problem/</link>
<pubDate>Fri, 19 Mar 2021 15:00:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/the_generation_ship_problem/</guid>
<description>&lt;p&gt;After talking about the hardware and software problems of
digital permanence, I&amp;rsquo;m struck by a classical Sci-Fi
motif with a conundrum: the &lt;strong&gt;Generation Ship&lt;/strong&gt;; a ship
outfitted with all of the technology, infrastructure, and
storage to support lightyear-scale human travel.&lt;/p&gt;
&lt;p&gt;But what about that technology on the ship? If we build
one of these ships, we need to accomplish one of several
things in regards to information storage:&lt;/p&gt;
&lt;h3 id=&#34;1-innovate-to-the-point-where-the-lifetime-of-the-storage-devices-is-able-to-support-lightyear-scale-travel&#34;&gt;1. Innovate to the point where the lifetime of the storage devices is able to support lightyear scale travel.&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s a tall order, given where we are right now with
physical storage devices. As I mentioned in one of my
previous posts, the average lifetime of physical storage
devices is less than 100 years, no matter if it is a hard
drive, solid-state drive, etc.&lt;/p&gt;
&lt;h3 id=&#34;2-provide-the-facility-to-create-new-storage-devices-to-replace-the-failing-old-ones&#34;&gt;2. Provide the facility to create new storage devices to replace the failing old ones.&lt;/h3&gt;
&lt;p&gt;Again, in my mind a tall order, since it would require
facilities on the ship to create storage devices. The
problem of having materials is at least solvable by just
sending the ship with all of the materials it needs in
advance.&lt;/p&gt;
&lt;h3 id=&#34;3-provide-the-facility-to-revitalize-storage-devices&#34;&gt;3. Provide the facility to revitalize storage devices.&lt;/h3&gt;
&lt;p&gt;One of the main reasons I&amp;rsquo;m even thinking about this is
because I&amp;rsquo;m an individual with limited resources.
Accordingly, I think about things in terms of
broken/working, on/off, etc. With enough resources, there
is a much larger chance of being able to repair, re-purpose,
and otherwise revitalize storage devices, increasing their
lifetime. E.g., if the only failure in the hard drive is the
control circuit, that is an &amp;ldquo;easy enough&amp;rdquo; repair.&lt;/p&gt;
&lt;p&gt;I like to toy with the idea of a generation ship a lot in
my head, but I think it&amp;rsquo;s really fun to think about the
technical possibilities and needs of a ship like this.&lt;/p&gt;
</description>
</item>
<item>
<title>Volatile Formats</title>
<link>https://beckmeyer.us/posts/volatile_formats/</link>
<pubDate>Thu, 18 Mar 2021 14:24:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/volatile_formats/</guid>
<description>&lt;p&gt;&lt;em&gt;Note: This is a continuation of the thoughts I started
thinking about in my &lt;a href=&#34;https://beckmeyer.us/posts/volatile_mediums/&#34;&gt;Volatile Mediums&lt;/a&gt; blog post.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The next level up from physical mediums for data storage
is the &lt;em&gt;way&lt;/em&gt; that the data is stored. In the digital age,
we have a plethora of formats for storing information.
For me, one of the most interesting areas of information
storage is the analog-digital space.&lt;/p&gt;
&lt;p&gt;The fundamental problem of storing audio, video, and other
replications of the physical world is that there is so much
information that we can collect with sensors
(think microphones, video cameras, etc.). It would be great
if we could go get the best camera and microphone out there,
record whatever people record these days, and have that
exact physical experience &amp;ldquo;played back&amp;rdquo; for us on a screen
and speaker/headphones.&lt;/p&gt;
&lt;p&gt;Unfortunately, there are several problems with this. Among
those is the actual design of the sensor. It takes a lot of
careful thought, engineering, and the like to create a truly
good microphone or camera. And after all of that, this sensor
will cost something. Hopefully, that cost will correspond to
the actual technical ability of that sensor! In any case,
not everyone can have the best camera or microphone due to
any number of constraints, not just those listed above.&lt;/p&gt;
&lt;p&gt;The second problem is the sampling issue. The sensor will
create some sort of output that can then be measured, or
&lt;strong&gt;sampled&lt;/strong&gt;, by an ADC (analog-to-digital converter). The
very word &amp;ldquo;sample&amp;rdquo; belies what this nearly magical box is
doing: it is only looking at certain portions or timestamps
of the analog signal. Granted, the time between samples
can be very small (e.g. 44.1 kHz is a fairly common sample
rate for audio), but there is still some loss of signal.
Once the ADC creates these samples, it converts them into
a digital format (something that can be stored on a
CD, hard drive, thumb drive, etc.).&lt;/p&gt;
&lt;p&gt;The third problem is the encoding issue. The ADC creates all
of these samples, but we need to start thinking about storage
limitations. Storing the raw output of a sensor can take a
lot of space: an average album length (40 minutes) could
easily take 400MB of space! Now, again, the physical storage
space is moving in the upward direction to combat this, but
storing isn&amp;rsquo;t the only problem. One prime issue is internet
bandwidth.&lt;/p&gt;
&lt;p&gt;The solution to this is compression, like a ZIP file. It
makes big files smaller by doing some fancy math tricks
that can be reversed by a computer to reconstruct the
original file. However, for audio/video files, another level
of compression exists which actually gets rid of some of the
information in the original file to save more space. This
is called &amp;ldquo;lossy&amp;rdquo; compression, as opposed to &amp;ldquo;lossless&amp;rdquo;
compression.&lt;/p&gt;
&lt;p&gt;Great! We&amp;rsquo;ve found a way to save more space. The problem
with lossy compression is that we have to decide which
information to throw away. Usually, this is frequencies
that the average human ear/eye can&amp;rsquo;t perceive. But, let&amp;rsquo;s
just say that some compression is a bit too &amp;ldquo;greedy&amp;rdquo; when it
comes to saving space and starts to cut into the band of
frequencies that can be perceived. Also note that
the design of these compression algorithms is an artform
and takes lots of careful consideration.&lt;/p&gt;
&lt;p&gt;The final problem I want to mention is the codec problem.
There are many different codecs available today, and for
each and every one of them to be useful, you need to have a
way to decode each and every one of them. Unfortunately,
this is sometimes very difficult.&lt;/p&gt;
&lt;p&gt;It could be a licensing
issue, where you don&amp;rsquo;t have the correct software installed
or purchased to actually decode that file on your computer.&lt;/p&gt;
&lt;p&gt;Or it could be a physical constraints issue, where your
computer isn&amp;rsquo;t powerful enough to decode the file at a fast
enough rate for you to view it without stuttering,
buffering, etc.&lt;/p&gt;
&lt;p&gt;Third, it could be a personal preference. Some people
have much more sensitive eyes/ears and need to have formats
that are more &lt;strong&gt;transparent&lt;/strong&gt;, meaning that the lossy file
is perceptually identical to the source it was encoded from.&lt;/p&gt;
&lt;p&gt;With all of these issues at play, I think there are several
key points to make:&lt;/p&gt;
&lt;h3 id=&#34;1-codecs-need-to-be-freely-available-for-widespread-use-with-no-strings-attached&#34;&gt;1. Codecs need to be freely available for widespread use with no strings attached.&lt;/h3&gt;
&lt;p&gt;Can&amp;rsquo;t stress this one enough: we need to make sure we are
doing everything possible to not let our information die
when a corporation or individual makes a decision that
impacts the &amp;ldquo;who, what, where, when, and how&amp;rdquo; of their codec
usage.&lt;/p&gt;
&lt;h3 id=&#34;2-lossless-compression-is-good-but-it-is-not-the-only-thing-we-need&#34;&gt;2. Lossless compression is good, but it is not the only thing we need.&lt;/h3&gt;
&lt;p&gt;We need to remember that not everyone has the ability to use
lossless codecs, whether that be because of internet
bandwidth limitations, storage limitation, or the like.
Instead, we need to continue to innovate in the lossy
compression space to narrow the perceptual gap between lossy
and lossless more and more.&lt;/p&gt;
&lt;h3 id=&#34;3-a-codec-should-never-become-obsolete&#34;&gt;3. A codec should never become obsolete.&lt;/h3&gt;
&lt;p&gt;This one may sound weird, but the fact is, if we&amp;rsquo;re talking
about long-term storage of information, we can&amp;rsquo;t let codecs
die, since there may come a day where we need a codec to
decode great-grandpa&amp;rsquo;s album that never made it big.&lt;/p&gt;
</description>
</item>
<item>
<title>OpenWRT &#43; Unbound &#43; adblock</title>
<link>https://beckmeyer.us/posts/openwrt_plus_unbound/</link>
<pubDate>Fri, 05 Feb 2021 19:03:15 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/openwrt_plus_unbound/</guid>
<description>&lt;p&gt;I decided to do some work on my Linksys WRT32X running OpenWRT to make it a
little more useful.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://nlnetlabs.nl/projects/unbound/about/&#34;&gt;Unbound&lt;/a&gt; is a DNS
resolver which I like because it&amp;rsquo;s recursive, meaning it directly queries the
root servers instead of relying on existing DNS servers run by Google,
Cloudflare, your ISP, or the like. I already have it running on several of my
servers and computers, but I figured it would be great if everything on my
network can use Unbound and be, well, &lt;em&gt;unbound&lt;/em&gt; from all of those intermediary
DNS servers.&lt;/p&gt;
&lt;p&gt;Luckily, OpenWRT already has Unbound packaged, and also has a useful LuCI app
that goes with it (LuCI is the graphical web interface that comes with OpenWRT).
All I had to do was install &lt;code&gt;luci-app-unbound&lt;/code&gt;, which pulls in all of the
necessary dependencies to run unbound.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_software.png&#34; alt=&#34;LuCI: Software&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_install.png&#34; alt=&#34;LuCI: Install&#34;&gt;&lt;/p&gt;
&lt;p&gt;After that finished installing, I
refreshed LuCI/OpenWRT and went to &amp;ldquo;Services&amp;rdquo; on the top, and there it is!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_services.png&#34; alt=&#34;LuCI: Services -&amp;gt; Recursive DNS&#34;&gt;&lt;/p&gt;
&lt;p&gt;At this point, you&amp;rsquo;ll have to get your hands dirty. You can either dig through
some LuCI menus or SSH in and make some edits. For reference, I&amp;rsquo;m using
&lt;a href=&#34;https://github.com/openwrt/packages/blob/openwrt-19.07/net/unbound/files/README.md#parallel-dnsmasq&#34;&gt;&amp;ldquo;Parallel dnsmasq&amp;rdquo;&lt;/a&gt; section from the README for unbound in the OpenWRT packages (which
has a lot of other useful information as well!). Essentially, I made the edits
to &lt;code&gt;/etc/config/unbound&lt;/code&gt; and &lt;code&gt;/etc/config/dhcp&lt;/code&gt; after SSH&amp;rsquo;ing in. However, you
can make the same edits through LuCI.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;/etc/config/unbound&lt;/code&gt; edits, you can make the edits to the file in
LuCI directly at &amp;ldquo;Services -&amp;gt; Recursive DNS -&amp;gt; Files -&amp;gt; Edit: UCI&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/unbound_config.png&#34; alt=&#34;LuCI: Edit /etc/config/unbound&#34;&gt;&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;/etc/config/dhcp&lt;/code&gt; edits, you can make the edits by finding the same
fields under &amp;ldquo;Network -&amp;gt; DHCP and DNS&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/dhcp_config.png&#34; alt=&#34;LuCI: Edit DHCP and DNS Settings&#34;&gt;&lt;/p&gt;
&lt;p&gt;However, the field names are different from the lines in the config, so they
would need to be researched to determine which fields in LuCI map to which
lines in &lt;code&gt;/etc/config/dhcp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At this point (or maybe after restarting unbound and dnsmasq, which is a lot
easier using SSH and &lt;code&gt;/etc/init.d ... restart&lt;/code&gt; as well), OpenWRT should now
be using unbound for resolving all DNS lookups, while dnsmasq is only used for
DHCP-DNS.&lt;/p&gt;
&lt;p&gt;Bonus: you can also enable a nice status dashboard in LuCI under
&amp;ldquo;Services -&amp;gt; Recursive DNS -&amp;gt; Status&amp;rdquo;, but this requires installing several more
software packages: &lt;code&gt;unbound-control&lt;/code&gt; and &lt;code&gt;unbound-control-setup&lt;/code&gt;. You will also
need to change a line in &lt;code&gt;/etc/config/unbound&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
option unbound_control &amp;#39;0&amp;#39;
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;becomes&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
option unbound_control &amp;#39;1&amp;#39;
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A word of warning: there is another section on &amp;ldquo;Unbound and odhcpd&amp;rdquo; which
tries to cut out dnsmasq completely. However, when I tried to set this up,
I got myself into a lot of trouble (had to reset OpenWRT, re-install any extra
software packages, and restore configuration from backup). It is also possible that if you mess up
the configuration for the &amp;ldquo;Parallel dnsmasq&amp;rdquo; method, you could end up in a
similar error state and have to start over. Please be careful when doing this
and don&amp;rsquo;t change anything you&amp;rsquo;re not supposed to.&lt;/p&gt;
&lt;p&gt;Now, moving on to adblock, which should be &lt;strong&gt;much&lt;/strong&gt; simpler to setup. First,
install &lt;code&gt;luci-app-adblock&lt;/code&gt; and refresh. Navigate to &amp;ldquo;Services -&amp;gt; Adblock&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock.png&#34; alt=&#34;Services -&amp;gt; Adblock&#34;&gt;&lt;/p&gt;
&lt;p&gt;Check the settings at the bottom. The only thing you need to get going is
to go to the &amp;ldquo;Blocklist Sources&amp;rdquo; tab and choose your blocklists.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_blocklist.png&#34; alt=&#34;Adblock: Blacklist sources&#34;&gt;&lt;/p&gt;
&lt;p&gt;The
&lt;a href=&#34;https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md&#34;&gt;adblock readme&lt;/a&gt;
has some more info on what each list is. After that,
make sure &amp;ldquo;Enabled&amp;rdquo; is checked under the &amp;ldquo;General Settings&amp;rdquo; tab:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_enable.png&#34; alt=&#34;Adblock: enable&#34;&gt;&lt;/p&gt;
&lt;p&gt;and click the &amp;ldquo;Refresh&amp;rdquo; button above:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_refresh.png&#34; alt=&#34;Adblock: refresh&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then you&amp;rsquo;re good to go; adblock should work out of the box with unbound; cheers!&lt;/p&gt;
&lt;p&gt;ADDENDUM: Another word of warning: once you&amp;rsquo;ve setup adblock, it will download
the blocklists, merge them into a single file at &lt;code&gt;/var/lib/unbound/adb_list.overall&lt;/code&gt;,
and try to restart unbound. I recommend not trying to view/interact with adblock
or unbound during this restart, which can take anywhere from 30 seconds - 2 minutes.
Just leave them alone in LuCI for a little bit&amp;hellip;&lt;/p&gt;
</description>
</item>
<item>
<title>Hello doas</title>
<link>https://beckmeyer.us/posts/hello_doas/</link>
<pubDate>Sat, 30 Jan 2021 15:15:55 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/hello_doas/</guid>
<description>&lt;p&gt;Today, I switched my workstation from &lt;code&gt;sudo&lt;/code&gt; to &lt;code&gt;doas&lt;/code&gt;. I&amp;rsquo;m running Void Linux,
and the process was fairly easy.&lt;/p&gt;
&lt;p&gt;First, I needed to figure out how to remove &lt;code&gt;sudo&lt;/code&gt; (yes, I realize I could have
installed &lt;code&gt;doas&lt;/code&gt; first, then removed &lt;code&gt;sudo&lt;/code&gt;, but I decided to do it the hard way.)
As it turns out, the &lt;a href=&#34;https://docs.voidlinux.org/xbps/advanced-usage.html#ignoring-packages&#34;&gt;advanced usage section of the XBPS manual&lt;/a&gt; details how to use the &lt;code&gt;ignorepkg&lt;/code&gt; entry in xbps.d with nothing
other than this exact use case! I created the file &lt;code&gt;/etc/xbps.d/20-ignorepkg-sudo.conf&lt;/code&gt; with contents&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ignorepkg=sudo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then ran &lt;code&gt;sudo xbps-remove sudo&lt;/code&gt; (an ironic command).&lt;/p&gt;
&lt;p&gt;After that, because I was stupid and removed &lt;code&gt;sudo&lt;/code&gt; before I had set up &lt;code&gt;doas&lt;/code&gt;,
I had to use plain-old &lt;code&gt;su&lt;/code&gt; to change to the root user and run &lt;code&gt;xi opendoas&lt;/code&gt;. I also
configured &lt;code&gt;doas&lt;/code&gt; in &lt;code&gt;/etc/doas.conf&lt;/code&gt; with the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# see doas.conf(5) for configuration details
permit nopass keepenv :admin
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I ran &lt;code&gt;groupadd admin&lt;/code&gt;, &lt;code&gt;usermod -aG admin joel&lt;/code&gt;, and then logged out so that my
user account would see the new group perms.&lt;/p&gt;
&lt;p&gt;And just like that, I can now run &lt;code&gt;doas xbps-install ...&lt;/code&gt; and all of my other commands,
just substituting &lt;code&gt;doas&lt;/code&gt; for &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The one thing I immediately missed was &lt;code&gt;sudoedit&lt;/code&gt;. Before I accidentally tried
to use &lt;code&gt;sudo&lt;/code&gt; for the first time, I had already accidentally tried to run &lt;code&gt;sudoedit&lt;/code&gt;
&lt;em&gt;at least&lt;/em&gt; 5 times. I had to fix this. I saw a discussion on Reddit where &lt;a href=&#34;https://www.reddit.com/r/linux/comments/l6y7nv/is_doas_a_good_alternative_to_sudo/gl4hs42?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3&#34;&gt;one user
suggested&lt;/a&gt; writing a script to replace the &lt;code&gt;sudoedit&lt;/code&gt; functionality.
I quickly starting hacking together something like that. I started with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/tmp_file
$EDITOR /tmp/doasedit/tmp_file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And quickly ran into my first road-block. The script is going to have to change
the permissions of that file before the user can edit it. But if the script changes
the permissions, how can I restore it to the original location with the right
permissions? &lt;code&gt;cp /tmp/doasedit/tmp_file $1&lt;/code&gt; won&amp;rsquo;t work. I thought about just using
cat to overwrite the file contents in-place (&lt;code&gt;cat /tmp/doasedit/tmp_file &amp;gt; $1&lt;/code&gt;).
That &lt;em&gt;could&lt;/em&gt; create some issues if a program has the file open. Instead, a better option
is to create two copies of the file&amp;ndash;one for editing, and one for preserving file
attributes:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $1 /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/file $1
rm -rf /tmp/doasedit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, the issue with this is that it only works with absolute paths.
I want to make it work for relative paths as well. I&amp;rsquo;m going to take advantage
of &lt;code&gt;realpath&lt;/code&gt;, which is part of the &lt;code&gt;coreutils&lt;/code&gt; package from Void. As a bonus, this
will also take care of the edge case where the given file is a symlink (IIRC,
&lt;code&gt;sudoedit&lt;/code&gt; didn&amp;rsquo;t follow symlinks, so I may be diverging here):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
srcfile=&amp;#34;$(realpath $1)&amp;#34;
doas cp $srcfile /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $srcfile /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/file $srcfile
rm -rf /tmp/doasedit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point, it works&amp;hellip;okay-ish. It can only be used in one instance currently
since I hard-coded &lt;code&gt;/tmp/doasedit/file&lt;/code&gt; and &lt;code&gt;/tmp/doasedit/edit&lt;/code&gt;, but that&amp;rsquo;s easily fixed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
destfile_pfx=&amp;#34;$(cat /dev/urandom | tr -cd &amp;#39;a-f0-9&amp;#39; | head -c 32)&amp;#34;
while [ -d &amp;#34;/tmp/doasedit/$destfile_pfx&amp;#34; ]; do
destfile_pfx=&amp;#34;$(cat /dev/urandom | tr -cd &amp;#39;a-f0-9&amp;#39; | head -c 32)&amp;#34;
done
mkdir -p /tmp/doasedit/$destfile_pfx
srcfile=&amp;#34;$(realpath $1)&amp;#34;
doas cp $srcfile /tmp/doasedit/$destfile_pfx/edit
doas chown -R $USER:$USER /tmp/doasedit/$destfile_pfx/edit
doas cp $srcfile /tmp/doasedit/$destfile_pfx/file
$EDITOR /tmp/doasedit/$destfile_pfx/edit
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
rm -rf /tmp/doasedit/$destfile_pfx
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point, the only thing missing is the check to see if the file was actually
edited:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&amp;gt;/dev/null
if cmp -s &amp;#34;/tmp/doasedit/$destfile_pfx/file&amp;#34; &amp;#34;$srcfile&amp;#34;; then
echo &amp;#34;Skipping write; no changes.&amp;#34;
else
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
fi
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I put this in a &lt;a href=&#34;https://github.com/AluminumTank/doasedit&#34;&gt;repo on GitHub&lt;/a&gt; if
anyone is interested. I know that a major
weakness of this script is the number of times it calls &lt;code&gt;doas&lt;/code&gt;, which could
break flows where password is required every time &lt;code&gt;doas&lt;/code&gt; is run.&lt;/p&gt;
</description>
</item>
<item>
<title>Volatile Mediums</title>
<link>https://beckmeyer.us/posts/volatile_mediums/</link>
<pubDate>Fri, 29 Jan 2021 23:36:00 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/volatile_mediums/</guid>
<description>&lt;p&gt;I&amp;rsquo;ve recently been thinking a lot about storage mediums [1] &amp;ndash; especially in the long-term.&lt;/p&gt;
&lt;p&gt;Technology has made a lot of progress. Digital storage mediums started out only being
able to store &lt;a href=&#34;https://en.wikipedia.org/wiki/Tape_drive&#34;&gt;224KB on a tape drive&lt;/a&gt;
for an average lifetime of &lt;a href=&#34;https://blog.storagecraft.com/data-storage-lifespan/&#34;&gt;&lt;em&gt;up to&lt;/em&gt; 30 years&lt;/a&gt;.
Now, we can store terrabytes of data on hard drives and solid-state drives. However,
no one ever really answered the question about long-term storage.&lt;/p&gt;
&lt;p&gt;(Note: the following is based off an assumption that the storage medium is only
being used to make backups or archive data. The device itself could be unplugged and stored
when no backup is in progress.)&lt;/p&gt;
&lt;p&gt;Even though &lt;em&gt;theoretically&lt;/em&gt; hard drives could store data for 20+ years, random bit flips, drive
failure, etc. all make hard drives too volatile of an option. As always, of course
redundancy takes away some of these issues.&lt;/p&gt;
&lt;p&gt;SSDs are in an even worse position: they cost significantly more than hard drives
per TB right now, and last I heard, there were still issues with bit fade when
unpowered.&lt;/p&gt;
&lt;p&gt;CD/DVD is sounding a lot better, but there are some serious issues here too.
Variable quality directly impacts the storage lifetime. Physically storing the
discs is a lot more risky since the disc itself doesn&amp;rsquo;t have as much built-in
protection as a hard drive or SSD has. You&amp;rsquo;ll need a much larger quantity to
store the terrabytes of data that you can easily dump on one hard drive. And finally, life
expectancy is still fairly low &amp;ndash; while manufacturers of recordable discs (the &amp;lsquo;R&amp;rsquo; in CD-R, DVD-R, etc.)
claim life expectancies of 100-200 (!) years under optimal conditions, others are &lt;em&gt;slightly&lt;/em&gt; more conservative,
&lt;a href=&#34;https://www.clir.org/pubs/reports/pub121/sec4/&#34;&gt;giving an estimate of 30 years&lt;/a&gt;.
Oh, and remember how I mentioned this is for recordable discs? That means they&amp;rsquo;re single write.
The random access (RW - CD-RW, DVD-RW, etc.) discs have even lower life expectancies.&lt;/p&gt;
&lt;p&gt;All in all, humanity has not gotten very far with the digital storage medium.
All of these life expectancies have an inconsequential variance when we zoom out
to the century view of history.&lt;/p&gt;
&lt;p&gt;[1] And no, I&amp;rsquo;m not talking about the kind you pay to see your dead great-great-aunt to figure out if
you&amp;rsquo;re actually related to George Washington.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is intended to be the beginning of a learning series/personal study on the issues surrounding
information preservation, digital permanence, and their related issues.&lt;/em&gt;&lt;/p&gt;
</description>
</item>
</channel>
</rss>

View File

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Moving Back To OpenSSL &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Moving Back To OpenSSL</h1>
<div class="title-header-date">
<time>Monday, March 22, 2021</time>
</div>
</div>
<p>Void Linux <a href="https://voidlinux.org/news/2021/02/OpenSSL.html">recently announced</a>
that they were going to move back to OpenSSL after originally <a href="https://voidlinux.org/news/2014/08/LibreSSL-by-default.html">switching to
LibreSSL in 2014</a>.
It seems that there are a lot of things at play here.</p>
<p>It seems that the main focus of the recent announcement is on the maintainability
and other difficulties of not using the <em>one true SSL/TLS library</em>. To me,
this pragmatically makes sense. However, every time something like this happens
I get this lingering feeling of worry&hellip;</p>
<p>Microsoft moving their default browser from their own implementation to
Chromium, and other browsers following suit.</p>
<p>Linux distributions moving <em>en masse</em> to <strong>systemd</strong>.</p>
<p>Distributed email being slowly crushed and killed by Google with GMail.</p>
<p>And many other examples that aren&rsquo;t immediately coming to mind.</p>
<p>I think it&rsquo;s great that OpenSSL as a project has made a comeback from the
Heartbleed fiasco, and that it is apparently more actively developed nowadays,
but the fact that we are even at the point of moving back to OpenSSL due to
difficulties with building software is worrying. To me, it looks like a
symptom of software becoming too entrenched and dependent on a single piece
of software.</p>
<p>This kind of accusation coming from anyone is going to be hypocritical, since
we all depend on Linux, X11, Wayland, systemd, or some common piece of software
that we take for granted and don&rsquo;t lose sleep over. However, I think what&rsquo;s
categorically different about this one is that an alternative was adopted,
worked on, but eventually &ldquo;failed&rdquo; (at least for Void, but also possibly for
Linux as well).</p>
<p>I don&rsquo;t know what the fix for this specific issue would be. I&rsquo;m not nearly
familiar enough with SSL/TLS or how you would develop software to be agnostic
of dependencies like this. But I think in order to honor principles like
the Unix philosophy, the KISS principle, and countless others, we need to
figure out a way to be more modular for dependency issues like this.</p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>OpenWRT &#43; Unbound &#43; adblock &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>OpenWRT &#43; Unbound &#43; adblock</h1>
<div class="title-header-date">
<time>Friday, February 5, 2021</time>
</div>
</div>
<p>I decided to do some work on my Linksys WRT32X running OpenWRT to make it a
little more useful.</p>
<p><a href="https://nlnetlabs.nl/projects/unbound/about/">Unbound</a> is a DNS
resolver which I like because it&rsquo;s recursive, meaning it directly queries the
root servers instead of relying on existing DNS servers run by Google,
Cloudflare, your ISP, or the like. I already have it running on several of my
servers and computers, but I figured it would be great if everything on my
network can use Unbound and be, well, <em>unbound</em> from all of those intermediary
DNS servers.</p>
<p>Luckily, OpenWRT already has Unbound packaged, and also has a useful LuCI app
that goes with it (LuCI is the graphical web interface that comes with OpenWRT).
All I had to do was install <code>luci-app-unbound</code>, which pulls in all of the
necessary dependencies to run unbound.</p>
<p><img src="/luci_software.png" alt="LuCI: Software"></p>
<p><img src="/luci_install.png" alt="LuCI: Install"></p>
<p>After that finished installing, I
refreshed LuCI/OpenWRT and went to &ldquo;Services&rdquo; on the top, and there it is!</p>
<p><img src="/luci_services.png" alt="LuCI: Services -&gt; Recursive DNS"></p>
<p>At this point, you&rsquo;ll have to get your hands dirty. You can either dig through
some LuCI menus or SSH in and make some edits. For reference, I&rsquo;m using
<a href="https://github.com/openwrt/packages/blob/openwrt-19.07/net/unbound/files/README.md#parallel-dnsmasq">&ldquo;Parallel dnsmasq&rdquo;</a> section from the README for unbound in the OpenWRT packages (which
has a lot of other useful information as well!). Essentially, I made the edits
to <code>/etc/config/unbound</code> and <code>/etc/config/dhcp</code> after SSH&rsquo;ing in. However, you
can make the same edits through LuCI.</p>
<p>For the <code>/etc/config/unbound</code> edits, you can make the edits to the file in
LuCI directly at &ldquo;Services -&gt; Recursive DNS -&gt; Files -&gt; Edit: UCI&rdquo;:</p>
<p><img src="/unbound_config.png" alt="LuCI: Edit /etc/config/unbound"></p>
<p>For the <code>/etc/config/dhcp</code> edits, you can make the edits by finding the same
fields under &ldquo;Network -&gt; DHCP and DNS&rdquo;:</p>
<p><img src="/dhcp_config.png" alt="LuCI: Edit DHCP and DNS Settings"></p>
<p>However, the field names are different from the lines in the config, so they
would need to be researched to determine which fields in LuCI map to which
lines in <code>/etc/config/dhcp</code>.</p>
<p>At this point (or maybe after restarting unbound and dnsmasq, which is a lot
easier using SSH and <code>/etc/init.d ... restart</code> as well), OpenWRT should now
be using unbound for resolving all DNS lookups, while dnsmasq is only used for
DHCP-DNS.</p>
<p>Bonus: you can also enable a nice status dashboard in LuCI under
&ldquo;Services -&gt; Recursive DNS -&gt; Status&rdquo;, but this requires installing several more
software packages: <code>unbound-control</code> and <code>unbound-control-setup</code>. You will also
need to change a line in <code>/etc/config/unbound</code>:</p>
<pre tabindex="0"><code>...
option unbound_control &#39;0&#39;
...
</code></pre><p>becomes</p>
<pre tabindex="0"><code>...
option unbound_control &#39;1&#39;
...
</code></pre><p>A word of warning: there is another section on &ldquo;Unbound and odhcpd&rdquo; which
tries to cut out dnsmasq completely. However, when I tried to set this up,
I got myself into a lot of trouble (had to reset OpenWRT, re-install any extra
software packages, and restore configuration from backup). It is also possible that if you mess up
the configuration for the &ldquo;Parallel dnsmasq&rdquo; method, you could end up in a
similar error state and have to start over. Please be careful when doing this
and don&rsquo;t change anything you&rsquo;re not supposed to.</p>
<p>Now, moving on to adblock, which should be <strong>much</strong> simpler to setup. First,
install <code>luci-app-adblock</code> and refresh. Navigate to &ldquo;Services -&gt; Adblock&rdquo;:</p>
<p><img src="/adblock.png" alt="Services -&gt; Adblock"></p>
<p>Check the settings at the bottom. The only thing you need to get going is
to go to the &ldquo;Blocklist Sources&rdquo; tab and choose your blocklists.</p>
<p><img src="/adblock_blocklist.png" alt="Adblock: Blacklist sources"></p>
<p>The
<a href="https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md">adblock readme</a>
has some more info on what each list is. After that,
make sure &ldquo;Enabled&rdquo; is checked under the &ldquo;General Settings&rdquo; tab:</p>
<p><img src="/adblock_enable.png" alt="Adblock: enable"></p>
<p>and click the &ldquo;Refresh&rdquo; button above:</p>
<p><img src="/adblock_refresh.png" alt="Adblock: refresh"></p>
<p>Then you&rsquo;re good to go; adblock should work out of the box with unbound; cheers!</p>
<p>ADDENDUM: Another word of warning: once you&rsquo;ve setup adblock, it will download
the blocklists, merge them into a single file at <code>/var/lib/unbound/adb_list.overall</code>,
and try to restart unbound. I recommend not trying to view/interact with adblock
or unbound during this restart, which can take anywhere from 30 seconds - 2 minutes.
Just leave them alone in LuCI for a little bit&hellip;</p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>The Generation Ship Problem &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>The Generation Ship Problem</h1>
<div class="title-header-date">
<time>Friday, March 19, 2021</time>
</div>
</div>
<p>After talking about the hardware and software problems of
digital permanence, I&rsquo;m struck by a classical Sci-Fi
motif with a conundrum: the <strong>Generation Ship</strong>; a ship
outfitted with all of the technology, infrastructure, and
storage to support lightyear-scale human travel.</p>
<p>But what about that technology on the ship? If we build
one of these ships, we need to accomplish one of several
things in regards to information storage:</p>
<h3 id="1-innovate-to-the-point-where-the-lifetime-of-the-storage-devices-is-able-to-support-lightyear-scale-travel">1. Innovate to the point where the lifetime of the storage devices is able to support lightyear scale travel.<a href="#1-innovate-to-the-point-where-the-lifetime-of-the-storage-devices-is-able-to-support-lightyear-scale-travel" class="heading-anchor" aria-label="Anchor"><img src="/images/chain-link.svg" class="color-adapting-image" height="20"></a></h3>
<p>That&rsquo;s a tall order, given where we are right now with
physical storage devices. As I mentioned in one of my
previous posts, the average lifetime of physical storage
devices is less than 100 years, no matter if it is a hard
drive, solid-state drive, etc.</p>
<h3 id="2-provide-the-facility-to-create-new-storage-devices-to-replace-the-failing-old-ones">2. Provide the facility to create new storage devices to replace the failing old ones.<a href="#2-provide-the-facility-to-create-new-storage-devices-to-replace-the-failing-old-ones" class="heading-anchor" aria-label="Anchor"><img src="/images/chain-link.svg" class="color-adapting-image" height="20"></a></h3>
<p>Again, in my mind a tall order, since it would require
facilities on the ship to create storage devices. The
problem of having materials is at least solvable by just
sending the ship with all of the materials it needs in
advance.</p>
<h3 id="3-provide-the-facility-to-revitalize-storage-devices">3. Provide the facility to revitalize storage devices.<a href="#3-provide-the-facility-to-revitalize-storage-devices" class="heading-anchor" aria-label="Anchor"><img src="/images/chain-link.svg" class="color-adapting-image" height="20"></a></h3>
<p>One of the main reasons I&rsquo;m even thinking about this is
because I&rsquo;m an individual with limited resources.
Accordingly, I think about things in terms of
broken/working, on/off, etc. With enough resources, there
is a much larger chance of being able to repair, re-purpose,
and otherwise revitalize storage devices, increasing their
lifetime. E.g., if the only failure in the hard drive is the
control circuit, that is an &ldquo;easy enough&rdquo; repair.</p>
<p>I like to toy with the idea of a generation ship a lot in
my head, but I think it&rsquo;s really fun to think about the
technical possibilities and needs of a ship like this.</p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,151 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Volatile Formats &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Volatile Formats</h1>
<div class="title-header-date">
<time>Thursday, March 18, 2021</time>
</div>
</div>
<p><em>Note: This is a continuation of the thoughts I started
thinking about in my <a href="https://beckmeyer.us/posts/volatile_mediums/">Volatile Mediums</a> blog post.</em></p>
<p>The next level up from physical mediums for data storage
is the <em>way</em> that the data is stored. In the digital age,
we have a plethora of formats for storing information.
For me, one of the most interesting areas of information
storage is the analog-digital space.</p>
<p>The fundamental problem of storing audio, video, and other
replications of the physical world is that there is so much
information that we can collect with sensors
(think microphones, video cameras, etc.). It would be great
if we could go get the best camera and microphone out there,
record whatever people record these days, and have that
exact physical experience &ldquo;played back&rdquo; for us on a screen
and speaker/headphones.</p>
<p>Unfortunately, there are several problems with this. Among
those is the actual design of the sensor. It takes a lot of
careful thought, engineering, and the like to create a truly
good microphone or camera. And after all of that, this sensor
will cost something. Hopefully, that cost will correspond to
the actual technical ability of that sensor! In any case,
not everyone can have the best camera or microphone due to
any number of constraints, not just those listed above.</p>
<p>The second problem is the sampling issue. The sensor will
create some sort of output that can then be measured, or
<strong>sampled</strong>, by an ADC (analog-to-digital converter). The
very word &ldquo;sample&rdquo; belies what this nearly magical box is
doing: it is only looking at certain portions or timestamps
of the analog signal. Granted, the time between samples
can be very small (e.g. 44.1 kHz is a fairly common sample
rate for audio), but there is still some loss of signal.
Once the ADC creates these samples, it converts them into
a digital format (something that can be stored on a
CD, hard drive, thumb drive, etc.).</p>
<p>The third problem is the encoding issue. The ADC creates all
of these samples, but we need to start thinking about storage
limitations. Storing the raw output of a sensor can take a
lot of space: an average album length (40 minutes) could
easily take 400MB of space! Now, again, the physical storage
space is moving in the upward direction to combat this, but
storing isn&rsquo;t the only problem. One prime issue is internet
bandwidth.</p>
<p>The solution to this is compression, like a ZIP file. It
makes big files smaller by doing some fancy math tricks
that can be reversed by a computer to reconstruct the
original file. However, for audio/video files, another level
of compression exists which actually gets rid of some of the
information in the original file to save more space. This
is called &ldquo;lossy&rdquo; compression, as opposed to &ldquo;lossless&rdquo;
compression.</p>
<p>Great! We&rsquo;ve found a way to save more space. The problem
with lossy compression is that we have to decide which
information to throw away. Usually, this is frequencies
that the average human ear/eye can&rsquo;t perceive. But, let&rsquo;s
just say that some compression is a bit too &ldquo;greedy&rdquo; when it
comes to saving space and starts to cut into the band of
frequencies that can be perceived. Also note that
the design of these compression algorithms is an artform
and takes lots of careful consideration.</p>
<p>The final problem I want to mention is the codec problem.
There are many different codecs available today, and for
each and every one of them to be useful, you need to have a
way to decode each and every one of them. Unfortunately,
this is sometimes very difficult.</p>
<p>It could be a licensing
issue, where you don&rsquo;t have the correct software installed
or purchased to actually decode that file on your computer.</p>
<p>Or it could be a physical constraints issue, where your
computer isn&rsquo;t powerful enough to decode the file at a fast
enough rate for you to view it without stuttering,
buffering, etc.</p>
<p>Third, it could be a personal preference. Some people
have much more sensitive eyes/ears and need to have formats
that are more <strong>transparent</strong>, meaning that the lossy file
is perceptually identical to the source it was encoded from.</p>
<p>With all of these issues at play, I think there are several
key points to make:</p>
<h3 id="1-codecs-need-to-be-freely-available-for-widespread-use-with-no-strings-attached">1. Codecs need to be freely available for widespread use with no strings attached.<a href="#1-codecs-need-to-be-freely-available-for-widespread-use-with-no-strings-attached" class="heading-anchor" aria-label="Anchor"><img src="/images/chain-link.svg" class="color-adapting-image" height="20"></a></h3>
<p>Can&rsquo;t stress this one enough: we need to make sure we are
doing everything possible to not let our information die
when a corporation or individual makes a decision that
impacts the &ldquo;who, what, where, when, and how&rdquo; of their codec
usage.</p>
<h3 id="2-lossless-compression-is-good-but-it-is-not-the-only-thing-we-need">2. Lossless compression is good, but it is not the only thing we need.<a href="#2-lossless-compression-is-good-but-it-is-not-the-only-thing-we-need" class="heading-anchor" aria-label="Anchor"><img src="/images/chain-link.svg" class="color-adapting-image" height="20"></a></h3>
<p>We need to remember that not everyone has the ability to use
lossless codecs, whether that be because of internet
bandwidth limitations, storage limitation, or the like.
Instead, we need to continue to innovate in the lossy
compression space to narrow the perceptual gap between lossy
and lossless more and more.</p>
<h3 id="3-a-codec-should-never-become-obsolete">3. A codec should never become obsolete.<a href="#3-a-codec-should-never-become-obsolete" class="heading-anchor" aria-label="Anchor"><img src="/images/chain-link.svg" class="color-adapting-image" height="20"></a></h3>
<p>This one may sound weird, but the fact is, if we&rsquo;re talking
about long-term storage of information, we can&rsquo;t let codecs
die, since there may come a day where we need a codec to
decode great-grandpa&rsquo;s album that never made it big.</p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Volatile Mediums &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Volatile Mediums</h1>
<div class="title-header-date">
<time>Friday, January 29, 2021</time>
</div>
</div>
<p>I&rsquo;ve recently been thinking a lot about storage mediums [1] &ndash; especially in the long-term.</p>
<p>Technology has made a lot of progress. Digital storage mediums started out only being
able to store <a href="https://en.wikipedia.org/wiki/Tape_drive">224KB on a tape drive</a>
for an average lifetime of <a href="https://blog.storagecraft.com/data-storage-lifespan/"><em>up to</em> 30 years</a>.
Now, we can store terrabytes of data on hard drives and solid-state drives. However,
no one ever really answered the question about long-term storage.</p>
<p>(Note: the following is based off an assumption that the storage medium is only
being used to make backups or archive data. The device itself could be unplugged and stored
when no backup is in progress.)</p>
<p>Even though <em>theoretically</em> hard drives could store data for 20+ years, random bit flips, drive
failure, etc. all make hard drives too volatile of an option. As always, of course
redundancy takes away some of these issues.</p>
<p>SSDs are in an even worse position: they cost significantly more than hard drives
per TB right now, and last I heard, there were still issues with bit fade when
unpowered.</p>
<p>CD/DVD is sounding a lot better, but there are some serious issues here too.
Variable quality directly impacts the storage lifetime. Physically storing the
discs is a lot more risky since the disc itself doesn&rsquo;t have as much built-in
protection as a hard drive or SSD has. You&rsquo;ll need a much larger quantity to
store the terrabytes of data that you can easily dump on one hard drive. And finally, life
expectancy is still fairly low &ndash; while manufacturers of recordable discs (the &lsquo;R&rsquo; in CD-R, DVD-R, etc.)
claim life expectancies of 100-200 (!) years under optimal conditions, others are <em>slightly</em> more conservative,
<a href="https://www.clir.org/pubs/reports/pub121/sec4/">giving an estimate of 30 years</a>.
Oh, and remember how I mentioned this is for recordable discs? That means they&rsquo;re single write.
The random access (RW - CD-RW, DVD-RW, etc.) discs have even lower life expectancies.</p>
<p>All in all, humanity has not gotten very far with the digital storage medium.
All of these life expectancies have an inconsequential variance when we zoom out
to the century view of history.</p>
<p>[1] And no, I&rsquo;m not talking about the kind you pay to see your dead great-great-aunt to figure out if
you&rsquo;re actually related to George Washington.</p>
<p><em>This is intended to be the beginning of a learning series/personal study on the issues surrounding
information preservation, digital permanence, and their related issues.</em></p>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

54
public/sitemap.xml Normal file
View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://beckmeyer.us/posts/consistency/</loc>
<lastmod>2021-04-04T00:00:00-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/tags/foss/</loc>
<lastmod>2021-04-04T00:00:00-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/</loc>
<lastmod>2021-04-04T00:00:00-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/</loc>
<lastmod>2021-04-04T00:00:00-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/tags/</loc>
<lastmod>2021-04-04T00:00:00-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/better/</loc>
<lastmod>2021-04-03T22:15:44-04:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/tags/poetry/</loc>
<lastmod>2021-04-03T22:15:44-04:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/tags/linux/</loc>
<lastmod>2021-03-22T11:00:00-04:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/moving_back_to_openssl/</loc>
<lastmod>2021-03-22T11:00:00-04:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/the_generation_ship_problem/</loc>
<lastmod>2021-03-19T15:00:00-04:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/tags/volatile-mediums/</loc>
<lastmod>2021-03-19T15:00:00-04:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/volatile_formats/</loc>
<lastmod>2021-03-18T14:24:00-04:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/openwrt_plus_unbound/</loc>
<lastmod>2021-02-05T19:03:15-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/hello_doas/</loc>
<lastmod>2021-01-30T15:15:55-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/posts/volatile_mediums/</loc>
<lastmod>2021-01-29T23:36:00-05:00</lastmod>
</url><url>
<loc>https://beckmeyer.us/categories/</loc>
</url><url>
<loc>https://beckmeyer.us/contact/</loc>
</url>
</urlset>

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>FOSS &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/tags/foss/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>FOSS</h1>
</div>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>FOSS on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/tags/foss/</link>
<description>Recent content in FOSS on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster>
<lastBuildDate>Sun, 04 Apr 2021 00:00:00 -0500</lastBuildDate><atom:link href="https://beckmeyer.us/tags/foss/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Consistency</title>
<link>https://beckmeyer.us/posts/consistency/</link>
<pubDate>Sun, 04 Apr 2021 00:00:00 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/consistency/</guid>
<description>&lt;p&gt;I&amp;rsquo;ve seen a lot of talk about this stuff:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Check out my FOSS project (hosted on Github)&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Wayland is a great innovation and boon to the community! Also, there are very few tools/alternatives available yet for your favorite X11 tool!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;We love open source! Also, we develop the most popular proprietary operating system!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Do as I say, not as I do.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We love to poke fun at and expose this kind of stuff, which is all fine and
dandy. I think it&amp;rsquo;s an interesting (and important) part of our humanity that
this kind of thing bugs us so much. Think about that last point, which at least
in my experience, is something I &lt;em&gt;loved&lt;/em&gt; to fault authorities for.&lt;/p&gt;
&lt;p&gt;Hypocrisy is fun and also infuriating to uncover in others, but how often do
we do a &amp;ldquo;consistency check&amp;rdquo; on ourselves? Is what we are saying evidenced by
the rest of our actions?&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a hard look sometimes. I know it is for me, since I&amp;rsquo;m &lt;strong&gt;very&lt;/strong&gt; quick
to judge others, but don&amp;rsquo;t often think about how I fail at my own principles.&lt;/p&gt;
&lt;p&gt;Example: As a FOSS advocate, it&amp;rsquo;s nearly natural to assume that everything will
be better and easier with more people using FOSS. When evidence seems to point
to the contrary (e.g. fighting with Matrix/Element to get it working for my
family and friends), I don&amp;rsquo;t own up to the fact that it isn&amp;rsquo;t easier, and that
is an actual problem.&lt;/p&gt;
&lt;p&gt;If we truly want to build a welcoming and wholesome community, let&amp;rsquo;s be careful
to do a consistency check to make sure nothing smells foul.&lt;/p&gt;
</description>
</item>
</channel>
</rss>

68
public/tags/index.html Normal file
View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Tags &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/tags/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Tags</h1>
</div>
<article class="all-list">
<div class="title-list">
<h3><a href="/contact/">Contact</a></h3>
<div class="title-list-date">
</div>
</div>
<div class="body-list">
<p></p>
<p>
Joel Beckmeyer
Matrix: @joel:thebeckmeyers.xyz
Fediverse: @TinfoilSubmarine@social.beckmeyer.us
</p>
</div>
</article>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

13
public/tags/index.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Tags on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/tags/</link>
<description>Recent content in Tags on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster>
<lastBuildDate>Sun, 04 Apr 2021 00:00:00 -0500</lastBuildDate><atom:link href="https://beckmeyer.us/tags/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Linux &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/tags/linux/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Linux</h1>
</div>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

244
public/tags/linux/index.xml Normal file
View File

@ -0,0 +1,244 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Linux on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/tags/linux/</link>
<description>Recent content in Linux on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster>
<lastBuildDate>Mon, 22 Mar 2021 11:00:00 -0400</lastBuildDate><atom:link href="https://beckmeyer.us/tags/linux/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Moving Back To OpenSSL</title>
<link>https://beckmeyer.us/posts/moving_back_to_openssl/</link>
<pubDate>Mon, 22 Mar 2021 11:00:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/moving_back_to_openssl/</guid>
<description>&lt;p&gt;Void Linux &lt;a href=&#34;https://voidlinux.org/news/2021/02/OpenSSL.html&#34;&gt;recently announced&lt;/a&gt;
that they were going to move back to OpenSSL after originally &lt;a href=&#34;https://voidlinux.org/news/2014/08/LibreSSL-by-default.html&#34;&gt;switching to
LibreSSL in 2014&lt;/a&gt;.
It seems that there are a lot of things at play here.&lt;/p&gt;
&lt;p&gt;It seems that the main focus of the recent announcement is on the maintainability
and other difficulties of not using the &lt;em&gt;one true SSL/TLS library&lt;/em&gt;. To me,
this pragmatically makes sense. However, every time something like this happens
I get this lingering feeling of worry&amp;hellip;&lt;/p&gt;
&lt;p&gt;Microsoft moving their default browser from their own implementation to
Chromium, and other browsers following suit.&lt;/p&gt;
&lt;p&gt;Linux distributions moving &lt;em&gt;en masse&lt;/em&gt; to &lt;strong&gt;systemd&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Distributed email being slowly crushed and killed by Google with GMail.&lt;/p&gt;
&lt;p&gt;And many other examples that aren&amp;rsquo;t immediately coming to mind.&lt;/p&gt;
&lt;p&gt;I think it&amp;rsquo;s great that OpenSSL as a project has made a comeback from the
Heartbleed fiasco, and that it is apparently more actively developed nowadays,
but the fact that we are even at the point of moving back to OpenSSL due to
difficulties with building software is worrying. To me, it looks like a
symptom of software becoming too entrenched and dependent on a single piece
of software.&lt;/p&gt;
&lt;p&gt;This kind of accusation coming from anyone is going to be hypocritical, since
we all depend on Linux, X11, Wayland, systemd, or some common piece of software
that we take for granted and don&amp;rsquo;t lose sleep over. However, I think what&amp;rsquo;s
categorically different about this one is that an alternative was adopted,
worked on, but eventually &amp;ldquo;failed&amp;rdquo; (at least for Void, but also possibly for
Linux as well).&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know what the fix for this specific issue would be. I&amp;rsquo;m not nearly
familiar enough with SSL/TLS or how you would develop software to be agnostic
of dependencies like this. But I think in order to honor principles like
the Unix philosophy, the KISS principle, and countless others, we need to
figure out a way to be more modular for dependency issues like this.&lt;/p&gt;
</description>
</item>
<item>
<title>OpenWRT &#43; Unbound &#43; adblock</title>
<link>https://beckmeyer.us/posts/openwrt_plus_unbound/</link>
<pubDate>Fri, 05 Feb 2021 19:03:15 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/openwrt_plus_unbound/</guid>
<description>&lt;p&gt;I decided to do some work on my Linksys WRT32X running OpenWRT to make it a
little more useful.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://nlnetlabs.nl/projects/unbound/about/&#34;&gt;Unbound&lt;/a&gt; is a DNS
resolver which I like because it&amp;rsquo;s recursive, meaning it directly queries the
root servers instead of relying on existing DNS servers run by Google,
Cloudflare, your ISP, or the like. I already have it running on several of my
servers and computers, but I figured it would be great if everything on my
network can use Unbound and be, well, &lt;em&gt;unbound&lt;/em&gt; from all of those intermediary
DNS servers.&lt;/p&gt;
&lt;p&gt;Luckily, OpenWRT already has Unbound packaged, and also has a useful LuCI app
that goes with it (LuCI is the graphical web interface that comes with OpenWRT).
All I had to do was install &lt;code&gt;luci-app-unbound&lt;/code&gt;, which pulls in all of the
necessary dependencies to run unbound.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_software.png&#34; alt=&#34;LuCI: Software&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_install.png&#34; alt=&#34;LuCI: Install&#34;&gt;&lt;/p&gt;
&lt;p&gt;After that finished installing, I
refreshed LuCI/OpenWRT and went to &amp;ldquo;Services&amp;rdquo; on the top, and there it is!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/luci_services.png&#34; alt=&#34;LuCI: Services -&amp;gt; Recursive DNS&#34;&gt;&lt;/p&gt;
&lt;p&gt;At this point, you&amp;rsquo;ll have to get your hands dirty. You can either dig through
some LuCI menus or SSH in and make some edits. For reference, I&amp;rsquo;m using
&lt;a href=&#34;https://github.com/openwrt/packages/blob/openwrt-19.07/net/unbound/files/README.md#parallel-dnsmasq&#34;&gt;&amp;ldquo;Parallel dnsmasq&amp;rdquo;&lt;/a&gt; section from the README for unbound in the OpenWRT packages (which
has a lot of other useful information as well!). Essentially, I made the edits
to &lt;code&gt;/etc/config/unbound&lt;/code&gt; and &lt;code&gt;/etc/config/dhcp&lt;/code&gt; after SSH&amp;rsquo;ing in. However, you
can make the same edits through LuCI.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;/etc/config/unbound&lt;/code&gt; edits, you can make the edits to the file in
LuCI directly at &amp;ldquo;Services -&amp;gt; Recursive DNS -&amp;gt; Files -&amp;gt; Edit: UCI&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/unbound_config.png&#34; alt=&#34;LuCI: Edit /etc/config/unbound&#34;&gt;&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;/etc/config/dhcp&lt;/code&gt; edits, you can make the edits by finding the same
fields under &amp;ldquo;Network -&amp;gt; DHCP and DNS&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/dhcp_config.png&#34; alt=&#34;LuCI: Edit DHCP and DNS Settings&#34;&gt;&lt;/p&gt;
&lt;p&gt;However, the field names are different from the lines in the config, so they
would need to be researched to determine which fields in LuCI map to which
lines in &lt;code&gt;/etc/config/dhcp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At this point (or maybe after restarting unbound and dnsmasq, which is a lot
easier using SSH and &lt;code&gt;/etc/init.d ... restart&lt;/code&gt; as well), OpenWRT should now
be using unbound for resolving all DNS lookups, while dnsmasq is only used for
DHCP-DNS.&lt;/p&gt;
&lt;p&gt;Bonus: you can also enable a nice status dashboard in LuCI under
&amp;ldquo;Services -&amp;gt; Recursive DNS -&amp;gt; Status&amp;rdquo;, but this requires installing several more
software packages: &lt;code&gt;unbound-control&lt;/code&gt; and &lt;code&gt;unbound-control-setup&lt;/code&gt;. You will also
need to change a line in &lt;code&gt;/etc/config/unbound&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
option unbound_control &amp;#39;0&amp;#39;
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;becomes&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
option unbound_control &amp;#39;1&amp;#39;
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A word of warning: there is another section on &amp;ldquo;Unbound and odhcpd&amp;rdquo; which
tries to cut out dnsmasq completely. However, when I tried to set this up,
I got myself into a lot of trouble (had to reset OpenWRT, re-install any extra
software packages, and restore configuration from backup). It is also possible that if you mess up
the configuration for the &amp;ldquo;Parallel dnsmasq&amp;rdquo; method, you could end up in a
similar error state and have to start over. Please be careful when doing this
and don&amp;rsquo;t change anything you&amp;rsquo;re not supposed to.&lt;/p&gt;
&lt;p&gt;Now, moving on to adblock, which should be &lt;strong&gt;much&lt;/strong&gt; simpler to setup. First,
install &lt;code&gt;luci-app-adblock&lt;/code&gt; and refresh. Navigate to &amp;ldquo;Services -&amp;gt; Adblock&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock.png&#34; alt=&#34;Services -&amp;gt; Adblock&#34;&gt;&lt;/p&gt;
&lt;p&gt;Check the settings at the bottom. The only thing you need to get going is
to go to the &amp;ldquo;Blocklist Sources&amp;rdquo; tab and choose your blocklists.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_blocklist.png&#34; alt=&#34;Adblock: Blacklist sources&#34;&gt;&lt;/p&gt;
&lt;p&gt;The
&lt;a href=&#34;https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md&#34;&gt;adblock readme&lt;/a&gt;
has some more info on what each list is. After that,
make sure &amp;ldquo;Enabled&amp;rdquo; is checked under the &amp;ldquo;General Settings&amp;rdquo; tab:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_enable.png&#34; alt=&#34;Adblock: enable&#34;&gt;&lt;/p&gt;
&lt;p&gt;and click the &amp;ldquo;Refresh&amp;rdquo; button above:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://beckmeyer.us/adblock_refresh.png&#34; alt=&#34;Adblock: refresh&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then you&amp;rsquo;re good to go; adblock should work out of the box with unbound; cheers!&lt;/p&gt;
&lt;p&gt;ADDENDUM: Another word of warning: once you&amp;rsquo;ve setup adblock, it will download
the blocklists, merge them into a single file at &lt;code&gt;/var/lib/unbound/adb_list.overall&lt;/code&gt;,
and try to restart unbound. I recommend not trying to view/interact with adblock
or unbound during this restart, which can take anywhere from 30 seconds - 2 minutes.
Just leave them alone in LuCI for a little bit&amp;hellip;&lt;/p&gt;
</description>
</item>
<item>
<title>Hello doas</title>
<link>https://beckmeyer.us/posts/hello_doas/</link>
<pubDate>Sat, 30 Jan 2021 15:15:55 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/hello_doas/</guid>
<description>&lt;p&gt;Today, I switched my workstation from &lt;code&gt;sudo&lt;/code&gt; to &lt;code&gt;doas&lt;/code&gt;. I&amp;rsquo;m running Void Linux,
and the process was fairly easy.&lt;/p&gt;
&lt;p&gt;First, I needed to figure out how to remove &lt;code&gt;sudo&lt;/code&gt; (yes, I realize I could have
installed &lt;code&gt;doas&lt;/code&gt; first, then removed &lt;code&gt;sudo&lt;/code&gt;, but I decided to do it the hard way.)
As it turns out, the &lt;a href=&#34;https://docs.voidlinux.org/xbps/advanced-usage.html#ignoring-packages&#34;&gt;advanced usage section of the XBPS manual&lt;/a&gt; details how to use the &lt;code&gt;ignorepkg&lt;/code&gt; entry in xbps.d with nothing
other than this exact use case! I created the file &lt;code&gt;/etc/xbps.d/20-ignorepkg-sudo.conf&lt;/code&gt; with contents&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ignorepkg=sudo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then ran &lt;code&gt;sudo xbps-remove sudo&lt;/code&gt; (an ironic command).&lt;/p&gt;
&lt;p&gt;After that, because I was stupid and removed &lt;code&gt;sudo&lt;/code&gt; before I had set up &lt;code&gt;doas&lt;/code&gt;,
I had to use plain-old &lt;code&gt;su&lt;/code&gt; to change to the root user and run &lt;code&gt;xi opendoas&lt;/code&gt;. I also
configured &lt;code&gt;doas&lt;/code&gt; in &lt;code&gt;/etc/doas.conf&lt;/code&gt; with the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# see doas.conf(5) for configuration details
permit nopass keepenv :admin
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I ran &lt;code&gt;groupadd admin&lt;/code&gt;, &lt;code&gt;usermod -aG admin joel&lt;/code&gt;, and then logged out so that my
user account would see the new group perms.&lt;/p&gt;
&lt;p&gt;And just like that, I can now run &lt;code&gt;doas xbps-install ...&lt;/code&gt; and all of my other commands,
just substituting &lt;code&gt;doas&lt;/code&gt; for &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The one thing I immediately missed was &lt;code&gt;sudoedit&lt;/code&gt;. Before I accidentally tried
to use &lt;code&gt;sudo&lt;/code&gt; for the first time, I had already accidentally tried to run &lt;code&gt;sudoedit&lt;/code&gt;
&lt;em&gt;at least&lt;/em&gt; 5 times. I had to fix this. I saw a discussion on Reddit where &lt;a href=&#34;https://www.reddit.com/r/linux/comments/l6y7nv/is_doas_a_good_alternative_to_sudo/gl4hs42?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3&#34;&gt;one user
suggested&lt;/a&gt; writing a script to replace the &lt;code&gt;sudoedit&lt;/code&gt; functionality.
I quickly starting hacking together something like that. I started with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/tmp_file
$EDITOR /tmp/doasedit/tmp_file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And quickly ran into my first road-block. The script is going to have to change
the permissions of that file before the user can edit it. But if the script changes
the permissions, how can I restore it to the original location with the right
permissions? &lt;code&gt;cp /tmp/doasedit/tmp_file $1&lt;/code&gt; won&amp;rsquo;t work. I thought about just using
cat to overwrite the file contents in-place (&lt;code&gt;cat /tmp/doasedit/tmp_file &amp;gt; $1&lt;/code&gt;).
That &lt;em&gt;could&lt;/em&gt; create some issues if a program has the file open. Instead, a better option
is to create two copies of the file&amp;ndash;one for editing, and one for preserving file
attributes:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
doas cp $1 /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $1 /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/file $1
rm -rf /tmp/doasedit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, the issue with this is that it only works with absolute paths.
I want to make it work for relative paths as well. I&amp;rsquo;m going to take advantage
of &lt;code&gt;realpath&lt;/code&gt;, which is part of the &lt;code&gt;coreutils&lt;/code&gt; package from Void. As a bonus, this
will also take care of the edge case where the given file is a symlink (IIRC,
&lt;code&gt;sudoedit&lt;/code&gt; didn&amp;rsquo;t follow symlinks, so I may be diverging here):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
mkdir -p /tmp/doasedit
srcfile=&amp;#34;$(realpath $1)&amp;#34;
doas cp $srcfile /tmp/doasedit/edit
doas chown -R $USER:$USER /tmp/doasedit/edit
doas cp $srcfile /tmp/doasedit/file
$EDITOR /tmp/doasedit/edit
cat /tmp/doasedit/edit | doas tee /tmp/doasedit/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/file $srcfile
rm -rf /tmp/doasedit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point, it works&amp;hellip;okay-ish. It can only be used in one instance currently
since I hard-coded &lt;code&gt;/tmp/doasedit/file&lt;/code&gt; and &lt;code&gt;/tmp/doasedit/edit&lt;/code&gt;, but that&amp;rsquo;s easily fixed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh
destfile_pfx=&amp;#34;$(cat /dev/urandom | tr -cd &amp;#39;a-f0-9&amp;#39; | head -c 32)&amp;#34;
while [ -d &amp;#34;/tmp/doasedit/$destfile_pfx&amp;#34; ]; do
destfile_pfx=&amp;#34;$(cat /dev/urandom | tr -cd &amp;#39;a-f0-9&amp;#39; | head -c 32)&amp;#34;
done
mkdir -p /tmp/doasedit/$destfile_pfx
srcfile=&amp;#34;$(realpath $1)&amp;#34;
doas cp $srcfile /tmp/doasedit/$destfile_pfx/edit
doas chown -R $USER:$USER /tmp/doasedit/$destfile_pfx/edit
doas cp $srcfile /tmp/doasedit/$destfile_pfx/file
$EDITOR /tmp/doasedit/$destfile_pfx/edit
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&amp;gt;/dev/null
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
rm -rf /tmp/doasedit/$destfile_pfx
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point, the only thing missing is the check to see if the file was actually
edited:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...
cat /tmp/doasedit/$destfile_pfx/edit | doas tee /tmp/doasedit/$destfile_pfx/file 1&amp;gt;/dev/null
if cmp -s &amp;#34;/tmp/doasedit/$destfile_pfx/file&amp;#34; &amp;#34;$srcfile&amp;#34;; then
echo &amp;#34;Skipping write; no changes.&amp;#34;
else
doas mv -f /tmp/doasedit/$destfile_pfx/file $srcfile
fi
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I put this in a &lt;a href=&#34;https://github.com/AluminumTank/doasedit&#34;&gt;repo on GitHub&lt;/a&gt; if
anyone is interested. I know that a major
weakness of this script is the number of times it calls &lt;code&gt;doas&lt;/code&gt;, which could
break flows where password is required every time &lt;code&gt;doas&lt;/code&gt; is run.&lt;/p&gt;
</description>
</item>
</channel>
</rss>

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>poetry &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/tags/poetry/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>poetry</h1>
</div>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>poetry on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/tags/poetry/</link>
<description>Recent content in poetry on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster>
<lastBuildDate>Sat, 03 Apr 2021 22:15:44 -0400</lastBuildDate><atom:link href="https://beckmeyer.us/tags/poetry/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Better?</title>
<link>https://beckmeyer.us/posts/better/</link>
<pubDate>Sat, 03 Apr 2021 22:15:44 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/better/</guid>
<description>&lt;p&gt;There are many that say&lt;br&gt;
(and I tend to agree)&lt;br&gt;
that free software is the best there could be.&lt;/p&gt;
&lt;p&gt;But please don&amp;rsquo;t mistake&lt;br&gt;
using software that&amp;rsquo;s free&lt;br&gt;
as a right to superiority.&lt;/p&gt;
&lt;p&gt;There are many that go&lt;br&gt;
from day to day living&lt;br&gt;
and don&amp;rsquo;t give a thought to what they are using.&lt;/p&gt;
&lt;p&gt;Are they worse for this?&lt;br&gt;
Are you better for caring?&lt;br&gt;
Sometimes the truth can be quite baring.&lt;/p&gt;
&lt;p&gt;That not every human&lt;br&gt;
in present circumstance&lt;br&gt;
is able or willing to take a chance.&lt;/p&gt;
&lt;p&gt;&amp;lsquo;Cause that&amp;rsquo;s what it is,&lt;br&gt;
taking a chance and going&lt;br&gt;
into the unknown with fear, and knowing&lt;/p&gt;
&lt;p&gt;that what you might find,&lt;br&gt;
may not truly be better.&lt;/p&gt;
&lt;p&gt;But instead simply different;&lt;br&gt;
and still made by a stranger.&lt;/p&gt;
</description>
</item>
</channel>
</rss>

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html class="no-js" lang="en-us" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
<meta charset="utf-8">
<base href="https://beckmeyer.us/">
<meta name="viewport" content="width=device-width">
<title>Volatile Mediums &ndash; Joel Beckmeyer&#39;s Blog</title>
<link rel="stylesheet" href="/css/styles.css">
<link id="theme_css" rel="stylesheet" href="/css/themes/light.css">
<link rel="alternate" type="application/rss+xml" href="https://beckmeyer.us/tags/volatile-mediums/index.xml" title="Joel Beckmeyer's Blog" />
</head>
<body>
<input class="show-hide-menu-input" style="display:none;" autocomplete="off" type="checkbox" id="toggle-1">
<div class="main">
<div class="header">
<div class="header-content">
<div class="title">
<a href="https://beckmeyer.us/">Joel Beckmeyer&#39;s Blog</a>
</div>
<div>
<div class="header-right">
<label id="show-hide-menu-label" class="clickable-header-label" for="toggle-1">
<img class="color-adapting-image" width="30" src="/images/hamburger.svg" alt="menu button">
</label>
</div>
<label class="overlay" for="toggle-1"></label>
<div class="dont-show">
Links:
</div>
<ul class="links">
<li><a href="/">Home</a></li>
<li><a href="/contact/">Contact</a></li>
<li><a href="/posts/">Posts</a></li>
</ul>
</div>
</div>
</div>
<div class="body">
<div class="body-content">
<div class="title-header">
<h1>Volatile Mediums</h1>
</div>
</div>
</div>
</div>
<hr class="dont-show">
<div class="footer">
<p>Have any questions? Let me know on <a href="https://matrix.to/#/@joel:thebeckmeyers.xyz">Matrix</a>, or start a discussion on <a href="https://social.beckmeyer.us/TinfoilSubmarine">Fediverse</a>!</p>
</div>
</body>
</html>

View File

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Volatile Mediums on Joel Beckmeyer&#39;s Blog</title>
<link>https://beckmeyer.us/tags/volatile-mediums/</link>
<description>Recent content in Volatile Mediums on Joel Beckmeyer&#39;s Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<managingEditor>joel@beckmeyer.us (Joel Beckmeyer)</managingEditor>
<webMaster>joel@beckmeyer.us (Joel Beckmeyer)</webMaster>
<lastBuildDate>Fri, 19 Mar 2021 15:00:00 -0400</lastBuildDate><atom:link href="https://beckmeyer.us/tags/volatile-mediums/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>The Generation Ship Problem</title>
<link>https://beckmeyer.us/posts/the_generation_ship_problem/</link>
<pubDate>Fri, 19 Mar 2021 15:00:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/the_generation_ship_problem/</guid>
<description>&lt;p&gt;After talking about the hardware and software problems of
digital permanence, I&amp;rsquo;m struck by a classical Sci-Fi
motif with a conundrum: the &lt;strong&gt;Generation Ship&lt;/strong&gt;; a ship
outfitted with all of the technology, infrastructure, and
storage to support lightyear-scale human travel.&lt;/p&gt;
&lt;p&gt;But what about that technology on the ship? If we build
one of these ships, we need to accomplish one of several
things in regards to information storage:&lt;/p&gt;
&lt;h3 id=&#34;1-innovate-to-the-point-where-the-lifetime-of-the-storage-devices-is-able-to-support-lightyear-scale-travel&#34;&gt;1. Innovate to the point where the lifetime of the storage devices is able to support lightyear scale travel.&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s a tall order, given where we are right now with
physical storage devices. As I mentioned in one of my
previous posts, the average lifetime of physical storage
devices is less than 100 years, no matter if it is a hard
drive, solid-state drive, etc.&lt;/p&gt;
&lt;h3 id=&#34;2-provide-the-facility-to-create-new-storage-devices-to-replace-the-failing-old-ones&#34;&gt;2. Provide the facility to create new storage devices to replace the failing old ones.&lt;/h3&gt;
&lt;p&gt;Again, in my mind a tall order, since it would require
facilities on the ship to create storage devices. The
problem of having materials is at least solvable by just
sending the ship with all of the materials it needs in
advance.&lt;/p&gt;
&lt;h3 id=&#34;3-provide-the-facility-to-revitalize-storage-devices&#34;&gt;3. Provide the facility to revitalize storage devices.&lt;/h3&gt;
&lt;p&gt;One of the main reasons I&amp;rsquo;m even thinking about this is
because I&amp;rsquo;m an individual with limited resources.
Accordingly, I think about things in terms of
broken/working, on/off, etc. With enough resources, there
is a much larger chance of being able to repair, re-purpose,
and otherwise revitalize storage devices, increasing their
lifetime. E.g., if the only failure in the hard drive is the
control circuit, that is an &amp;ldquo;easy enough&amp;rdquo; repair.&lt;/p&gt;
&lt;p&gt;I like to toy with the idea of a generation ship a lot in
my head, but I think it&amp;rsquo;s really fun to think about the
technical possibilities and needs of a ship like this.&lt;/p&gt;
</description>
</item>
<item>
<title>Volatile Formats</title>
<link>https://beckmeyer.us/posts/volatile_formats/</link>
<pubDate>Thu, 18 Mar 2021 14:24:00 -0400</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/volatile_formats/</guid>
<description>&lt;p&gt;&lt;em&gt;Note: This is a continuation of the thoughts I started
thinking about in my &lt;a href=&#34;https://beckmeyer.us/posts/volatile_mediums/&#34;&gt;Volatile Mediums&lt;/a&gt; blog post.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The next level up from physical mediums for data storage
is the &lt;em&gt;way&lt;/em&gt; that the data is stored. In the digital age,
we have a plethora of formats for storing information.
For me, one of the most interesting areas of information
storage is the analog-digital space.&lt;/p&gt;
&lt;p&gt;The fundamental problem of storing audio, video, and other
replications of the physical world is that there is so much
information that we can collect with sensors
(think microphones, video cameras, etc.). It would be great
if we could go get the best camera and microphone out there,
record whatever people record these days, and have that
exact physical experience &amp;ldquo;played back&amp;rdquo; for us on a screen
and speaker/headphones.&lt;/p&gt;
&lt;p&gt;Unfortunately, there are several problems with this. Among
those is the actual design of the sensor. It takes a lot of
careful thought, engineering, and the like to create a truly
good microphone or camera. And after all of that, this sensor
will cost something. Hopefully, that cost will correspond to
the actual technical ability of that sensor! In any case,
not everyone can have the best camera or microphone due to
any number of constraints, not just those listed above.&lt;/p&gt;
&lt;p&gt;The second problem is the sampling issue. The sensor will
create some sort of output that can then be measured, or
&lt;strong&gt;sampled&lt;/strong&gt;, by an ADC (analog-to-digital converter). The
very word &amp;ldquo;sample&amp;rdquo; belies what this nearly magical box is
doing: it is only looking at certain portions or timestamps
of the analog signal. Granted, the time between samples
can be very small (e.g. 44.1 kHz is a fairly common sample
rate for audio), but there is still some loss of signal.
Once the ADC creates these samples, it converts them into
a digital format (something that can be stored on a
CD, hard drive, thumb drive, etc.).&lt;/p&gt;
&lt;p&gt;The third problem is the encoding issue. The ADC creates all
of these samples, but we need to start thinking about storage
limitations. Storing the raw output of a sensor can take a
lot of space: an average album length (40 minutes) could
easily take 400MB of space! Now, again, the physical storage
space is moving in the upward direction to combat this, but
storing isn&amp;rsquo;t the only problem. One prime issue is internet
bandwidth.&lt;/p&gt;
&lt;p&gt;The solution to this is compression, like a ZIP file. It
makes big files smaller by doing some fancy math tricks
that can be reversed by a computer to reconstruct the
original file. However, for audio/video files, another level
of compression exists which actually gets rid of some of the
information in the original file to save more space. This
is called &amp;ldquo;lossy&amp;rdquo; compression, as opposed to &amp;ldquo;lossless&amp;rdquo;
compression.&lt;/p&gt;
&lt;p&gt;Great! We&amp;rsquo;ve found a way to save more space. The problem
with lossy compression is that we have to decide which
information to throw away. Usually, this is frequencies
that the average human ear/eye can&amp;rsquo;t perceive. But, let&amp;rsquo;s
just say that some compression is a bit too &amp;ldquo;greedy&amp;rdquo; when it
comes to saving space and starts to cut into the band of
frequencies that can be perceived. Also note that
the design of these compression algorithms is an artform
and takes lots of careful consideration.&lt;/p&gt;
&lt;p&gt;The final problem I want to mention is the codec problem.
There are many different codecs available today, and for
each and every one of them to be useful, you need to have a
way to decode each and every one of them. Unfortunately,
this is sometimes very difficult.&lt;/p&gt;
&lt;p&gt;It could be a licensing
issue, where you don&amp;rsquo;t have the correct software installed
or purchased to actually decode that file on your computer.&lt;/p&gt;
&lt;p&gt;Or it could be a physical constraints issue, where your
computer isn&amp;rsquo;t powerful enough to decode the file at a fast
enough rate for you to view it without stuttering,
buffering, etc.&lt;/p&gt;
&lt;p&gt;Third, it could be a personal preference. Some people
have much more sensitive eyes/ears and need to have formats
that are more &lt;strong&gt;transparent&lt;/strong&gt;, meaning that the lossy file
is perceptually identical to the source it was encoded from.&lt;/p&gt;
&lt;p&gt;With all of these issues at play, I think there are several
key points to make:&lt;/p&gt;
&lt;h3 id=&#34;1-codecs-need-to-be-freely-available-for-widespread-use-with-no-strings-attached&#34;&gt;1. Codecs need to be freely available for widespread use with no strings attached.&lt;/h3&gt;
&lt;p&gt;Can&amp;rsquo;t stress this one enough: we need to make sure we are
doing everything possible to not let our information die
when a corporation or individual makes a decision that
impacts the &amp;ldquo;who, what, where, when, and how&amp;rdquo; of their codec
usage.&lt;/p&gt;
&lt;h3 id=&#34;2-lossless-compression-is-good-but-it-is-not-the-only-thing-we-need&#34;&gt;2. Lossless compression is good, but it is not the only thing we need.&lt;/h3&gt;
&lt;p&gt;We need to remember that not everyone has the ability to use
lossless codecs, whether that be because of internet
bandwidth limitations, storage limitation, or the like.
Instead, we need to continue to innovate in the lossy
compression space to narrow the perceptual gap between lossy
and lossless more and more.&lt;/p&gt;
&lt;h3 id=&#34;3-a-codec-should-never-become-obsolete&#34;&gt;3. A codec should never become obsolete.&lt;/h3&gt;
&lt;p&gt;This one may sound weird, but the fact is, if we&amp;rsquo;re talking
about long-term storage of information, we can&amp;rsquo;t let codecs
die, since there may come a day where we need a codec to
decode great-grandpa&amp;rsquo;s album that never made it big.&lt;/p&gt;
</description>
</item>
<item>
<title>Volatile Mediums</title>
<link>https://beckmeyer.us/posts/volatile_mediums/</link>
<pubDate>Fri, 29 Jan 2021 23:36:00 -0500</pubDate>
<author>joel@beckmeyer.us (Joel Beckmeyer)</author>
<guid>https://beckmeyer.us/posts/volatile_mediums/</guid>
<description>&lt;p&gt;I&amp;rsquo;ve recently been thinking a lot about storage mediums [1] &amp;ndash; especially in the long-term.&lt;/p&gt;
&lt;p&gt;Technology has made a lot of progress. Digital storage mediums started out only being
able to store &lt;a href=&#34;https://en.wikipedia.org/wiki/Tape_drive&#34;&gt;224KB on a tape drive&lt;/a&gt;
for an average lifetime of &lt;a href=&#34;https://blog.storagecraft.com/data-storage-lifespan/&#34;&gt;&lt;em&gt;up to&lt;/em&gt; 30 years&lt;/a&gt;.
Now, we can store terrabytes of data on hard drives and solid-state drives. However,
no one ever really answered the question about long-term storage.&lt;/p&gt;
&lt;p&gt;(Note: the following is based off an assumption that the storage medium is only
being used to make backups or archive data. The device itself could be unplugged and stored
when no backup is in progress.)&lt;/p&gt;
&lt;p&gt;Even though &lt;em&gt;theoretically&lt;/em&gt; hard drives could store data for 20+ years, random bit flips, drive
failure, etc. all make hard drives too volatile of an option. As always, of course
redundancy takes away some of these issues.&lt;/p&gt;
&lt;p&gt;SSDs are in an even worse position: they cost significantly more than hard drives
per TB right now, and last I heard, there were still issues with bit fade when
unpowered.&lt;/p&gt;
&lt;p&gt;CD/DVD is sounding a lot better, but there are some serious issues here too.
Variable quality directly impacts the storage lifetime. Physically storing the
discs is a lot more risky since the disc itself doesn&amp;rsquo;t have as much built-in
protection as a hard drive or SSD has. You&amp;rsquo;ll need a much larger quantity to
store the terrabytes of data that you can easily dump on one hard drive. And finally, life
expectancy is still fairly low &amp;ndash; while manufacturers of recordable discs (the &amp;lsquo;R&amp;rsquo; in CD-R, DVD-R, etc.)
claim life expectancies of 100-200 (!) years under optimal conditions, others are &lt;em&gt;slightly&lt;/em&gt; more conservative,
&lt;a href=&#34;https://www.clir.org/pubs/reports/pub121/sec4/&#34;&gt;giving an estimate of 30 years&lt;/a&gt;.
Oh, and remember how I mentioned this is for recordable discs? That means they&amp;rsquo;re single write.
The random access (RW - CD-RW, DVD-RW, etc.) discs have even lower life expectancies.&lt;/p&gt;
&lt;p&gt;All in all, humanity has not gotten very far with the digital storage medium.
All of these life expectancies have an inconsequential variance when we zoom out
to the century view of history.&lt;/p&gt;
&lt;p&gt;[1] And no, I&amp;rsquo;m not talking about the kind you pay to see your dead great-great-aunt to figure out if
you&amp;rsquo;re actually related to George Washington.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is intended to be the beginning of a learning series/personal study on the issues surrounding
information preservation, digital permanence, and their related issues.&lt;/em&gt;&lt;/p&gt;
</description>
</item>
</channel>
</rss>

BIN
public/unbound_config.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
static/adblock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
static/adblock_enable.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
static/adblock_refresh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
static/dhcp_config.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
static/luci_install.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
static/luci_services.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
static/luci_software.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
static/unbound_config.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

@ -0,0 +1 @@
Subproject commit 1957c02a76816e567f531ec9167fbdd17fc38f8c