2374 lines
242 KiB
XML
2374 lines
242 KiB
XML
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||
<channel>
|
||
<title>Bryce Vandegrift's Website</title>
|
||
<link>https://brycev.com/</link>
|
||
<description>Updates to Bryce Vandegrift's blog</description>
|
||
<language>en-us</language>
|
||
|
||
<atom:link href="https://brycev.com/rss.xml" rel="self" type="application/rss+xml" />
|
||
|
||
|
||
<item>
|
||
<title>New Domain Name</title>
|
||
<link>https://brycev.com/blog/new-domain-name/</link>
|
||
<pubDate>Wed, 14 May 2025 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/new-domain-name/</guid>
|
||
<description><p>It&rsquo;s about time that I got a new domain name for my website. My current/old
|
||
domain name, <a href="https://brycevandegrift.xyz">brycevandegrift.xyz</a>, is quite a
|
||
cumbersome and unorthodox domain name. It&rsquo;s not easy to remember and the
|
||
<code>.xyz</code> domain name can also be somewhat confusing. Not only that, but I&rsquo;ve had
|
||
less tech literate people tell me that they thought my domain wasn&rsquo;t actually
|
||
a real domain name. Add to the fact that many email services automatically
|
||
mark <code>.xyz</code> domain names as spam, and you can see why I want to change my
|
||
domain name.</p>
|
||
<p>I originally got a <code>.xyz</code> domain name because it was fairly cheap (only
|
||
<strong>99¢</strong>!), however using my <em>full</em> name was probably not the right way to go.
|
||
My emails also got marked as spam or just filtered by some email servers.</p>
|
||
<h2 id="new-domain-name">New domain name</h2>
|
||
<p>I&rsquo;ve been eyeballing <strong><a href="https://brycev.com">brycev.com</a></strong> for quite some time and
|
||
I finally pulled the trigger and bought it. <code>.com</code> domains are usually the
|
||
most memorable and trusted domain names out there so I decided to go with
|
||
that. Right now <code>brycev.com</code> just redirects to <code>brycevandegrift.xyz</code>, but over
|
||
the next few weeks I will be slowly replacing instances of my old domain name
|
||
with my new domain name. I will probably also keep <code>brycevandegrift.xyz</code>
|
||
indefinitely and have it redirect to <code>brycev.com</code>.</p>
|
||
<p>I&rsquo;ll slowly migrate my website, email, and XMPP server over to using my new
|
||
domain name. I&rsquo;ll also need to issue a new GPG/PGP key for my new email
|
||
address. So keep an eye out and I&rsquo;ll post any necessary updates.</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Blogging on Paper</title>
|
||
<link>https://brycev.com/blog/blogging-on-paper/</link>
|
||
<pubDate>Mon, 31 Mar 2025 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/blogging-on-paper/</guid>
|
||
<description><p>I&rsquo;ve been wanting to post more articles on my blog, however I often
|
||
find myself away from my computer or I often have more important
|
||
tasks to take care of on my computer. Either way, I can&rsquo;t write
|
||
as many articles for my blog as I would like to on my computer.</p>
|
||
<p>It wasn&rsquo;t until I read a blog post by Ray Patrick (who
|
||
has sadly taken down his blog) titled
|
||
<a href="https://web.archive.org/web/20240229190333if_/https://raypatrick.xyz/blog/2024/01/24/in-praise-of-the-manual-typewriter/">&ldquo;In Praise of the Manual Typewriter&rdquo;</a>
|
||
that I formed an idea. I could type out the articles
|
||
that I want to compose on a typewriter. This would allow me to
|
||
formulate any articles that I would like to later post to my blog.
|
||
I could also handwrite any articles if needed.</p>
|
||
<p>I&rsquo;ve been in possession of a Royal Mercury typewriter
|
||
for quite some time now and I have been looking to get some use
|
||
out of it. It&rsquo;s a somewhat small, portable typewriter that is easy
|
||
to carry around. This means that I can take it with me almost anywhere
|
||
that I go. And guess what? I don&rsquo;t have to constantly keep it charged
|
||
like a laptop&hellip;although it does need paper and ink which could be
|
||
a slight disadvantage.</p>
|
||
<p>I also realized that I could use OCR (Optical Character
|
||
Recognition) programs like <a href="https://tesseract-ocr.github.io/">Tesseract</a>
|
||
in order to easily convert
|
||
anything that I type or write while I&rsquo;m away from my computer into
|
||
text to put on my blog. I might have to do some manual editing and
|
||
correcting once it&rsquo;s converted into plaintext, but I think that
|
||
the extra effort would be well worth it.</p>
|
||
<p>This method of writing articles might very much help me
|
||
to write more in general, not just for my blog. Keep an eye out
|
||
though, you might see me putting more on my blog/website within the
|
||
upcoming months.</p>
|
||
<hr>
|
||
|
||
|
||
<figure ><a href="https://brycev.com/p/paper-blog.webp"><img src="https://brycev.com/p/paper-blog.webp" alt="This post written on paper"></a></figure>
|
||
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>OpenBSD Server: smtpd</title>
|
||
<link>https://brycev.com/blog/openbsd-smtpd/</link>
|
||
<pubDate>Fri, 07 Mar 2025 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/openbsd-smtpd/</guid>
|
||
<description><p>At last, the final part to this series. You can catch up on parts 1 and 2
|
||
<a href="https://brycev.com/blog/openbsd-server-install">here</a> and <a href="https://brycev.com/blog/openbsd-httpd">here</a> respectively.
|
||
Setting up an email server is no easy task, it takes a lot of configuration and
|
||
sometimes trial and error. This guide should be good enough for small email
|
||
servers that don&rsquo;t get too many emails.
|
||
So let&rsquo;s go ahead and finally setup an email server for our system.</p>
|
||
<h2 id="some-needed-packages">Some Needed Packages</h2>
|
||
<p>First, we need to install some extra packages for our email server to work the
|
||
way we want it to. We will need <code>rspamd</code> to filter out spam, <code>dovecot</code> in order
|
||
to use IMAP and or POP3 to view our emails, and we will need
|
||
<code>dovecot-pigeonhole</code> to help sort our emails:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas pkg_add rspamd-- dovecot-- dovecot-pigeonhole-- opensmtpd-filter-rspamd
|
||
</span></span></code></pre></div><h2 id="dns-records">DNS Records</h2>
|
||
<p>In order for our email server to properly work and also to not get filtered or
|
||
marked as spam, we will need to add some DNS records.</p>
|
||
<h3 id="mx-record">MX Record</h3>
|
||
<p>A MX record is required to tell other SMTP servers where to deliver emails
|
||
sent to our address. For our MX record we can have our emails redirected to
|
||
<code>mail.example.com</code><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. When creating an MX record, this is what it should look
|
||
like:</p>
|
||
<pre tabindex="0"><code>Record Type Host Value MX Priority TTL
|
||
V V V V V
|
||
MX @ mail.example.com 0 3600
|
||
</code></pre><p>Our record type should (obviously) be MX, our host should be empty (which is
|
||
sometimes represented as an <code>@</code> symbol), our value is where our mail should go
|
||
which is <code>mail.example.com</code>, our MX priority should just be 0 for now, and our
|
||
TTL is set to 3600 seconds (or 1 hour).</p>
|
||
<p>For reference, this is how my MX record is setup for <code>brycevandegrift.xyz</code>:</p>
|
||
|
||
|
||
<figure ><a href="https://brycev.com/p/mx-record.webp"><img src="https://brycev.com/p/mx-record.webp" alt="My personal MX record"></a></figure>
|
||
|
||
<h3 id="spf-record">SPF Record</h3>
|
||
<p>Our SPF record is vital in order to detect spam. It defines what servers can
|
||
send emails from a domain. In our case, only <code>mail.example.com</code> will be sending
|
||
emails on our behalf, so we can set our SPF record accordingly:</p>
|
||
<pre tabindex="0"><code>Record Type Host Value TTL
|
||
V V V V
|
||
TXT @ v=spf1 mx all 3600
|
||
</code></pre><p>Our SPF record is just a normal TXT record that has the string &ldquo;v=spf1 mx all&rdquo;
|
||
in it which allows emails to be sent in reference to our MX record.</p>
|
||
<h3 id="dkim-record">DKIM Record</h3>
|
||
<p>We need a DKIM record in order to cryptographically sign and verify the
|
||
emails we send. Without DKIM your emails will <strong>NOT</strong> be accepted by most email
|
||
servers and will be marked as spam. In order to use DKIM we will need to
|
||
generate our private and public keys on our system. We can generate our keys and
|
||
give them the correct permissions like so:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#75715e"># First enter root session</span>
|
||
</span></span><span style="display:flex;"><span>su
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>umask <span style="color:#ae81ff">077</span>
|
||
</span></span><span style="display:flex;"><span>install -d -o root -g wheel -m <span style="color:#ae81ff">755</span> /etc/mail/dkim
|
||
</span></span><span style="display:flex;"><span>install -d -o root -g _rspamd -m <span style="color:#ae81ff">775</span> /etc/mail/dkim/private
|
||
</span></span><span style="display:flex;"><span>openssl genrsa -out /etc/mail/dkim/private/example.com.key <span style="color:#ae81ff">2048</span>
|
||
</span></span><span style="display:flex;"><span>openssl rsa -in /etc/mail/dkim/private/example.com.key -pubout -out /etc/mail/dkim/example.com.pub
|
||
</span></span><span style="display:flex;"><span>chgrp _rspamd /etc/mail/dkim/private/example.com.key /etc/mail/dkim/private/
|
||
</span></span><span style="display:flex;"><span>chmod <span style="color:#ae81ff">440</span> /etc/mail/dkim/private/example.com.key
|
||
</span></span><span style="display:flex;"><span>chmod <span style="color:#ae81ff">775</span> /etc/mail/dkim/private/
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Exit root session</span>
|
||
</span></span><span style="display:flex;"><span>exit
|
||
</span></span></code></pre></div><p>Now that we successfully generated our private and public DKIM keys, we need to
|
||
put our public DKIM key into our DKIM record. We can get our DKIM public key as
|
||
a single line by running this <code>awk</code> command:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas awk <span style="color:#e6db74">&#39;/PUBLIC/ { $0=&#34;&#34; } { printf (&#34;%s&#34;,$0) } END { print }&#39;</span> /etc/mail/dkim/example.com.pub
|
||
</span></span></code></pre></div><p>We can now copy that string and put it into our DKIM record.</p>
|
||
<pre tabindex="0"><code>Record Type Host Value TTL
|
||
V V V V
|
||
TXT dkim._domainkey v=DKIM1;k=rsa;p=&lt;YOUR DKIM KEY&gt; 3600
|
||
</code></pre><p>Just replace <code>&lt;YOUR DKIM KEY&gt;</code> with the string you just copied and your DKIM
|
||
record is good to go.</p>
|
||
<h3 id="dmarc-record">DMARC Record</h3>
|
||
<p>We now need to add a DMARC record to our DNS records. DMARC is just another way
|
||
of preventing email spoofing and spam by telling receiving email servers what to
|
||
do with potentially invalid emails. Here is a good default to use for you DMARC
|
||
record:</p>
|
||
<pre tabindex="0"><code>Record Type Host Value TTL
|
||
V V V V
|
||
TXT @ v=DMARC1;p=reject;rua=mailto:dmarc@example.com;sp=reject;aspf=r; 3600
|
||
</code></pre><p>Wow, the value for this record is quite long, let&rsquo;s break down what it means.
|
||
<code>p=reject</code> and <code>sp=reject</code> just means to immediately discard any invalid emails,
|
||
<code>aspf=r</code> means that <em>any</em> email sent from <em>any</em> subdomain of example.com is
|
||
valid, and <code>rua=dmarc@example.com</code> tells where the mail server receives DMARC
|
||
reports (don&rsquo;t worry, you shouldn&rsquo;t care about DMARC reports, they are mostly
|
||
useless).</p>
|
||
<h3 id="ptr-record">PTR Record</h3>
|
||
<p>Finally, our last record! All you need to do is set a PTR record (also called a
|
||
Reverse DNS pointer) that points to
|
||
<code>mail.example.com</code>. That&rsquo;s it. This is yet <strong>another</strong> mechanism to prevent
|
||
spam. Please note that there are different ways to set a PTR record, most ways
|
||
involve finding a &ldquo;Reverse DNS&rdquo; option for your VPS/hosting provider and using
|
||
that.</p>
|
||
<h2 id="email-configuration">Email Configuration</h2>
|
||
<p>At last, we can now configure the setting for our email server. Our first order
|
||
of business is to get a valid certificate for our <code>mail.example.com</code> subdomain.
|
||
This process should be somewhat familiar if you read my last article. Let&rsquo;s
|
||
first append this to the end of our <code>/etc/acme-client.conf</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">domain</span> <span style="color:#66d9ef">mail.example.com</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">domain</span> <span style="color:#66d9ef">key</span> <span style="color:#e6db74">&#34;/etc/ssl/private/mail.example.com.key&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">domain</span> <span style="color:#66d9ef">full</span> <span style="color:#66d9ef">chain</span> <span style="color:#66d9ef">certificate</span> <span style="color:#e6db74">&#34;/etc/ssl/mail.example.com.fullchain.pem&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">sign</span> <span style="color:#66d9ef">with</span> <span style="color:#66d9ef">letsencrypt</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>Now we just need to add this to <code>/etc/httpd.conf</code> in order to get a certificate
|
||
for <em>any</em> subdomain of example.com:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> <span style="color:#e6db74">&#34;*&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#960050;background-color:#1e0010">*</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">80</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">location</span> <span style="color:#e6db74">&#34;/.well-known/acme-challenge/*&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">root</span> <span style="color:#e6db74">&#34;/acme&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">request</span> <span style="color:#66d9ef">strip</span> <span style="color:#ae81ff">2</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">location</span> <span style="color:#960050;background-color:#1e0010">*</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">block</span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">302</span> <span style="color:#e6db74">&#34;https://$HTTP_HOST$REQUEST_URI&#34;</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>Now we just run this command to generate a certificate for <code>mail.example.com</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas acme-client -v mail.example.com
|
||
</span></span></code></pre></div><p>Finally, we shouldn&rsquo;t forget to automatically renew our certificates, so change
|
||
<code>/etc/weekly.local</code> as follows:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#75715e"># Check for new certificates every week</span>
|
||
</span></span><span style="display:flex;"><span>acme-client example.com
|
||
</span></span><span style="display:flex;"><span>acme-client mail.example.com
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>rcctl restart httpd smtpd dovecot
|
||
</span></span></code></pre></div><h3 id="spam">Spam</h3>
|
||
<p>The first program that we should configure is <code>rspamd</code>. Only a few things need
|
||
to be set in order for it to work properly. Go ahead and create a file at
|
||
<code>/etc/rspamd/local.d/dkim_signing.conf</code> and add this to it:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#75715e"># This should always be true
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">allow_username_mismatch</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span><span style="color:#960050;background-color:#1e0010">;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Allow rspamd to sign with our DKIM key
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">domain</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">example.com</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">path</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;/etc/mail/dkim/private/example.com.key&#34;</span><span style="color:#960050;background-color:#1e0010">;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">selector</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;dkim&#34;</span><span style="color:#960050;background-color:#1e0010">;</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>This is entirely optional, but if you want more performance you can enable
|
||
and start <code>redis</code> as a cache backend:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas rcctl enable redis
|
||
</span></span><span style="display:flex;"><span>doas rcctl start redis
|
||
</span></span></code></pre></div><p>Now enable and start <code>rspamd</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas rcctl enable rspamd
|
||
</span></span><span style="display:flex;"><span>doas rcctl start rspamd
|
||
</span></span></code></pre></div><h3 id="smtp">SMTP</h3>
|
||
<p>Now let&rsquo;s configure OpenSMTPD in order to send and receive emails. We will need
|
||
to create a config file at <code>/etc/mail/smtpd.conf</code> and configure it like so:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#75715e"># Set locations to certificates
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">pki</span> <span style="color:#66d9ef">example.com</span> <span style="color:#66d9ef">cert</span> <span style="color:#e6db74">&#34;/etc/ssl/mail.example.com.fullchain.pem&#34;</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">pki</span> <span style="color:#66d9ef">example.com</span> <span style="color:#66d9ef">key</span> <span style="color:#e6db74">&#34;/etc/ssl/private/mail.example.com.key&#34;</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">pki</span> <span style="color:#66d9ef">example.com</span> <span style="color:#66d9ef">dhe</span> <span style="color:#66d9ef">auto</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Delimiter for email addresses
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">smtp</span> <span style="color:#66d9ef">sub-addr-delim</span> <span style="color:#960050;background-color:#1e0010">&#39;</span><span style="color:#66d9ef">_</span><span style="color:#960050;background-color:#1e0010">&#39;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Sets rspamd as our filter
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">filter</span> <span style="color:#66d9ef">rspamd</span> <span style="color:#66d9ef">proc-exec</span> <span style="color:#e6db74">&#34;filter-rspamd&#34;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Sets ports to use for mail transfer
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#66d9ef">all</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">25</span> <span style="color:#66d9ef">tls</span> <span style="color:#66d9ef">pki</span> <span style="color:#e6db74">&#34;example.com&#34;</span> <span style="color:#66d9ef">filter</span> <span style="color:#e6db74">&#34;rspamd&#34;</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#66d9ef">all</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">465</span> <span style="color:#66d9ef">smtps</span> <span style="color:#66d9ef">pki</span> <span style="color:#e6db74">&#34;example.com&#34;</span> <span style="color:#66d9ef">auth</span> <span style="color:#66d9ef">mask-src</span> <span style="color:#66d9ef">filter</span> <span style="color:#e6db74">&#34;rspamd&#34;</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#66d9ef">all</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">587</span> <span style="color:#66d9ef">tls-require</span> <span style="color:#66d9ef">pki</span> <span style="color:#e6db74">&#34;example.com&#34;</span> <span style="color:#66d9ef">auth</span> <span style="color:#66d9ef">mask-src</span> <span style="color:#66d9ef">filter</span> <span style="color:#e6db74">&#34;rspamd&#34;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Load mail aliases
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">table</span> <span style="color:#66d9ef">aliases</span> <span style="color:#66d9ef">file</span><span style="color:#960050;background-color:#1e0010">:</span>/etc/mail/aliases
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Actions for mail delievery
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">action</span> <span style="color:#e6db74">&#34;local&#34;</span> <span style="color:#66d9ef">lmtp</span> <span style="color:#e6db74">&#34;/var/dovecot/lmtp&#34;</span> <span style="color:#66d9ef">alias</span> <span style="color:#960050;background-color:#1e0010">&lt;</span><span style="color:#66d9ef">aliases</span><span style="color:#960050;background-color:#1e0010">&gt;</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">action</span> <span style="color:#e6db74">&#34;outbound&#34;</span> <span style="color:#66d9ef">relay</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Actions for recieving mail
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">match</span> <span style="color:#66d9ef">from</span> <span style="color:#66d9ef">any</span> <span style="color:#66d9ef">for</span> <span style="color:#66d9ef">domain</span> <span style="color:#e6db74">&#34;example.com&#34;</span> <span style="color:#66d9ef">action</span> <span style="color:#e6db74">&#34;local&#34;</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">match</span> <span style="color:#66d9ef">from</span> <span style="color:#66d9ef">local</span> <span style="color:#66d9ef">for</span> <span style="color:#66d9ef">local</span> <span style="color:#66d9ef">action</span> <span style="color:#e6db74">&#34;local&#34;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Actions for sending mail
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">match</span> <span style="color:#66d9ef">from</span> <span style="color:#66d9ef">any</span> <span style="color:#66d9ef">auth</span> <span style="color:#66d9ef">for</span> <span style="color:#66d9ef">any</span> <span style="color:#66d9ef">action</span> <span style="color:#e6db74">&#34;outbound&#34;</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">match</span> <span style="color:#66d9ef">from</span> <span style="color:#66d9ef">local</span> <span style="color:#66d9ef">for</span> <span style="color:#66d9ef">any</span> <span style="color:#66d9ef">action</span> <span style="color:#e6db74">&#34;outbound&#34;</span>
|
||
</span></span></code></pre></div><p>Now we need to place our mail delievery address in <code>/etc/mail/mailname</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">mail.example.com</span>
|
||
</span></span></code></pre></div><p>And now we can test our <code>smtpd</code> config by running:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas smtpd -n -f /etc/mail/smtpd.conf
|
||
</span></span></code></pre></div><p>If everything is all good then you can restart <code>smtpd</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas rcctl restart smtpd
|
||
</span></span></code></pre></div><h3 id="imappop3">IMAP/POP3</h3>
|
||
<p>The last part of our email server is <code>dovecot</code> which allows us to view our
|
||
emails using IMAP and or POP3. In order to use our certificates we will need to
|
||
configure <code>/etc/dovecot/conf.d/10-ssl.conf</code> like so:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">ssl_cert</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">&lt;</span>/etc/ssl/mail.example.com.fullchain.pem
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ssl_key</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">&lt;</span>/etc/ssl/private/mail.example.com.key
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">ssl_dh</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">&lt;</span>/etc/dovecot/dh.pem
|
||
</span></span></code></pre></div><p>We need to generate a Diffie-Hellman key in order to make each TLS connection
|
||
unique (these commands might take a <em>while</em> to generate a key):</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas openssl dhparam -out /etc/dovecot/dh.pem <span style="color:#ae81ff">4096</span>
|
||
</span></span><span style="display:flex;"><span>doas chown _dovecot:_dovecot /etc/dovecot/dh.pem
|
||
</span></span><span style="display:flex;"><span>doas chmod <span style="color:#ae81ff">400</span> /etc/dovecot/dh.pem
|
||
</span></span></code></pre></div><p>Now we need to configure our mailbox and some basic settings for <code>dovecot</code>. Edit
|
||
<code>/etc/dovecot/conf.d/10-mail.conf</code> so it resembles the following:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#75715e"># Where to put user maildir
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">mail_location</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">maildir</span><span style="color:#960050;background-color:#1e0010">:~</span>/Maildir
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> <span style="color:#66d9ef">inbox</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">inbox</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">yes</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">mmap_disable</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">yes</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">first_valid_uid</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">1000</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">mail_plugin_dir</span> <span style="color:#f92672">=</span> /usr/local/lib/dovecot
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">protocol</span> <span style="color:#960050;background-color:#1e0010">!</span><span style="color:#66d9ef">indexer-worker</span> {
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">mbox_write_locks</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">fcntl</span>
|
||
</span></span></code></pre></div><p>Let&rsquo;s edit <code>/etc/dovecot/conf.d/20-lmtp.conf</code> in order to allow <code>sieve</code> and mail
|
||
plugins:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">protocol</span> <span style="color:#66d9ef">lmtp</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">mail_plugins</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#66d9ef">mail_plugins</span> <span style="color:#66d9ef">sieve</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>We now meed to modify <code>/etc/dovecot/conf.d/15-mailboxes.conf</code> and add this
|
||
inside the <code>namespace inbox {</code> section of the file in order to create a Spam
|
||
folder:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">mailbox</span> <span style="color:#66d9ef">Spam</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">auto</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">create</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">special_use</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">\</span><span style="color:#66d9ef">Junk</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>If you don&rsquo;t plan on using IMAP and only wish to use POP3 for viewing/sending
|
||
emails then this last step is entirely optional, however I encourage users to
|
||
use IMAP instead of POP3. To enable IMAP we just need to edit
|
||
<code>/etc/dovecot/conf.d/20-imap.conf</code> like so:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">protocol</span> <span style="color:#66d9ef">imap</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">mail_plugins</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#66d9ef">mail_plugins</span> <span style="color:#66d9ef">imap_sieve</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">mail_max_userip_connections</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">25</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><h4 id="sieve-and-filtering">Sieve and Filtering</h4>
|
||
<p>Finally, the last part of setting up <code>dovecot</code> is configuring <code>sieve</code> in order
|
||
to filter and group emails properly. Go ahead and edit
|
||
<code>/etc/dovecot/conf.d/90-plugin.conf</code> so it looks like the following:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">plugin</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">sieve_plugins</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">sieve_imapsieve</span> <span style="color:#66d9ef">sieve_extprograms</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"># Moving to Spam
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">imapsieve_mailbox</span><span style="color:#ae81ff">1</span><span style="color:#66d9ef">_name</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">Spam</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">imapsieve_mailbox</span><span style="color:#ae81ff">1</span><span style="color:#66d9ef">_causes</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">COPY</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">imapsieve_mailbox</span><span style="color:#ae81ff">1</span><span style="color:#66d9ef">_before</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">file</span><span style="color:#960050;background-color:#1e0010">:</span>/usr/local/lib/dovecot/sieve/report-spam.sieve
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"># Moving from Spam
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">imapsieve_mailbox</span><span style="color:#ae81ff">2</span><span style="color:#66d9ef">_name</span> <span style="color:#f92672">=</span> <span style="color:#960050;background-color:#1e0010">*</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">imapsieve_mailbox</span><span style="color:#ae81ff">2</span><span style="color:#66d9ef">_from</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">Spam</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">imapsieve_mailbox</span><span style="color:#ae81ff">2</span><span style="color:#66d9ef">_causes</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">COPY</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">imapsieve_mailbox</span><span style="color:#ae81ff">2</span><span style="color:#66d9ef">_before</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">file</span><span style="color:#960050;background-color:#1e0010">:</span>/usr/local/lib/dovecot/sieve/report-ham.sieve
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">sieve_pipe_bin_dir</span> <span style="color:#f92672">=</span> /usr/local/lib/dovecot/sieve
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">sieve_global_extensions</span> <span style="color:#f92672">=</span> <span style="color:#f92672">+</span><span style="color:#66d9ef">vnd.dovecot.pipe</span> <span style="color:#f92672">+</span><span style="color:#66d9ef">vnd.dovecot.environment</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>This configuration allows sieve to &ldquo;learn&rdquo; what types of emails are spam and
|
||
what types of messages are not spam (sometimes called &ldquo;ham&rdquo; 🍖) depending on
|
||
where you move them. In order to make these filters functional we need to create
|
||
two sieve scripts. The first one is
|
||
<code>/usr/local/lib/dovecot/sieve/report-spam.sieve</code>. Let&rsquo;s create it and add the
|
||
following to it:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sieve" data-lang="sieve"><span style="display:flex;"><span><span style="color:#f92672">require</span> [<span style="color:#e6db74">&#34;vnd.dovecot.pipe&#34;</span>, <span style="color:#e6db74">&#34;copy&#34;</span>, <span style="color:#e6db74">&#34;imapsieve&#34;</span>, <span style="color:#e6db74">&#34;environment&#34;</span>, <span style="color:#e6db74">&#34;variables&#34;</span>];
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>if <span style="color:#960050;background-color:#1e0010">environment</span> <span style="color:#f92672">:matches</span> <span style="color:#e6db74">&#34;imap.user&#34;</span> <span style="color:#e6db74">&#34;*&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">set</span> <span style="color:#e6db74">&#34;username&#34;</span> <span style="color:#e6db74">&#34;${1}&#34;</span>;
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">pipe</span> <span style="color:#f92672">:copy</span> <span style="color:#e6db74">&#34;sa-learn-spam.sh&#34;</span> [ <span style="color:#e6db74">&#34;${username}&#34;</span> ];
|
||
</span></span></code></pre></div><p>The second filter is <code>/usr/local/lib/dovecot/sieve/report-ham.sieve</code> and should
|
||
look like this:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sieve" data-lang="sieve"><span style="display:flex;"><span><span style="color:#f92672">require</span> [<span style="color:#e6db74">&#34;vnd.dovecot.pipe&#34;</span>, <span style="color:#e6db74">&#34;copy&#34;</span>, <span style="color:#e6db74">&#34;imapsieve&#34;</span>, <span style="color:#e6db74">&#34;environment&#34;</span>, <span style="color:#e6db74">&#34;variables&#34;</span>];
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>if <span style="color:#960050;background-color:#1e0010">environment</span> <span style="color:#f92672">:matches</span> <span style="color:#e6db74">&#34;imap.mailbox&#34;</span> <span style="color:#e6db74">&#34;*&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">set</span> <span style="color:#e6db74">&#34;mailbox&#34;</span> <span style="color:#e6db74">&#34;${1}&#34;</span>;
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>if string <span style="color:#e6db74">&#34;${mailbox}&#34;</span> <span style="color:#e6db74">&#34;Trash&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> stop;
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>if <span style="color:#960050;background-color:#1e0010">environment</span> <span style="color:#f92672">:matches</span> <span style="color:#e6db74">&#34;imap.user&#34;</span> <span style="color:#e6db74">&#34;*&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">set</span> <span style="color:#e6db74">&#34;username&#34;</span> <span style="color:#e6db74">&#34;${1}&#34;</span>;
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">pipe</span> <span style="color:#f92672">:copy</span> <span style="color:#e6db74">&#34;sa-learn-ham.sh&#34;</span> [ <span style="color:#e6db74">&#34;${username}&#34;</span> ];
|
||
</span></span></code></pre></div><p>Now we will create two shell scripts for these filters. The first one is
|
||
<code>/usr/local/lib/dovecot/sieve/sa-learn-ham.sh</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#75715e">#!/bin/sh
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>exec /usr/local/bin/rspamc -d <span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>1<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> learn_ham
|
||
</span></span></code></pre></div><p>The second one is <code>/usr/local/lib/dovecot/sieve/sa-learn-spam.sh</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#75715e">#!/bin/sh
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>exec /usr/local/bin/rspamc -d <span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>1<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> learn_spam
|
||
</span></span></code></pre></div><p>And we need to make them executable:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas chmod +x /usr/local/lib/dovecot/sieve/sa-learn-spam.sh /usr/local/lib/dovecot/sieve/sa-learn-ham.sh
|
||
</span></span></code></pre></div><p>Now we need to compile the sieve filters to actually use them:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas sievec /usr/local/lib/dovecot/sieve/report-spam.sieve
|
||
</span></span><span style="display:flex;"><span>doas sievec /usr/local/lib/dovecot/sieve/report-ham.sieve
|
||
</span></span></code></pre></div><p>Lastly, let&rsquo;s enable and start <code>dovecot</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas rcctl enable dovecot
|
||
</span></span><span style="display:flex;"><span>doas rcctl start dovecot
|
||
</span></span></code></pre></div><h2 id="done">Done!</h2>
|
||
<p><strong>Congrats!</strong> You now have your own email server running on OpenBSD! You can now
|
||
login to your email server using your preferred email client. If you don&rsquo;t have
|
||
a preferred email client then you can use <a href="https://thunderbird.net">Thunderbird</a>
|
||
if you want a GUI or <a href="https://aerc-mail.org/">aerc</a> if you want to view emails
|
||
from the terminal.</p>
|
||
<p>You can now enjoy using email knowing that your inbox won&rsquo;t be monitored. 😎</p>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>Just a friendly reminder to change &ldquo;example.com&rdquo; to your specific domain
|
||
name.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>OpenBSD Server: httpd</title>
|
||
<link>https://brycev.com/blog/openbsd-httpd/</link>
|
||
<pubDate>Thu, 27 Feb 2025 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/openbsd-httpd/</guid>
|
||
<description><p>I finally got around to writing part 2 of this series. If you have not read part
|
||
1 yet, then you can find it <a href="https://brycev.com/blog/openbsd-server-install">here</a>. So now that we
|
||
have our base server installed, we can go ahead and setup <code>httpd</code> to serve our
|
||
website.</p>
|
||
<h2 id="setup-httpd">Setup httpd</h2>
|
||
<p>Let&rsquo;s go ahead and create a very simple http server using <code>httpd</code> just to make
|
||
sure that everything is working properly. We can make a config file for <code>httpd</code>
|
||
at <code>/etc/httpd.conf</code> like so:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> <span style="color:#e6db74">&#34;example.com&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#960050;background-color:#1e0010">*</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">80</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">alias</span> <span style="color:#e6db74">&#34;www.example.com&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">root</span> <span style="color:#e6db74">&#34;/htdocs/example.com&#34;</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">types</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">include</span> <span style="color:#e6db74">&#34;/usr/share/misc/mime.types&#34;</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>This will create a web server for &ldquo;example.com&rdquo; (make sure to replace
|
||
&ldquo;example.com&rdquo; with your domain name) on port 80 and will redirect traffic from
|
||
&ldquo;<a href="https://www.example.com">www.example.com</a>&rdquo; to &ldquo;example.com&rdquo;. Next we need to create
|
||
<code>/var/www/htdocs/example.com</code> to host our files:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mkdir -p /var/www/htdocs/example.com
|
||
</span></span></code></pre></div><p>Let&rsquo;s just put a very basic webpage at <code>/var/www/htdocs/example.com/index.html</code>
|
||
to serve as our homepage.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#75715e">&lt;!DOCTYPE html&gt;</span>
|
||
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">html</span> <span style="color:#a6e22e">lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;en&#34;</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;<span style="color:#f92672">head</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;<span style="color:#f92672">title</span>&gt;Example webpage&lt;/<span style="color:#f92672">title</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;<span style="color:#f92672">meta</span> <span style="color:#a6e22e">charset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;utf-8&#34;</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;/<span style="color:#f92672">head</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;<span style="color:#f92672">body</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;<span style="color:#f92672">h1</span>&gt;This is an example webpage&lt;/<span style="color:#f92672">h1</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;<span style="color:#f92672">p</span>&gt;Looks like it works!&lt;/<span style="color:#f92672">p</span>&gt;
|
||
</span></span><span style="display:flex;"><span> &lt;/<span style="color:#f92672">body</span>&gt;
|
||
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">html</span>&gt;
|
||
</span></span></code></pre></div><p>Now, in order to make sure that our httpd config file is correct and does not
|
||
have any errors, we can run this command to check it:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas httpd -n
|
||
</span></span></code></pre></div><p>If your configuration is correct, then it will spit out <code>configuration ok</code> and
|
||
you can move on. If not, then it will spit out what error you have to fix in the
|
||
<code>/etc/httpd.conf</code> file. Finally we can enable httpd on boot and start it using
|
||
the <code>rcctl</code> command:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas rcctl enable httpd
|
||
</span></span><span style="display:flex;"><span>doas rcctl start httpd
|
||
</span></span></code></pre></div><p><strong>Congrats!</strong> You now have a web page on the internet at &ldquo;example.com&rdquo;!</p>
|
||
<h2 id="getting-a-certificate">Getting a certificate</h2>
|
||
<p>Now that we verified that a normal web server works, we can go ahead and setup
|
||
ACME in order to obtain a certificate in order to allow HTTPS connects to our
|
||
website. First we need to create a file named <code>/etc/acme-client.conf</code> and add
|
||
this to our file:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">authority</span> <span style="color:#66d9ef">letsencrypt</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">api</span> <span style="color:#66d9ef">url</span> <span style="color:#e6db74">&#34;https://acme-v02.api.letsencrypt.org/directory&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">account</span> <span style="color:#66d9ef">key</span> <span style="color:#e6db74">&#34;/etc/acme/letsencrypt-privkey.pem&#34;</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">domain</span> <span style="color:#66d9ef">example.com</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"># Allows an alias
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">alternative</span> <span style="color:#66d9ef">names</span> { <span style="color:#66d9ef">www.example.com</span> }
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">domain</span> <span style="color:#66d9ef">key</span> <span style="color:#e6db74">&#34;/etc/ssl/private/example.com.key&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">domain</span> <span style="color:#66d9ef">full</span> <span style="color:#66d9ef">chain</span> <span style="color:#66d9ef">certificate</span> <span style="color:#e6db74">&#34;/etc/ssl/example.com.fullchain.pem&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">sign</span> <span style="color:#66d9ef">with</span> <span style="color:#66d9ef">letsencrypt</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>The first section defines Let&rsquo;s Encrypt as our certificate authority. The
|
||
second section defines a domain to fetch a certificate for. It will place our
|
||
domain key at <code>/etc/ssl/private/example.com.key</code> and our certificate at
|
||
<code>/etc/ssl/example.com.fullchain.pem</code> (remember to replace &ldquo;example.com&rdquo; with
|
||
your domain).</p>
|
||
<p>Now we have to edit <code>/etc/httpd.conf</code> in order to ACME to generate a certificate
|
||
for our domain:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> <span style="color:#e6db74">&#34;example.com&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#960050;background-color:#1e0010">*</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">80</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">alias</span> <span style="color:#e6db74">&#34;www.example.com&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">root</span> <span style="color:#e6db74">&#34;/htdocs/example.com&#34;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">location</span> <span style="color:#e6db74">&#34;/.well-known/acme-challenge/*&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">request</span> <span style="color:#66d9ef">strip</span> <span style="color:#ae81ff">2</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">root</span> <span style="color:#e6db74">&#34;/acme&#34;</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">types</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">include</span> <span style="color:#e6db74">&#34;/usr/share/misc/mime.types&#34;</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>Now we can run this command in order to generate a certificate for our domain:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>acme-client -v example.com
|
||
</span></span></code></pre></div><h2 id="setup-https">Setup HTTPS</h2>
|
||
<p>Now that we have our certificate, let&rsquo;s go ahead and edit our <code>/etc/httpd.conf</code>
|
||
file in order to use HTTPS for our web server:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-lighty" data-lang="lighty"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> <span style="color:#e6db74">&#34;example.com&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#960050;background-color:#1e0010">*</span> <span style="color:#66d9ef">tls</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">443</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">alias</span> <span style="color:#e6db74">&#34;www.example.com&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">root</span> <span style="color:#e6db74">&#34;/htdocs/example.com&#34;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">tls</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">certificate</span> <span style="color:#e6db74">&#34;/etc/ssl/example.com.fullchain.pem&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">key</span> <span style="color:#e6db74">&#34;/etc/ssl/private/example.com.key&#34;</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">location</span> <span style="color:#e6db74">&#34;/.well-known/acme-challenge/*&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">request</span> <span style="color:#66d9ef">strip</span> <span style="color:#ae81ff">2</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">root</span> <span style="color:#e6db74">&#34;/acme&#34;</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">server</span> <span style="color:#e6db74">&#34;example.com&#34;</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">listen</span> <span style="color:#66d9ef">on</span> <span style="color:#960050;background-color:#1e0010">*</span> <span style="color:#66d9ef">port</span> <span style="color:#ae81ff">80</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">alias</span> <span style="color:#e6db74">&#34;www.example.com&#34;</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">block</span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">301</span> <span style="color:#e6db74">&#34;https://example.com$REQUEST_URI&#34;</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">types</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">include</span> <span style="color:#e6db74">&#34;/usr/share/misc/mime.types&#34;</span>
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>Finally we can restart <code>httpd</code> and go to &ldquo;example.com&rdquo; and we will have a secure
|
||
connection to the website.</p>
|
||
<h2 id="automatically-renew-certificates">Automatically renew certificates</h2>
|
||
<p>The final part of this post is going to take care of lose ends by automatically
|
||
renewing our certificate before it expires. Most certificates expire after only
|
||
a few months, so we want to automatically renew them. In order to do so we can
|
||
make a new file at <code>/etc/weekly.local</code>. Any commands that we put in this file
|
||
will run once a week, so lets put this in <code>/etc/weekly.local</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#75715e"># Check for new certificates every week</span>
|
||
</span></span><span style="display:flex;"><span>acme-client -v example.com
|
||
</span></span><span style="display:flex;"><span>rcctl restart httpd
|
||
</span></span></code></pre></div><h2 id="almost-done">Almost Done</h2>
|
||
<p>That&rsquo;s the end of part 2.
|
||
The final part of this 3 part series will be about setting up an email server
|
||
using <code>smtpd</code> and setting up spam filtering (as well as other things). So stay
|
||
tuned for part 3.</p>
|
||
<hr>
|
||
<p>You can now read part 3 of this series <a href="https://brycev.com/blog/openbsd-smtpd">here</a>.</p>
|
||
<hr>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>OpenBSD Server: Initial Setup</title>
|
||
<link>https://brycev.com/blog/openbsd-server-install/</link>
|
||
<pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/openbsd-server-install/</guid>
|
||
<description><p><em>This is the first part in a series of posts. Find <a href="https://brycev.com/blog/openbsd-httpd">part 2</a>
|
||
and <a href="https://brycev.com/blog/openbsd-smtpd">part 3</a> when they are ready</em></p>
|
||
<hr>
|
||
<p>For those of you who don&rsquo;t follow my blog, in my
|
||
<a href="https://brycev.com/blog/migrating-my-vps">previous blog post</a> I talked about migrating my VPS to
|
||
use OpenBSD instead of Debian stable. I recently finished migrating my VPS and
|
||
would like to document the process in order to help anyone setting up their own
|
||
OpenBSD server or VPS.</p>
|
||
<p>Before we get started, make sure that you have your DNS records for your domain
|
||
name pointing to your server IP address.</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/openbsd.webp" title="OpenBASED" alt="OpenBSD logo"></figure>
|
||
|
||
<h2 id="installing-openbsd">Installing OpenBSD</h2>
|
||
<p>One thing that might stop most people from using OpenBSD on a VPS specifically
|
||
is the fact that most hosting providers <strong>don&rsquo;t</strong> allow you to custom
|
||
operating systems besides the ones that they offer. Luckily, my VPS provider
|
||
<a href="https://my.frantech.ca/aff.php?aff=6418">Frantech</a><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, allows me to upload my
|
||
own ISO images in order for you to install <strong>any</strong> OS that I like. So make sure
|
||
that your VPS provider actually allows you to run OpenBSD.</p>
|
||
<p>Go ahead and install OpenBSD normally. Here are a few tips when installing
|
||
OpenBSD for a server:</p>
|
||
<ul>
|
||
<li>Make sure to start <code>sshd</code> by default (otherwise you can&rsquo;t login)</li>
|
||
<li>Create a user for your system</li>
|
||
<li>Make sure you allow root ssh login (we&rsquo;ll need it temporarily)</li>
|
||
<li>You can delete the <code>swap</code>, <code>/usr/X11R6</code>, <code>/usr/src/</code>, and <code>/usr/obj</code>
|
||
partitions when partitioning your disk as we don&rsquo;t need them (make sure to use
|
||
that free space though)</li>
|
||
<li>Make sure you select to install <strong>all</strong> sets unless you know what you&rsquo;re
|
||
doing</li>
|
||
</ul>
|
||
<p><strong>Congrats!</strong> You now have a basic OpenBSD installation.</p>
|
||
<h2 id="configuring">Configuring</h2>
|
||
<p>First thing is first, we need root privileges. So run this in order to connect
|
||
as the root user:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>ssh root@example.com
|
||
</span></span></code></pre></div><p>where <code>example.com</code> is your domain name. As the root user we need to create the
|
||
<code>/etc/doas.conf</code> file and add the wheel group to it. We can do so by running:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;permit persist :wheel&#34;</span> &gt; /etc/doas.conf
|
||
</span></span></code></pre></div><p>We can now exit our current ssh session in order to login as the user we created
|
||
when we installed OpenBSD.</p>
|
||
<p>Let&rsquo;s first update our system by running these commands using <code>doas</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas syspatch
|
||
</span></span><span style="display:flex;"><span>doas pkg_add -Uu
|
||
</span></span></code></pre></div><p>The <code>syspatch</code><sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> command applies any necessary patches to your system and <code>pkg_add -Uu</code> just updates packages. Speaking of adding packages, you can use <code>pkg_add</code>
|
||
in order to install your favorite text editor (you&rsquo;ll need it).
|
||
While we are at it, let&rsquo;s go ahead and disable ssh
|
||
logins for root since we don&rsquo;t need it anymore. Edit <code>/etc/ssh/sshd_config</code> and
|
||
add this line to it:</p>
|
||
<pre tabindex="0"><code>PermitRootLogin no
|
||
</code></pre><p>Finally, let&rsquo;s create the file <code>/etc/sysctl.conf</code> that will contain system-wide
|
||
settings. We will put this in <code>/etc/sysctl.conf</code>:</p>
|
||
<pre tabindex="0"><code>kern.maxproc=8192
|
||
kern.maxfiles=32768
|
||
kern.maxthread=16384
|
||
kern.shminfo.shmall=536870912
|
||
kern.shminfo.shmmax=2147483647
|
||
kern.shminfo.shmmni=4096
|
||
</code></pre><p>Please note that these settings are for <strong>my</strong> system and will chage from system
|
||
to system. As a rule of thumb:</p>
|
||
<ul>
|
||
<li><code>kern.shminfo.shmmax</code> should be set to <strong>half</strong> of your maximum RAM (in bytes)</li>
|
||
<li><code>kern.shminfo.shmall</code> should be set to <code>kern.shminfo.shmmax</code> divided by 4096
|
||
(4096 is the page size in OpenBSD).</li>
|
||
</ul>
|
||
<p>These are just a few settings that will get a bit more performance out of our
|
||
OpenBSD system. It just increases the maximum number of processes able to run at
|
||
once as well as the maximum amount of shared memory.
|
||
You can find a detailed explanation of these settings by looking
|
||
at the man page for <code>sysctl</code> (hint: run <code>man 2 sysctl</code>).</p>
|
||
<h2 id="stay-tuned">Stay tuned</h2>
|
||
<p>That&rsquo;s just the beginning of setting up an OpenBSD server, but keep a close eye
|
||
on my blog as I will upload the next part of this guide somewhat soon which will
|
||
be about setting up a static web server using <code>httpd</code>&hellip;assuming that I get
|
||
around to writing it eventually.</p>
|
||
<hr>
|
||
<p>You can now read part 2 of this series <a href="https://brycev.com/blog/openbsd-httpd">here</a>.</p>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>This is an affiliate link&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>Make sure to reboot whenever <code>syspatch</code> applies patches in order to reload
|
||
the OpenBSD kernel.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Migrating My VPS</title>
|
||
<link>https://brycev.com/blog/migrating-my-vps/</link>
|
||
<pubDate>Fri, 07 Feb 2025 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/migrating-my-vps/</guid>
|
||
<description><p>Please note that on February 11, 2025 I will be migrating my VPS to a
|
||
different operating system. This means that my website, email, and XMPP server
|
||
will be down for most of the day. If you need to contact me please wait until
|
||
Feburary 12, 2025.</p>
|
||
<p>I&rsquo;ve been using Debian stable on my VPS ever since I
|
||
wrote my <a href="https://brycev.com/blog/i-finally-have-a-vps">original post</a> about getting a VPS,
|
||
however I have decided that I would like to use
|
||
<a href="https://www.openbsd.org/">OpenBSD</a> on my VPS instead. OpenBSD offers more
|
||
security while still being very simple which fits my needs a lot more for a
|
||
server operating system when compared to Debian stable.</p>
|
||
<p>After migrating my system, I&rsquo;ll most likely create a guide on how to setup an
|
||
OpenBSD system as it&rsquo;s pretty easy, but not a well documented process.</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>First Livestream Soon</title>
|
||
<link>https://brycev.com/blog/first-livestream-soon/</link>
|
||
<pubDate>Sat, 03 Aug 2024 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/first-livestream-soon/</guid>
|
||
<description><p>I&rsquo;ve recently decided that I&rsquo;m going to do a livestream. This livestream is
|
||
mostly just a test, but feel free to stop on by if you want to.
|
||
I have no idea what to expect&hellip;so I&rsquo;ll see how this goes.
|
||
The stream will start on August 7 at 5:30 PM (EST).</p>
|
||
<p>The link is here:
|
||
<a href="https://www.youtube.com/watch?v=y5eZXwXIrBI">https://www.youtube.com/watch?v=y5eZXwXIrBI</a></p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Microwave Transformers</title>
|
||
<link>https://brycev.com/blog/microwave-transformers/</link>
|
||
<pubDate>Sat, 20 Apr 2024 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/microwave-transformers/</guid>
|
||
<description><p>A few years ago I was (and I still am) interested in electrical engineering
|
||
and learning about how electricity works. I built circuits and repaired
|
||
various different electronic devices around my house that were broken.
|
||
My favorite part however, was working with high voltage. The cheapest and
|
||
most effective gateway drug into high voltage that I encountered was actually
|
||
the humble microwave oven.</p>
|
||
<h2 id="the-guts-of-a-microwave-oven">The Guts of a Microwave Oven</h2>
|
||
<p>Believe it or not, microwave ovens are actually deceptively simple. It really
|
||
consists of 3 main parts:</p>
|
||
<ul>
|
||
<li>The control panel</li>
|
||
<li>The magnetron</li>
|
||
<li>The high voltage transformer</li>
|
||
</ul>
|
||
<p>The control panel is pretty self explanatory, it lets the
|
||
user input the time into the microwave oven, change settings, and etc.
|
||
In fact, a control panel isn&rsquo;t <em>really</em> necessary, all that the control
|
||
panel does is turn the transformer on and off, which could potentially be
|
||
done manually.
|
||
The magnetron is the part that actually generates the microwave radiation
|
||
needed to cook your food. The high voltage transformer is what provides the
|
||
necessary power for the magnetron to actually work. The transformer is what
|
||
we will be focusing on.</p>
|
||
<h2 id="the-transformer">The Transformer</h2>
|
||
<p>If you&rsquo;re unfamiliar with transformers and how they work, I would recommend
|
||
learning a bit about them <a href="http://hyperphysics.phy-astr.gsu.edu/hbase/magnetic/transf.html">here</a>.
|
||
Otherwise, let&rsquo;s continue.</p>
|
||
<p>The transformer within a microwave oven is very special. Most high voltage
|
||
transformers that you can easily get a hold of are very&hellip;limited. Usually
|
||
these transformers output a high voltage (around 5,000 volts max), but have at
|
||
a pretty low current (less than 5 milliamps). While this can potentially hurt
|
||
you and leave burns, it is usually not enough to kill you. Microwave oven
|
||
transformers are <strong>very</strong> different.</p>
|
||
<p>While microwave oven transformers are pretty easy to get a hold of, they can
|
||
output a <strong>scary</strong> amount of power. The average microwave oven transformer can
|
||
output anywhere from 2,000 to 4,000 volts at around <strong>500 milliamps</strong> (or 0.5
|
||
amps). That&rsquo;s around <strong>1-2 thousand watts</strong> of power!</p>
|
||
<h2 id="some-fun">Some Fun</h2>
|
||
<p>With high voltage like this, you can do some really cool stuff.
|
||
But first, a disclaimer:</p>
|
||
<blockquote>
|
||
<h3 id="disclaimer">Disclaimer</h3>
|
||
<p>This should go without saying, but do <strong>NOT</strong> work with microwave ovens and
|
||
microwave oven transformers unless you know 100% what you are doing!
|
||
These things can <em>easily</em> kill you.</p>
|
||
<p>Human skin is usually 100 killoohms, this means that if you touch even a
|
||
2,000 volt microwave transformer, then you could have at <em>least</em> 20
|
||
milliamps flow through your body<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. This is enough current to seize your
|
||
muscles so you can&rsquo;t let go. 💀</p>
|
||
<p>I am <strong>NOT</strong> responsible for anything stupid that you do.</p></blockquote>
|
||
<p>This is the transformer that I pulled out of a microwave oven. Like most
|
||
transformers there&rsquo;s two coils, the primary and the secondary<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.
|
||
These are illustrated below:</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/transformer.webp" alt="Mircowave Transformer"></figure>
|
||
|
||
<p>By hooking up the primary side of the transformer to 120 volts AC (a.k.a.
|
||
Mains electricity) and attaching wires to the secondary side, I was able to get
|
||
some pretty cool arcs. I achieved this by bridging the gap between the
|
||
secondary side with a nail. This setup is called a
|
||
<a href="https://teslauniverse.com/build/plans/jacobs-ladder">Jacob&rsquo;s Ladder</a>.</p>
|
||
<video width="640" height="480" preload="none" controls>
|
||
<source src="https://brycev.com/ac-arcs.webm" type="video/webm">
|
||
</video>
|
||
|
||
<p>We can do better. We can build a self-sustaining (non-manual) Jacob&rsquo;s
|
||
Ladder&hellip;but how?</p>
|
||
<h2 id="more-power">More Power</h2>
|
||
<p>In order to create a self-sustaining and self-starting Jacob&rsquo;s Ladder I needed
|
||
more power. But how exactly can we add more power to this circuit? One
|
||
microwave oven transformer already draws a lot of power, but how about <strong>two</strong>
|
||
microwave oven transformers? That&rsquo;s right, I got a hold of <em>another</em> microwave
|
||
oven transformer.</p>
|
||
<p>Careful consideration is needed in order to hook up two of these microwave oven
|
||
transformers. I wired the two transformers in series with a &ldquo;center tap&rdquo; going
|
||
straight to ground (otherwise my breaker would trip). This gives me anywhere
|
||
from 4,000 volts to 8,000 volts AC. Next I need to turn that AC voltage into
|
||
DC voltage.</p>
|
||
<p>Sadly, I did not have enough high voltage components to make a <em>true</em> AC to
|
||
DC conversion system&hellip;but I hobbled one together anyways. I was able to
|
||
use two microwave oven capacitors as resistors<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> since I didn&rsquo;t have any
|
||
high power resistors on hand. In order to turn AC into &ldquo;DC&rdquo; I took and very
|
||
simple [but stupid] approach. During the negative AC cycle, all the current
|
||
is dumped into a pair of diodes&hellip;that&rsquo;s it. Does it waste a <strong>lot</strong> of power?
|
||
Yes. But does it work? <strong>Yes</strong>. I made a schematic below in order to better
|
||
illustrate the circuit.</p>
|
||
|
||
|
||
<figure ><a href="https://brycev.com/p/circuit.webp"><img src="https://brycev.com/p/circuit.webp" alt="Jacob&#39;s Ladder circuit"></a></figure>
|
||
|
||
<p>And here is the final product. A <strong>working</strong> Jacob&rsquo;s Ladder!</p>
|
||
<video width="640" height="480" preload="none" controls>
|
||
<source src="https://brycev.com/dc-arcs.webm" type="video/webm">
|
||
</video>
|
||
|
||
<p>I&rsquo;m not sure if you noticed in that video, but my breaker popped. This circuit
|
||
just draws too much power. I could improve this circuit, but I think I&rsquo;ve
|
||
decided to end my project here.
|
||
That being said, I think this was enough high
|
||
voltage fun for one day. :)</p>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>These are actually very conservative estimates. In reality, much more
|
||
current is likely to flow through your body&hellip;which would kill you even faster.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>Most microwave oven transformers actually have a third coil (see the
|
||
image).
|
||
This coil usually generates a very low voltage with a high current capability.
|
||
This is used to heat the magnetron filament, however we are not concerned with
|
||
it.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:3">
|
||
<p>For those who don&rsquo;t know, capacitors behave similar to resistors when
|
||
passing AC current through them due to
|
||
<a href="http://hyperphysics.phy-astr.gsu.edu/hbase/electric/accap.html#c2">capacitive reactance</a>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>My Conversion</title>
|
||
<link>https://brycev.com/blog/my-conversion/</link>
|
||
<pubDate>Mon, 11 Mar 2024 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/my-conversion/</guid>
|
||
<description><p>I&rsquo;ve been putting off writing this blog post for 2 (almost 3) years now.
|
||
There <strong>is</strong> a good reason for why I did that. Part of it was that I didn&rsquo;t
|
||
know how to put my experience into words until now, and the other part
|
||
was just procrastination. So now I feel like I finally have the experience
|
||
and knowledge to write about something that is very important to me.</p>
|
||
<h2 id="a-bit-of-background">A Bit of Background</h2>
|
||
<p>In the past I have never really been a religious person, nor have I really
|
||
ever liked religion. I always either found it silly, meaningless, or something
|
||
between those two. In high school I was something akin to Agnostic, I didn&rsquo;t
|
||
fully believe in God, but I wasn&rsquo;t really sure.
|
||
In middle school I was a proud Atheist who had a smug
|
||
satisfaction &ldquo;knowing&rdquo; that God did not exist. So take my word when I say the
|
||
events within the past few years of my life completely took me by surprise.</p>
|
||
<h2 id="i-am-now-a-roman-catholic">I Am Now A Roman Catholic</h2>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/augustine.webp" title="Based Saint Augustine of Hippo" alt="Saint Augustine of Hippo"></figure>
|
||
|
||
<p>Ok, <em>technically</em> I&rsquo;ve been a Catholic for the last 2-3 years and I got
|
||
confirmed last year, but I&rsquo;ve been
|
||
putting off &ldquo;officially&rdquo; saying anything until now. I was actually considering
|
||
Catholicism when I originally started this blog all the way back in November of
|
||
2021 (my <a href="https://brycevandegrift.xyz/blog/new-blog/">first blog post</a>), but I
|
||
didn&rsquo;t start taking it seriously until sometime in 2022.
|
||
For me, it seemed like it all happened very quickly.</p>
|
||
<blockquote>
|
||
<p>&ldquo;But did you consider religion <em>xyz</em>?&rdquo;
|
||
&ndash;Probably Someone</p></blockquote>
|
||
<p>I actually did consider quite a few. I considered different forms of
|
||
Christianity like Anglicanism, Orthodoxy, and even Baptist<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. I even
|
||
considered things like Islam, Buddhism, and even Hinduism briefly. However, I
|
||
never found a intellectual tradition that truly rivaled Catholic tradition<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.
|
||
I also personally looked for the religion that I thought was 100% <strong>true</strong> and
|
||
Catholicism seemed to fit that bill.
|
||
It should go without saying, but
|
||
basing your religious decisions on anything else besides truth (like personal
|
||
preference) is a very small brained move.</p>
|
||
<p>I didn&rsquo;t really have a bias either. I used to <strong>hate</strong> the Catholic Church, but
|
||
I soon grew to find out that my hatred was <em>very</em> much misplaced. As Venerable
|
||
Archbishop Fulton Sheen put it:</p>
|
||
<blockquote>
|
||
<p>&ldquo;Not 100 people in the United States hate the Roman Catholic Church, but
|
||
millions hate what they think the Roman Catholic Church is.&rdquo; &ndash;Archbishop
|
||
Fulton J. Sheen</p></blockquote>
|
||
<p>This very much encapsulates the essence of what stopped me from converting to
|
||
Catholicism in the past. I hated what I <em>thought</em> Catholicism was, but I soon
|
||
came to love what it <em>actually</em> is.</p>
|
||
<h2 id="joining-a-webring">Joining a Webring</h2>
|
||
<p>After being invited to the <a href="https://heaventree.xyz">Heaven Tree</a> webring almost
|
||
a year ago, I decided to accept the invitation last month. Now I didn&rsquo;t wait a
|
||
year to accept the invitation just to be rude. I waited quite a while because I
|
||
was not sure if I really wanted to identify as a Catholic or even as a Christian
|
||
for that matter. It really took me the last year to solidify my identity as a
|
||
Catholic and to accept it. So I sort of think that joining this webring is
|
||
me cementing myself as a Catholic.</p>
|
||
<h2 id="what-now">What Now?</h2>
|
||
<p>Not much about my blog or YouTube channel will change&hellip;at least in the short
|
||
term. I might post more stuff about theology or other topics related to it, but
|
||
as always I don&rsquo;t really have a specific direction for my blog or channel. I
|
||
just post about whatever I feel like saying and that&rsquo;s the way it will probably
|
||
always be. So don&rsquo;t be surprised if things change over time.</p>
|
||
<p>I am very grateful for my conversion and all that it has brought me. DEO GRATIAS.</p>
|
||
<blockquote>
|
||
<p>&ldquo;Late have I loved you, Beauty so ancient and so new, late have I loved you!</p>
|
||
<p>Lo, you were within,
|
||
but I outside, seeking there for you,
|
||
and upon the shapely things you have made
|
||
I rushed headlong – I, misshapen.
|
||
You were with me, but I was not with you.
|
||
They held me back far from you,
|
||
those things which would have no being,
|
||
were they not in you.</p>
|
||
<p>You called, shouted, broke through my deafness;
|
||
you flared, blazed, banished my blindness;
|
||
you lavished your fragrance, I gasped; and now I pant for you;
|
||
I tasted you, and now I hunger and thirst;
|
||
you touched me, and I burned for your peace.&rdquo;</p>
|
||
<p>&ndash;Saint Augustine of Hippo</p></blockquote>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>The only reason I even <strong>remotely</strong> considered Baptist was due to their
|
||
incredible zeal. Baptist theology is extremely deficient and almost
|
||
non-sensical.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>I mean, have you even looked at the Summa Theologica?&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Using a Dot Matrix Printer in 2024</title>
|
||
<link>https://brycev.com/blog/using-a-dot-matrix-printer-in-2024/</link>
|
||
<pubDate>Wed, 14 Feb 2024 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/using-a-dot-matrix-printer-in-2024/</guid>
|
||
<description><p>Modern printers suck. They&rsquo;re either overpriced, unreliable, ink/toner hogs,
|
||
or a combination of all 3.</p>
|
||
<p>Inkjet printers are cheap, have a good picture quality, and can print on
|
||
many surfaces. However, they are also <strong>very</strong> unreliable and usually don&rsquo;t
|
||
last over 3 years. Not only that but inkjet printer cartridges can cost
|
||
and arm and a leg, which is dumb considering ink (outside the cartridge)
|
||
is dirt cheap. Inkwell printers do solve the ink issue by having an ink
|
||
reservoir which means that you are not trapped into buying DRM infested
|
||
ink cartridges.</p>
|
||
<p>Laser printers are reliable, have a <strong>great</strong> picture quality, and are
|
||
usually more serviceable. However, they are often <strong>very</strong> large and
|
||
sometimes overly complicated. Just like with inkjet printers, laser printer
|
||
toner is insanely expensive and can cost anywhere from $60-$140 per cartridge.
|
||
It doesn&rsquo;t help that
|
||
[good] laser printers themselves are also very expensive, costing anywhere
|
||
from $500-$2,000.</p>
|
||
<p>Both laser and inkjet printers also suffer from having &ldquo;internet&rdquo; connectivity
|
||
put on them. I&rsquo;m not talking about a simple LAN connection, I&rsquo;m talking
|
||
about having your printer connected to Hewlett Packard&rsquo;s, Canon&rsquo;s, or
|
||
Epson&rsquo;s servers over the internet. Obviously, I&rsquo;m not a big fan of having
|
||
my printer being able to relay information to anywhere outside my house
|
||
without my permission.</p>
|
||
<p>So, what are we left with after laser and inkjet printers. Well, there are
|
||
thermal printers which are really cheap, require no ink/toner, and can print
|
||
quickly. However, they require special paper, the prints are usually not high
|
||
quality, and since a thermal printer <em>burns</em> the image onto paper, the image
|
||
wears off the paper after a year or so. You also can&rsquo;t print in color.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
|
||
<p>I guess that means we are left with&hellip;</p>
|
||
<h2 id="dot-matrix-printers">Dot Matrix Printers</h2>
|
||
<p>Dot matrix printers are relatively cheap, usually costing no more than
|
||
$500. They&rsquo;re also simple since a dot matrix printer&rsquo;s method of printing is
|
||
relatively straight forward (I&rsquo;ll explain how they work in a moment). Since
|
||
they&rsquo;re simple, that also means that they&rsquo;re also <strong>very</strong> reliable and easy
|
||
to service. Dot matrix ink ribbons are also cheap compared to inkjet ink
|
||
and laser printer toner. There are also color options for dot matrix printers.
|
||
The only real apparent downside of dot matrix printers is speed as it usually
|
||
takes a while to print compared to other printers.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
|
||
<h2 id="how-they-work">How They Work</h2>
|
||
<p>If you&rsquo;re not familiar with how dot matrix printers work, you would be
|
||
surprised by how simple they are. A dot matrix printer, as the name implies,
|
||
prints in a matrix of dots. As the print head moves from left to right, it
|
||
presses the ink onto the paper via a series of tiny pins that create the
|
||
final image. It does this line by line until the entire picture is printed.
|
||
If you want to see one in action look <a href="https://youtu.be/A_vXA058EDY">here</a>.</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/dotmatrix.webp" alt="How a dot matrix printer works"></figure>
|
||
|
||
<p>Sadly, as you can tell from the video, this means that dot matrix printers
|
||
are somewhat slow and sometimes loud compared to their contenders.</p>
|
||
<h2 id="my-not-really-new-printer">My (Not Really) New Printer</h2>
|
||
<p>About a year or two ago I acquired an Apple ImageWriter II off of eBay for
|
||
about $50. It had some wear and tear on it and was <em>severely</em> yellowed (which
|
||
I don&rsquo;t mind) and it was also previously used in an industrial setting. But
|
||
despite all of that, it worked great! The only problem it had was that one
|
||
of the pins on the print head did not work, which you will see in a moment.
|
||
Considering there is only <strong>one</strong> problem with it after 30 years of industrial
|
||
use is amazing and really shows the reliability of these things.</p>
|
||
<p>I planned to use this thing for a while, but I kept on putting it off
|
||
for about 1-2 years. It wasn&rsquo;t until the last 2 weeks that I decided to
|
||
get this thing working.</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/imagewriter.webp" title="The last good Apple product" alt="Apple Imagewriter II"></figure>
|
||
|
||
<h2 id="getting-it-to-work">Getting It To Work</h2>
|
||
<h3 id="printing-text">Printing Text</h3>
|
||
<p>The first problem I encountered was how to even hook this thing up to my
|
||
modern computer. My desktop has a 9 pin serial card and the ImageWriter is a
|
||
serial printer, so I figured that I should start there. The printer came with a
|
||
cable to covert the 8 pin DIN socket on the printer to a 25 pin serial
|
||
connector, so I decided to buy a 25 pin to 9 pin null modem serial cable and a
|
||
25 pin serial coupler. I hooked it up as followed:</p>
|
||
<pre tabindex="0"><code> DB-25 Serial Port
|
||
| |
|
||
DB-9 Serial Port-------+ | | +-------DIN 8 Serial Port
|
||
| | | |
|
||
| | | |
|
||
+-----------+ | | +-------+ | | +---------+
|
||
| | v v | | v v | |
|
||
| Computer +-+--+-+Coupler+-+-+-+ Printer |
|
||
| | | | | |
|
||
+-----------+ +-------+ +---------+
|
||
</code></pre><p>Next, I had to get access to <code>/dev/ttyS1</code> which is where my serial port
|
||
connected to the printer is located. To do that I just created a simple udev
|
||
rule to change the permissions of <code>/dev/ttyS1</code> on boot.</p>
|
||
<pre tabindex="0"><code>KERNEL==&#34;ttyS1&#34;, GROUP=&#34;plugdev&#34;, MODE=&#34;0660&#34;
|
||
</code></pre><p>Finally, I had to change the settings of the serial port using <code>stty</code>.
|
||
The settings needed to be:</p>
|
||
<ul>
|
||
<li>9600 baud rate</li>
|
||
<li>8 character bits</li>
|
||
<li>1 stop bit</li>
|
||
<li>No parity</li>
|
||
</ul>
|
||
<p>So in order to set them accordingly I ran:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>stty -F /dev/ttyS1 <span style="color:#ae81ff">9600</span> cs8 -cstopb -parenb
|
||
</span></span></code></pre></div><p>And finally, I sent some data to test the printer.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;This is a test&#34;</span> &gt; /dev/ttyS1
|
||
</span></span></code></pre></div><p>And&hellip;<strong>it worked!</strong></p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/testprint.webp" alt="It works"><figcaption>Success!</figcaption></figure>
|
||
|
||
<h3 id="printing-pdfs">Printing PDFs</h3>
|
||
<p>Printing text from a modern computer onto a 30 year old printer is pretty
|
||
cool, but I wanted to see how well it could print PDFs. I actually planned
|
||
to write a program to translate a PDF to a format that I could output to
|
||
the ImageWriter, needless to say, this would take a while. Luckily, I found
|
||
out that <a href="https://www.ghostscript.com/">Ghostscript</a> actually supports output
|
||
to the Apple ImageWriter family. Four drivers where available:</p>
|
||
<ul>
|
||
<li>appledmp (Generic Apple dot matrix driver)</li>
|
||
<li>iwlo (Apple ImageWriter)</li>
|
||
<li>iwhi (Apple ImageWriter II)</li>
|
||
<li>iwlq (Apple ImageWriter LQ)</li>
|
||
</ul>
|
||
<p>I choose <a href="https://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png">this</a>
|
||
as my test image.</p>
|
||
<p>In order to create a file that I could send to the printer I needed to
|
||
first convert the PNG into a PDF file with ImageMagick, run Ghostscript,
|
||
and then output it to the printer:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>convert Tux.png Tux.pdf
|
||
</span></span><span style="display:flex;"><span>gs -q -dBATCH -dNOPAUSE -sDEVICE<span style="color:#f92672">=</span>iwhi -sPAPERSIZE<span style="color:#f92672">=</span>letter -dFIXEDMEDIA -dPSFitPage -r160x144 -sOutputFile<span style="color:#f92672">=</span>tux Tux.pdf
|
||
</span></span><span style="display:flex;"><span>cat tux &gt; /dev/ttyS1
|
||
</span></span></code></pre></div><p>The output from the printer was&hellip;<em>interesting</em>.</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/tuxtest.webp" alt="Failed print"></figure>
|
||
|
||
<blockquote>
|
||
<p>Side note, you can see the visible lines that go across the print. That is
|
||
actually the broken pin on the print head, I plan on replacing the print
|
||
head eventually.</p></blockquote>
|
||
<p>This was good and bad. Good because graphics printing works.
|
||
Bad because I had no idea what was causing this image to corrupt.
|
||
At this point I had no idea what was wrong. I assumed the problem was that
|
||
the Ghostscript driver was faulty, however I tried all 4 Apple ImageWriter
|
||
drivers and they all had a similar result. At one point I thought the serial
|
||
connection was bad, but these errors were too consistent to be a connection
|
||
issue. I looked at the
|
||
<a href="https://mirrors.apple2.org.za/ftp.apple.asimov.net/documentation/hardware/printers/Apple%20ImageWriter%20II%20Technical%20Reference%20Manual.pdf">Apple ImageWriter II Technical Reference Manual</a>
|
||
and that&rsquo;s when I found the problem.</p>
|
||
<hr>
|
||
<h4 id="a-side-note-about-printers">A Side Note About Printers</h4>
|
||
<p>One thing that I was ignorant about when it came to printers is that
|
||
almost every printer has a <strong>buffer</strong>. The buffer stores data for the current
|
||
print job (sometimes future print jobs as well), feeds it to the printer
|
||
once it needs to print that data, and then disposes of that data once it
|
||
has been printed. Most modern printers have a decent buffer size to hold
|
||
print data. Most printing software keeps track of how much data
|
||
is sent to the printer buffer. This means that we never really have to worry
|
||
about prints being messed up since print buffers are automatically managed
|
||
for us.</p>
|
||
<hr>
|
||
<p>Once I read that the Apple ImageWriter II only has a print buffer size of
|
||
<strong>2 kilobytes</strong> I knew what the problem was.</p>
|
||
<p>The problem about sending data at 9600 baud to the printer was that it was
|
||
sending data at a faster rate than the printer could actually print, which was
|
||
overwriting data in the buffer which caused it to print garbage. In order
|
||
to remedy this I did something no man has ever done&hellip;<em>lower</em> the baud rate.</p>
|
||
<p>Once I set the baud rate on the printer and my computer&rsquo;s serial port to
|
||
2400 baud and printed the image, I got this:</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/matrixtux.webp" alt="Printed image of Tux"></figure>
|
||
|
||
<p><strong>Success!</strong></p>
|
||
<p>There are a few errors on the right of Tux and a missing line, but that is
|
||
just a problem with Ghostscript that I can&rsquo;t fix. It usually does not show
|
||
up on most other prints.</p>
|
||
<h3 id="printing-faster">Printing Faster</h3>
|
||
<p>The printer works perfectly at 2400 baud and lower.
|
||
The only problem is that this printer is now <em>slow</em>. 2400 baud is
|
||
not fast at all! There are pauses during printing where the printer is
|
||
waiting to receive serial data from the computer. So how do I increase the
|
||
data transfer rate but also limit the data transferred to 2kb? Well, that&rsquo;s
|
||
where a program called <code>split</code> comes in handy. <code>split</code> is a standard POSIX
|
||
utility that is available on <strong>ALL</strong> POSIX systems. It takes an input file
|
||
a splits it into multiple output files, but it also has a <code>-b</code> option
|
||
which allows you to limit the split files to a specific size. In this case,
|
||
we can limit the file size to 2kb and send them one at a time at 9600 baud.
|
||
All I have to do is run:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>split -b 2k tux
|
||
</span></span></code></pre></div><p>And now we have 67 different 2kb files starting with &ldquo;x&rdquo; that we can send one at a time.
|
||
In order to print them one at a time I wrote a script that just loops
|
||
over these files:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#75715e">#!/bin/sh
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
|
||
</span></span><span style="display:flex;"><span>files<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#66d9ef">$(</span>ls -1 x*<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> x in $files; <span style="color:#66d9ef">do</span>
|
||
</span></span><span style="display:flex;"><span> cat $x &gt; /dev/ttyS1
|
||
</span></span><span style="display:flex;"><span> sleep <span style="color:#ae81ff">5</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span>
|
||
</span></span></code></pre></div><p>Of course this is <strong>not</strong> an efficient way of printing. There are moments
|
||
where the printer is waiting for data to be received, but this is good enough.
|
||
In order to achieve close to 100% efficiency, you would need to
|
||
calculate how fast the print head and page feed move on the host, but
|
||
I&rsquo;m <em>way</em> too lazy to do that.</p>
|
||
<h2 id="the-result">The Result</h2>
|
||
<p>The result is a printer that is somewhat slow, but gets the job done. All
|
||
I need now is to get <a href="https://en.wikipedia.org/wiki/Continuous_stationery">tractor/continuous feed paper</a> so I don&rsquo;t have to load
|
||
paper manually. For me, this printer is definitely a good enough solution
|
||
until I get a new printer (if this one even fails).<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
|
||
<video width="640" height="480" preload="none" controls>
|
||
<source src="https://brycev.com/print.webm" type="video/webm">
|
||
</video>
|
||
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>I think there actually <em>are</em> thermal printers that can print in color
|
||
(I have no idea how), but they seem very rare.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>Dot matrix printers <em>do</em> have more downsides like the fact that pins
|
||
on the print head can break easily, but since you can replace the print heads
|
||
<strong>and</strong> print heads are relatively cheap this is negligible.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:3">
|
||
<p>I&rsquo;ve been keeping my eye on any used Epson dot matrix printers. 👀&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Why I Switched to Alpine</title>
|
||
<link>https://brycev.com/blog/why-i-switched-to-alpine/</link>
|
||
<pubDate>Mon, 06 Nov 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/why-i-switched-to-alpine/</guid>
|
||
<description>
|
||
|
||
<figure ><img src="https://brycev.com/p/alpine.webp" alt="Alpine Linux logo"></figure>
|
||
|
||
<p>I&rsquo;ve been a <a href="https://voidlinux.org/">Void Linux</a> user for about 2 years and I want to say it has been
|
||
a good run. Void Linux has been an absolutely great Linux distribution and
|
||
has served me well for quite a while. However, every Linux distribution is not
|
||
without it&rsquo;s shortcomings. Although Void Linux is a <strong>great</strong> distribution,
|
||
I still think that it had a few shortcomings that <a href="https://alpinelinux.org/">Alpine Linux</a> fixes.</p>
|
||
<h2 id="what-alpine-does-better-than-void">What Alpine Does Better Than Void</h2>
|
||
<h3 id="packages">Packages</h3>
|
||
<p>Although the main Void Linux repositories have more packages than most other
|
||
distributions, the selection is still a bit&hellip;lacking. As of writing this,
|
||
Void Linux has around 13,369 packages. Which is still <strong>a lot</strong> of packages,
|
||
however Alpine Linux more than <strong>doubles</strong> Void at around 28,583 packages<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
|
||
<p>One thing that bugs me is that even though Void supports musl libc, not all
|
||
13,369 packages are available for musl. As you would have guessed, Alpine does
|
||
not have this problem since musl is the default.</p>
|
||
<p>Another thing that kind of bugs me is how long it took for packages I
|
||
submitted to Void&rsquo;s package repos to get accepted. Some of my requests
|
||
were <strong>never</strong> responded to and others were just forgotten about entirely.
|
||
When submitting packages to Alpine&rsquo;s packages repos my requests were almost
|
||
answered the same day and 100% of my packages (so far) have been accepted
|
||
into the testing branch.</p>
|
||
<h3 id="xbps">XBPS</h3>
|
||
<p>Now don&rsquo;t get me wrong, the XBPS package manager is great, however apk
|
||
(Alpine&rsquo;s package manager) is superior when compared to XBPS. For example, when updating
|
||
my system after a month on Void it would take around 3-4 minutes to update
|
||
using XBPS. Whenever I update after a month on Alpine it usually takes
|
||
less than a minute!</p>
|
||
<p>A set of packages that show this perfectly are the <code>texlive</code> packages. The
|
||
time it takes to install an entire texlive distribution on disk is
|
||
notoriously long. Alpine&rsquo;s apk installs texlive <em>way</em> faster than XBPS.
|
||
Not only that, but apk manages cached packages in a much better way than
|
||
XBPS, in my opinion.</p>
|
||
<p>I don&rsquo;t think I will ever see a package manager as fast, light, and minimal
|
||
as apk.</p>
|
||
<h3 id="busybox">BusyBox</h3>
|
||
<p>One thing that keeps Alpine small is instead of using the GNU Coreutils,
|
||
Alpine uses the BusyBox Coreutils. For a long time user of the GNU Coreutils
|
||
like me, the switch can be very jarring, however the payoff is (in my opinion)
|
||
worth it. The BusyBox Coreutils are actually easier to learn since they have
|
||
less features and options. They also have the upside of being more POSIX
|
||
compliant than the GNU Coreutils so writing scripts with BusyBox usually
|
||
results in more portability.</p>
|
||
<h3 id="musl-musl-musl-">musl, musl, musl 🐚</h3>
|
||
<p>Void and Alpine both support musl libc, but a major difference is that Alpine
|
||
supports <strong>only</strong> musl<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. For those of you who are not well versed in C
|
||
libraries, musl is essentially a smaller and more tidy C library replacement
|
||
for glibc (the GNU C library). As I mentioned above, this means that all
|
||
28,583 Alpine packages are compiled for musl.</p>
|
||
<p>For reasons that I won&rsquo;t get into (since it would take too long) musl is
|
||
generally better than glibc, but sometimes isn&rsquo;t as compatible as glibc,
|
||
you can find out more about that <a href="https://wiki.musl-libc.org/functional-differences-from-glibc.html">here</a>.
|
||
I think one of the best comparisons of musl and glibc can be found
|
||
<a href="https://www.etalabs.net/compare_libcs.html">here</a>. musl binaries tend to
|
||
be smaller, faster, and more portable compared to glibc.</p>
|
||
<p>As a C programmer, working with musl is a <strong>dream</strong> compared to glibc.</p>
|
||
<h3 id="its-great-use-it-already">It&rsquo;s Great, Use It Already</h3>
|
||
<p>Overall, Alpine Linux fixes almost every gripe that I had with Void Linux
|
||
and also fixes problems that I didn&rsquo;t even know I had. The entire Alpine
|
||
Linux distribution is easy to understand, simple, and fast.
|
||
There are many, many
|
||
more things that Alpine does better than Void, but if I listed them <em>all</em>
|
||
then it would take forever. But so far, Alpine Linux is probably one of the
|
||
<strong>best</strong> Linux distributions that I have ever used.</p>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>These numbers where obtained by running <code>xbps-query -Rs &quot;*&quot; | wc -l</code>
|
||
and <code>apk search &quot;*&quot; | wc -l</code> respectively.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>Technically Alpine <em>does</em> support glibc if you wish to install it
|
||
through apk.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>FFmpeg Video Calls</title>
|
||
<link>https://brycev.com/blog/ffmpeg-video-calls/</link>
|
||
<pubDate>Mon, 18 Sep 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/ffmpeg-video-calls/</guid>
|
||
<description><p>If you have seen any of the <a href="https://youtu.be/VGRHzB8ANAo">videos I made on</a>
|
||
<a href="https://youtu.be/4NKmEjzfJ98">FFmpeg</a> you would know that I absolutely love
|
||
it and I think that it is the absolute <strong>BEST</strong> video/multimedia program ever
|
||
made.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> FFmpeg has so many features and it implements almost all of them
|
||
extremely well. So it comes to no surprise, after I initially made my FFmpeg
|
||
videos I found out that FFmpeg can actually be used to create video streams and
|
||
send them over the internet. After I found out about this I wondered if it
|
||
could be used as a sort of minimal way to create video calls. After
|
||
experimenting for just a few <em>minutes</em> I found a way to stream video over the
|
||
internet via FFmpeg.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>ffmpeg -f alsa -i default <span style="color:#ae81ff">\ </span><span style="color:#75715e"># Get audio from mic</span>
|
||
</span></span><span style="display:flex;"><span>-i /dev/video0 <span style="color:#ae81ff">\ </span><span style="color:#75715e"># Get video from camera</span>
|
||
</span></span><span style="display:flex;"><span>-s 640x480 <span style="color:#ae81ff">\ </span><span style="color:#75715e"># Scale down to 640x480</span>
|
||
</span></span><span style="display:flex;"><span>-c:v libx264 -preset:v ultrafast <span style="color:#ae81ff">\ </span><span style="color:#75715e"># Encode fast!</span>
|
||
</span></span><span style="display:flex;"><span>-tune zerolatency -intra-refresh <span style="color:#ae81ff">1</span> <span style="color:#ae81ff">\ </span><span style="color:#75715e"># Reduce latency</span>
|
||
</span></span><span style="display:flex;"><span>-f mpegts <span style="color:#ae81ff">\ </span><span style="color:#75715e"># Put everything into mpegts stream</span>
|
||
</span></span><span style="display:flex;"><span>-b:v 1M udp://localhost:1313 <span style="color:#75715e"># Send video over localhost:1313</span>
|
||
</span></span></code></pre></div><p>In order to actually view this video you would need a video player that is
|
||
able to read/receive from UDP. Luckily such a program exists:
|
||
<a href="https://youtu.be/iR76e9XUodI">mpv</a>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mpv --profile<span style="color:#f92672">=</span>low-latency udp://localhost:1313
|
||
</span></span></code></pre></div><p>Now to actually send this over the internet and not just over LAN or localhost you
|
||
would need to replace <code>localhost:1313</code> with the IP address of the recipient
|
||
for FFmpeg and the IP address of the sender for mpv. This is will let
|
||
you be able to do peer-to-peer video calls using only FFmpeg and mpv (or any
|
||
other UDP compatible video player). FFplay, a media player that comes with
|
||
FFmpeg, can play UDP streams, so technically this can be done using <strong>only</strong>
|
||
FFmpeg. If you replace <code>-f /dev/video0</code> with
|
||
<code>-i x11grab</code> you can also screencast to another computer as well, pretty neat.</p>
|
||
<p>Theoretically, you could do more than just one-on-one video calls, you could
|
||
have 4, 7, or even 15 people using this method. It would definitely be tedious
|
||
to set it up, but it would be possible. And of course if you don&rsquo;t want to use
|
||
video at all you can easily use this method for audio calls.</p>
|
||
<p>I think this example shows just how versatile FFmpeg can be. Not only that
|
||
but the settings I used for this example are not actually optimal, it was
|
||
just a test but it worked great. This is just the tip of the iceberg too,
|
||
you can also use this to stream movies from another computer,
|
||
video games, general live streaming, and much more.
|
||
I personally
|
||
find it crazy that you can basically do audio and video calls using <strong>only</strong>
|
||
FFmpeg and this shows just how absolutely amazing it is.</p>
|
||
<video width="640" height="480" preload="none" controls>
|
||
<source src="https://brycev.com/cameracast.webm" type="video/webm">
|
||
</video>
|
||
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>In fact, the creator of FFmpeg, Fabrice Bellard, also made QEMU and the
|
||
Tiny C Compiler (TCC) both of which are very widely used pieces of software
|
||
that are very well made.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>A Branded Life</title>
|
||
<link>https://brycev.com/blog/a-branded-life/</link>
|
||
<pubDate>Thu, 06 Jul 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/a-branded-life/</guid>
|
||
<description><p>Modern &ldquo;brands&rdquo; are a weird thing when you really think about them.
|
||
Disney, Hewlett Packard, and Nike. What do all 3 of these have in common?
|
||
They&rsquo;re all considered brands. But what exactly is a brand? Before the
|
||
industrial age, a brand was just a way to differentiate a product from a
|
||
competitor&rsquo;s product. In order to differentiate it one would often <em>brand</em>
|
||
their name or alias in the product itself.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> However, the concept of a
|
||
brand has evolved over the last 100-200 years. Instead of being just a
|
||
name or logo, a brand is often associated with what people hear
|
||
(jingles/slogans), taste, see, and more. How many times have you heard
|
||
someone say, &ldquo;Hey, this <strong>X</strong> is just like <strong>Y</strong> brand?&rdquo; As a result of this
|
||
recognition, modern branding strategies have exploded in popularity. For the
|
||
companies that brand their products like this, it creates more customer
|
||
loyalty and therefore more money.</p>
|
||
<p>But is branding (in the modern sense) a good thing?</p>
|
||
<h2 id="everything-is-a-brand">Everything is a Brand</h2>
|
||
<p>One thing that I tend to find very annoying is the modern obsession of brands
|
||
to the point where <strong>everything</strong> has to be a brand. From homemade crafts to
|
||
personal websites, it seems like there are so many attempts at creating a
|
||
modern brand that are just not necessary.</p>
|
||
<p>Let me share an experience that I had somewhat recently. I had a friend
|
||
buy me a book from a local book shop as a gift. When I received it I thanked
|
||
them for the gift and I read it later. I noticed something rather odd
|
||
about this book&hellip;there was <strong>no</strong> branding. <strong>No</strong> <em>brand name</em>, <strong>no</strong> name, and
|
||
not even a <strong>copyright notice</strong>. Needless to say I was taken back by this
|
||
as it seemed abnormal. But why did I think it was abnormal? If I had to guess,
|
||
it was probably because seeing someone not milking their work and
|
||
committing a sort of selfless act seemed out of place, especially in this
|
||
day and age.</p>
|
||
<p>When was the last time you saw a book without a logo or brand name?
|
||
I only have two books in my <em>entire</em> collection that fit that criteria.
|
||
Actually, when is the last time you saw <strong>anything</strong> without a logo
|
||
or brand name? Go through the room you&rsquo;re in right now and count how many
|
||
items you have that don&rsquo;t have a brand name and or logo. No, seriously, do it.
|
||
You will be genuinely surprised.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
|
||
<h2 id="the-safe-zone">The Safe Zone</h2>
|
||
<p>One very important downside of modern brands that impact customers is
|
||
what I like to call the &ldquo;<em>safe zone</em>&rdquo;. The &ldquo;safe zone&rdquo; is a situation in which a
|
||
customer buys products of specific brands either due to trust, loyalty,
|
||
familiarity, or a mix of all three. This results in the customer not buying
|
||
anything else unless it&rsquo;s from one of their chosen brands.</p>
|
||
<p>This usually results in dependence on a specific brand. This is, of course,
|
||
intended. And while it is <strong>very</strong> beneficial to the brand itself, it can
|
||
be detrimental to the customer. On one hand, the customer is provided safety
|
||
and security knowing that what they get from a specific brand will be
|
||
(mostly) consistent. On the other hand, this can trap the customer into
|
||
dependence on a brand since not buying from a trusted brand would
|
||
be too &ldquo;risky&rdquo; or &ldquo;unsafe&rdquo; (hence the name &ldquo;safe zone&rdquo;).</p>
|
||
<p>This effect can happen on such a large scale that many brand names are
|
||
immediately associated with a non-branded objects. For example, do you hear
|
||
people say cola or Coca-Cola more? Do you hear people say tissue or
|
||
Kleenex more? Do you hear people say slow cooker or Crock-Pot more? The
|
||
list goes on and on. Not only does this result in other products being
|
||
noticed less, but it also draws a negative light on other products and make
|
||
them seem inferior compared to larger brands.</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/consoom.webp" title="Must consooooome!" alt="consoomer"></figure>
|
||
|
||
<h2 id="drm">DRM</h2>
|
||
<p><a href="https://www.defectivebydesign.org/what_is_drm">Digital Restrictions Management</a>,
|
||
more commonly referred to as Digital Rights Management, is one way that a
|
||
brand keeps customers. DRM essentially restricts what the customer/user
|
||
can do with a product. This is usually very prevalent among popular
|
||
companies/brands especially in the technology sector.</p>
|
||
<p>The best example I can probably think of is ink cartridges for inkjet printers.
|
||
Most major brands of inkjet printers use proprietary ink cartridges with DRM
|
||
built into the cartridges themselves. If you try to use a different type of ink
|
||
cartridge on your printer, <strong>it won&rsquo;t work</strong>. If you try to refill the ink in
|
||
your cartridge, <strong>it won&rsquo;t work</strong>. If you buy third party ink cartridges,
|
||
<strong>they won&rsquo;t work</strong>.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> It&rsquo;s not because it is &ldquo;incompatible&rdquo;, it&rsquo;s ink,
|
||
it&rsquo;s because the manufacturer wants to force you into brand loyalty and to
|
||
buy their products.</p>
|
||
<p>Now it doesn&rsquo;t take a genius to understand that DRM is bad, but for the
|
||
handful of people who don&rsquo;t understand why DRM is <em>objectively</em> awful,
|
||
here are a few <a href="https://creativecommons.org/2017/07/09/terrible-horrible-no-good-bad-drm/">links to</a>
|
||
<a href="https://www.defectivebydesign.org/so_youve_got_some_questions_do_you#examples">understand</a>
|
||
<a href="https://www.audioholics.com/news/drm-bad-killing-online-music">why</a>.</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/printer.webp" alt="Printer DRM"><figcaption>Classic printer DRM at work.</figcaption></figure>
|
||
|
||
<p>Although the modern conception of branding is very beneficial from an economic
|
||
and financial standpoint, it can have many negative side effects outside the
|
||
economic and financial realm. It can result in enforcing restrictions on the
|
||
customer, physiologically locking them into dependence, and creates obsession
|
||
with branding. Although this is great for the brand owners, it sucks for the
|
||
everyday customer. Granted, there are many more factors that go into branding
|
||
but I think these points really highlight the nature of the current situation.</p>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>This, of course, is a centuries old tradition and goes all the way back
|
||
to branding livestock to prove ownership.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>Unless you make it a habit to tear off labels and branding of products
|
||
that you buy. In which case, I wouldn&rsquo;t blame you for doing that.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:3">
|
||
<p>And this isn&rsquo;t made any better by the fact that inkjet printer ink
|
||
is extremely expensive, especially if it is purchased from the manufacturers
|
||
themselves.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Stop Saying C/C++</title>
|
||
<link>https://brycev.com/blog/stop-saying-c-and-c++/</link>
|
||
<pubDate>Thu, 18 May 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/stop-saying-c-and-c++/</guid>
|
||
<description><p>For as long as I can remember, I have heard people say C/C++ when referring to
|
||
a project written in C and or C++. A lot of programming/developer jobs also
|
||
refer to C/C++ when they need a programmer who knows either C or C++. To most
|
||
people who have never touched C or C++ this might not seem like a big deal.
|
||
However, the problem is that when people say this term (C/C++) they make it
|
||
seem like C and C++ are similar or closely related programming languages.
|
||
<strong>That is not true.</strong> Although C++ was based off of C when it was first
|
||
created, these two languages have slowly drifted apart over the years to the
|
||
point where they share less and less in common<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
|
||
<h2 id="c-and-c-are-very-different">C and C++ are VERY Different</h2>
|
||
<p>There is probably someone who is going to say, &ldquo;Well you can write C code in
|
||
a C++ program, so technically C is a subset of C++.&rdquo; The only problem is that
|
||
you can write C code in <a href="https://ziglang.org/documentation/master/#C">Zig</a>,
|
||
<a href="https://pkg.go.dev/cmd/cgo">Go</a>, <a href="https://github.com/nim-lang/Nim/wiki/Nim-for-C-programmers">Nim</a>,
|
||
and basically almost every other language out there has a C FFI! So should I refer to Zig,
|
||
Go, and Nim as C/Zig, C/Go, and C/Nim? Obviously <strong>no</strong>.</p>
|
||
<h3 id="c-with-classes">C with Classes</h3>
|
||
<blockquote>
|
||
<p>&ldquo;But C++ is just C with classes!&rdquo;</p></blockquote>
|
||
<p><strong>No</strong>, it isn&rsquo;t. Anyone who says this obviously has never worked with C++. C++ has
|
||
completely different standard libraries, implementations, and standards than C.
|
||
It is true that when C++ was first made it was just C with classes<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>, that has
|
||
long been false ever since C++ has implemented features separate from C.</p>
|
||
<h3 id="incompatibility">Incompatibility</h3>
|
||
<h4 id="void-pointers">Void Pointers</h4>
|
||
<p>One such case where C++ is incompatible with C is with void pointers.
|
||
For example, this program will compile with a C compiler (like GCC), but it
|
||
will not compile with a C++ compiler (like G++):</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdlib.h&gt;</span><span style="color:#75715e">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> <span style="color:#f92672">*</span>a <span style="color:#f92672">=</span> <span style="color:#a6e22e">malloc</span>(<span style="color:#ae81ff">5</span>);
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>All this code does is allocate 5 bytes to an integer pointer <code>a</code>. This program
|
||
works perfectly fine when compiled with GCC, but if I compile this program with
|
||
G++ this error is returned:</p>
|
||
<pre tabindex="0"><code>main.c: In function &#39;int main()&#39;:
|
||
main.c:4:24: error: invalid conversion from &#39;void*&#39; to &#39;int*&#39; [-fpermissive]
|
||
4 | int *a = malloc(5);
|
||
| ~~~~~~^~~
|
||
| |
|
||
| void*
|
||
</code></pre><p>The reason this happens is that <code>malloc</code> returns a void pointer and C++ cannot
|
||
convert a void pointer into an integer pointer unless it is specifically cast
|
||
to an integer pointer.</p>
|
||
<h4 id="kr-syntax">K&amp;R Syntax</h4>
|
||
<p>Another big incompatibility with C and C++ is that C++ is actually incompatible
|
||
with <a href="https://en.wikipedia.org/wiki/C_(programming_language)#K&amp;R_C">K&amp;R</a> syntax. Given this example function formatted in K&amp;R syntax:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">gcd</span>(a, b)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> a;
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> b;
|
||
</span></span><span style="display:flex;"><span>{
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (b <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> a;
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">gcd</span>(b, (a <span style="color:#f92672">%</span> b));
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>It will compile perfectly fine for GCC (as expected), however G++ gives us
|
||
<em>another</em> set of errors&hellip;</p>
|
||
<pre tabindex="0"><code>gcd.c:3:9: error: &#39;a&#39; was not declared in this scope
|
||
3 | int gcd(a, b)
|
||
| ^
|
||
gcd.c:3:12: error: &#39;b&#39; was not declared in this scope
|
||
3 | int gcd(a, b)
|
||
| ^
|
||
gcd.c:3:13: error: expression list treated as compound expression in initializer [-fpermissive]
|
||
3 | int gcd(a, b)
|
||
| ^
|
||
gcd.c:6:1: error: expected unqualified-id before &#39;{&#39; token
|
||
6 | {
|
||
| ^
|
||
</code></pre><p>This makes it almost impossible to use K&amp;R syntax with C++ unless you format
|
||
your function arguments according to <a href="https://gist.github.com/nicholatian/2d9514feaf9a95e7561a433ac404b141">ANSI C</a>.
|
||
(I know not many people care about K&amp;R syntax, but I think that it is still an
|
||
important difference).</p>
|
||
<p>There are also many other things in C that will not transfer over to C++ like
|
||
complex numbers, default return types, and more, but
|
||
I think you already get the picture by now. These incompatibilities are not
|
||
anything that would break the entire C language if used in conjunction with
|
||
C++, but these small differences slowly add up.</p>
|
||
<h3 id="hard-for-beginners">Hard for Beginners</h3>
|
||
<p>Not differentiating between C and C++ also has the side effect of ostracizing new
|
||
users. Many beginner programmers are lead by the term &ldquo;C/C++&rdquo; to think that
|
||
they&rsquo;re basically the same language. In fact there are <a href="https://medium.com/@yekayama/stop-making-c-c-tutorials-2fa9bc114488">many</a> tutorials out there
|
||
that are advertised as &ldquo;C/C++ tutorials&rdquo;, continuing the confusion.
|
||
This can also scare away C beginners by making them think that understanding
|
||
the complexities of C++ are required to understand C (<em>SPOILER</em>: They&rsquo;re not).
|
||
I have fallen for this trap in the past, as well as many others.
|
||
C is honestly a very simple programming language, C++ is not.</p>
|
||
<h2 id="c-and-c-programmers-are-very-different">C and C++ Programmers are VERY Different</h2>
|
||
<p>With the new C++ standards given throughout the years like C++11, C++20, and
|
||
etc. C++ programmers have been given more tools and functions that don&rsquo;t exist
|
||
in standard C. This usually results in modern C programs having more lines of
|
||
code than modern C++, however this means that modern C is usually more readable
|
||
than modern C++. Here is an example question from <a href="https://leetcode.com/problems/maximum-count-of-positive-integer-and-negative-integer/">LeetCode</a>.
|
||
Solutions differ, but most C solutions look something like this:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">maximumCount</span>(<span style="color:#66d9ef">int</span> <span style="color:#f92672">*</span>nums, <span style="color:#66d9ef">int</span> numsSize) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int</span> pos <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>, neg <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">int</span> i <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; i <span style="color:#f92672">&lt;</span> numsSize; i<span style="color:#f92672">++</span>) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (nums[i] <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>) pos<span style="color:#f92672">++</span>;
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (nums[i] <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span>) neg <span style="color:#f92672">++</span>;
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> pos <span style="color:#f92672">&gt;</span> neg <span style="color:#f92672">?</span> pos : neg;
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>Even though this code is pretty compact for C standards it is still <em>very</em>
|
||
readable. Now for the C++ solutions, there are a lot of variations to this
|
||
solution so I will use one that&rsquo;s different <em>enough</em> from C.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">maximumCount</span>(std<span style="color:#f92672">::</span>vector<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">int</span><span style="color:#f92672">&gt;</span> nums) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">auto</span> [a, b] <span style="color:#f92672">=</span> std<span style="color:#f92672">::</span>equal_range(nums.begin(), nums.end(), <span style="color:#ae81ff">0</span>);
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> std<span style="color:#f92672">::</span>max(std<span style="color:#f92672">::</span>distance(nums.begin(), a), std<span style="color:#f92672">::</span>distance(b, nums.end()));
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>This uses <code>vector</code> and <code>algorithm</code> from the C++ standard library<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>.
|
||
As you can see this code is <em>much</em> more compact but is definitely not as
|
||
readable as the C code. Although the C solution can be compiled by a C++
|
||
compiler I wanted to highlight just how different they can be from each other.
|
||
This is but one example of how C and C++ programmers have slowly separated
|
||
when it comes to programming.</p>
|
||
<h3 id="many-c-programmers-wont-touch-c">Many C Programmers Won&rsquo;t Touch C++</h3>
|
||
<p>I&rsquo;m pretty sure everyone knows the C programmer stereotype by now, the only
|
||
thing is that it is <strong>TRUE</strong>.
|
||
Lots of <a href="https://suckless.org/">Suckless</a> users and developers only use
|
||
C and POSIX shell in their programs. <a href="https://harmful.cat-v.org/software/c++/">Cat-v</a> endorses
|
||
C and C-like languages, but despises C++. Even
|
||
<a href="https://lore.kernel.org/all/alpine.LFD.0.999.0709061839510.5626@evo.linux-foundation.org/">Linus Torvalds</a>,
|
||
the creator Linux and Git, won&rsquo;t touch C++.
|
||
Heck, even I love C but I can&rsquo;t stand programming in C++.</p>
|
||
<p>This is probably the biggest reason why employers <strong>SHOULD NOT</strong> put C/C++
|
||
on job descriptions, especially if they&rsquo;re only looking for C developers.
|
||
All they are doing is scaring away competent C developers.</p>
|
||
|
||
|
||
<figure ><a href="https://brycev.com/p/cpp.webp"><img src="https://brycev.com/p/cpp.webp" id="smallimg" alt="Stop doing C&#43;&#43;!"></a></figure>
|
||
|
||
<h2 id="the-solution">The Solution</h2>
|
||
<p>If you&rsquo;re referring to a C program or programmer just say &ldquo;C&rdquo;.
|
||
If you&rsquo;re referring to a C++ program or programmer just say &ldquo;C++&rdquo;.
|
||
If you&rsquo;re referring to both used separately say something like:</p>
|
||
<ul>
|
||
<li>C and C++</li>
|
||
<li>C, C++</li>
|
||
<li>C++ with C</li>
|
||
<li>Etc.</li>
|
||
</ul>
|
||
<p><strong>NOT C/C++</strong></p>
|
||
<p>Only if you&rsquo;re using C <em>together</em> with C++ would it be acceptable to
|
||
say C/C++.</p>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>Please note that although these are real concerns with C and C++,
|
||
this is more of a rant than anything else (and somewhat satire).&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>Fun fact: C++ <em>was</em> actually called <a href="https://www.stroustrup.com/bs_faq.html#invention">&ldquo;C with Classes&rdquo;</a> before it was
|
||
initially released.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
<li id="fn:3">
|
||
<p>Credit to <a href="https://youtu.be/U6I-Kwj-AvY">code_report</a> for these two solutions.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>I Finally Have a VPS</title>
|
||
<link>https://brycev.com/blog/i-finally-have-a-vps/</link>
|
||
<pubDate>Sun, 12 Mar 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/i-finally-have-a-vps/</guid>
|
||
<description><p>After a little less than a year of waiting, I finally obtained a VPS
|
||
from <a href="https://my.frantech.ca/">Frantech/BuyVM</a>. I was told that they are an
|
||
exceptional VPS provider, and it turns out to be <strong>true</strong>. Their pricing is
|
||
extremely fair as I can get <em>double</em> what <a href="https://www.vultr.com/">Vultr</a>
|
||
offers for the same exact price (plus unlimited bandwidth). Their support
|
||
was also pretty fast so I was able to setup everything relatively quickly.
|
||
My only complaint is that the number of servers is limited so it might take
|
||
a while to actually get one. Despite Frantech <em>obviously</em> being better, Vultr
|
||
is still a solid choice for a VPS and they make it very easy to setup one.</p>
|
||
<p>I am now hosting my web page from my VPS instead of <a href="https://sourcehut.org/">Sourcehut</a>
|
||
and I am hosting my email instead of using <a href="https://disroot.org">Disroot</a>.
|
||
Keep in mind that these services (Sourcehut and Disroot<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>) are great services
|
||
and I would 100% recommend them, however I believe that hosting everything
|
||
yourself is better.</p>
|
||
<p>That being said, I do have unlimited bandwidth and about 19GB of storage space
|
||
that I still have yet to use. If any of you guys have ideas for what I should
|
||
do (hosting internet radio, SearX instance, Mastodon instance, forum, etc.) you
|
||
can let me know by email.</p>
|
||
<p>If you would like a VPS for yourself, you can use the links above to get one
|
||
from Frantech, if they&rsquo;re available. If not, Vultr is always a solid option
|
||
for a VPS (although you do get less). <strong>Or</strong> you can use my referral links
|
||
to get a VPS below. It&rsquo;s a nice and indirect way to support me.</p>
|
||
<h3 id="referral-links">Referral Links</h3>
|
||
<ul>
|
||
<li><a href="https://my.frantech.ca/aff.php?aff=6418">Frantech/BuyVM</a></li>
|
||
<li><a href="https://www.vultr.com/?ref=9386356">Vultr</a> (Normal affiliate link)</li>
|
||
<li><a href="https://www.vultr.com/?ref=9386357-8H">Vultr</a> (<strong>Get $100</strong> to use for a VPS)</li>
|
||
</ul>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>Disroot provides services like cloud storage, XMPP chat, paste bin, Git,
|
||
and more. They&rsquo;re an amazing replacement for the Google suite.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Odysee Channel</title>
|
||
<link>https://brycev.com/blog/odysee-channel/</link>
|
||
<pubDate>Wed, 08 Mar 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/odysee-channel/</guid>
|
||
<description><p>For those of you who don&rsquo;t already know, I recently synced my entire YouTube
|
||
channel to <a href="https://odysee.com/@bryce:c">Odysee</a>. So for those of you who want to avoid YouTube and Google
|
||
entirely that is now an option. I will continue to upload videos to YouTube
|
||
but they will be automaticly synced to Odysee shortly after I upload them
|
||
(usually takes about an hour). I don&rsquo;t plan on uploading exclusively onto
|
||
Odysee, but I might post some videos that I normally wouldn&rsquo;t post onto
|
||
YouTube for one reason or another, so keep an eye out. 🧑🚀</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Updating My GPG Key</title>
|
||
<link>https://brycev.com/blog/updating-my-gpg-key/</link>
|
||
<pubDate>Sun, 15 Jan 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/updating-my-gpg-key/</guid>
|
||
<description><p>I have updated my GPG key. I will <strong>not</strong> be able to read any new encrypted emails
|
||
that use my old GPG key.</p>
|
||
<p>You can find my new GPG key <a href="https://brycevandegrift.xyz/bpv.gpg">here</a> or import it
|
||
directly by running:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>curl -fL <span style="color:#e6db74">&#34;https://brycevandegrift.xyz/bpv.gpg&#34;</span> | gpg --import
|
||
</span></span></code></pre></div></description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Why I Am Switching to Firefox</title>
|
||
<link>https://brycev.com/blog/why-i-am-switching-to-firefox/</link>
|
||
<pubDate>Thu, 05 Jan 2023 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/why-i-am-switching-to-firefox/</guid>
|
||
<description><p>For the past year I have used <a href="https://qutebrowser.org/">Qutebrowser</a> almost exclusively as my main
|
||
web browser. I even made a video on how extensible and great it is <a href="https://youtu.be/N79au5Xq65s">here</a>.
|
||
However there have been a few glaring issues with it over other browsers
|
||
like Firefox that I have noticed over the past year. Although Qutebrowser
|
||
is a great web browser, I think that these issues are too important for
|
||
me to ignore.</p>
|
||
<p>Now before I start bashing Qutebrowser on where it falls short of my
|
||
expectations, I should rightfully praise it for what it does right compared
|
||
to other web browsers. Qutebrowser does have a lot of cool and innovative
|
||
features that most web browsers wouldn&rsquo;t even think about implementing.</p>
|
||
<h2 id="what-qutebrowser-does-right">What Qutebrowser does right</h2>
|
||
<h3 id="keybindings-and-ui">Keybindings and UI</h3>
|
||
<p>Unlike most browsers, Qutebrowser has Vim keybindings by default. This means
|
||
that every single action is bound to a specific key or combination of keys.
|
||
This makes using and navigating in Qutebrower leagues faster than in other
|
||
browsers like Firefox. There are extensions for Firefox that do allow you
|
||
to use Vim keybindings, however they are not as tightly integrated into the
|
||
browser as Qutebrowser. For Qutebrowser, <strong>every single action has a keybinding</strong>.</p>
|
||
<p>The user interface for Qutebrowser (or possibly lake thereof), in my opinion,
|
||
is very clean and nice to look at. Not only does it look nice, but it is also
|
||
highly customizable so you can change it to suit your personal preference.</p>
|
||
<h3 id="adblocking-by-default">AdBlocking by default</h3>
|
||
<p>By default, Qutebrowser has simple hosts adblocking enabled. Even though
|
||
there are far better adblocking solutions (uBlock Origin is the gold standard),
|
||
Qutebrowser still earns some points for having some sort of adblocking enabled
|
||
by default. Qutebrowser also has an adblocking mode simular to Brave Browser&rsquo;s
|
||
adblocking mode if hosts adblocking isn&rsquo;t enough for you.</p>
|
||
<h3 id="python">Python</h3>
|
||
|
||
|
||
<figure ><a href="https://brycev.com/p/boomer-python.webp"><img src="https://brycev.com/p/boomer-python.webp" alt="Boomer stuff"></a></figure>
|
||
|
||
<p>Now I know that using Python as a language for writing a big application has
|
||
some serious drawbacks, however in the case of Qutebrowser, writing it in
|
||
Python gives it some unique traits. For starters, writing Qutebrowser in
|
||
Python makes it easier to customize and extend in numerous ways. Being able
|
||
to program in my own keybindings, extra features, and more is (for a lack of a
|
||
better word) <strong>awesome</strong>. Although there are better language choices than
|
||
Python (for example Lua is a solid choice<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>) for what it is, having
|
||
Qutebrowser written in Python comes with some great benefits</p>
|
||
<h2 id="what-qutebrowser-does-wrong">What Qutebrowser does wrong</h2>
|
||
<h3 id="bloated">Bloated</h3>
|
||
<p>This point somewhat ties into the fact that Qutebrowser is written in Python,
|
||
but Qutebrowser is anything but small or fast. Qutebrowser uses just about
|
||
the same amount of resources on my computer as Firefox (which is considered a
|
||
bloated browser) and still runs slower. It also takes up a lot more space
|
||
on my system than Firefox as well. The executable for Qutebrowser isn&rsquo;t
|
||
actually that big, however the dependices needed to run it take up more space
|
||
than Firefox itself.</p>
|
||
<h3 id="adblocking">Adblocking</h3>
|
||
<p>Like I stated earlier, Qutebrowser has adblocking enabled by default, which is
|
||
really nice, however I don&rsquo;t think that its builtin adblocker does enough.
|
||
My standard for adblocking (as mentoned before) is uBlock Origin, and the
|
||
adblocking options that Qutebrowser provides are not really too impressive.
|
||
Compared to uBlock Origin, Qutebrowser&rsquo;s adblockers don&rsquo;t nearly do as much.</p>
|
||
<h3 id="python-1">Python</h3>
|
||
<p>Didn&rsquo;t I just say that writing Qutebrowser in Python was a good thing?
|
||
Well&hellip;yes, but actually no. Python does provide Qutebrowser with an easy
|
||
language to write the program in as well as configure and extend the program
|
||
in, but the biggest downside of writing a browser in Python is speed. Qutebrowser,
|
||
being written in Python, is just a little less resource intensive than Firefox
|
||
on my system, however it is about half as fast. This compromise in performance is
|
||
expected for a program written in Python and for a browser, performance is
|
||
pretty important.</p>
|
||
<h2 id="why-firefox">Why Firefox?</h2>
|
||
<p>Firefox is the only web browser that is free software and also mitigates
|
||
all of the problems I have discussed. Even though Firefox is still a bit
|
||
bloated, it does fix adblocking (with uBlock Origin) and it is written in a more sane programming
|
||
language. Firefox does not come with adblocking or keybindings by default like
|
||
Qutebrowser, but they can be added in with extensions like the aforementioned
|
||
<a href="https://ublockorigin.com/">uBlock Origin</a> or <a href="https://tridactyl.xyz/">Tridactyl</a>.
|
||
It is sometimes a pain to change the default settings for Firefox since a lot
|
||
of useless and harmful things are enabled by default like telemetry, Pocket,
|
||
Firefox Accounts, and more. After all of that is said and done, Firefox is
|
||
actually a pretty good web browser.</p>
|
||
<p>Although Firefox is bloated, sometimes you need a bloated browser for
|
||
the bloated internet.</p>
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<hr>
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>There is actually a web browser written in Lua called <a href="https://luakit.github.io/">LuaKit</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Rust in the Linux Kernel</title>
|
||
<link>https://brycev.com/blog/rust-in-the-linux-kernel/</link>
|
||
<pubDate>Tue, 25 Oct 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/rust-in-the-linux-kernel/</guid>
|
||
<description><p>I know, I know, everyone is talking about support for the <a href="https://www.rust-lang.org/">Rust</a> programming
|
||
language being <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8aebac82933ff1a7c8eede18cab11e1115e2062b">added to the Linux kernel</a>, and I&rsquo;m no exception. This event
|
||
is <strong>HUGE</strong> when it comes to Linux kernel development. Since the Linux kernel
|
||
is predominantly written in C and has been that way for about the last 30
|
||
years, this comes as a very big surprise. I honestly would have expected
|
||
C++ to be integrated in the Linux kernel if it weren&rsquo;t for Linus Torvald&rsquo;s
|
||
<a href="https://lore.kernel.org/all/alpine.LFD.0.999.0709061839510.5626@evo.linux-foundation.org/">hatred for C++</a> (granted, I dislike C++ as well).</p>
|
||
<p>Now I&rsquo;m not here to praise Rust as some sort of gift to the Linux kernel, nor
|
||
am I here to talk horribly about it and say that it has no use in the Linux
|
||
kernel whatsoever, because it does have a use. I am here to take a look at
|
||
what Rust does and doesn&rsquo;t do good and see if that lines up with the needs of
|
||
the Linux kernel.</p>
|
||
<h2 id="speedperformance">Speed/Performance</h2>
|
||
<p>The average speed of programs written in Rust is about on par with programs
|
||
written in C from what I&rsquo;ve seen. You can look at some of the benchmarks
|
||
<a href="https://programming-language-benchmarks.vercel.app/c-vs-rust">here</a>, but I also have a quick and simple one that I whipped up.
|
||
This example uses a very lazy and inefficient version of the Fibonacci
|
||
algorithm that I used a while ago in my <a href="https://brycevandegrift.xyz/blog/the-importance-of-lisp/#recursion">lisp article</a>.</p>
|
||
<p>Now I&rsquo;m no expert programmer so don&rsquo;t complain if I didn&rsquo;t write either of
|
||
these programs &ldquo;correctly&rdquo;, it&rsquo;s just a simple benchmark</p>
|
||
<p><a href="https://brycevandegrift.xyz/hardware/">Machine specs</a></p>
|
||
<p>Implemented in C:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdio.h&gt;</span><span style="color:#75715e">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&lt;stdlib.h&gt;</span><span style="color:#75715e">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int32_t</span> <span style="color:#a6e22e">fib</span>(<span style="color:#66d9ef">int32_t</span> num) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (num <span style="color:#f92672">&lt;=</span> <span style="color:#ae81ff">1</span>) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> num;
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fib</span>(num <span style="color:#f92672">-</span> <span style="color:#ae81ff">1</span>) <span style="color:#f92672">+</span> <span style="color:#a6e22e">fib</span>(num <span style="color:#f92672">-</span> <span style="color:#ae81ff">2</span>);
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>() {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">int32_t</span> result <span style="color:#f92672">=</span> <span style="color:#a6e22e">fib</span>(<span style="color:#ae81ff">45</span>);
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">printf</span>(<span style="color:#e6db74">&#34;%d</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, result);
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>Implemented in Rust:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">fib</span>(num: <span style="color:#66d9ef">i32</span>) -&gt; <span style="color:#66d9ef">i32</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> num <span style="color:#f92672">&lt;=</span> <span style="color:#ae81ff">1</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> num;
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> fib(num <span style="color:#f92672">-</span> <span style="color:#ae81ff">1</span>) <span style="color:#f92672">+</span> fib(num <span style="color:#f92672">-</span> <span style="color:#ae81ff">2</span>);
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> result:<span style="color:#66d9ef">i32</span> <span style="color:#f92672">=</span> fib(<span style="color:#ae81ff">45</span>);
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">println!</span>(<span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#34;</span>, result);
|
||
</span></span><span style="display:flex;"><span>}
|
||
</span></span></code></pre></div><p>The average time for C compiled with GCC and <code>-O2</code> optimization was 3.30
|
||
seconds and Rust compiled with RustC and <code>-O2</code> as well was 4.32 seconds.
|
||
C without optimizations was 9.31 seconds and Rust without optimizations was
|
||
12.69 seconds on average. So unoptimized Rust is a decent bit slower than C
|
||
and optimized Rust is about a second behind C which is what I would expect.
|
||
A bit of a performance hit is what I would expect for a language that focuses
|
||
more on memory safety rather than pure speed.</p>
|
||
<h2 id="size">Size</h2>
|
||
<p>When it comes to size, Rust and C are both around the same as well. Although
|
||
I sometimes do hear complaints about Rust&rsquo;s standard library being large, the
|
||
Rust standard library probably isn&rsquo;t going to be included in the Linux kernel.
|
||
Compiling a &ldquo;Hello, World!&rdquo; program in GCC with <code>-O2</code> is around 21KB normally
|
||
and 15KB stripped. Compiling the same program in RustC with <code>-O2</code> results in a
|
||
21KB binary normally and a 14KB binary stripped (no standard library included).
|
||
So Rust can actually end up with smaller binaries than C on some occasions,
|
||
but in reality I would honestly expect the same size (if not slightly bigger)
|
||
binary sizes for Rust for most cases.</p>
|
||
<h2 id="compilerfrontend">Compiler/Frontend</h2>
|
||
<p>The Rust compiler is probably one of Rust&rsquo;s biggest strengths compared to C.
|
||
The Rust compiler is a very helpful tool for developers. There are other just as
|
||
helpful tools that the creators of Rust provide separately like <a href="https://github.com/rust-lang/rustfmt">rustfmt</a>
|
||
(like gofmt if you have used Go before), <a href="https://github.com/rust-lang/rust-clippy">Clippy</a>,
|
||
and more. But the Rust compiler is probably one of the most straightforward
|
||
and user friendly (in a mostly good way) compilers that I have ever seen.
|
||
Just take a look at the difference between an error message in GCC v.s. an
|
||
error message in RustC. The same mistake is being made in both languages.</p>
|
||
<p>An error message from GCC:</p>
|
||
<pre tabindex="0"><code>test.c: In function &#39;main&#39;:
|
||
test.c:8:32: warning: passing argument 1 of &#39;sumOfSquares&#39; makes integer from pointer without a cast
|
||
[-Wint-conversion]
|
||
8 | int32_t result = sumOfSquares(&#34;Number&#34;);
|
||
| ^~~~~~~~
|
||
| |
|
||
| char *
|
||
test.c:3:30: note: expected &#39;int32_t&#39; {aka &#39;int&#39;} but argument is of type &#39;char *&#39;
|
||
3 | int32_t sumOfSquares(int32_t x, int32_t y) {
|
||
| ~~~~~~~~^
|
||
test.c:8:19: error: too few arguments to function &#39;sumOfSquares&#39;
|
||
8 | int32_t result = sumOfSquares(&#34;Number&#34;);
|
||
| ^~~~~~~~~~~~
|
||
test.c:3:9: note: declared here
|
||
3 | int32_t sumOfSquares(int32_t x, int32_t y) {
|
||
| ^~~~~~~~~~~~
|
||
</code></pre><p>An error message from RustC:</p>
|
||
<pre tabindex="0"><code>error[E0061]: this function takes 2 arguments but 1 argument was supplied
|
||
--&gt; test.rs:6:19
|
||
|
|
||
6 | let _result = sum_of_squares(&#34;Number&#34;);
|
||
| ^^^^^^^^^^^^^^----------
|
||
| ||
|
||
| |expected `i32`, found `&amp;str`
|
||
| an argument of type `i32` is missing
|
||
|
|
||
note: function defined here
|
||
--&gt; test.rs:1:4
|
||
|
|
||
1 | fn sum_of_squares(x: i32, y: i32) -&gt; i32 {
|
||
| ^^^^^^^^^^^^^^ ------ ------
|
||
help: provide the argument
|
||
|
|
||
6 | let _result = sum_of_squares(/* i32 */, /* i32 */);
|
||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
error: aborting due to previous error
|
||
|
||
For more information about this error, try `rustc --explain E0061`.
|
||
</code></pre><p>These error messages may look similar, but in my opinion the error/warning
|
||
messages from RustC are just a bit more clear than the messages from GCC and
|
||
definitely a lot clearer than other compilers.</p>
|
||
<p>When it comes to the Rust frontend, LLVM, I don&rsquo;t really mind it as a frontend.
|
||
For the Linux kernel, I think that GCC would be a better frontend for Rust to
|
||
use and there is work being done on just <a href="https://github.com/Rust-GCC/gccrs">that</a>.
|
||
But many languages use like <a href="https://dlang.org/">D</a> (<a href="https://github.com/ldc-developers/ldc">LDC</a>), newer versions of <a href="https://www.haskell.org/">Haskell</a>, <a href="https://ziglang.org/">Zig</a>, and
|
||
many other languages use LLVM and they generate pretty good results most of
|
||
the time. Is it the most ideal frontend when working with the Linux kernel,
|
||
probably not, but is it the worst? Definitely not.</p>
|
||
<h2 id="memory-safety">Memory Safety</h2>
|
||
<p>What everyone knows Rust for, it&rsquo;s memory safety. The biggest tool that Rust
|
||
has at it&rsquo;s disposal to try to guarantee memory safety is the borrow checker.
|
||
For those of you who don&rsquo;t know what the borrow checker is, the borrow checker
|
||
assigns memory to a variable known as an owner. Once the owner of a piece of
|
||
data is out of scope, it deallocates the memory. You can also &ldquo;borrow&rdquo; the
|
||
memory (hence the name &ldquo;borrow checker), but I won&rsquo;t go too into detail,
|
||
since there are plenty of better explaniations of Rust&rsquo;s borrow checker. Just
|
||
keep in mind that the borrow checker is very important for memory safety.</p>
|
||
<p>I think that memory safety is Rust&rsquo;s biggest and most important contribution
|
||
to the Linux kernel. Memory safety can eliminate a lot if not the majority of
|
||
bugs out there in the wild and I think that the Linux kernel is no exception.
|
||
If used correctly, I think that Rust&rsquo;s memory safety could make the Linux
|
||
kernel even more robust than it already is with little to no sacrifices.</p>
|
||
<h2 id="conclusion">Conclusion</h2>
|
||
<p>Overall, I think that the inclusion of Rust in the Linux kernel isn&rsquo;t too bad
|
||
of a decision. Don&rsquo;t get me wrong, there are some bad or not fully fleshed
|
||
out parts to the language, but otherwise it&rsquo;s pretty solid. Now I&rsquo;m no expert
|
||
programmer in either C or Rust, but I think that there could be a very good
|
||
balance within the Linux kernel if Rust is used correctly.</p>
|
||
<p>That being said, I&rsquo;m personally still not sold on Rust&rsquo;s inclusion into the Linux
|
||
kernel. Despite the advantages of memory safety and a better compiler there
|
||
are still lots of parts of Rust that are not fully fleshed out and could
|
||
cause various problems for the Linux kernel. Although I think that Rust is
|
||
the best choice of any language out there to add to the Linux kernel,
|
||
I personally don&rsquo;t think that another language needs to be added to the Linux
|
||
kernel. I guess all that I can do is wait and see if this addition to the Linux
|
||
kernel is a good one or not.</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>The Importance of Lisp</title>
|
||
<link>https://brycev.com/blog/the-importance-of-lisp/</link>
|
||
<pubDate>Tue, 13 Sep 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/the-importance-of-lisp/</guid>
|
||
<description><p>Lisp (also known as LISP) is a family of programming languages that have had a
|
||
significant impact on the world of computing. Lisp has had and still
|
||
has a great influence on the evolution of programming languages and computing
|
||
theory as a whole. It remains a very easy language to learn and not that hard
|
||
to master.</p>
|
||
<p>For those of you who don&rsquo;t know what Lisp is, Lisp stands for &ldquo;LISt Processor&rdquo;.
|
||
A Lisp program is made up of at least of at least one &ldquo;list&rdquo; which is
|
||
indicated by an expression surrounded by parentheses. So for example,
|
||
if you wanted to multiply 2 and 4, you would give an expression like this
|
||
to a Lisp interpreter or compiler:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>(* <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">4</span>) <span style="color:#75715e">; Results in 8</span>
|
||
</span></span></code></pre></div><p>The Lisp interpreter or compiler evaluates the contents of the list to
|
||
produce a result. The first element of the list is the operator being used,
|
||
in this case its multiplication (<code>*</code>). Any other items in the list are
|
||
arguments given to the operator, in this case <code>2</code> and <code>4</code>. If you are familiar
|
||
with Polish Notation or Prefix Notation then this may look very similar, the
|
||
only difference being the addition of parentheses to enclose the expression.</p>
|
||
<p>We can easily create compound expressions by just putting lists inside of
|
||
lists like so:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>(- <span style="color:#ae81ff">10</span> (/ <span style="color:#ae81ff">4</span> <span style="color:#ae81ff">2</span>)) <span style="color:#75715e">; Equivalent to 10 - (4 / 2)</span>
|
||
</span></span><span style="display:flex;"><span>(+ (* <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">2</span>) (* <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">5</span>)) <span style="color:#75715e">; Equivalent to (2 * 2) + (2 * 5)</span>
|
||
</span></span></code></pre></div><p>It takes a bit of getting used to, but Lisp&rsquo;s notation makes it very easy to
|
||
string together compound expressions.</p>
|
||
<h2 id="practical-lisp">Practical Lisp</h2>
|
||
<p>Nowadays there are two different major dialects of Lisp, <strong>Common Lisp</strong> and
|
||
<strong>Scheme</strong>. There are not that many differences between Common Lisp and
|
||
Scheme so I will use the Scheme dialect in the rest of these examples since
|
||
I am familiar with it.</p>
|
||
<p>If we want to, we can define custom operators, functions, or variables just
|
||
like in any other programming language. To do so in Scheme we use the
|
||
<code>define</code> keyword:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>(<span style="color:#66d9ef">define </span>x <span style="color:#ae81ff">24</span>) <span style="color:#75715e">; Define the variable x as 24</span>
|
||
</span></span><span style="display:flex;"><span>(<span style="color:#66d9ef">define </span>mult *) <span style="color:#75715e">; Define the operator mult as multiplication</span>
|
||
</span></span><span style="display:flex;"><span>(<span style="color:#66d9ef">define </span>(<span style="color:#a6e22e">circum</span> radius) (* <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">3.14</span> radius)) <span style="color:#75715e">; Define circumference as 2 * π * radius</span>
|
||
</span></span></code></pre></div><p>You may have noticed that we defined all three of these with the same <code>define</code>
|
||
keyword, so what makes a variable different from a function? Nothing really.
|
||
The great thing about Lisp is that almost everything defined under a <code>define</code>
|
||
statement is treated the same. This means that almost anything we can do with
|
||
variables we can do with functions and vice versa. So, for example, we can
|
||
create a function like this:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>(<span style="color:#66d9ef">define </span>(<span style="color:#a6e22e">applyFunc</span> func arg1 arg2) (<span style="color:#a6e22e">func</span> arg1 arg2))
|
||
</span></span></code></pre></div><p>This function, <code>applyFunc</code>, takes three arguments: a function and two arguments
|
||
for the given function. It then applies the two arguments to the given function
|
||
and spits out a result. We can test our <code>applyFunc</code> function like so:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>(<span style="color:#66d9ef">define </span>(<span style="color:#a6e22e">sum-of-squares</span> x y) (+ (* x x) (* y y))) <span style="color:#75715e">; Same as x^2 + y^2</span>
|
||
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">applyFunc</span> sum-of-squares <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">4</span>)
|
||
</span></span></code></pre></div><p>Now this may look fairly useless at the moment because we can just call
|
||
<code>sum-of-squares</code> directly and pass it arguments manually. However, being able
|
||
to pass functions as arguments opens a whole new world of possibilities when
|
||
it comes to programming.</p>
|
||
<h2 id="higher-order-functions">Higher-Order Functions</h2>
|
||
<p>This brings us to an important topic, anonymous functions using the <code>lambda</code>
|
||
keyword. The <code>lambda</code> keyword creates a one-time use function, this can be
|
||
very useful for passing to another function as an argument. As an example we
|
||
can use a lambda function with our <code>applyFunc</code> function.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>(<span style="color:#a6e22e">applyFunc</span> (<span style="color:#66d9ef">lambda </span>(<span style="color:#a6e22e">x</span> y) (* x y)) <span style="color:#ae81ff">2</span> <span style="color:#ae81ff">4</span>) <span style="color:#75715e">; Same a 2 * 4</span>
|
||
</span></span></code></pre></div><p>The example above creates a one-time use function <code>(lambda (x y) (* x y))</code>
|
||
and passes it to <code>applyFunc</code> with the arguments <code>2</code> and <code>4</code>. Although the
|
||
result isn&rsquo;t that spectacular, the implications of lambda functions opens up
|
||
a whole new world of possibilities for programming that only exist in
|
||
functional languages like Lisp. Functions that take functions or return
|
||
functions are called <code>higher-order functions</code>.</p>
|
||
<p>Lisp was one of, if not the first language to implement higher-order functions
|
||
in a programming language. Other high-level programming languages like Lua,
|
||
Python, Haskell, and more followed suit much later.</p>
|
||
<h2 id="recursion">Recursion</h2>
|
||
<p>Another important concept pioneered by Lisp in the world of programming is
|
||
recursion. A function is a recursive function when it calls itself, pretty
|
||
simple. Almost all recursive functions also have a base-case or exit clause
|
||
in order to stop recurring, otherwise they run forever.
|
||
If you still don&rsquo;t understand recursion then read this sentence again. ;)</p>
|
||
<p>As an example, let&rsquo;s translate the equation for Fibonacci numbers into a
|
||
Lisp expression. The mathematical definition is a follows:</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/fib.webp" title="Recursive Fibonacci Equation" alt="Fibonacci Equation"></figure>
|
||
|
||
<p>A translation from mathematical notation into Lisp would look like this:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>(<span style="color:#66d9ef">define </span>(<span style="color:#a6e22e">fib</span> n) <span style="color:#75715e">; Begin function</span>
|
||
</span></span><span style="display:flex;"><span>(<span style="color:#66d9ef">if </span>(&lt;= n <span style="color:#ae81ff">1</span>) n <span style="color:#75715e">; If n &lt;= 1 then return n</span>
|
||
</span></span><span style="display:flex;"><span>(+ (<span style="color:#a6e22e">fib</span> (- n <span style="color:#ae81ff">1</span>)) (<span style="color:#a6e22e">fib</span> (- n <span style="color:#ae81ff">2</span>))))) <span style="color:#75715e">; Else return fib(n-1) + fib(n-2)</span>
|
||
</span></span></code></pre></div><p>As you can see, the <code>fib</code> function defined above calls itself until it meets
|
||
the base requirements to end the recursive loop. Recursion makes it stupidly
|
||
easy to translate recursive mathematical functions to Lisp expressions.
|
||
Just like higher-order functions, Lisp was one of the first programming languages
|
||
to implement this and other languages followed afterwards.</p>
|
||
<h2 id="hold-up">Hold Up</h2>
|
||
<p>Now, before you go out and write your next project in Lisp, you should keep
|
||
something in mind. Lisp is <strong>not</strong> the fastest or smallest language out there, it
|
||
was not designed to be so. There are some pretty good implementations of Lisp
|
||
out in the wild, but don&rsquo;t expect them to outperform C, Go, Lua, or even
|
||
Python most of the time.</p>
|
||
<p>If you&rsquo;re going to program something in Lisp you should keep these things in
|
||
mind:</p>
|
||
<ul>
|
||
<li>How important is execution speed?</li>
|
||
<li>How important is program/runtime size?</li>
|
||
<li>How important is portability?</li>
|
||
</ul>
|
||
<p>If you value any three of these too much, then you might not want to write
|
||
your program in Lisp. You probably don&rsquo;t want to write a program that only
|
||
takes up a few kilobytes in Lisp, nor would you want to write a program that
|
||
needs millisecond speed either. However for all other needs Lisp works
|
||
perfectly fine if not exceptionally great!</p>
|
||
<p>But this brings us back to the importance of Lisp altogether. Most people
|
||
look at Lisp and see a language that innovated countless things in the field
|
||
of programming languages, but eventually got replaced by newer languages. But
|
||
Lisp as a language is still very much alive and making improvements and
|
||
innovations to this day. It is still a very good programming language for
|
||
tackling many tasks and remains one of my favorite programming languages.</p>
|
||
|
||
|
||
<figure ><a href="https://brycev.com/p/lisp.webp"><img src="https://brycev.com/p/lisp.webp" alt="LISP machine"></a></figure>
|
||
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Switching to Hugo</title>
|
||
<link>https://brycev.com/blog/switching-to-hugo/</link>
|
||
<pubDate>Sat, 10 Sep 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/switching-to-hugo/</guid>
|
||
<description><p>Over the last couple of days I have been migrating my blog from using a
|
||
markdown/Pandoc blog system to using <a href="https://gohugo.io/">Hugo</a> for my entire website.</p>
|
||
<p>For those of you who don&rsquo;t know what Hugo is, Hugo is a static site generator
|
||
that is written in <a href="https://go.dev/">Go</a>. It takes plain markdown and converts
|
||
it to plain HTML and CSS just like Pandoc. The biggest difference it has from
|
||
Pandoc is that Hugo is written specifically for creating static sites. To put
|
||
it bluntly, Hugo does one thing, and it does it well.</p>
|
||
<p>I might make a video on Hugo on some point as there&rsquo;s actually a lot of depth
|
||
to it and it&rsquo;s very customizable and extensible. But despite having a lot of
|
||
depth to it, Hugo generates relatively small and fast static webpages.
|
||
It&rsquo;s honestly a very good static site generator and I will be using it over my
|
||
markdown/Pandoc blog system from now on.</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Changing My Website Host</title>
|
||
<link>https://brycev.com/blog/changing-my-website-host/</link>
|
||
<pubDate>Sun, 26 Jun 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/changing-my-website-host/</guid>
|
||
<description><p>For the longest time I have used <a href="https://www.infinityfree.net/">Infinity Free</a> as the host for my website since it has free website hosting.
|
||
However, I haven’t been able to successfully set up a SSL certificate without using Cloudflare.
|
||
Cloudflare has not had a good reputation and, in my opinion, <a href="https://www.unixsheikh.com/articles/stay-away-from-cloudflare.html">cannot be trusted</a> <a href="https://www.devever.net/~hl/cloudflare">at all</a>.</p>
|
||
<h2 id="1-sourcehut">1. <a href="https://sourcehut.org/">Sourcehut</a></h2>
|
||
<p>Sourcehut provides static website hosting, git repository hosting, gemini hosting (sadly no gopher hosting) and many other things.
|
||
The upside of using Sourcehut versus a lot of other platforms for hosting my website is that they use only free and open source software for hosting.</p>
|
||
<p>Hosted websites are automatically outfitted with SSL certificates which reduces the hassle (and they don’t use Cloudflare).
|
||
My git repositories are also hosted at Sourcehut so it would make sense to move my website there.
|
||
Sourcehut also provides paste bins, mailing lists, wikis, and more useful tools.</p>
|
||
<p>One caveat is that, even though service is currently 100% free (as in free beer), once Sourcehut is out of alpha, there will probably be a price tag associated with all the services (although, right now the price doesn&rsquo;t look that bad.)</p>
|
||
<h2 id="2-get-a-vps">2. Get a VPS</h2>
|
||
<p>This may be my best option in the long run as it’s the closest thing to self hosting that I can get.
|
||
I can host my website, git repositories, as well as almost anything else that I like including chat servers, forums, email, and etc.</p>
|
||
<p>The biggest downside of this is the price, which can vary from a couple dozen dollars a year to a few <strong>hundred</strong> dollars a year.</p>
|
||
<h2 id="3-move-to-some-other-3rd-party-static-site-host">3. Move to some other 3rd party static site host</h2>
|
||
<p>I’m probably more likely to self host my website before I resort to hosting it using <em>another</em> not well known 3rd party service.
|
||
My trust in most 3rd party hosts is slowly dwindling as the years go by.</p>
|
||
<h2 id="the-verdict">The verdict</h2>
|
||
<p>I currently plan to move my website to Sourcehut hosting for the time being, however I plan to eventually self host everything I need and become self reliant.
|
||
I also might move my website to a more elegant static site generator as writing and managing everything from scratch is starting to make everything a bit more cumbersome.</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Corebooting a Thinkpad X220</title>
|
||
<link>https://brycev.com/blog/corebooting-a-thinkpad-x220/</link>
|
||
<pubDate>Tue, 31 May 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/corebooting-a-thinkpad-x220/</guid>
|
||
<description>
|
||
|
||
<figure ><img src="https://brycev.com/p/thinkpad.webp" alt="My Thinkpad X220"><figcaption>My Thinkpad X220</figcaption></figure>
|
||
|
||
<h2 id="you-need">You Need</h2>
|
||
<ul>
|
||
<li>A Thinkpad X220</li>
|
||
<li>A Raspberry Pi</li>
|
||
<li>Female to female jumper wires</li>
|
||
<li>SOIC8 test clip</li>
|
||
<li>Another computer</li>
|
||
</ul>
|
||
<h2 id="disassembly">Disassembly</h2>
|
||
<p>For disassembly you can watch my video <a href="https://www.youtube.com/watch?v=hERguULT7Vo">here</a>.</p>
|
||
<p>But you’ll just have to remove all the screws with the keyboard icon and all the screws with the box(ish) icon.
|
||
(Like I said, you can watch the video).</p>
|
||
<h2 id="attaching-the-clip-to-the-bios-chip">Attaching the clip to the BIOS chip</h2>
|
||
<p>In order to actually read/write to the BIOS chip you need to attach the SOIC8 clip to the bios chip.</p>
|
||
<h3 id="x220-bios-pinout">X220 BIOS pinout</h3>
|
||
<pre tabindex="0"><code> ______
|
||
MOSI 5 --| |-- 4 GND
|
||
CLK 6 --| BIOS |-- 3 No Connection
|
||
No Connection 7 --| |-- 2 MISO
|
||
VCC (3.3V) 8 --|______|-- 1 CS
|
||
</code></pre><h3 id="raspberry-pi-pinout">Raspberry Pi pinout</h3>
|
||
<pre tabindex="0"><code> CS GND
|
||
2 | | 40
|
||
+-----------------------v-----v-----------+
|
||
| x x x x x x x x x x x x x x x x x x x x |
|
||
| x x x x x x x x x x x x x x x x x x x x |
|
||
+-----------------^-^-^-^-----------------+
|
||
1 | | | | 39
|
||
VCC | | CLK
|
||
MOSI/ \MISO
|
||
</code></pre><h2 id="setting-up-the-raspberry-pi">Setting up the Raspberry Pi</h2>
|
||
<p>Make sure to update your Raspberry PI and install and the needed packages as well as flashrom using these commands:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>sudo apt-get update <span style="color:#f92672">&amp;&amp;</span> sudo apt-get upgrade
|
||
</span></span><span style="display:flex;"><span>sudo apt-get install build-essential pciutils usbutils libpci-dev libusb-dev libftdi1 libftdi-dev zlib1g-dev
|
||
</span></span><span style="display:flex;"><span>git clone https://review.coreboot.org/flashrom.git
|
||
</span></span><span style="display:flex;"><span>cd flashrom
|
||
</span></span><span style="display:flex;"><span>make -j3 <span style="color:#f92672">&amp;&amp;</span> sudo make install
|
||
</span></span></code></pre></div><p>Now we need to download the Coreboot repo on our Raspberry PI.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git clone --recursive https://review.coreboot.org/coreboot.git ~/coreboot
|
||
</span></span></code></pre></div><p>Next we need to install ifdtool on the Raspberry PI, you can do that by running:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>cd ~/coreboot/util/ifdtool
|
||
</span></span><span style="display:flex;"><span>make -j3 <span style="color:#f92672">&amp;&amp;</span> sudo make install
|
||
</span></span></code></pre></div><h2 id="reading-the-bios">Reading the BIOS</h2>
|
||
<p>First, we are going to create an alias so we don’t need to type in a long drawn out command every time we want to read/write to the BIOS.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>alias fr<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;sudo flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1024&#39;</span>
|
||
</span></span></code></pre></div><p>Now we can get the name of our BIOS chip by just running <code>fr</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>fr
|
||
</span></span></code></pre></div><p>The output should give you multiple chip names.
|
||
All of these are the same chip just with different names so you can use any of them, mine is “MX25L6405”.
|
||
We are going to use this to set a <code>CHIP</code> variable.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>CHIP<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;MX25L6405&#34;</span>
|
||
</span></span></code></pre></div><p>We are now ready to read the flash from the BIOS chip.
|
||
We are going to do this a few times in order to make sure that the connection is consistent when reading and writing.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>fr -c <span style="color:#e6db74">&#34;</span>$CHIP<span style="color:#e6db74">&#34;</span> -r flash01.bin
|
||
</span></span><span style="display:flex;"><span>fr -c <span style="color:#e6db74">&#34;</span>$CHIP<span style="color:#e6db74">&#34;</span> -r flash02.bin
|
||
</span></span><span style="display:flex;"><span>fr -c <span style="color:#e6db74">&#34;</span>$CHIP<span style="color:#e6db74">&#34;</span> -r flash03.bin
|
||
</span></span><span style="display:flex;"><span>md5sum flash01.bin flash02.bin flash03.bin
|
||
</span></span></code></pre></div><p>The output for <code>md5sum</code> for all three of the files should be exactly the same.
|
||
If the checksum for all three files are not the same then <strong>DO NOT CONTINUE!!!</strong>
|
||
Make sure that your connection is good and retry until everything reads correctly.
|
||
(If necessary, the spispeed can be lowered from 1024 for a more reliable read).</p>
|
||
<h2 id="optional-removing-the-management-engine">(Optional) Removing the management engine</h2>
|
||
<p>First we need to download me_cleaner.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git clone https://github.com/corna/me_cleaner ~/me_cleaner
|
||
</span></span></code></pre></div><p>Now we can run me_cleaner on our flash file, in this case I will be using <code>flash01.bin</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>~/me_cleaner/me_cleaner.py -S flash01.bin
|
||
</span></span></code></pre></div><p>If all goes well you should see a message that says: <code>Done! Good Luck!</code></p>
|
||
<h2 id="separating-the-image">Separating the image</h2>
|
||
<p>Now we can run ifdtool on our flash image in order to separate it.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>ifdtool -x flash01.bin
|
||
</span></span></code></pre></div><p>You should now have four different <code>.bin</code> files: 1. <code>flashregion_0_flashdescriptor.bin</code> 2. <code>flashregion_1_bios.bin</code> (Not needed) 3. <code>flashregion_2_intel_me.bin</code> 4. <code>flashregion_3_gbe.bin</code></p>
|
||
<p>We can now rename all the files to have a shorter name.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mv flashregion_0_descriptor.bin descriptor.bin
|
||
</span></span><span style="display:flex;"><span>mv flashregion_2_intel_me.bin me.bin
|
||
</span></span><span style="display:flex;"><span>mv flashregion_3_gbe.bin gbe.bin
|
||
</span></span></code></pre></div><h2 id="setting-up-coreboot">Setting up Coreboot</h2>
|
||
<p>If you want to compile Coreboot on your Raspberry PI you can go ahead, however it might take anywhere from a few hours to a few <strong>DAYS</strong>, so be warned.
|
||
I copied my “.bin” files to my laptop in order to compile faster.</p>
|
||
<p>Now we want to download the Coreboot repo onto our computer that we are compiling Coreboot on.
|
||
(This may take a while).
|
||
(If you are compiling Coreboot on your Raspberry PI you can skip this).</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git clone --recursive https://review.coreboot.org/coreboot.git ~/coreboot
|
||
</span></span></code></pre></div><blockquote>
|
||
<h2 id="optional-downloading-vga-bios">(Optional) Downloading VGA BIOS</h2>
|
||
<p>Windows and some Linux distributions rely on the VGA BIOS in order to display video.
|
||
So you can optionally download it if you need it.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>curl -fLO <span style="color:#e6db74">&#34;https://github.com/thetarkus/x220-coreboot-guide/raw/master/vga-8086-0126.bin&#34;</span>
|
||
</span></span></code></pre></div></blockquote>
|
||
<p>Now we need to make a directory to place our “.bin” files.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mkdir -p ~/coreboot/3rdparty/blobs/mainboard/lenovo/x220
|
||
</span></span><span style="display:flex;"><span>mv descriptor.bin ~/coreboot/3rdparty/blobs/mainboard/lenovo/x220/
|
||
</span></span><span style="display:flex;"><span>mv me.bin ~/coreboot/3rdparty/blobs/mainboard/lenovo/x220/
|
||
</span></span><span style="display:flex;"><span>mv gbe.bin ~/coreboot/3rdparty/blobs/mainboard/lenovo/x220/
|
||
</span></span></code></pre></div><h2 id="configuring-coreboot">Configuring Coreboot</h2>
|
||
<p>On the computer you’re compiling Coreboot with, you’ll need to install these development packages (or their equivalents).
|
||
On Ubuntu, Debian, or any derivative you can run:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>sudo apt-get install git build-essential gnat flex bison libncurses5-dev wget zlib1g-dev
|
||
</span></span></code></pre></div><p>On Void Linux (what I use) I ran:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>sudo xbps-install git base-devel ncurses-devel wget zlib-devel gcc-ada
|
||
</span></span></code></pre></div><p>Now we can go into the Coreboot directory and run make <code>nconfig</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>cd ~/coreboot
|
||
</span></span><span style="display:flex;"><span>make nconfig
|
||
</span></span></code></pre></div><p>You should see a menu pop up, now we can configure our Coreboot build.
|
||
Below is a list of what needs to be enabled, you can leave the rest of the settings just the way they are.</p>
|
||
<pre tabindex="0"><code>General Setup
|
||
- [*] Compress ramstage with LZMA
|
||
- [*] Include coreboot .config file into the ROM image
|
||
- [*] Allow use of binary-only repository
|
||
|
||
Mainboard
|
||
- Mainboard vendor (Lenovo)
|
||
- Mainboard model (Thinkpad X220)
|
||
- ROM chip size (8192 KB (8 MB))
|
||
- (0x100000) Size of CBFS filesystem in ROM
|
||
|
||
Chipset
|
||
- [*] Enable VMX for virtualization
|
||
- Include CPU microcode in CBFS (Generate from tree)
|
||
- Flash ROM locking on S3 resume (Don&#39;t lock ROM sections on S3 resume)
|
||
- [*] Add Intel descriptor.bin file
|
||
(3rdparty/blobs/mainboard/$(MAINBOARDDIR)/descriptor.bin) Path and filename of the descriptor.bin file
|
||
- [*] Add Intel ME/TXE firmware
|
||
(3rdparty/blobs/mainboard/$(MAINBOARDDIR)/me.bin) Path to management engine firmware
|
||
- [*] Add gigabit ethernet firmware
|
||
(3rdparty/blobs/mainboard/$(MAINBOARDDIR)/gbe.bin) Path to gigabit ethernet firmware
|
||
|
||
Devices
|
||
- Graphics initialization (Run VGA Option ROMs)
|
||
- [*] Use native graphics initialization
|
||
- [*] Add a VGA BIOS image
|
||
(/home/$USER/vga-8086-0126.bin) VGA BIOS path and filename
|
||
(8086,0126) VGA device PCI IDs
|
||
|
||
Generic Drivers
|
||
- [*] PS/2 keyboard init
|
||
- [*] Support Intel PCI-e WiFi adapters
|
||
|
||
Console
|
||
- [*] Squelch AP CPUs from early console.
|
||
- [*] Show POST codes on the debug console
|
||
|
||
System tables
|
||
- [*] Generate SMBIOS tables
|
||
|
||
Payload
|
||
- Add a payload (SeaBIOS)
|
||
- SeaBIOS version (master)
|
||
- (3000) PS/2 keyboard controller initialization timeout (milliseconds)
|
||
- [*] Harware init during option ROM execution
|
||
- [*] Include generated option rom that implements legacy VGA BIOS compatibility
|
||
- [*] Use LZMA compression for payloads
|
||
</code></pre><p>You can press <code>F6</code> to save your config and then press <code>F9</code> to exit.
|
||
Now we can actually compile Coreboot now.</p>
|
||
<blockquote>
|
||
<h3 id="optional-create-cross-compiler">(Optional) Create Cross Compiler</h3>
|
||
<p>If you don’t have an <code>i386</code> cross compiler you can make one by running:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>make crossgcc-i386
|
||
</span></span><span style="display:flex;"><span>make iasl
|
||
</span></span></code></pre></div></blockquote>
|
||
<p>Let’s compile coreboot by running:</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>make -j<span style="color:#66d9ef">$(</span>nproc<span style="color:#66d9ef">)</span>
|
||
</span></span></code></pre></div><p>This might take a while.</p>
|
||
<p><strong>NOTE:</strong> If you can’t compile Coreboot, try checking and making sure you did everything correctly.</p>
|
||
<h2 id="flashing-coreboot">Flashing Coreboot</h2>
|
||
<p><strong>WARNING: Proceed with caution, you can possibly brick your computer if you are not careful!!!</strong></p>
|
||
<p>You should now be left with a file named <code>coreboot.rom</code> in the <code>~/coreboot</code> directory.
|
||
You can copy this file back to your Raspberry PI into order to flash it.</p>
|
||
<p>Now let’s go ahead and read our flash chip again to make sure that our connection is still good.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>fr -c <span style="color:#e6db74">&#34;</span>$CHIP<span style="color:#e6db74">&#34;</span> -r flash01.bin
|
||
</span></span><span style="display:flex;"><span>fr -c <span style="color:#e6db74">&#34;</span>$CHIP<span style="color:#e6db74">&#34;</span> -r flash02.bin
|
||
</span></span><span style="display:flex;"><span>fr -c <span style="color:#e6db74">&#34;</span>$CHIP<span style="color:#e6db74">&#34;</span> -r flash03.bin
|
||
</span></span><span style="display:flex;"><span>md5sum flash01.bin flash02.bin flash03.bin
|
||
</span></span></code></pre></div><p>And, like before, if all the checksums match, you can go ahead and flash <code>coreboot.rom</code>.</p>
|
||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>fr -c <span style="color:#e6db74">&#34;</span>$CHIP<span style="color:#e6db74">&#34;</span> -w coreboot.rom
|
||
</span></span></code></pre></div><p>Now, for the moment of truth, go ahead and boot your Thinkpad.
|
||
If it won’t boot, don’t sweat, just rebuild and try again.
|
||
If Coreboot won’t work on your Thinkpad no matter what you try, then you can just flash a backup of the BIOS that you read earlier and your computer should work just fine.</p>
|
||
<h2 id="aftermath">Aftermath</h2>
|
||
<p><strong>Congrats!!!</strong> You successfully freed your computer from the spying eyes of Intel and your local three letter government agency.
|
||
You can now enjoy your computing in peace.</p>
|
||
<h3 id="contact">Contact</h3>
|
||
<p>If you have any questions or comments you can find my contact info <a href="https://brycevandegrift.xyz/contact/">here</a>.</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Website Redesign</title>
|
||
<link>https://brycev.com/blog/website-redesign/</link>
|
||
<pubDate>Mon, 07 Mar 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/website-redesign/</guid>
|
||
<description><p>I have decided to redesign most of my website.
|
||
It’s mostly a facelift, but there are a couple under-the-hood changes done.</p>
|
||
<p>I have also decided to officially add a link to my <a href="https://www.youtube.com/channel/UCOSqzSTg4QZXdi7jvV-9rUg">YouTube channel</a> on my homepage, as well as add a link to my <a href="https://sr.ht/~bpv/">Sourcehut page</a> and my <a href="https://brycevandegrift.xyz/rss.xml">rss feed</a>.</p>
|
||
<p>I plan to reorganize my website as time goes on, but for now a simple redesign will do.
|
||
I also plan to at least convert my homepage to <a href="https://www.w3schools.com/Html/html_xhtml.asp">xhtml</a> in the future, as I think that I would provide a bit more compatibility with web browsers.</p>
|
||
<p>As time goes on I will make changes to my website as needed.</p>
|
||
<h2 id="a-note-about-github-and-gitlab">A note about GitHub and GitLab</h2>
|
||
<p>If you don’t know already, I am not a big fan of GitHub.
|
||
I don’t like having a GitHub account, but it’s almost necessary for collaborating on projects.
|
||
I have updated my <a href="https://github.com/BryceVandegrift">GitHub account</a> for hosting my git repos.
|
||
Don’t expect me to answer issues or accept code from these platforms (for now (although that might change)), for that please visit my Sourcehut page.</p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>New Youtube Channel</title>
|
||
<link>https://brycev.com/blog/new-youtube-channel/</link>
|
||
<pubDate>Sun, 20 Feb 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/new-youtube-channel/</guid>
|
||
<description><p>Recently, I have decided to start up a YouTube channel.
|
||
I mostly plan to upload informative videos, but things could always change.
|
||
Right now, I am uploading videos about GNU/Linux and other technical topics related to technology, however I believe that I will expand in the future.</p>
|
||
<p>In the future, I plan to upload all of my past and future videos onto Odysee/LBRY as I think it’s a superior platform compared to YouTube.
|
||
I might even consider uploading to other niche video sites eventually.</p>
|
||
<p>You can view my first video about GnuPG (GPG) <a href="https://youtu.be/GhiLR4zRqMI">here</a>.</p>
|
||
<p><a href="https://www.youtube.com/channel/UCOSqzSTg4QZXdi7jvV-9rUg">YouTube link</a></p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>Personal Update</title>
|
||
<link>https://brycev.com/blog/personal-update/</link>
|
||
<pubDate>Tue, 01 Feb 2022 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/personal-update/</guid>
|
||
<description><p>Recently, I have been pretty busy with college classes and haven’t had much time to work on personal projects.
|
||
In addition to classes I have also been busy with other personal aspects of life which I would not like to disclose currently.
|
||
I will be active again once I finish the semester (hopefully).</p>
|
||
<p>If anything comes up, feel free to email me here: <a href="https://brycevandegrift.xyz/contact/">https://brycevandegrift.xyz/contact/</a></p>
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>My Thoughts on BSDs</title>
|
||
<link>https://brycev.com/blog/my-thoughts-on-bsds/</link>
|
||
<pubDate>Fri, 31 Dec 2021 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/my-thoughts-on-bsds/</guid>
|
||
<description><p>For those of you who are not a big fan of Linux but want something that caters more to the Unix philosophy, a distribution of BSD (Berkeley Software Distribution) may be right for you.
|
||
Unlike Linux, most BSD systems’ tools, kernels, and programs are built from the ground up for that specific BSD distribution.
|
||
This also means that it can take a while for a feature or program that’s popular on Linux to make its way to a specific BSD distribution.
|
||
But, BSD it is worth a try nonetheless.</p>
|
||
<p>There are four major versions of BSD that I believe to be useable as an everyday operating system: FreeBSD, OpenBSD, NetBSD, and DragonFlyBSD.</p>
|
||
<h2 id="freebsd">FreeBSD</h2>
|
||
<p><a href="https://www.freebsd.org/">FreeBSD</a> is probably the most popular BSD distribution of all time.
|
||
FreeBSD has the most packages, the most support, and the most users compared to any other BSD distribution.
|
||
FreeBSD’s default file system choices are UFS (Unix File System) and ZFS (Z File System) which isn’t that bad considering ZFS is a pretty reliable file system.
|
||
FreeBSD also has support of other file systems like FAT and EXT as well as Linux binary compatibility which is pretty nice.
|
||
To be honest FreeBSD has a lot of cool and interesting features that are worth checking out.</p>
|
||
<h2 id="openbsd">OpenBSD</h2>
|
||
<p><a href="https://www.openbsd.org/">OpenBSD</a> is another flavor of BSD that is focused more on security than anything other operating system.
|
||
The people behind OpenBSD are also some of the same people behind projects like OpenSSH, LibreSSL, and even tmux (to some degree).
|
||
Although OpenBSD lacks a decent amount of software and certain features, it makes up for it in system security and stability.
|
||
Overall, I would say that it is a pretty solid operating system.</p>
|
||
<h2 id="netbsd">NetBSD</h2>
|
||
<p><a href="https://netbsd.org/">NetBSD</a> is a distribution of BSD that is focused on portability more than any other operating system out there.
|
||
NetBSD is also well known for its low resource usage as well.
|
||
NetBSD not only has support for amd64, i386, and arm, but it also supports more obscure architectures like mips, powerpc, riscv, and more.
|
||
NetBSD is also very small and can be stripped down even from it’s very small state.
|
||
I remember hearing rumors about NetBSD being able to run on a literal toaster in the past, which I find pretty impressive.
|
||
If you prefer size and portability over anything else, I would recommend NetBSD.</p>
|
||
<h2 id="dragonflybsd">DragonFlyBSD</h2>
|
||
<p><a href="https://www.dragonflybsd.org/">DragonFlyBSD</a> is a distribution of BSD that is tailored for performance and speed.
|
||
I believe that DragonFlyBSD definitely delivers on it’s promise of speed.
|
||
Overall multi-threading and multi-processor support as well as speed is very competitive with even the fastest of Linux systems.
|
||
Swapcache, a different type of swap made for DragonFlyBSD, also helps with greatly boosting performance for large workloads.
|
||
The HAMMER file systems are also very neat.
|
||
The HAMMER file systems have instant crash recovery, snapshots, support for multiple volumes, and much more.
|
||
If you want a fast and efficient operating system, I would definitely recommend trying DragonFlyBSD.</p>
|
||
|
||
|
||
<figure ><img src="https://brycev.com/p/bsd.webp" title="bsd" alt="BSD"></figure>
|
||
|
||
</description>
|
||
</item>
|
||
|
||
<item>
|
||
<title>New Blog</title>
|
||
<link>https://brycev.com/blog/new-blog/</link>
|
||
<pubDate>Mon, 29 Nov 2021 00:00:00 +0000</pubDate>
|
||
<guid>https://brycev.com/blog/new-blog/</guid>
|
||
<description><p>Recently, I have been working on a new blog system that takes Markdown and converts it into a very simple HTML page as well as an RSS feed.
|
||
The blog system is written entirely in POSIX shell and is around 100 lines of code.</p>
|
||
<p>If successful, it should generate a blog page, an RSS feed, as well as a rolling blog index page.
|
||
The only downside is that it requires Pandoc which isn&rsquo;t that small of a package, but it makes making blog posts a lot easier to write as I can write in Markdown instead of HTML.</p>
|
||
<p>I based some of it from Luke Smith’s blog script <a href="https://github.com/LukeSmithxyz/lb">here</a>.
|
||
I have added a few quirks of my own and I also plan to greatly expand on it in the future.</p>
|
||
</description>
|
||
</item>
|
||
|
||
</channel>
|
||
</rss>
|