<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>A Geek with Guns</title>
      <link>https://www.christopherburg.com</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://www.christopherburg.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Fri, 15 May 2026 09:00:00 -0600</lastBuildDate>
      <item>
          <title>The Return of Your Apps, Please</title>
          <pubDate>Fri, 15 May 2026 09:00:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/the-return-of-your-apps-please/</link>
          <guid>https://www.christopherburg.com/blog/the-return-of-your-apps-please/</guid>
          <description xml:base="https://www.christopherburg.com/blog/the-return-of-your-apps-please/">&lt;p&gt;In &lt;a href=&quot;&#x2F;blog&#x2F;your-apps-please&#x2F;&quot;&gt;my previous post&lt;&#x2F;a&gt; I discussed how the ability to attend concerts is increasingly locked behind using either an iOS device or a device running a Google approved version of Android. The issue I described isn&#x27;t an isolated incident. More and more of our lives are being locked behind our smartphones. The two major smartphone operating system providers, Google and Apple, know this and are using their positions to lock us into their platforms. This is especially egregious of Google since it introduced Android as an open platform, which it no longer is.&lt;&#x2F;p&gt;
&lt;p&gt;Since introducing Android, Google has slowly been locking it down. Now there are effectively two tiers of Android: the Google blessed tier that can participate in our smartphone centric lives and the bastard child tier that can&#x27;t. Less somebody think I&#x27;m being hyperbolic, Google demonstrated this fact with the latest update to &lt;a href=&quot;https:&#x2F;&#x2F;reclaimthenet.org&#x2F;google-broke-recaptcha-for-de-googled-android-users&quot;&gt;reCAPTCH&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Google has tied its next-generation reCAPTCHA system to Google Play Services on Android, meaning anyone running a &lt;a href=&quot;https:&#x2F;&#x2F;reclaimthenet.org&#x2F;the-deal-that-could-change-de-googled-phones-forever&quot;&gt;de-Googled phone&lt;&#x2F;a&gt; will automatically fail verification when the system decides to challenge them.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;reCAPTCHA is used by many websites, including government and educational websites, to thwart access by bots. Instead of providing an image-based puzzle, the new version of reCAPTCHA will require you to scan a QR code with your phone. The dirty trick, which is covered in more detail on &lt;a href=&quot;https:&#x2F;&#x2F;grapheneos.social&#x2F;@GrapheneOS&#x2F;116550899908879585&quot;&gt;this post&lt;&#x2F;a&gt; from GrapheneOS&#x27;s Mastodon instance, is that on Android this authentication mechanism is tied to Google Play Services, which is Google&#x27;s proprietary framework for Android, on a Google certified device. That means people with de-Googled phones, such as any phone running LineageOS or GrapheneOS, will be unable to access any website where reCAPTCHA suspects you&#x27;re a bot.&lt;&#x2F;p&gt;
&lt;p&gt;With this change, attending concerts won&#x27;t be the only thing locked behind using an iPhone or Google blessed Android device. Huge swaths of the web will be too. This also creates a potential Catch-22 situation. Since many government websites use reCAPTCHA, people not using a Google blessed Android device will inevitably be unable to access government websites, which could result in legal consequences depending on the website in question. Imaging being unable to renew your driver&#x27;s license or pay your taxes because you don&#x27;t own the right kind of smartphone.&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t the reality we&#x27;re heading towards, it&#x27;s the reality we&#x27;re at right now. The European Union is working on a European Digital Identity, which &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eu-digital-identity-wallet&#x2F;eudi-app-android-wallet-ui&#x2F;issues&#x2F;287&quot;&gt;will require Google Play Integrity&lt;&#x2F;a&gt;. Google Play Integrity, like the new version of reCAPTCHA, only works on Google certified devices. This not only expands the two tier system I mentioned to European citizenship, but also demonstrates that the European Union has no opposition to Google being a monopoly despite the rhetoric of its politicians. While the European Union makes a show of stopping Google&#x27;s &quot;monopoly&quot; through lawsuits involving its app store, it hands Google a literal monopoly over the European Digital Identity application. To reiterate a long running theme of this blog, your government doesn&#x27;t love you.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Your Apps, Please</title>
          <pubDate>Sat, 25 Apr 2026 19:00:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/your-apps-please/</link>
          <guid>https://www.christopherburg.com/blog/your-apps-please/</guid>
          <description xml:base="https://www.christopherburg.com/blog/your-apps-please/">&lt;p&gt;I&#x27;m going to date myself. When I first started attending concerts, you bought physical tickets. These paper tickets could be purchased in several ways. You could visit the venue ticket box during business hours and purchase them. Ticket would normally be available weeks or even months ahead of a concert or you could buy them when you arrived for the concert if it wasn&#x27;t sold out.  If you lived too far from the venue, you could purchase tickets over the phone and either have them mailed to you or will call (that&#x27;s and old term for picking your tickets up at the venue). As the Internet became more prominent, many venues started to offer online purchases. Tickets purchased online could be either mailed to you, will call, or printed at home using your printer. These were the halcyon days of concert ticket purchasing in my opinion.&lt;&#x2F;p&gt;
&lt;p&gt;All good things must come to an end though. Attending concerts today is often a pain in the ass because venues have moved to using apps for ticketing. This idea sounds convenient on paper. Everybody carries their phone with them to concerts so they can hold them up and record the entire show to post on social media so their friends know they were there. Since everybody has their phone with them all the time, making the device the method of acquiring tickets and entering concerts only makes sense, right? Except some of us don&#x27;t carry our phones with us all the time. Some of us like to actually watch the concert with our own eyes rather than filtered through a screen. But more importantly, not all of us use venue approved smartphones.&lt;&#x2F;p&gt;
&lt;p&gt;There are several major problems with apps being used for tickets. The first one I will cover is the combination of shitty technology and nonexistent customer support that defines modern services. Anybody who has had a problem with a Google or Microsoft product will understand this pain. Getting a hold of a human being at either company is basically impossible. If your problem can&#x27;t be solved through simple online methods, your problem often isn&#x27;t going to be solved. One venue I used to frequent uses &lt;a href=&quot;https:&#x2F;&#x2F;www.axs.com&#x2F;&quot;&gt;AXS&lt;&#x2F;a&gt;. I say used to frequent because AXS is a unique ticketing service in that they won&#x27;t actually sell me tickets. You see, their website and app are both convinced that I&#x27;m a bot. Creating an account took long enough that one could legitimately write an epic poem about it. Once I managed to create an account, I couldn&#x27;t use the service. Getting human support isn&#x27;t an option. I did find their online support page and submitted a ticket thinking a human being would respond at some point. Instead, several days later, I received a link to chat with a large language model that was completely incapable of solving my issue. I&#x27;m calling out AXS in this case because it&#x27;s my most recent encounter, but the same headaches are true of many ticketing apps.&lt;&#x2F;p&gt;
&lt;p&gt;The second major problem is the seemingly endless number of apps you need to install. Ticketmaster used to be the go-to app for ticketing, but they&#x27;re a shower of bastards so venues rightly sought alternatives. This has lead to a seemingly endless number of apps. Each app also requires you to sign up for yet another service. Some services, like AXS, make signing up a tremendous pain in the ass. A few services, like &lt;a href=&quot;https:&#x2F;&#x2F;dice.fm&#x2F;&quot;&gt;Dice&lt;&#x2F;a&gt;, make the process straight forward and easy. Most are somewhere in between. It wouldn&#x27;t be so bad if there appeared to be an end to the madness, but like Sisyphus pushing his rock, we seem to be damned to signing up for new services and installing new apps for all eternity.&lt;&#x2F;p&gt;
&lt;p&gt;The third major problem, and this is the biggest one in my opinion, is that you need to own a venue approved smartphone. This means you either need an iPhone or an Android phone running the stock OS. If you use anything else, good fucking luck. GrapheneOS works in most cases so long as you have Google Play Services installed (I install it in a separate, isolated profile along with all the stupid ticketing apps). If you don&#x27;t have Google Play Services installed, you&#x27;re out of luck for many apps (including Ticketmaster). What if you use something radically different, like a &lt;a href=&quot;https:&#x2F;&#x2F;furilabs.com&#x2F;&quot;&gt;phone running mainline Linux&lt;&#x2F;a&gt;? Some ticketing apps can be made to run in an Android emulator with microG, but not all. If that doesn&#x27;t work for the specific app you need for a concert, you won&#x27;t get to attend that concert. The reliance on apps for ticketing helps Apple and Google maintain their duopoly over the smartphone market.&lt;&#x2F;p&gt;
&lt;p&gt;The old ways were better. Anybody who could afford the tickets could attend a concert. Now being able to afford the tickets isn&#x27;t enough. You must also own an iOS or Android device, be lucky enough to not be tagged as a bot by the ticketing service, and have the wherewithal to not blow your brains out while you navigate the Byzantine account sign up process that many services utilize. Rubbing salt into the wound is the fact you don&#x27;t have ticket stubs you can tack into a scrapbook to remember all the concerts you attended (for you younger folk, tickets at two pieces and the venue ripped off one piece when you got to the concert and you kept the other, which is referred to as the stub, and a scrapbook is a physical book you could paste photographs, ticket stubs, and other paper objects in).&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>The Endless Cycle of Enshitification</title>
          <pubDate>Thu, 16 Apr 2026 16:00:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/the-endless-cycle-of-enshitification/</link>
          <guid>https://www.christopherburg.com/blog/the-endless-cycle-of-enshitification/</guid>
          <description xml:base="https://www.christopherburg.com/blog/the-endless-cycle-of-enshitification/">&lt;p&gt;I&#x27;ve lived through a few epochs, moments in time where things changed so dramatically that we commonly talk about our world as it existed before and after. 9&#x2F;11 was the first epoch that I was aware of living through (the fall of the Soviet Union happened when I was too young to know or care about it). COVID-19 is another. The differences between the pre-COVID-19 years and post-COVID-19 years are significant. During COVID-19 we experienced a dramatic drop in quality of life. Not because of the disease, but because of the fallout from the worldwide response to the disease. The world has never recovered from this. It&#x27;s been caught in a continuous cycle of enshitification ever since.&lt;&#x2F;p&gt;
&lt;p&gt;The damage to education caused by the response to COVID-19 is hard to understate. Math and literacy rates were already trending downward before COVID-19, but they fell off of a cliff during and keep dropping after. It&#x27;s not just K-12 schools either. College level education quality has been dropping too. The popularity of large language models (commonly and incorrectly referred to as AI) has exacerbated this trend. This isn&#x27;t helped by the fact that education is no longer focused on the exercise of learning itself but on making the grade (which are often divorced from each other). It&#x27;s common for stories covering this phenomenon to focus on students using large language models to skip doing the work. I submit &lt;a href=&quot;https:&#x2F;&#x2F;arstechnica.com&#x2F;science&#x2F;2026&#x2F;04&#x2F;to-teach-in-the-time-of-chatgpt-is-to-know-pain&#x2F;&quot;&gt;this story&lt;&#x2F;a&gt; penned by a college instructor as exhibit one:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;But since the appearance of ChatGPT, the instructor’s job isn’t just to teach the subject and frantically attempt to keep every student’s plate spinning. Increasingly, it’s to moonlight as a detective and prosecutor because students without the motivation to do the work don’t have to skip it anymore. They can turn in a work-shaped simulacrum almost as easily. And a substantial number do—in a &lt;a href=&quot;https:&#x2F;&#x2F;newsroom.collegeboard.org&#x2F;new-research-majority-high-school-students-use-generative-ai-schoolwork&quot;&gt;recent College Board survey&lt;&#x2F;a&gt; of 600 high school students, 84 percent said they had used generative AI for schoolwork.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This part of the story wasn&#x27;t what jumped out at me though. This part was:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;For the last few years, I’ve been exclusively teaching asynchronous online courses, meaning recorded videos rather than live sessions.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Enshitification in education isn&#x27;t coming solely from lazy students trying to make the grade without doing any work. It&#x27;s coming from both sides of the teacher-student relationship. Before COVID-19 college classes were largely in-person. There were remote classes, but they were the exception rather than the rule. During COVID-19 most classes became remote. This resulted in an overall drop in quality for both the teachers and students. After COVID-19 many classes remain remote despite no remaining restrictions against in-person classes.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s easy to blame students who use large language models to avoid doing their work for being lazy. But it&#x27;s equally true that instructors prerecording video lessons (asynchronous learning to use the academic buzzword) are being lazy and avoiding doing their work. An instructor&#x27;s job isn&#x27;t to simply regurgitate information. If students want that, they can go on YouTube. An instructor&#x27;s job is to help students learn. That not only requires covering material but also requires helping students understand the material. This may require explaining the material in several different ways, having one-on-one conversations with students, pointing students to additional resources, developing hands-on exercises that can help students walk through the logic, etc.&lt;&#x2F;p&gt;
&lt;p&gt;If an instructor is simply recording videos for students to watch, those students are going to pick up on the instructor&#x27;s laziness. They will respond in kind with their own laziness. After all if the instructor doesn&#x27;t care why should the students? The enshitification cycle feeds on itself like an ouroboros. The cycle can&#x27;t be stopped and certainly can&#x27;t be reversed unless one or more of the people responsible for perpetuating it stop. I will argue that in the case of the teacher-student relationship the teacher should be the one to stop perpetuating the cycle. Amongst the responsibilities of an instructor is the responsibility to demonstrate a belief that the material is worth learning.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m sure there are teachers who stand out in your memory because they seemed to be exceptionally good at teaching. I can recall many. One of my high school science teachers excelled at her job. Part of her success was her obvious love of the topic. Her excitement when it came to science demonstrated that she truly believed that the material was worth learning. Many of my college professors were the same way. They obviously loved the subjects they taught and their love of the subject alone could convince students that the material was worth learning.&lt;&#x2F;p&gt;
&lt;p&gt;Thwarting students&#x27; use of large language models is actually quite simple. Return to in-person classes and the use of hand written (they were called blue book exams when I was in college) and oral examinations. Will some students still find a way to cheat? Yes. But I suspect most won&#x27;t because successful cheating under these conditions requires far more sophistication. The bigger challenge is overcoming students&#x27; apathy. I believe that requires teachers to first overcome their own apathy, which is an equal challenge.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Disabling Homebrew in Dinosaur OS</title>
          <pubDate>Fri, 13 Feb 2026 13:00:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/disabling-homebrew-in-dinosaur-os/</link>
          <guid>https://www.christopherburg.com/blog/disabling-homebrew-in-dinosaur-os/</guid>
          <description xml:base="https://www.christopherburg.com/blog/disabling-homebrew-in-dinosaur-os/">&lt;p&gt;Since I &lt;a href=&quot;&#x2F;blog&#x2F;introducing-dinosaur-os&#x2F;&quot;&gt;released Dinosaur OS&lt;&#x2F;a&gt; last September, I&#x27;ve had to make very few changes to my image. This is a testament to the overall stability of Bluefin, the image upon which Dinosaur OS is based. But I started receiving error notifications a couple of weeks ago whenever the automatic update service ran. The initial error was actually due to a Flatpak problem. The developer of a package I installed uploaded a new version with the same version number as my currently installed version. This cause the Flatpak update program to fail. I managed to fix that, but the service was still displaying an error because it wasn&#x27;t able to update Homebrew.&lt;&#x2F;p&gt;
&lt;p&gt;Homebrew is a package manager that was originally written for macOS. It was released back when I used macOS so I tried it and discovered that it was a train wreck and opted to use &lt;a href=&quot;https:&#x2F;&#x2F;www.macports.org&#x2F;&quot;&gt;MacPorts&lt;&#x2F;a&gt; instead. Homebrew had a number of bizarre design decisions. The biggest was it wanted to install packages at a system level. Normally that&#x27;s not a problem with a package manager, but Homebrew tied the system level directory to your user account&#x27;s user ID number. Effectively Homebrew installed packages at a system level that only a single user account to use or modify. There was an option to install packages into your home directory, but a number of packages failed to run when you did that.&lt;&#x2F;p&gt;
&lt;p&gt;When it was announced that Homebrew was available for Linux, I dismissed it entirely. Why would I want a poorly designed package manager on a system that already has a plethora of very good package managers? My experience with Homebrew was so bad that I initially intended to remove it from Dinosaur OS. I ultimately decided that enough time had passed that I should give Homebrew another chance. My latest experience mirrored my previous experience.&lt;&#x2F;p&gt;
&lt;p&gt;Homebrew on Linux suffers the same problem as it does on macOS. It doesn&#x27;t support systems with multiple user accounts well. When Bluefin installs Homebrew, it creates the &lt;code&gt;&#x2F;home&#x2F;linuxbrew&#x2F;&lt;&#x2F;code&gt; directory and sets its user and group IDs to 1000. Bluefin is based on Fedora and by default the first user account created on a Fedora system has the user and group IDs of 1000. All packages installed with Homebrew are installed into the &lt;code&gt;&#x2F;home&#x2F;linuxbrew&#x2F;&lt;&#x2F;code&gt; directory. This means Homebrew on Bluefin is configured so that only the very first user account created on the system can use it.&lt;&#x2F;p&gt;
&lt;p&gt;This is fine for most users, but I&#x27;m not most users. I have two user accounts on my system. The first is my administrator account, the second is a regular user account that I use for my day to day tasks. Administrator rights are required to create new user accounts so obviously I create my administrator account first. This means the actual account I use day to day, which has the user and group IDs of 1001 (the default on Fedora systems for the second user account created), can&#x27;t use Homebrew.&lt;&#x2F;p&gt;
&lt;p&gt;There are ways around this. I could change the owner permissions on &lt;code&gt;&#x2F;home&#x2F;linuxbrew&#x2F;&lt;&#x2F;code&gt; to 1001. Homebrew on Bluefin is setup using the &lt;code&gt;brew-setup.service&lt;&#x2F;code&gt; systemd service, which sets the permissions. I could change that unit file in my image to set the user and group IDs to 1001. Either option would allow my day to day user account to use Homebrew installed packages, but would prevent my administrator account from using them. The bottom line is Homebrew is a poorly designed package manager.&lt;&#x2F;p&gt;
&lt;p&gt;I chose a third option: ignore Homebrew entirely. There was no downside to this option at first, but a few weeks ago changes were made to Bluefin&#x27;s automatic updater that caused me to reexamine my decision. As noted at the beginning of this article, I started receiving notifications that the automatic update service failed. Checking journalctl showed me the source of the error was that the update utility, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ublue-os&#x2F;uupd&quot;&gt;UUPD&lt;&#x2F;a&gt;, was unable to upgrade Homebrew. This failure was caused by &lt;code&gt;&#x2F;home&#x2F;linuxbrew&#x2F;&lt;&#x2F;code&gt;, which normally contains the brew executable used to install and update packages, being empty (I didn&#x27;t investigate why it was empty since I was already done with Homebrew).&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately disabling and removing Homebrew from Bluefin is straight forward. Homebrew is installed by the &lt;code&gt;brew-setup.service&lt;&#x2F;code&gt; systemd service, which is enabled by default on Bluefin. Disabling the service prevents it from automatically installing Homebrew so Dinosaur OS disables it. I also add a script, &lt;code&gt;&#x2F;usr&#x2F;libexec&#x2F;remove-brew&lt;&#x2F;code&gt;, to the image, which removes Homebrew from a system if it&#x27;s already installed. This makes Dinosaur OS nondestructive in that it won&#x27;t automatically remove Homebrew from a system where it&#x27;s already installed. Removing Homebrew requires manual work. It also means Homebrew can be installed again by either starting or enabling &lt;code&gt;brew-setup.service&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I still had the problem where UUPD would throw an error because it was unable to update Homebrew (which was now missing entirely). UUPD on Bluefin accepts arguments that disable update modules though. The final change I made to Dinosaur OS is adding &lt;code&gt;--disable-module-brew&lt;&#x2F;code&gt; to the ExecStart line of &lt;code&gt;uupd.service&lt;&#x2F;code&gt;, which is activated by a timer periodically. &lt;code&gt;uupd.service&lt;&#x2F;code&gt; is a system file, which means the user cannot edit it. Therefore, if you&#x27;re running Dinosaur OS and install Homebrew, your Homebrew packages won&#x27;t be automatically updated by &lt;code&gt;uupd.service&lt;&#x2F;code&gt;. The best way to change this behavior is to copy &lt;code&gt;&#x2F;usr&#x2F;lib&#x2F;systemd&#x2F;system&#x2F;brew-update.service&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;etc&#x2F;systemd&#x2F;system&#x2F;uupd.service&lt;&#x2F;code&gt; and remove &lt;code&gt;--disable-module-brew&lt;&#x2F;code&gt; from the ExecStart line.&lt;&#x2F;p&gt;
&lt;p&gt;Overall I still like Bluefin a lot. I agree with most of the design decisions and appreciate that it&#x27;s been easy for me to change the decisions I dislike. I continue to run Dinosaur OS on my desktop systems and haven&#x27;t faced any catastrophic problems. If you want to create your own image based on Bluefin and want an example image to get started, check the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ChristopherBurg&#x2F;dinosaur-os&quot;&gt;Dinosaur OS repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Getting Started with Kettlebells</title>
          <pubDate>Fri, 06 Feb 2026 20:00:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/getting-started-with-kettlebells/</link>
          <guid>https://www.christopherburg.com/blog/getting-started-with-kettlebells/</guid>
          <description xml:base="https://www.christopherburg.com/blog/getting-started-with-kettlebells/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;I developed an interest in physical fitness about a decade and a half ago. This interest lead me to pursue martial arts, biking, and eventually kettlebell lifting (along with many other activities). The reason I got into kettlebell lifting is because I wanted to improve my strength and endurance. Kettlebells were tools I could use in the comfort of my small apartment. Now I have a home and a gym in my basement. I still lift kettlebells three or four times a week.&lt;&#x2F;p&gt;
&lt;p&gt;Getting started is the hardest part of any journey. This post is intended to help anybody who&#x27;s interested in starting kettlebell lifting. It&#x27;s not intended to be all encompassing. Too much information can be as bad as too little. Decision paralysis thwarts as many journeys as fear and laziness. Therefore, this post is opinionated. It will provide only a handful of options. Wherever options are provided, know that there are many more options out there. They aren&#x27;t brought up to cut down on the noise. The hardest part of any journey is also the most important. It&#x27;s more important to get started than to travel the optimal path. Any progress forward is better than no progress while you try to develop the optimal plan.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;note-on-units&quot;&gt;Note on Units&lt;&#x2F;h1&gt;
&lt;p&gt;Weights in this post will be provided in kilograms. Why would a post written by an American living in the United States use metric units? Two reasons. First, the historical unit of weight for kettlebells is the pood. The pood is an old imperial Russia unit. It&#x27;s equal to about 16 kg. This means kettlebell weights divide nicely into kilograms. Second, kettlebell lifting is an international sport. International sports use the metric system because almost everybody outside of the United States does.&lt;&#x2F;p&gt;
&lt;p&gt;To make your life a bit easier, here are the American equivalents to the weights used in this post (along with the weight in poods to illustrate my point about dividing nicely into kilograms):&lt;&#x2F;p&gt;
&lt;p&gt;16 kg = 35 lb (1 pood)
20 kg = 44 lb (1.25 poods)
24 kg = 53 lb (1.5 poods)
28 kg = 62 lb (1.75 poods)
32 kg = 70 lb (2 poods)&lt;&#x2F;p&gt;
&lt;h1 id=&quot;types-of-kettlebells&quot;&gt;Types of Kettlebells&lt;&#x2F;h1&gt;
&lt;p&gt;There are two major types of kettlebells: hard style and competition style. Hard style are typically made out of cast iron. The size of the bell depends on the weight. Heavier hard style kettlebells are larger than lighter ones. Competition style kettlebells are typically made out of steel. The size of the bell is the same regardless of the weight. A 16 kg competition style kettlebell is the same size as a 32 kg one.&lt;&#x2F;p&gt;
&lt;p&gt;I exclusive used hard style kettlebells until this year. Now I own both. I recommend hard style kettlebells when you&#x27;re starting out though. Hard style kettlebells are typically cheaper, often much cheaper, than competition style ones. You can do all of the traditional kettlebell lifts with either style of kettlebell so you might as well save yourself some money.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll see articles online claim that competition kettlebells don&#x27;t work well for two handed lifts such as two handed swings due to the handle size and shape. This isn&#x27;t my experience. I have no issue doing two handed swings with competition style kettlebells and I have large hands. You&#x27;ll also see articles claim that competition style kettlebells are more durable because they&#x27;re made of steel instead of cast iron. This is a distinction without a difference. The only way you&#x27;ll break either style of kettlebell is by being a complete dumbass.&lt;&#x2F;p&gt;
&lt;p&gt;The two hard style kettlebells I typically recommend are &lt;a href=&quot;https:&#x2F;&#x2F;repfitness.com&#x2F;products&#x2F;kettlebells-kg&quot;&gt;REP Fitness&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;bellsofsteel.us&#x2F;collections&#x2F;traditional-kettlebells&#x2F;products&#x2F;powder-coated-kettlebells&quot;&gt;Bells of Steel&lt;&#x2F;a&gt;. Both offer reasonably priced high-quality cast iron kettlebells with &quot;free&quot; shipping (free shipping means the price of shipping is baked into the price of the kettlebell). Buy whichever is cheaper at the time or in stock.&lt;&#x2F;p&gt;
&lt;p&gt;If your budget is tight, I&#x27;ve read reviews for &lt;a href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Yes4All-Solid-Cast-Kettlebell-Weights&#x2F;dp&#x2F;B0061ZLTYY&quot;&gt;Yes4All&lt;&#x2F;a&gt; kettlebells and they seem to be decent. I can&#x27;t recommend them since I&#x27;ve never seen them in person.&lt;&#x2F;p&gt;
&lt;p&gt;Another option I&#x27;ll note is &lt;a href=&quot;https:&#x2F;&#x2F;bellsofsteel.us&#x2F;collections&#x2F;adjustable-kettlebells&#x2F;products&#x2F;adjustable-kettlebell&quot;&gt;Bells of Steel adjustable kettlebells&lt;&#x2F;a&gt;. These are adjustable competition style kettlebells. They&#x27;re a good option if space is tight and you can afford to pay more upfront. I prefer fixed weight kettlebells because sometimes I like to switch weights during my workouts and changing an adjustable kettlebell&#x27;s weight is a slow process. That doesn&#x27;t matter when you&#x27;re starting out though.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;starting-weight&quot;&gt;Starting Weight&lt;&#x2F;h1&gt;
&lt;p&gt;Recommending a starting weight is tricky. Everybody is different. If you know anybody who owns kettlebells or dumbbells, ask them if you can press a few overhead. You want a weight that you can press overhead a few times. I&#x27;ll cite the most common rule of thumb. Men and women who haven&#x27;t done any strength training should start with 16 kg and 8 kg respectively. Men and women who have done some strength training should start with 20 kg and 12 kg respectively.&lt;&#x2F;p&gt;
&lt;p&gt;The difficulty of most kettlebell lifts can be adjusted through technique. If 20 kg is too light for two handed swings, change to one handed swings. If 20 kg is too heavy to strict press overhead, push press it. If a weight is beginning to feel too light, you can do more reps in less time to increase the difficulty. There are limits to this. If you can strict press a 24 kg kettlebell overhead, an 8 kg kettlebell isn&#x27;t going to be a challenge no matter what (that&#x27;s not to say an 8 kg kettlebell will be completely without value). Likewise, if you can barely strict press a 16 kg kettlebell overhead, you&#x27;re not going to get a 32 kg kettlebell overhead.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s better to go a bit light than a bit heavy when you&#x27;re starting. Beginners should focus on technique. It&#x27;s almost impossible to focus on technique if you&#x27;re barely able to move the kettlebell you&#x27;re using.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;programs&quot;&gt;Programs&lt;&#x2F;h1&gt;
&lt;p&gt;There are two programs I recommend to beginners: &lt;a href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Kettlebell-Strength-Secret-Soviet-Supermen&#x2F;dp&#x2F;0938045695&quot;&gt;Rite of Passage&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Kettlebell-Simple-Sinister-Revised-Updated&#x2F;dp&#x2F;0989892433&quot;&gt;Simple and Sinister&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Both programs require a single kettlebell. Both books do a good job of covering the technical aspects of the lifts they use. This is important. There are books for beginners, which go into detail on the how of lifts, and books for people who have experience, which typically don&#x27;t explain how to perform lifts. You want to learn how to properly perform lifts. There are also a lot of good videos online that go over the hows of lifts. If you can find a coach in your area, you can also hire them to teach you how to perform lifts (this is probably the fastest and safest option).&lt;&#x2F;p&gt;
&lt;p&gt;Rite of Passage is covered in the book Enter the Kettlebell. Between the two programs, I like this one slightly better because I like to press weight overhead. The program uses cleans, strict presses, swings, and snatches. There is also the option to add pull ups. The strict press is probably the lift that gives you the most bang for your buck. It&#x27;s the staple of many great kettlebell programs such as The Giant, Dry Fighting Weight, and The Armor Building Formula. Swings add an endurance component to the program. Snatches are something you will need to study for a while, but once you learn how to snatch, you unlock another lift that provides tremendous bang for your buck. Rite of Passage is a three day a week program.&lt;&#x2F;p&gt;
&lt;p&gt;Simple and Sinister used to be &lt;em&gt;the&lt;&#x2F;em&gt; recommended program for beginners. It&#x27;s the program I ran when I started. I&#x27;ve seen a number of people in online kettlebell communities argue that Simple and Sinister isn&#x27;t a good program. They&#x27;re full of shit in my opinion. Although I like Rite of Passage better, Simple and Sinister is an excellent program for people who haven&#x27;t done any strength training. The program uses Turkish get ups and swings. Turkish get ups teach you the invaluable skill of getting up off the ground while holding weight. It will improve your overall movement quality. It can also be run more frequently than Rite of Passage.&lt;&#x2F;p&gt;
&lt;p&gt;It doesn&#x27;t matter which program you pick. If you want to press weight overhead, go with Rite of Passage. If you want to get up off of the ground while holding weight, go with Simple and Sinister. If you can&#x27;t decide, flip a coin.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;That&#x27;s it. That&#x27;s the guide. Buy a kettlebell of appropriate weight, pick a program, and start lifting.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Complex Systems, Simple Answers</title>
          <pubDate>Fri, 06 Feb 2026 13:00:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/complex-systems-simple-answers/</link>
          <guid>https://www.christopherburg.com/blog/complex-systems-simple-answers/</guid>
          <description xml:base="https://www.christopherburg.com/blog/complex-systems-simple-answers/">&lt;p&gt;The universe we occupy is a very complex system that contains an uncountable number of complex systems within itself. One of the most common illustrations of this fact is weather forecasting. Weather forecasts are notorious for being inaccurate. The reason for this isn&#x27;t because the weatherman is incompetent, it&#x27;s because weather is a complex system. Edward Norton Lorenz, a meteorologist who founded chaos theory, noted the complexity of weather systems through &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Butterfly_effect&quot;&gt;the butterfly effect&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;He noted that the butterfly effect is derived from the example of the details of a tornado (the exact time of formation, the exact path taken) being influenced by minor perturbations such as a distant butterfly flapping its wings several weeks earlier.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The terrestrial weather system isn&#x27;t the only complex system. Space weather is a thing and a great deal of effort is put into predicting it. Like predicting terrestrial weather, predicting space weather is notoriously inaccurate. A few other complex systems are the movement of tectonic plates, propagation of electromagnetic radiation, and human behavior.&lt;&#x2F;p&gt;
&lt;p&gt;The human brain prefers simple answers. Prescientific man often explained complex phenomenon like weather as the action of gods and other supernatural beings. A typhoon wiping out a coastal city might be explained as the god of the sea punishing the inhabitants because they did something he didn&#x27;t like. Postscientific man isn&#x27;t that different. Although our scientific understanding has largely done away with accusing the gods for all that happens, we still end up creating simple answers for complex systems.&lt;&#x2F;p&gt;
&lt;p&gt;This comes up most frequently when people try to blame an individual or group for events that are the result of complex systems. Crime rates are a good example. Many factors play into crime rates. Socioeconomic conditions are the most commonly cited factors, but there are many more. The laws themselves play a huge role because an act isn&#x27;t a crime unless there&#x27;s a law against it. If the government passes a law against an until then lawful and very common activity (see Prohibition in the United States), the rate of crime increases. Weather plays a factor in crime rates. Cities in the northern hemisphere typically have a higher rate of violent crime during the summer. Individual attitudes are a major factor. If there is a large number of people who are unhappy with their current conditions, they are more likely to perform criminal acts such as vandalism. Many people ignore all of these factors and instead blame crime rates on blacks or immigrants and call it a day.&lt;&#x2F;p&gt;
&lt;p&gt;Political systems are also complex. A political system involves many people acting in the name of a government. These government vary from dictatorships to democracies. Different systems have different numbers of participants. The laws that get passed depend on a number of factors. Consider the legislative process in a common democratic system. A law might be introduced by a politician on behalf of a lobbyist. The lobbyist may want the law passed to prevent new competitors from entering their market. The politician might received benefits from the lobbyist ranging from paid vacations to promises of employment after they exit politics. Another law might be introduced because a politician sees people participating in activities they personally find immoral (again, see Prohibition in the United States). Once a law is introduced, there is a complex system of wheeling and dealing that commonly happens before the law is either rejected or passed into law. Many people ignore all of these factors and instead blame one political party for all the political ills in their country. Or they might blame the Jews or, more recently, British royalty (a new conspiracy theory gaining headway here in the United States).&lt;&#x2F;p&gt;
&lt;p&gt;What is an answer that doesn&#x27;t correctly answer a question? It&#x27;s bullshit. This provides some incite into why all of the perceived ills in the world seem to go unaddressed. Too many people have opted for bullshit rather than answers. But don&#x27;t be too harsh of those people. We humans aren&#x27;t well adapted to analyzing and addressing complex systems. All of us opt for bullshit. Some of us opt for it more than others, but we all do it. We especially do it when an answer can&#x27;t be identified. Our brains prefer simple answers and absolutely despise having no answers. When an individual accumulates too many questions without answers they often succumb to some form of nihilism, but that&#x27;s not the only option.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re willing to accept the fact that there are many questions without answers and come to peace with that fact, you can live in a sort of harmony. Many religions and philosophies exist around this idea. Stoicism emphasizes that you cannot control things outside of yourself but you can control how you react to events. Even though I cannot control who rules the nation, I can prevent myself from become emotional because of it. You don&#x27;t have to be angry because you don&#x27;t like the ruler of a nation. Daoism is centered on the Dao, the source of all existence. Critically Daoism teaches that the Dao is beyond our comprehension and therefore cannot be completely understood. This is a good frame of mind when living in a universe full of unanswerable questions. Accepting that you cannot fully comprehend events that are happening can help avoid falling under the influence of those who claim to have the answer and therefore from being manipulated by them.&lt;&#x2F;p&gt;
&lt;p&gt;I can&#x27;t say for certain what will make you happy in life. I will say that my life became happier once I accepted that I don&#x27;t know the answer to everything. That acceptance has allowed me to achieve peace by not getting worked up over things outside of my control. I know the universe is composed of complex systems that are incomprehensible to me and I enjoy that there is mystery in this universe. I live my life how I want and care not at all about the opinions of others. They don&#x27;t know the answers either. I strongly urge you to explore the same frame of mind and see if it bring you peace too.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Setup IPv6 in WireGuard</title>
          <pubDate>Tue, 30 Dec 2025 15:30:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/setup-ipv6-in-wireguard/</link>
          <guid>https://www.christopherburg.com/blog/setup-ipv6-in-wireguard/</guid>
          <description xml:base="https://www.christopherburg.com/blog/setup-ipv6-in-wireguard/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;Over the holiday break I finished upgrading all of my self-hosted services to make them available via IPv6. The upgrade was straightforward for all of my services except one: my WireGuard &lt;abbr title=&quot;Virtual Private Network&quot;&gt;VPN&lt;&#x2F;abbr&gt; server. I wanted to provide my VPN clients with IPv6 connectivity without using &lt;abbr title=&quot;Network Address Translation&quot;&gt;NAT&lt;&#x2F;abbr&gt;. Unfortunately most of the guides online use NAT for IPv4 and IPv6. NAT is necessary for IPv4, but goes against the very design of IPv6. I wanted to provide each client with a globally routable IPv6 address. This ended up being simple once I figured it out.&lt;&#x2F;p&gt;
&lt;p&gt;I previous wrote a guide &lt;a href=&quot;&#x2F;archive&#x2F;getting-a-static-ip-address-with-a-cheap-vps-and-wireguard&#x2F;&quot;&gt;for setting up WireGuard to share a public static IPv4 address&lt;&#x2F;a&gt;. The formatting was ruined in the transition from my old WordPress blog to this statically generated one, but it explains how to setup a WireGuard VPN server for IPv4. This post will explain how to setup a WireGuard VPN server for IPv6.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;preamble&quot;&gt;Preamble&lt;&#x2F;h1&gt;
&lt;p&gt;First a major caveat. As of this writing, I&#x27;ve had this iteration of my VPN server running for two days. I&#x27;ve tested it on my home network, on my phone&#x27;s cellular network, and on an IPv4 only network through my travel router. IPv6 appears to work in all cases. I haven&#x27;t finished thorough testing though. There may be a number of corner cases that don&#x27;t work. I will update this guide as I find and fix them. Therefore, if you find something broken, check back and I might have discovered it and posted the solution already.&lt;&#x2F;p&gt;
&lt;p&gt;I also pieced my setup together by taking bits and pieces of several online guides. I pillaged from &lt;a href=&quot;https:&#x2F;&#x2F;mkaczanowski.com&#x2F;ndppd-ipv6-ndp-proxy&#x2F;&quot;&gt;this guide&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;blog.frehi.be&#x2F;2022&#x2F;06&#x2F;11&#x2F;setting-up-wireguard-vpn-with-ipv6&#x2F;&quot;&gt;this guide&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;blog.miyuru.lk&#x2F;setup-wireguard-with-global-ipv6&#x2F;&quot;&gt;this guide&lt;&#x2F;a&gt;, and &lt;a href=&quot;https:&#x2F;&#x2F;utcc.utoronto.ca&#x2F;~cks&#x2F;space&#x2F;blog&#x2F;linux&#x2F;ModernProxyIPv6AndARP&quot;&gt;this guide&lt;&#x2F;a&gt;. If there are unnecessary configuration steps in this guide, I likely took it from one of these guides and didn&#x27;t test my final setup without the configuration. Such mistakes are entirely my fault.&lt;&#x2F;p&gt;
&lt;p&gt;In order to follow this guide, you need a source of IPv6 addresses and specifically a separate subnet from your hosting network. My &lt;abbr title=&quot;Internet Service Provider&quot;&gt;ISP&lt;&#x2F;abbr&gt; provides me with a &#x2F;48 prefix. This gives me roughly a bajillion addresses and subnets.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conventions-used-in-this-guide&quot;&gt;Conventions Used in This Guide&lt;&#x2F;h1&gt;
&lt;p&gt;For the purposes of this guide, I&#x27;m going to use the following IP addresses (&lt;code&gt;2001:db8&lt;&#x2F;code&gt; is the &lt;a href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3849&quot;&gt;prefix reserved for examples and documentation&lt;&#x2F;a&gt; for those not aware):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;2001:db8:1234::&#x2F;48&lt;&#x2F;code&gt;: The prefix provided by our ISP.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;2001:db8:1234:9999::&#x2F;64&lt;&#x2F;code&gt;: The subnet of our hosting network. The subnet &lt;code&gt;9999&lt;&#x2F;code&gt; was chosen for readability purposes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;2001:db8:1234:ffff::&#x2F;64&lt;&#x2F;code&gt;: The subnet provided to our WireGuard VPN clients. Throughout this guide remember that the subnet with numbers is for our hosting network and the subnet with letters is for our VPN clients.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;2001:db8:1234:9999::1&lt;&#x2F;code&gt;: The IPv6 address used by clients to connect to our WireGuard VPN server.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;2001:db8:1234:ffff::1&lt;&#x2F;code&gt;: The IPv6 address of the WireGuard interface. This differs from the above address in that a client only uses it after it has connected to the WireGuard VPN server through the above address. Once connected, clients will use this address as their gateway.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;2001:db8:1234:ffff::1:1&lt;&#x2F;code&gt;: The IPv6 address provided to the first of our WireGuard VPN clients. This address will be incremented subsequently so our second client will have an IPv6 address of &lt;code&gt;2001:db8:1234:ffff::1:2&lt;&#x2F;code&gt;, our third &lt;code&gt;2001:db8:1234:ffff::1:3&lt;&#x2F;code&gt;, etc.&lt;&#x2F;p&gt;
&lt;p&gt;I will also use &lt;code&gt;en0&lt;&#x2F;code&gt; as the name of the network interface of our WireGuard VPN server, &lt;code&gt;51820&lt;&#x2F;code&gt; as the port used to connect to WireGuard on our server, and &lt;code&gt;wg-vpn.conf&lt;&#x2F;code&gt; as the name of our WireGuard configuration file.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-actual-guide&quot;&gt;The Actual Guide&lt;&#x2F;h1&gt;
&lt;p&gt;The first thing you will need to do is ensure that the router between your hosting network and ISP is setup to route the subnet for our VPN clients to our VPN server. How you do this will depend on both your ISP and your router. For my Ubiquiti Cloud Gateway Ultra, I created a static route that routes the entire &lt;code&gt;2001:db8:1234:ffff::&#x2F;64&lt;&#x2F;code&gt; subnet to &lt;code&gt;2001:db8:1234:9999::1&lt;&#x2F;code&gt;. You will also need to configure your router&#x27;s firewall to allow incoming WireGuard traffic to your VPN server.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m hosting my VPN server on Fedora Server. By default, IPv6 forwarding isn&#x27;t enabled on Fedora Server. I enabled it by adding &lt;code&gt;net.ipv6.conf.all.forwarding=1&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;etc&#x2F;sysctl.conf&lt;&#x2F;code&gt; and issued the &lt;code&gt;sysctl -p&lt;&#x2F;code&gt; command to load the changes. I also added several other lines. &lt;code&gt;&#x2F;etc&#x2F;sysctl.conf&lt;&#x2F;code&gt; on my VPN server contains the following contents:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;net.ipv4.ip_forward=1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;net.ipv6.conf.en0.proxy_ndp=1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;net.ipv6.conf.all.forwarding=1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;net.ipv6.conf.en0.accept_ra=2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first line enables IPv4 forwarding. It&#x27;s enabled by default on Fedora Server, but I added the line just to ensure it&#x27;s always enabled. The second line enables proxying &lt;abbr title=&quot;Neighbor Discovery Protocol&quot;&gt;NDP&lt;&#x2F;abbr&gt; packets, which is used by IPv6 to discover neighboring devices. The final line enables router advertisements while IPv6 forwarding is enabled. I added it to the file when I was trying to dole out IPv6 addresses through another method. I&#x27;m not sure if it&#x27;s needed for my final setup. This is one of those potentially unnecessary configuration steps I mentioned in the preamble for this guide.&lt;&#x2F;p&gt;
&lt;p&gt;The only port I opened on my VPN server&#x27;s firewall is &lt;code&gt;51820&lt;&#x2F;code&gt; for &lt;abbr title=&quot;User Datagram Protocol&quot;&gt;UDP&lt;&#x2F;abbr&gt; packets. WireGuard only uses UDP so you don&#x27;t need to open the port for &lt;abbr title=&quot;Transmission Control Protocol&quot;&gt;TCP&lt;&#x2F;abbr&gt;. I also enabled masquerading capabilities. Masquerading capabilities are only needed for NAT, which means it&#x27;s only necessary for IPv4. You don&#x27;t need to enable it if you&#x27;re only using IPv6 on your VPN server.&lt;&#x2F;p&gt;
&lt;p&gt;Everything else happens in the WireGuard configuration file located at &lt;code&gt;&#x2F;etc&#x2F;wireguard&#x2F;wg-vpn.conf&lt;&#x2F;code&gt;. The first section of the configuration file sets up the interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[Interface]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PrivateKey = &amp;lt;Your Server&amp;#39;s Private Key&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Address = 2001:db8:1234:ffff::1&#x2F;64
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;SaveConfig = false
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ListenPort = 51820
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is all pretty basic. &lt;code&gt;PrivateKey&lt;&#x2F;code&gt; obvious contains your server&#x27;s private key that was generated with &lt;code&gt;wg genkey&lt;&#x2F;code&gt;. &lt;code&gt;Address&lt;&#x2F;code&gt; is the IPv6 address of the WireGuard interface. Clients will use this address as their gateway once they&#x27;ve connected to our VPN server. &lt;code&gt;SaveConfig&lt;&#x2F;code&gt; determines if the current configuration is saved when the WireGuard interface is shutdown. I generate my configuration files with Ansible so I don&#x27;t want any state maintained and disable this feature. &lt;code&gt;ListenPort&lt;&#x2F;code&gt; is the port through which clients will connect to the VPN server.&lt;&#x2F;p&gt;
&lt;p&gt;The next section is where the heavy lifting is done. &lt;code&gt;PostUp&lt;&#x2F;code&gt; commands run when the WireGuard server is being started. &lt;code&gt;PostDown&lt;&#x2F;code&gt; commands run when the WireGuard server is being stopped. In this case, the &lt;code&gt;PostDown&lt;&#x2F;code&gt; commands simply undo the &lt;code&gt;PostUp&lt;&#x2F;code&gt; commands. Also note that &lt;code&gt;%i&lt;&#x2F;code&gt; stands for the WireGuard interface name, which is &lt;code&gt;wg-vpn&lt;&#x2F;code&gt; since the configuration file is &lt;code&gt;wg-vpn.conf&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostUp = ip6tables -A FORWARD -i en0 -o %i -j ACCEPT;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostUp = ip6tables -A FORWARD -i %i -j ACCEPT;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostUp = ip -6 neighbor add proxy 2001:db8:1234:ffff::1:1 dev en0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostUp = ip -6 neighbor add proxy 2001:db8:1234:ffff::1:2 dev en0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostUp = ip -6 neighbor add proxy 2001:db8:1234:ffff::1:3 dev en0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostDown = ip6tables -D FORWARD -i en0 -o %i -j ACCEPT;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostDown = ip6tables -D FORWARD -i %i -j ACCEPT;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostDown = ip -6 neighbor del proxy 2001:db8:1234:ffff::1:1 dev en0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostDown = ip -6 neighbor del proxy 2001:db8:1234:ffff::1:2 dev en0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PostDown = ip -6 neighbor del proxy 2001:db8:1234:ffff::1:3 dev en0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;PostUp = ip6tables -A FORWARD -i en0 -o %i -j ACCEPT;&lt;&#x2F;code&gt; and &lt;code&gt;PostUp = ip6tables -A FORWARD -i %i -j ACCEPT;&lt;&#x2F;code&gt; enable IPv6 forwarding between the server&#x27;s network interface (&lt;code&gt;en0&lt;&#x2F;code&gt; in this example) and the WireGuard interface (&lt;code&gt;wg-vpn&lt;&#x2F;code&gt; in this example). This allowed IPv6 traffic originating from our clients to be forwarded out of the VPN server&#x27;s network interface and return traffic routed from the VPN server&#x27;s network interface to the appropriate client.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;PostUp = ip -6 neighbor add proxy 2001:db8:1234:ffff::1:1 dev en0&lt;&#x2F;code&gt; and the following two lines setup NDP proxies for each client. You could probably replace all of these lines with &lt;code&gt;PostUp = ip -6 neighbor add proxy 2001:db8:1234:ffff::&#x2F;64 dev en0&lt;&#x2F;code&gt;. Again I generate my configuration file with an Ansible playbook so it&#x27;s just as easy for me to loop through my list of clients and add a line per client. As mention above, the &lt;code&gt;PostDown&lt;&#x2F;code&gt; lines simply undo the &lt;code&gt;PostUp&lt;&#x2F;code&gt; lines when the WireGuard interface is stopped.&lt;&#x2F;p&gt;
&lt;p&gt;The final part of the file contains configuration information for each peer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[Peer]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PublicKey = &amp;lt;The Client&amp;#39;s Public Key&amp;gt; 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;AllowedIPs = 2001:db8:1234:ffff::1:1&#x2F;128
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[Peer]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PublicKey = &amp;lt;The Client&amp;#39;s Public Key&amp;gt; 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;AllowedIPs = 2001:db8:1234:ffff::1:2&#x2F;128
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[Peer]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PublicKey = &amp;lt;The Client&amp;#39;s Public Key&amp;gt; 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;AllowedIPs = 2001:db8:1234:ffff::1:3&#x2F;128
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is straightforward. &lt;code&gt;PublicKey&lt;&#x2F;code&gt; contains the client&#x27;s public key and &lt;code&gt;AllowedIPs&lt;&#x2F;code&gt; contains the IPv6 address we&#x27;re assigning to the client. Running &lt;code&gt;systemctl start wg-quick@wg-vpn.service&lt;&#x2F;code&gt; will bring the WireGuard interface up so clients can start connecting.&lt;&#x2F;p&gt;
&lt;p&gt;The configuration file for each client is simple:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[Interface]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Address = 2001:db8:1234:ffff::1:1&#x2F;64
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PrivateKey = &amp;lt;The Client&amp;#39;s Private Key&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[Peer]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;AllowedIPs = ::&#x2F;0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Endpoint = [2001:db8:1234:9999::1]:51820
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;PublicKey = &amp;lt;Your Server&amp;#39;s Public Key&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;Address&lt;&#x2F;code&gt; is the globally routable IPv6 address our VPN server is assigning to the client. &lt;code&gt;PrivateKey&lt;&#x2F;code&gt; is the client&#x27;s private key. There&#x27;s similarly little to say about the &lt;code&gt;[Peer]&lt;&#x2F;code&gt; section, which contains connection information for the VPN server.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;AllowedIPs = ::&#x2F;0&lt;&#x2F;code&gt; tells the client to route all IPv6 traffic through the WireGuard interface. &lt;code&gt;Endpoint&lt;&#x2F;code&gt; contains the IPv6 address clients use to connect to the VPN server. Note the square brackets. Because IPv6 addresses use &#x27;:&#x27; as a separator and &#x27;:&#x27; is also used by convention to separate an IP address from a port number, the square brackets are used to disambiguate the &#x27;:&#x27; in the IPv6 address from the &#x27;:&#x27; differentiating the port number.&lt;&#x2F;p&gt;
&lt;p&gt;When the client connects to the VPN server, it will have the globally routable IPv6 address of &lt;code&gt;2001:db8:1234:ffff::1:1&lt;&#x2F;code&gt;. If you connect to a website that tests IPv6 connectivity such as &lt;a href=&quot;https:&#x2F;&#x2F;test-ipv6.run&#x2F;&quot;&gt;this IPv4 and IPv6 connectivity test&lt;&#x2F;a&gt;, it should show &lt;code&gt;2001:db8:1234:ffff::1:1&lt;&#x2F;code&gt; as your IPv6 address.&lt;&#x2F;p&gt;
&lt;p&gt;There you have it, a WireGuard VPN server that provides clients with globally routable IPv6 addresses.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Advice for Self Hosters</title>
          <pubDate>Tue, 23 Dec 2025 19:45:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/advice-for-self-hosters/</link>
          <guid>https://www.christopherburg.com/blog/advice-for-self-hosters/</guid>
          <description xml:base="https://www.christopherburg.com/blog/advice-for-self-hosters/">&lt;p&gt;I just finished upgrading my final self hosted service to be available over IPv6. This was a staged upgrade handled over several months. All of the upgrades went smoothly. I attribute this success to years of stupidity. I&#x27;ve made a number of mistakes over the years. Some of them cost me a great deal of time and grief. But they all taught me valuable lessons. This post is a collection of some of those lessons. If You&#x27;re interested in self-hosting, I hope this advice proves valuable to you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-automate-everything&quot;&gt;1. Automate everything.&lt;&#x2F;h2&gt;
&lt;p&gt;This is probably the most important lesson I&#x27;ve learned over the years. The reason my server upgrades went so well is because all of my builds are automated. This allows me to treat all of my servers like cattle. When the time is right, I slaughter them. The time is usually right when there&#x27;s a major Fedora release. This is because most of my services run on Fedora Server at the moment. When a new major version is released, I don&#x27;t do a dnf system-upgrade. Instead I nuke the virtual machine that hosts my service, create a new one, and install everything from scratch.&lt;&#x2F;p&gt;
&lt;p&gt;My builds weren&#x27;t always automated. I manually built all of my servers for many years. Because of how arduous building some of my servers was, I would sometimes let the host operating system get woefully out of date. Eventually they would get to a point where I had to rebuild them. Sometimes this was due to a hardware failure. Sometimes it was due to a security vulnerability in my stack. What I discovered is that I didn&#x27;t remember all of the ins and outs of building the server. The task would take much longer because I had to rediscover everything I forgot. That isn&#x27;t a problem now that everything is automated.&lt;&#x2F;p&gt;
&lt;p&gt;This advice doesn&#x27;t apply only to building servers. Your backups should be automated. If your backups aren&#x27;t automated, they won&#x27;t get done. TLS certificate renewals should also be automated, especially now that certificate lifetimes are becoming shorter and shorter. &lt;em&gt;Everything&lt;&#x2F;em&gt; should be automated.&lt;&#x2F;p&gt;
&lt;p&gt;You&#x27;ll hear a lot of advice about the best automation tools. Each automation tool has ups and downs. I settled on Ansible for automating my system builds. It&#x27;s a good tool in general but configurations are done in YAML and YAML sucks. NixOS is an option more people seem to be adopting. The upside is the entire system build is declared in a configuration file. The downside is you have to use NixOS (I don&#x27;t think NixOS is bad, I just want to note that you can&#x27;t use the NixOS method with other operating systems). Don&#x27;t let yourself succumb to decision paralysis. Look up a few automation tools, pick one that looks good, and learn it. Even shell scripts are better than nothing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-consider-maintenance&quot;&gt;2. Consider maintenance.&lt;&#x2F;h2&gt;
&lt;p&gt;Every self hosted service will require maintenance. How easy or hard the maintenance is will determine how often it gets done. I&#x27;ll use TLS certificate management as an example. TLS certificates have a lifetime. That lifetime is &lt;a href=&quot;https:&#x2F;&#x2F;www.digicert.com&#x2F;blog&#x2F;tls-certificate-lifetimes-will-officially-reduce-to-47-days&quot;&gt;becoming shorter and shorter&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;From today until March 15, 2026, the maximum lifetime for a TLS certificate is 398 days.&lt;&#x2F;li&gt;
&lt;li&gt;As of March 15, 2026, the maximum lifetime for a TLS certificate will be 200 days.&lt;&#x2F;li&gt;
&lt;li&gt;As of March 15, 2027, the maximum lifetime for a TLS certificate will be 100 days.&lt;&#x2F;li&gt;
&lt;li&gt;As of March 15, 2029, the maximum lifetime for a TLS certificate will be 47 days.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Certificate management used to be much more complicated than today. You had to create an account with a certificate authority. Once you had an account, you had to verify your identity, usually by providing a picture of your government ID. Then you could get a certificate for your domains that was good for one to two years. The maintenance wasn&#x27;t insignificant, but you only had to go through the process every one or two years. However, it was often easier to create your own certificate authorities if your self hosted services that were only available on your local network or were only used by devices you controlled.&lt;&#x2F;p&gt;
&lt;p&gt;Now the maintenance burden is changing. As certificate lifetimes shrink, it&#x27;ll become infeasible to manually manage your TLS certificates. If automating your certificate maintenance isn&#x27;t possible, which it might not be for a service only available on your local network, you can still provide a secure connection to it using something like WireGuard. WireGuard keys have no prescribed lifetime. Depending on your situation, it might be easier to make your self hosted service only available over a WireGuard connection so you can avoid the hassle of dealing with certificates.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-simple-is-usually-better&quot;&gt;3. Simple is usually better.&lt;&#x2F;h2&gt;
&lt;p&gt;The best illustration of this rule is &lt;a href=&quot;&#x2F;blog&#x2F;if-you-re-reading-this&#x2F;&quot;&gt;my post about Caddy&lt;&#x2F;a&gt;. I migrated my reverse proxy server (and since then all of my HTTP servers) from Nginx to Caddy. The reason for this migration was that Caddy is much simpler to configure than Nginx. What can easily require two dozen lines of configuration in Nginx can often be done in a single line in Caddy.&lt;&#x2F;p&gt;
&lt;p&gt;My migration from OpenVPN to WireGuard was done for similar reasons. OpenVPN is a very flexible protocol. Unfortunately that flexibility comes with significant complexity and that complexity hides a lot of footguns. WireGuard on the other hand is opinionated. There&#x27;s very little flexibility. That lack of flexibility means configuring a WireGuard interface is simple and there are no obvious footguns.&lt;&#x2F;p&gt;
&lt;p&gt;Another example is my self hosted Nextcloud instance. My original Nextcloud instance was built (using Ansible, of course) by setting up the database backend, installing all of the required packages, copying the Nextcloud PHP files to the web root, and bringing everything up with systemd services. Then the Nextcloud team released their &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nextcloud&#x2F;all-in-one&quot;&gt;All-in-One Docker container&lt;&#x2F;a&gt;. Installing the All-in-One Docker container is &lt;em&gt;much&lt;&#x2F;em&gt; easier than building everything from scratch. I use it now because it&#x27;s simple to install and maintain (it can do automatic updates).&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll point to this blog as my final example. For many years this was a WordPress blog. Last year I finally &lt;a href=&quot;&#x2F;blog&#x2F;a-fresh-start&#x2F;&quot;&gt;migrated it to a static website&lt;&#x2F;a&gt;. I can&#x27;t overstate how much simpler this blog is to maintain. I no longer need a database or PHP-FPM. I don&#x27;t have to worry about the seemingly endless security issues that WordPress suffers. Best of all is I don&#x27;t have to worry about a WordPress update &lt;a href=&quot;https:&#x2F;&#x2F;wordpress.org&#x2F;gutenberg&#x2F;&quot;&gt;enshitifying writing and editing posts&lt;&#x2F;a&gt; (Gutenberg was such a terrible experience that I had a WordPress plugin to bring back the old editor). Now I can write my posts with any text editor I please.&lt;&#x2F;p&gt;
&lt;p&gt;I won&#x27;t go so far as to say that the simpler option is always better. But preferring the simpler option is a sane default.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;4-practice-your-recovery-plan&quot;&gt;4. Practice your recovery plan.&lt;&#x2F;h2&gt;
&lt;p&gt;I noted that you should have automated backups in my first suggestion. But a backup isn&#x27;t useful if you can&#x27;t restore the data. The only thing harder than getting people to backup their data is getting them to test restoring it.&lt;&#x2F;p&gt;
&lt;p&gt;Since I automate (see how important my first suggestion is) building my systems and I rebuild them every time there&#x27;s a major Fedora release, I have an opportunity to test my recovery plan roughly every six months (Fedora releases a new major version about twice a year). Part of my automated builds involves pulling data from my hot backup system. I know my restores work because I test them frequently. Get in the habit of testing yours. It&#x27;s much better to know how to restore backups when you don&#x27;t need them than to find out you can&#x27;t restore them when you do need them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;5-have-fun&quot;&gt;5. Have fun.&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ll level with you. If playing with operating systems, building servers, and learning networking doesn&#x27;t sound fun to you, self-hosting isn&#x27;t for you. If you&#x27;re not having fun when things are working, you definitely won&#x27;t have fun when things aren&#x27;t working.&lt;&#x2F;p&gt;
&lt;p&gt;Self-hosting is part research, part engineering, and part detective work. The research is the easy part. You think of a service you need, find what options are ability that fulfill that need, read the documentation (if there is no documentation, don&#x27;t use it), and end up with an idea of how well the service will fill your need and how easy it will be to setup and maintain. Then comes building the service. This is where the engineering part comes in. If you listen to my advice, you&#x27;ll automated the building process. But even manually building a service will require engineering effort. Then eventually something will go wrong. This is where the detective part comes in. What went wrong? What are the likely causes? How can those causes be address? Is it DNS? It can&#x27;t be DNS. It was DNS!&lt;&#x2F;p&gt;
&lt;p&gt;Life is too for voluntary suffering. If self-hosting isn&#x27;t a fun hobby to you, go find a hobby you&#x27;ll enjoy instead.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Gun Restrictions Do Not Work</title>
          <pubDate>Mon, 15 Dec 2025 17:30:00 -0600</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/gun-restrictions-do-not-work/</link>
          <guid>https://www.christopherburg.com/blog/gun-restrictions-do-not-work/</guid>
          <description xml:base="https://www.christopherburg.com/blog/gun-restrictions-do-not-work/">&lt;p&gt;There&#x27;s been &lt;a href=&quot;https:&#x2F;&#x2F;apnews.com&#x2F;article&#x2F;australia-shooting-sydney-bondi-beach-31f711f09f677d0f88091ece25f651c1&quot;&gt;another mass shooting in Australia&lt;&#x2F;a&gt;. The investigation is ongoing so I have no desire to focus on the minutia currently being reported. Much of it will likely change as the investigation progresses. What I want to focus on is that, despite promises made by Australian politicians and gun grabbers, gun restrictions failed once again. Australia already has &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gun_laws_of_Australia&quot;&gt;strict restrictions on gun ownership&lt;&#x2F;a&gt;. Australian law explicitly states that gun ownership is a privilege. Owning a gun requires a license and getting the license requires an applicant to provide a &quot;genuine reason&quot; that cannot be self-defense. If the government decides to bestow you with the privilege of a license, you must renew it every set number of years (which varies slightly depending on region).&lt;&#x2F;p&gt;
&lt;p&gt;Despite these already stringent restrictions, the Australian government has promised &lt;a href=&quot;https:&#x2F;&#x2F;apnews.com&#x2F;article&#x2F;australia-shooting-bondi-beach-sydney-3be76a51c820d547ee4697bd25c1bafd&quot;&gt;even more restriction&lt;&#x2F;a&gt; in response to the most recent mass shooting. Even I was a bit surprised by this announcement since I can&#x27;t imaging what other restrictions they can put in place. (That was sarcasm. I wasn&#x27;t even slightly surprised.) To use the phrase commonly misattributed to Einstein, &quot;The definition of insanity is doing the same thing over and over again and expecting a different result.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Advocates for restricting gun ownership have long promised that doing so would end gun violence. When the policies they advocate are passed into law, their promise goes unfulfilled. Their response is that gun ownership wasn&#x27;t restricted &lt;em&gt;enough&lt;&#x2F;em&gt; and demand even more restrictions. When those are passed into law, their promise still goes unfulfilled. It&#x27;s an endless cycle of innocent gun owners being punished without the promised end being reached. Australia is a prime example of this point. Australian gun owners have been ruthlessly bludgeoned by their politicians and yet mass shootings continue to happen there. Punishing them further won&#x27;t end gun violent in that country.&lt;&#x2F;p&gt;
&lt;p&gt;Advocates for restricting gun ownership always find a boogeyman to blame for the failure of their policies. A common one here in the United States is that state level gun restrictions fail because people smuggle guns from neighboring states that have fewer restrictions. This shouldn&#x27;t be an issue in Australia since the entire country has strict restrictions and is surrounded by an ocean. Their only noteworthy neighbor &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gun_law_in_New_Zealand&quot;&gt;has arguably stricter restrictions&lt;&#x2F;a&gt;. A boogeyman that has become trend in the last few years is 3D printers. This boogeyman at least relates to the real reason gun restrictions don&#x27;t work.&lt;&#x2F;p&gt;
&lt;p&gt;The reason gun restrictions will never work is because guns are mechanically simple devices. Anybody can build a viable gun from parts found in a hardware store as &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Assassination_of_Shinzo_Abe&quot;&gt;Tetsuya Yamagami demonstrated&lt;&#x2F;a&gt;. Restrictions against gun ownership only work against those who desire to remain within the law. People who desire to commit acts of violence have no concern about remaining within the law so gun restrictions don&#x27;t work against them. They will acquire the means to commit violence one way or another. The only outcome of gun restrictions is that the law abiding are made defenseless against the lawless.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Just Do It</title>
          <pubDate>Fri, 28 Nov 2025 12:00:00 +0000</pubDate>
          <author>Christopher Burg</author>
          <link>https://www.christopherburg.com/blog/just-do-it/</link>
          <guid>https://www.christopherburg.com/blog/just-do-it/</guid>
          <description xml:base="https://www.christopherburg.com/blog/just-do-it/">&lt;p&gt;Knowledge builds upon knowledge. If you study two different fields of knowledge, you inevitably discover connections between them. The more I study physical fitness, the more associations I discover between it and economics.&lt;&#x2F;p&gt;
&lt;p&gt;Ludwig von Mises in his magnum opus &lt;a href=&quot;https:&#x2F;&#x2F;mises.org&#x2F;library&#x2F;book&#x2F;human-action&quot;&gt;Human Action&lt;&#x2F;a&gt; opens part one with the chapter appropriately titled Acting Man wherein he describes the field of praxeology, the study of human action. Whether you subscribe to the Austrian tradition of economics or not, I would highly recommend reading part one of Human Action. What it states applies to many fields including physical fitness. For the purposes of this post, I will open with the following excerpt:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;To express wishes and hopes and to announce planned action may be forms of action in so far as they aim in themselves at the realization of a certain purpose. But they must not be confused with the actions to which they refer. They are not identical with the actions they announce, recommend, or reject. Action is a real thing. What counts is a man&#x27;s total behavior, and not his talk about planned but not realized acts.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Here is where most people falter. They recognize that they exist in a less satisfactory state and express a desire to move to a more satisfactory state and that&#x27;s where they stop. They never take action the action that they express.&lt;&#x2F;p&gt;
&lt;p&gt;This came up recently in a conversation between a friend and myself. More than a year ago after an uncomfortable discussion with her doctor she had expressed a desire to lose weight and improve her overall fitness. To her credit, she sought out a personal trainer. Unfortunately she found a personal trainer who is too ready to tell clients what they want to hear, not what they need to hear. My friend went through a few life changes that let her slip into the vortex of &#x27;being too busy.&#x27; She had reverted to old dietary habits and was skipping workout sessions. The progress she made over the last year started to slip away.&lt;&#x2F;p&gt;
&lt;p&gt;This is when her personal trainer should&#x27;ve taken a page from Mises and told her that expressing intent and taking action towards achieving that intent are not the same. Instead she said a bunch of platitudes like saying that the important part is wanting the change. The implication being that wanting the change will motivate my friend to take action &#x27;when she&#x27;s ready.&#x27; While there are efforts that can be obtained through words, physical fitness isn&#x27;t one of them.&lt;&#x2F;p&gt;
&lt;p&gt;Friends don&#x27;t come to me to hear what they want to hear. They come to me to hear my opinion, which is typically expressed with the subtlety of a sledgehammer to the face. My friend explained her recent situation. I told her she should find a different personal trainer, one who is willing to be upfront with clients. I closed with a phrase that I&#x27;m probably saying too often now, &quot;To quote the Nike motto, you need to &#x27;just do it.&#x27;&quot;&lt;&#x2F;p&gt;
&lt;p&gt;From a praxeological perspective, wanting to lose weight and be more physically fit is no different than wanting a new car or house. You exists in a less satisfactory state; being fat, unfit, without a new car, or without a new house; and you want substitute it with a more satisfactory state. Expressing your desire is an action, but it is not the action being expressed. Expressing a desire to lose weight is the act of expression, not the act of controlling calories or exercising.&lt;&#x2F;p&gt;
&lt;p&gt;In order to realize your goals in life, you need to perform the actions you express. Wanting the change, despite the claims of a certain personal trainer, is not the important part. It is a part, you need to feel that you are in a less satisfactory state before you can move to a more satisfactory one, but it is not the part that will allow you to realize your goal.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
