<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>A Geek with Guns</title>
    <link rel="self" type="application/atom+xml" href="https://www.christopherburg.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://www.christopherburg.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-02-13T13:00:00-06:00</updated>
    <id>https://www.christopherburg.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Disabling Homebrew in Dinosaur OS</title>
        <published>2026-02-13T13:00:00-06:00</published>
        <updated>2026-02-13T13:00:00-06:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/disabling-homebrew-in-dinosaur-os/"/>
        <id>https://www.christopherburg.com/blog/disabling-homebrew-in-dinosaur-os/</id>
        
        <content type="html" 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;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting Started with Kettlebells</title>
        <published>2026-02-06T20:00:00-06:00</published>
        <updated>2026-02-06T20:00:00-06:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/getting-started-with-kettlebells/"/>
        <id>https://www.christopherburg.com/blog/getting-started-with-kettlebells/</id>
        
        <content type="html" 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;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Complex Systems, Simple Answers</title>
        <published>2026-02-06T13:00:00-06:00</published>
        <updated>2026-02-06T13:00:00-06:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/complex-systems-simple-answers/"/>
        <id>https://www.christopherburg.com/blog/complex-systems-simple-answers/</id>
        
        <content type="html" 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;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setup IPv6 in WireGuard</title>
        <published>2025-12-30T15:30:00-06:00</published>
        <updated>2025-12-30T15:30:00-06:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/setup-ipv6-in-wireguard/"/>
        <id>https://www.christopherburg.com/blog/setup-ipv6-in-wireguard/</id>
        
        <content type="html" 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;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Advice for Self Hosters</title>
        <published>2025-12-23T19:45:00-06:00</published>
        <updated>2025-12-23T19:45:00-06:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/advice-for-self-hosters/"/>
        <id>https://www.christopherburg.com/blog/advice-for-self-hosters/</id>
        
        <content type="html" 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;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gun Restrictions Do Not Work</title>
        <published>2025-12-15T17:30:00-06:00</published>
        <updated>2025-12-15T17:30:00-06:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/gun-restrictions-do-not-work/"/>
        <id>https://www.christopherburg.com/blog/gun-restrictions-do-not-work/</id>
        
        <content type="html" 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;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Just Do It</title>
        <published>2025-11-28T12:00:00+00:00</published>
        <updated>2025-11-28T12:00:00+00:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/just-do-it/"/>
        <id>https://www.christopherburg.com/blog/just-do-it/</id>
        
        <content type="html" 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;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why I Don&#x27;t Have A Smart Home</title>
        <published>2025-11-22T12:00:00+00:00</published>
        <updated>2025-11-22T12:00:00+00:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/why-i-don-t-have-a-smart-home/"/>
        <id>https://www.christopherburg.com/blog/why-i-don-t-have-a-smart-home/</id>
        
        <content type="html" xml:base="https://www.christopherburg.com/blog/why-i-don-t-have-a-smart-home/">&lt;p&gt;Based on the title of this post, you probably assume that this post will be a long rant about the privacy nightmare that is smart devices. It&#x27;s not. I&#x27;ve covered that ad nauseam and they don&#x27;t apply if you make use of self-hosted open source projects like &lt;a href=&quot;https:&#x2F;&#x2F;www.home-assistant.io&#x2F;&quot;&gt;Home Assistant&lt;&#x2F;a&gt;. I self-host all of my own services already so I have the technical knowhow to setup a smart home using Home Assistant. I still don&#x27;t though.&lt;&#x2F;p&gt;
&lt;p&gt;My reason can be summed up in a single word: maintenance. The older I get, the more I find myself considering the future maintenance of any project I undertake. I won&#x27;t undertake a project unless the gains outweigh the maintenance that will be required down the road. A dumb home is relatively low maintenance (as far as homes go). Light switches, thermostats, and garage door buttons seldom break. If one of those dumb controls isn&#x27;t working, troubleshooting is pretty straight forward. The first culprit is usually power. Is the breaker off? Is the control on a circuit with a ground fault circuit interrupter? If so, is that tripped? If all else fails, a quick prodding with a multimeter will tell you whether there&#x27;s power at the control. If the control is receiving power and is still not working, there&#x27;s a pretty good chance the control is broken. Swapping out things like light switches, thermostats, and garage door buttons is straight forward.&lt;&#x2F;p&gt;
&lt;p&gt;The devices that those controls control are often more complicated. Troubleshooting your furnace in the dead of winter or your air conditioner in the height of summer can require some knowhow, but that doesn&#x27;t change if you have a smart home. My biggest gripe with smart homes is they add complexity to the troubleshooting and repair process. Troubleshooting a basic electrical circuit is fairly straight forward. If I turn on a light switch and the associated light doesn&#x27;t come on, the first thing I check is the light bulb. Swapping a light bulb takes seconds. If the light still doesn&#x27;t come on, I check the breaker box, which also takes seconds. I&#x27;ve never had a light switch break, but if I get to the point where I discover the switch itself is bad, I go to the hardware store, buy a replacement, and spend a few minutes replacing the bad one of the good one.&lt;&#x2F;p&gt;
&lt;p&gt;When you introduce smart devices, you necessarily introduce networking and software. Both are complicated. Many smart controls and devices are wireless, which adds complexity on top of networking. Anybody who has had to troubleshoot an intermittent Wi-Fi issue knows how much of a pain in the ass it can be. With a dumb home, if my Wi-Fi goes down, my lights, heating, air conditioning, and garage doors still work.&lt;&#x2F;p&gt;
&lt;p&gt;The complexity introduces another problem too. I maintain the entire technology infrastructure in my home because my wife doesn&#x27;t have the technical background I do. I periodically have to travel for work. With a dumb home, if something goes wrong when I&#x27;m away, she can call one of several people we know who can come over and likely figure out the problem. If something is seriously broken, she can call an electrician or plumber. This isn&#x27;t the case with a smart home. An electrician or plumber isn&#x27;t going to troubleshoot a complex networking issue. Even a system administrator won&#x27;t be able to fix it because they don&#x27;t know how the network is setup and even if they did, they don&#x27;t have access to any of the systems.&lt;&#x2F;p&gt;
&lt;p&gt;Smart homes have a lot of interesting capabilities, but none of them are worth the maintenance for me. Were I single and didn&#x27;t have work, shooting competitions, martial arts, and a bunch of other things fighting for my limited time, I&#x27;d be more inclined to explore the idea. But I&#x27;m not single and I&#x27;d much rather spend my time at the gun range and dojo than debugging a networking issue so I can get my lights to turn on again.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Long Cycle Training</title>
        <published>2025-11-21T12:00:00+00:00</published>
        <updated>2025-11-21T12:00:00+00:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/long-cycle-training/"/>
        <id>https://www.christopherburg.com/blog/long-cycle-training/</id>
        
        <content type="html" xml:base="https://www.christopherburg.com/blog/long-cycle-training/">&lt;p&gt;If you could only do one exercise for the rest of your life, what would it be? Setting aside the absurdity of the question, most thought exercises are built on absurdity after all, I would say the double kettlebell clean and jerk. If a particularly clever person asked the question and pointed out that those are two exercises, I would say double kettlebell long cycle. Checkmate smartass.&lt;&#x2F;p&gt;
&lt;p&gt;Long cycle training is a shorthand way of saying chained clean and jerks. I believe the term comes from the kettlebell sport world, but every time I think I know the source of a term, somebody proves me wrong. Suffice to say that long cycle is a kettlebell sport event. It&#x27;s also a damn good strength training exercise. The thing I love about the exercise is the efficiency. If we analyze the clean and jerk through Dan John&#x27;s five basic human movements; push, pull, hinge, squat, and loaded carry; the clean and jerk definitely involves four of them and can arguably involve all five. The clean is a hinge and a pull and the jerk is a squat (two actually) and a push. If you hold the weights in the rack position, you can argue it&#x27;s a loaded carry too. The clean and jerk basically hits everything. When you chain them together into long sets, they also work your cardio system (which is great if you, like me, don&#x27;t really enjoy dedicated cardio work). In a half hour of long cycle training, you get a lot of work done that hits most if not all of your basic movements.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve trained long cycle on and off over the years, but this year I really discovered my love for it. Besides a few short breaks to train other lifts, this year I&#x27;ve focused on long cycle training. Last month I read Denis Vasilev&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;www.denisvasilevkettlebell.com&#x2F;product-page&#x2F;kettlebell-sport-a-training-methodology-tutorial-by-denis-vasilev-hardcopy&quot;&gt;Kettlebell Sport Training Methodology&lt;&#x2F;a&gt;. This was my first foray into kettlebell sport. I&#x27;ve always focused on hard style. I&#x27;m still performing hard style clean and jerks, but I wanted to read about a different training perspective.&lt;&#x2F;p&gt;
&lt;p&gt;For those who don&#x27;t know, the long cycle event in kettlebell sport involves the lifter performing clean and jerks for 10 minutes without putting the kettlebells down. Denis Vasilev is one of the greats and won numerous world championships. He&#x27;s completed over 100 clean and jerks in 10 minutes with a pair of 32 kg kettlebells. I figured it was worth my time to read what the man has to say. The most useful fact I took from his book was the total volume of clean and jerks he&#x27;s performed. It makes sense. The more you practice something, the better you get at it. If you want to get good at writing, you need to write a lot. If you want to get good at running, you need to run a lot. If you want to get good at clean and jerks, you need to do clean and jerks a lot.&lt;&#x2F;p&gt;
&lt;p&gt;Based on that idea, I&#x27;ve been experimenting with a slightly different training methodology over the last two weeks. I have a nice set of kettlebells. I have pairs of every weight from 8 kg up to 48 kg in 4 kg increments. That gives me a lot of flexibility. My methodology for the last two weeks is broken down into three days: a high rep with light weight day, a medium rep with medium weight day, and a low rep with heavy weight day (light, medium, and heavy for me obviously). I use ladder sets and add more rungs with lighter weights. Each day I set my timer for 30 minutes and crank out as many good quality ladder sets as I can.&lt;&#x2F;p&gt;
&lt;p&gt;I had to move my Sunday session to Monday due to a septic backup (the joys of owning a home). So on Monday I did ladders of 2, 3, 5, and 10 using a pair of 24 kg kettlebells. The sets of 10 were brutal. I completed 50 total reps. Tuesday I did ladders of 2, 3, and 5 using a pair of 28 kg kettlebells. Again I completed 50 total reps. I wasn&#x27;t expecting that since I completed 40 total reps with this setup last week. I&#x27;m not complaining. Tonight I did sets of two with a pair of 32 kg kettlebells. I can squeeze out a set of three, but the third rep isn&#x27;t a clean as I want so I&#x27;m sticking to sets of two for now. I completed a total of 28 reps. Therefore, I completed a total of 128 clean and jerks this week.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s too early for me to declare this methodology good, bad, or merely adequate. I am enjoying it though and each day is challenging for different reasons. The high reps with light weight day challenges my endurance, especially the sets of 10. It&#x27;s as much a mental game as a physical game to get through those sets. The medium reps with medium weight day is a good overall challenge of strength and endurance. The high reps with heavy weight day is a challenge of my strength. I think this will be a good method for closing the year. I&#x27;ll try to remember to report back my thoughts after week six.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Discipline to Do Less</title>
        <published>2025-10-20T12:00:00+00:00</published>
        <updated>2025-10-20T12:00:00+00:00</updated>
        
        <author>
          <name>
            Christopher Burg
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.christopherburg.com/blog/the-discipline-to-do-less/"/>
        <id>https://www.christopherburg.com/blog/the-discipline-to-do-less/</id>
        
        <content type="html" xml:base="https://www.christopherburg.com/blog/the-discipline-to-do-less/">&lt;p&gt;The topic of discipline usually comes up in conversations about physical fitness in the context of needing to do the work. You need to develop the discipline to do your workouts every week. You need to develop the discipline to eat a healthy diet. You need to develop the discipline to get enough sleep. But there&#x27;s another side to discipline as it pertains to physical fitness. You need the discipline to do less.&lt;&#x2F;p&gt;
&lt;p&gt;This will likely sound crazy to anybody who doesn&#x27;t workout regularly. Why would anybody need discipline to do less, they are likely to wonder. The fact of the matter is exercise becomes addictive once you get into the habit of doing it regularly. This isn&#x27;t surprisingly since strength training, like running and other forms of physical exercises, releases endorphins. But I don&#x27;t think you can fully understand this until you experience it. Suffice to say that once you regularly workout, you want to workout more.&lt;&#x2F;p&gt;
&lt;p&gt;There is such a thing as too much of a good thing. Exercise is definitely an example of this. Your body requires two things to grow: stimulus and time to adapt. Exercise is the stimulus. Recovery is the time to adapt. If you exercise too much, your body doesn&#x27;t have the necessary time to recover. The sinister thing about this is that it doesn&#x27;t happen immediately. It often takes a few weeks before you feel the effects of too much exercise. When you do feel the effects, it&#x27;s often in the form of an injury.&lt;&#x2F;p&gt;
&lt;p&gt;I recently finished going through a modified version (I replaced the overhead presses and front squat days with clean and jerk days) of phase one of Geoff Neupert&#x27;s Maximorum program. It&#x27;s a deceptive program. The first few weeks look fairly reasonable. This has lead a lot of people on various kettlebell forums to ask what they should add to the program. I&#x27;ve run through this program as written. I can tell you that you shouldn&#x27;t add anything to it. The reason is cumulative fatigue. While the program is pretty reasonable for the first two or three weeks, the cumulative fatigue plus the more challenging sets makes the tail end of the first six weeks brutal. Then there are six more weeks after that.&lt;&#x2F;p&gt;
&lt;p&gt;Maximorum isn&#x27;t the only program like this. I&#x27;ve seen people ask what they can add to Pavel Tsatsouline&#x27;s Rite of Passage, Dan John&#x27;s Armor Building Formula, and most other popular kettlebell programs. Rite of Passage includes an optional variety day. It&#x27;s meant to be a day where you practice movements, do mobility work, and other low impact things. People often turn it into a full blown lifting day and it bites them in the ass. Turning the variety day into a full blown lifting day invites cumulative fatigue to the show up and before you know it cumulative fatigue brings its good friend injury.&lt;&#x2F;p&gt;
&lt;p&gt;Any off days are a great opportunity to do too much. Depending on my schedule, I run either a three or four days a week kettlebell program. Two days a week I do two different martial arts. One art is a form of kenjutsu and the other is a form of iaido. Both are much lower in intensity than combat sports like judo, boxing, or Brazilian jujitsu. This allows me to use them as active recovery days. That leaves me with one or two free days. I admit that I have a problem with filling that day or two with extra work that I shouldn&#x27;t be doing. It takes real discipline for me to leave those as recovery days where I do, at most, light to moderate cardio. It&#x27;s too easy to do a &quot;light&quot; lifting session on those days. Those sessions might seem easy, but they interfere with my recovery from my actual lifting days by adding to the cumulative fatigue. Whenever I give into that urge, I end up regretting it after a week or two.&lt;&#x2F;p&gt;
&lt;p&gt;Developing the discipline to regularly exercise is important. Once you&#x27;re regularly exercising, developing the discipline to not do too much is equally important.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
