<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Arya's blog</title>
    <link>https://aryak.me</link>
    <description>The blog of Arya</description>
    <copyright>Copyright 2022-23, Arya Kiran</copyright>
    <ttl>60</ttl>
	<atom:link href="https://aryak.me/rss.xml" rel="self" type="application/rss+xml" />
<item>
  <pubDate>Thu, 17 Oct 2024 14:44:26 +0000</pubDate>
  <category>2024/10/17/4</category>
  <title>Streaming our FOSS Meetups using just freesoftware!</title>
  <link>https://aryak.me/blog/08-fossmeetup-livestream.html</link>
  <description><![CDATA[
<p>I volunteer for <a href="https://fossunited.org/c/mumbai">FOSS United
Mumbai</a>, and we organize meetups related to FOSS every month.</p>
<p>We have often done some hacky jugaad to stream our meetups, but due
to their last minute nature and lack of proper resources, they have
often been low quality or failed entirely.</p>
<p>With the on-ground experience I have gained as the live streaming
lead at <a href="https://fossunited.org/indiafoss/2024">IndiaFOSS
2024</a> and <a href="https://indiafoss.net/2023">2023</a>, I wanted to
put these ideas into a blog-post format, so this could help out the <a
href="https://fossunited.org/city-communities">other chapters of FOSS
United</a>, and potentially non-FOSS United events too!</p>
<p>My guide is primarily divided into four parts:</p>
<ul>
<li>Scrcpy, which deals with getting the video of the meetup by
(ab)using the camera of your phone</li>
<li>VDO.ninja, which retrieves a high quality, low-latency stream of the
speaker’s screen in a user-friendly manner</li>
<li>OBS, which combines the outputs of both Scrcpy and VDO.ninja
together with a nice template, to send to the streaming server (OSP, or
perhaps YouTube)</li>
<li>OSP (FOSS United specific), which is the web UI which we stream to,
and use to make clips out of the live stream</li>
</ul>
<p>A large part of the guide assumes you use linux, but it should work
with MacOS. PS: if you are hosting a FOSS Meetup, streaming from a
Mac/Windows Box doesn’t make much sense either way :-)</p>
<h2 id="scrcpy-setup">Scrcpy Setup</h2>
<p>Requirements:</p>
<ul>
<li>Laptop with Linux/MacOS (only tested with linux though)</li>
<li>Scrcpy 2.x</li>
<li>Android 12+ phone</li>
</ul>
<p>On the phone:</p>
<ul>
<li>Enable Developer Options by tapping Build Number 7 times in the
Software Information section of About Phone in the Settings app. <img
src="/static/blog/photo_2024-10-17_23-01-56.jpg" /></li>
<li>Go to the newly enabled developer options menu, allow USB Debugging.
<img src="/static/blog/photo_2024-10-17_23-01-59.jpg" /></li>
<li>Connect phone to the laptop via USB, and authorize the Laptop
<ul>
<li>If there is no option asking you to authorize, there should be a
silent notification in your notif tray regarding USB preferences. Click
that and select ADB (if not available, chose file transfer - that should
be an equivalent option) <img
src="/static/blog/photo_2024-10-17_23-01-52.jpg" /></li>
<li>It might also be that the cable is old/damaged, and does not support
data transfer. If previous option didn’t yield any results, try using a
different cable</li>
</ul></li>
</ul>
<p>On the laptop:</p>
<ul>
<li>Install ADB</li>
<li>Install Scrcpy (<a
href="https://github.com/Genymobile/scrcpy/blob/master/doc/linux.md">Linux</a>
| <a
href="https://github.com/Genymobile/scrcpy/blob/master/doc/macos.md">MacOS</a>
| <a
href="https://github.com/Genymobile/scrcpy/blob/master/doc/windows.md">Windows</a>)</li>
<li>Run this command:
<code>/usr/local/bin/scrcpy --video-source=camera --camera-id=0 --audio-source=mic --orientation=90</code>
<ul>
<li>Sometimes the ideal resolution and framerate will not be the perfect
16:9 one that is required. In that case, add the following argument:
<code>--camera-size=1920x1080 --camera-fps=60</code></li>
<li>If you want to add any custom settings, consult <a
href="https://aryak.me/blog/06-phone-webcam-scrcpy.html">this other
blogpost of mine</a> or <a
href="https://github.com/Genymobile/scrcpy/blob/master/doc/camera.md">the
scrcpy docs</a></li>
<li>If you want a landscape camera output, remove the –orientation
flag</li>
<li>Setting the camera ID to 0 should use the back camera by default,
but if front camera needs to be used, set the ID to 1</li>
</ul></li>
<li>This should open a window with a full-sized preview of the camera:
<img src="/static/blog/photo_2024-10-17_23-02-02.jpg" /></li>
</ul>
<h2 id="screensy-screenshare-setup">Screensy / Screenshare Setup</h2>
<p>I would recommend you use this instead of VDO.ninja, ONLY IF BOTH
DEVICES ARE ON SAME NETWORK/WIFI.</p>
<p>The Setup</p>
<ul>
<li>On the speaker’s laptop, open https://screensy.marijn.it. Start
screen sharing and note down the URL (making sure that the text that
follows the <code>#</code> is included)</li>
</ul>
<h2 id="vdo.ninja-screenshare-setup">VDO.Ninja / Screenshare Setup</h2>
<p>NOTE: YOU ARE BETTER OFF USING SCREENSY INSTEAD - UNLESS YOU CANNOT
GET BOTH LAPTOPS ON THE SAME NETWORK.</p>
<p>Requirements:</p>
<ul>
<li>A browser which supports screenshare on the speaker’s PC, any
browser on the streaming PC</li>
</ul>
<p>The Setup:</p>
<ul>
<li>On streaming PC, open vdo.ninja, and create a room. Give a valid
room name, and set the option select the “The guests can see the
director, but not other guests’ videos” option, and then enter the
control centre <img
src="/static/blog/photo_2024-10-17_23-02-05.jpg" /></li>
<li>From the control centre, copy the link to invite a guest, and ask
the next speaker to open it on his laptop. <img
src="/static/blog/photo_2024-10-17_23-02-11.jpg" /></li>
<li>On the speaker’s laptop, select screenshare with room, and then in
the settings cogweel, make it use highest quality. <img
src="/static/blog/photo_2024-10-17_23-02-13.jpg" /></li>
<li>Back on the streaming PC in the control centre, press highlight on
the newly appeared preview, and then copy link of “capture a group
scene”. Keep the link safe, its needed in the next OBS setup <img
src="/static/blog/photo_2024-10-17_23-02-16.jpg" /></li>
</ul>
<h2 id="open-streaming-platform-setup-specific-to-foss-united">Open
Streaming Platform Setup (specific to FOSS United)</h2>
<p>On https://stream.fossunited.org, each city chapter/foss club can
request an account for streaming and uploading their talks. Login to the
account that is provided to you, navigate to My Channels and create a
new channel.</p>
<p>Add the specific details like default title, description, profile
picture etc., and then copy the auto-generated stream key.</p>
<p>If you want to stream simultaneously to youtube, you can add a new
RTMP Restream Destination in this format:
<code>rtmp://a.rtmp.youtube.com/live2/&lt;STREAM KEY&gt;</code>, and
enable the new destination. By doing this, all new streams will be
simultaneously streamed to YouTube as well. <img
src="/static/blog/photo_2024-10-17_23-26-05.jpg" /></p>
<h3 id="making-a-clip-for-each-talk">Making a clip for each talk</h3>
<p>After the live stream has ended, you might want to separate the
stream into smaller chunks, with a separate video for each of the talks.
This can be done using the clips feature of OSP.</p>
<p>Once the stream ends, the stream will be converted into a recording
and uploaded on to the channel from where it was being streamed.</p>
<p>Open the video, and in it the cogweel, from where you can select the
create clip option. Using the slider, move to the desired start and end
point, give it a valid description and title, and then create the clip.
A video is attached for reference:</p>
<p><video src="/static/blog/osp-clip.mp4" controls=""><a
href="/static/blog/osp-clip.mp4">Video</a></video></p>
<h2 id="obs-setup">OBS Setup</h2>
<p>Requirements:</p>
<ul>
<li><p>OBS Installation, with the default browser plugin enabled (the
plugin is not enabled on debian as of writing FYI, so use the flatpak
version if on Debian)</p></li>
<li><p>An X11 environment (if under wayland, run
<code>env -u WAYLAND_DISPLAY obs</code></p></li>
<li><p>Run setup wizard, optimize for streaming, and use 1920x1080 as
the base resolution. For stream key, enter the one from your service
provider (if you are using OSP, consult the next section)</p></li>
<li><p>Disable MIC/AUX, and keep Desktop Audio enabled</p></li>
<li><p>In OBS, add a window source (Labelled XComposite Window Capture
on linux) for scrcpy</p></li>
<li><p>In OBS, add a browser source, and make the url point towards the
screensy link that you copied initially. If you are using VDO.ninja
instead, the url will be the one from the “capture group scene” from the
VDO.ninja setup.</p></li>
<li><p>At the end, it should look something like this: <img
src="/static/blog/photo_2024-10-17_23-02-18.jpg" /></p></li>
<li><p>Start streaming!</p></li>
</ul>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/08-fossmeetup-livestream.html</guid>
  </item>
<item>
  <pubDate>Thu, 29 Feb 2024 14:44:26 +0000</pubDate>
  <category>2024/02/29/4</category>
  <title>How to encrypt an existing Debian install (LegacyBIOS)</title>
  <link>https://aryak.me/blog/07-encrypt-ext4-debian-install.html</link>
  <description><![CDATA[
<p>Recently, I decided to encrypt the VPSes of <a
href="https://psf.lt">Project Segfault</a>, as it coincided with the
migration of one of our servers, our EU node.</p>
<p>However, while moving our US node, we faced a few problems, in the
fact that I didn’t want to wipe the disk, nor did I want to do some jank
stuff like reinstalling debian and then replacing the files.</p>
<p>Therefore, my only solution came down to creating a new encrypted
partition, copying the entire directory tree of the old partition to the
new one via rsync, and then making grub and co. point to the new
stuff.</p>
<p>So, in order to do this, you first need to shrink your existing
partition so you can create the new one, which I did using GParted on
the GParted LiveCD.</p>
<p>Past that, you have to create the new primary partition in the empty
space created, which I did via CFDisk, since GParted requires you to
format while creating a partition (from what I could see), and it
doesn’t support creating LUKS partitions.</p>
<p>Additionally, since you can’t use the “good” PBKDF, argon2i(d) (which
is more secure and gives faster speeds) with the current version of grub
available on Debian 12, you have to move boot to a separate unencrypted
partition. This can be done by merely creating a new ~512 MiB ext2
primary partition via GParted</p>
<p>Past this, I had to create the LUKS stuff. To do so, I ran the
following commands:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Format partition as LUKS encrypted</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">cryptsetup</span> luksFormat <span class="at">--type</span> luks2 <span class="at">--pbkdf</span> argon2i /dev/DEVICE</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="co"># Open partition, and map it to /dev/mapper/crypt</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ex">cryptsetup</span> luksOpen /dev/DEVICE crypt</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co"># Overwrite the entire device with 0s, just to be a bit more secure</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="fu">dd</span> if=/dev/zero of=/dev/mapper/crypt status=progress bs=4096</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="co"># Create ext4 partition on the mapped device</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="ex">mkfs.ext4</span> /dev/mapper/crypt</span></code></pre></div>
<p>Then, to copy the content to the new partition, I used the following
commands:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">mkdir</span> <span class="at">-p</span> /mnt/<span class="dt">{old</span><span class="op">,</span><span class="dt">new}</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="fu">mount</span> /dev/OLD_DEVICE /mnt/old</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="fu">mount</span> /dev/mapper/crypt /mnt/new</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="fu">mkdir</span> <span class="at">-p</span> /mnt/new/boot</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="fu">mount</span> /dev/BOOT_DEVICE /mnt/new/boot</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="fu">rsync</span> <span class="at">-av</span> /mnt/old/<span class="pp">*</span> /mnt/new</span></code></pre></div>
<p>After all the data is copied, I need to enter a chroot environment in
order to configure a few more things. This is done through the following
commands:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">mount</span> <span class="at">-t</span> sysfs /sys /mnt/new/sys/</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="fu">mount</span> <span class="at">-t</span> proc /proc /mnt/new/proc/</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="fu">mount</span> <span class="at">--rbind</span> /dev /mnt/new/dev/</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="fu">chroot</span> /mnt/new</span></code></pre></div>
<p>Inside the chroot environment, you need to first install some
cryptsetup related stuff, and then update the fstab file:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">apt</span> install cryptsetup cryptsetup-initramfs</span></code></pre></div>
<p>/etc/crypttab (the file which tells the system what encrypted
partitions to mount):</p>
<pre><code>crypt   UUID=UUID_OF_PARTITION_FROM_BLKID   none    luks,discard</code></pre>
<p>/etc/fstab:</p>
<pre><code>/dev/mapper/crypt   /   ext4    rw  0   1
/dev/BOOT_PARTITION /boot   ext2    rw  0   1</code></pre>
<p>Past this, you need to reinstall grub:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">grub-install</span> /dev/DISK <span class="co"># for legacy BIOS, note this is the disk not the partition (ie. /dev/vda not /dev/vda1)</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">update-grub</span></span></code></pre></div>
<p>And that should be it, once you reboot, you should boot into a
password prompt, past which you can boot into your newly encrypted
system!</p>
<p>PS: don’t forget to remove the old partition :D</p>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/07-encrypt-ext4-debian-install.html</guid>
  </item>
<item>
  <pubDate>Sat, 27 Jan 2024 14:44:26 +0000</pubDate>
  <category>2024/01/27/6</category>
  <title>Using my phone as a webcam with just scrcpy andADB</title>
  <link>https://aryak.me/blog/06-phone-webcam-scrcpy.html</link>
  <description><![CDATA[
<p>Recently, we decided to start streaming <a
href="https://fossunited.org">FOSS United Mumbai</a> events to our <a
href="https://sovran.video">Peertube instance</a>, and hence we needed a
camera.</p>
<p>Since we couldn’t procure a good camera that can capture text from
the projector well, I started experimenting with other alternatives.</p>
<p>The first solution I tried was a generic IP camera based solution,
which of course came with the latencies involved with network-based
stuff and hence wasn’t suitable for this purpose.</p>
<p>Then, I tried droidcam, which uses ADB, but again, it had a paywall
for anything over 480p.</p>
<p>Past this, my <em>jugaad</em> solution was to use scrcpy via USB ADB,
open the normal camera app and then just capture part of the window with
the content, but that came with the issue of only being able to use 4:3
aspect ratio, and potentially worse quality since liveview is rarely as
good as actuals.</p>
<p>Later, I discovered that scrcpy can natively capture the phone camera
since Android 12+ and Scrcpy 2.x+.</p>
<p>This came with the first problem, debian <strong>testing</strong> is
still stuck on 1.x of scrcpy!</p>
<p>Note to self: maybe I should try porting a 2.x to Debian :D</p>
<p>As outlined in the <a
href="https://github.com/Genymobile/scrcpy/blob/master/doc/camera.md">docs</a>,
scrcpy can capture both front and back cameras, at all supported
resolutions, and even the audio from the phone’s mic (which is useful
considering how shitty the mics are on modern laptops these days) .</p>
<p>So at the end, I ended up with this command:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">/usr/local/bin/scrcpy</span> <span class="at">--video-source</span><span class="op">=</span>camera <span class="at">--camera-id</span><span class="op">=</span>0 <span class="at">--camera-size</span><span class="op">=</span>3264x1836</span></code></pre></div>
<p>Now, at this point, I just needed to run OBS under Xwayland, add it
as an Xcomposite video capture, and start streaming!</p>
<p>But then, if you want to use it as a webcam, you just have to install
v4l2loopback (and run modprobe v4l2loopback), and then click “Start
Virtual Camera” instead of Start Streaming.</p>
<p>Do note though, you might have to change output type to scene under
the settings section right next to the start virtual camera button.</p>
<p>But thats about it. This is still a bit jank, considering you need
scrcpy and OBS both running in the background, but it generally does the
job pretty well, and a good phone’s webcam is miles better than any
other mid-range web-cam you can get.</p>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/06-phone-webcam-scrcpy.html</guid>
  </item>
<item>
  <pubDate>Fri, 03 Nov 2023 14:44:26 +0000</pubDate>
  <category>2023/11/03/5</category>
  <title>Enabling AltGr+4 for rupee/euro on Hyprland</title>
  <link>https://aryak.me/blog/05-rupee-sign-on-hyprland.html</link>
  <description><![CDATA[
<p>Enabling the rupee sign (or the euro sign for that matter) on
Hyprland is pretty simple, but not well documented from my
“research”.</p>
<p>To begin with, you need to use the altgr-intl layout in order to be
able to use it in the first place. This also gives you access to <a
href="https://raw.githubusercontent.com/google/us-altgr-intl/master/images/keyboard_english_us_intl.png">many
other characters</a> as well.</p>
<p>To do this, add <code>kb_variant = altgr-intl</code> in the input
section of your <code>hyprland.conf</code>.</p>
<p>Past this, the configuration is pretty simple, you just have to add
the required options to <code>kb_options</code>.</p>
<p>You can get a list of these with
<code>localectl list-x11-keymap-options</code>.</p>
<p>In my case, I needed <code>rupeesign:4</code></p>
<p>At the end, this is how the hyprland.conf’s input section looks:</p>
<pre><code>input {
    kb_layout = us
    kb_options = rupeesign:4, caps:backspace
    kb_variant = altgr-intl
    [...mouse stuff...]
}</code></pre>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/05-rupee-sign-on-hyprland.html</guid>
  </item>
<item>
  <pubDate>Sat, 19 Aug 2023 14:44:26 +0000</pubDate>
  <category>2023/08/19/6</category>
  <title>Why philosophy should be part of the educationsystem</title>
  <link>https://aryak.me/blog/04-philosophy-should-be-part-of-edu-system.html</link>
  <description><![CDATA[
<p>I was recently reading the essay, On Liberty, by John Stuart Mill and
I was very intrigued by some of the points brought up by the book.</p>
<p>This led me to think again about something I have been pondering
about in and out for ages, the place of philosophy in the educational
system.</p>
<h2 id="the-problem">The problem</h2>
<p>I’ll start with the problem. To be honest, this generation is
extremely apolitical, and non-politically active.</p>
<p>All they care about is getting good marks, passing 10th/12th and
getting a good college/job, while ignoring the big and important
question, the state of our nation.</p>
<p>When noone cares about the nation, asatyamev hi jayate (injustice
alone will prevail), for there is no person to keep check on the
government.</p>
<p>Every person’s goal in life is to serve themselves. Me first,
everything secondary. This is how humans work.</p>
<p>The government is meant to mediate this but its not a bulletproof
entity, its made of people, whose primary goal is to serve
themselves.</p>
<p>This is why we need someone to keep the government in check, and
unintellectual and aloofness from politics does not help.</p>
<p>This I feel, is excacerbated by the education system, especially
here, which encourages rote learning.</p>
<h2 id="the-state-of-the-current-education-system">The state of the
current education system</h2>
<p>This is especially bad with social studies, where it is important to
be opinion based, not “I just memorized this chapter and can get 100 in
tommorow’s exam”.</p>
<p>I guess this could apply to the sciences, mathematics etc. but it is
even more important in the social sciences and humanities.</p>
<p>Social Studies must be opinions, what you think about this thing, who
is in the right and who is in the wrong according to you, with multiple
sources to understand from.</p>
<p>People should be marked based on the intellectual-ness of the answer,
not based on how “politically-correct” or similar to textbook the answer
is.</p>
<p>Here is where philosophy plays an important role.</p>
<p>While social studies only covers laws, history and generally how our
current system came to be, philosophy questions the basic theory.</p>
<p>Philosophy awakens the intellectual-ness, and makes people think
critically.</p>
<p>It encourages and makes people go into deep thoughts and intellectual
discussions, which benifit them mentally and society in large as we get
more intelligent people.</p>
<p>This encouragement that used to be prevailent in the ancient times of
Gurukuls has been effectively wiped off by the advent of the structured
educational system.</p>
<h2
id="my-ideas-for-how-philosophy-could-be-implemented-in-education">My
ideas for how philosophy could be implemented in education</h2>
<p>Philosophy is a vast and varied subject.</p>
<p>I would say, extracts from philosophical texts from the big 4
traditions (western, indian, chinese, islamic) should be given to
students about a specific topic, which of course must be suitable for
their grade and they should be asked to comment on what they think about
each.</p>
<p>In my opinion, everything should be marked based on the intellect of
the answer, and when marks are deducted for “wrong-think”, students
should be able to appeal to a board setup to answer and co-ordinate with
schools about these kind of marking conflicts.</p>
<h2 id="the-untouchable-subjects">The “untouchable” subjects</h2>
<p>There are many subjects that are untouchable in any normal debate, be
it caste, morality, religion etc.</p>
<p>This is BAD and leads to forcing of opinions and generally lack of
intellectualism around these topics.</p>
<p>You cannot and should not take a blind follow approach to anything.
Question every single thing you have to do, be it rhetorical or directed
towards someone else.</p>
<h2 id="the-law">The law</h2>
<p>The law should be more liberal when it comes to “wrong-think”. Speech
should be allowed as long as it does not incite or promote violence.</p>
<p>I know incite violence is vague as hell, and that is of course
because of how varied stuff can cause people to get mad.</p>
<p>A small social media post about something inciteful can cause more
harm than someone saying extremely inciting/dangerous things to even a
big audience.</p>
<p>“Hate speech” can not be regulated, and the intentions of something
cannot be easily made out.</p>
<p>To be frank, I don’t have any ideas about this. Maybe a committee to
decide what constitutes a hate-speech and what does not, but then there
are of course biases.</p>
<p>If you go with a simple “if there is violence due to your post we
arrest you”, you risk arresting people whose post unintentionally
incited the same.</p>
<p>But, at the end of the day, the law should be more allowing for free
thinking and intellectual discussions, as long as of course, it doesnt
incite violent acts.</p>
<h2 id="societal-stuff">Societal stuff</h2>
<p>People also are moulded more and more into non-individualistic
robots, who all share the same happiness and same opinions.</p>
<p>People like something just because others like it, and if they don’t
like it they are treated like outcasts from society.</p>
<p>People have no individualistic goals in life, just the standard
“getting good marks, passing 10th/12th and getting a good
college/job”</p>
<p>While these are also extremely important, we need to stress on the
importance of a life where people aren’t just robots who do what they
are told to do (or NPCs as the zoomers call it).</p>
<p>This could be lessened by philosophy, which imbibes critical thinking
in the mind of those who read it.</p>
<p>I should have published this on Independence day since well a lot of
these were ponderings about the Indian independence and what it gave us
Indians, but well procrastination :)</p>
<p>I know this is a bit rambly but I hope you get the point :P</p>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/04-philosophy-should-be-part-of-edu-system.html</guid>
  </item>
<item>
  <pubDate>Wed, 16 Aug 2023 14:44:26 +0000</pubDate>
  <category>2023/08/16/3</category>
  <title>Linux on the Thinkpad E14 G5 AMD</title>
  <link>https://aryak.me/blog/03-e14-linux.html</link>
  <description><![CDATA[
<p>I recently got a thinkpad E14 gen5 with a ryzen 5 7th gen to replace
my Acer Aspire 7.</p>
<p>Of course I wanted to replace the default windows with linux, but I
was too lazy to reinstall and hence just put my old NVMe SSD in the
laptop thanks to the availability of 2 M.2 slots.</p>
<p>Before this I had to disable secure boot in the bios which I did
along with a few other “important” changes (which I’ll cover later)</p>
<p>Past this, most things worked out of the box after removing my old
Nvidia drivers. Ryzen is really good on linux :P</p>
<p>However, 2 things didn’t work correctly, the Fingerprint sensor and
WiFi card.</p>
<h2 id="realtek-wifi">Realtek WiFi</h2>
<p>After the initial setup, my realtek wifi card was having frequent
disconnection issues. It will suddenly just stop transmitting data and
the fix was to reconnect to the wifi network.</p>
<p>Another issue is that the Realtek WiFi card only works with kernels
6.2+. This wasn’t an issue for me as a Debian Sid user but when I first
tested the compatibility on an Ubuntu 22.04 ISO before adding my drive,
this was pretty weird/confusing.</p>
<p>After a bit of searching, I figured out that the random disconnection
was due to NetworkManager’s randomized mac addresses.</p>
<p>To fix this, I just had to append the following to the
NetworkManager.conf file:</p>
<pre><code>[device]
wifi.scan-rand-mac-address=no</code></pre>
<h2 id="goodix-fingerprint">Goodix Fingerprint</h2>
<p>I thought the fingerprint was useless for good, until I discovered
that Lenovo provided drivers for their fingerprint sensor through one of
the manuals I was searching through.</p>
<p>Originally I didn’t find anything, since the driver page for my model
didn’t show linux, but after a bit of searching again, I stumbled across
<a
href="https://support.lenovo.com/in/en/downloads/ds560884-goodix-fingerprint-driver-for-linux-thinkpad-e14-gen-4-e15-gen-4">this
support page</a> that gave links to drivers.</p>
<p>Since I ran debian testing and its mostly compatible with what Ubuntu
has, I tried just installing libfprint-2-2 normally and then the
driver’s deb, but the deb refused to install since it needed <a
href="https://gitlab.freedesktop.org/3v1n0/libfprint/-/tree/tod?ref_type=heads">libfprint-2-tod</a>
(a fork of libfprint with support for TOD/touch based fingerprint
readers).</p>
<p>I tried installing the deb from ubuntu repos and then install the
driver, which succeeded, but didn’t make the device work.</p>
<p>Later, I installed ubuntu 22.04 on a secondary partition to check if
it worked on ubuntu, which it did.</p>
<p>One thing I noticed, however was that it used <a
href="https://launchpad.net/~andch/+archive/ubuntu/staging-fprint/+packages">a
ppa</a> instead of regular libfprint(-tod) from canonical repos.</p>
<p>Then, I tried installing libfprint and libfprint-tod debs from that
ppa and the goodix deb from lenovo, and after a reboot, everything
worked!</p>
<p>Once it was up, I installed fprintd and libpam-fprintd, at which
point I did the fprintd-enroll and fprintd-verify.</p>
<p>After these succeeded, I ran
<code>pam-auth-update --enable fprintd</code>. This made fprintd work on
pam stuff like sudo and TTY logins.</p>
<p>With this, the last remaining non-working feature of my thinkpad was
working as well :D</p>
<h2 id="the-bios">The BIOS</h2>
<p>Once I got my thinkpad, basically the first thing I did was tweak the
BIOS.</p>
<p>Getting into the BIOS is dead simple compared to other laptops, just
press enter (which it tells you during bootup) and it will take you to a
menu, from where you can choose to go to the BIOS with F1.</p>
<p>I was pleasantly surprised to see a modern BIOS, with touchpad
support. Coming from laptops which only had blue and white bioses and
barely any tweaks, this was a welcome upgrade :)</p>
<p>First thing to disable was secure boot. It was present in Security
section of the BIOS and was pretty easy to disable</p>
<p>Then, I permanently disabled some enterprise spyware utility (update:
it was called Absolute under Security).</p>
<p>There was also Lenovo Cloud Services in Config -&gt; Network, which I
of course disabled.</p>
<p>While in Security, I disabled Enhanced Windows Biometric Security (in
Virtualization) and Microsoft Device Guard.</p>
<p>And thats it for now, I’ll update this blogpost if I face any other
issues or discover other stuff. Thanks for sticking around :)</p>
<p>If you have any questions, feel free to <a href="/contact">contact
me</a>!</p>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/03-e14-linux.html</guid>
  </item>
<item>
  <pubDate>Mon, 17 Apr 2023 14:44:26 +0000</pubDate>
  <category>2023/04/17/1</category>
  <title>How we migrated Project Segfault’s matrix homeserverto matrix-docker-ansible-deploy</title>
  <link>https://aryak.me/blog/02-mdad.html</link>
  <description><![CDATA[
<p>Yesterday, we completed Project Segfault’s migration from
matrix.org’s official docker image for synapse to
matrix-docker-ansible-deploy.</p>
<p>This was because of how much of a pain it is to setup workers,
especially with docker. The docs aren’t great about it either..</p>
<p>For these reasons, we turned to matrix-docker-ansible-deploy.</p>
<p>The first issue we encountered was how spread out the docs were,
though very precise and well-explained.</p>
<p>Once we cloned the repo, we first had to setup the inventory hosts
file.</p>
<p>Since we cloned the repo to the DockerVM itself, we had a weird
solution for this.</p>
<pre><code>[matrix_servers]
matrix.projectsegfau.lt ansible_host=localhost ansible_ssh_user=root</code></pre>
<p>After this, we had to add the pubkey of the VM to its own
<code>authorized_keys</code>. Wacky :P</p>
<p>With that sorted, we had to start configuring.</p>
<p>Firstly, we had to prevent it from installing docker.</p>
<p>This is important since (re)installing docker will break a lot,
especially for our pre-existing services.</p>
<pre><code>matrix_playbook_docker_installation_enabled: false</code></pre>
<p>After that, we had to add our old secret keys back to the config file
so that it won’t break federation:</p>
<pre><code>matrix_synapse_macaroon_secret_key: &quot;xxx&quot;
matrix_synapse_registration_shared_secret: &quot;xxx&quot;
matrix_synapse_form_secret: &quot;xxx&quot;</code></pre>
<p>The signing key had to be re-added as well, but later after the setup
was complete.</p>
<p>After that, we turned to the thing we migrated for, synapse
workers:</p>
<p>Since the generic and federation_sender workers have to process a lot
of data, we made 4 of each (totally didn’t copy the number from envs.net
:P).</p>
<pre><code>matrix_synapse_workers_enabled: true
matrix_synapse_workers_preset: one-of-each
matrix_synapse_workers_federation_sender_count: 4
matrix_synapse_workers_generic_worker_count: 4</code></pre>
<p>Another important thing we had to take into consideration was
postgres. We ran postgres on a separate VM and connected to the database
on it.</p>
<pre><code>matrix_synapse_database_host: &quot;192.168.5.4&quot;
matrix_synapse_database_user: &quot;synapse&quot;
matrix_synapse_database_password: &quot;xxx&quot;
matrix_synapse_database_database: &quot;synapse&quot;
devture_postgres_enabled: false</code></pre>
<p>After the database, we had to set up registration/login stuff.</p>
<p>A weird thing I noticed about matrix-docker-ansible-deploy’s email
configuration is that it uses its own relay, above our mail
credentials.</p>
<pre><code>matrix_mailer_sender_address: &quot;matrix@projectsegfau.lt&quot;
matrix_mailer_relay_use: true
matrix_mailer_relay_host_name: &quot;mail.projectsegfau.lt&quot;
matrix_mailer_relay_host_port: 587
matrix_mailer_relay_auth: true
matrix_mailer_relay_auth_username: &quot;matrix@projectsegfau.lt&quot;
matrix_mailer_relay_auth_password: &quot;xxx&quot;
matrix_synapse_registrations_require_3pid: [ email ]
matrix_synapse_enable_registration: true
matrix_synapse_configuration_extension_yaml: |
  oidc_providers:
    - idp_id: authentik
      idp_name: &quot;authentik&quot;
      idp_icon: &quot;mxc://envs.net/429bd4b307d32b919a94823f03acc7c24a7da61f&quot;
      discover: true
      issuer: &quot;https://auth.p.projectsegfau.lt/application/o/matrix/&quot;
      client_id: &quot;xxx&quot;
      client_secret: &quot;xxx&quot;
      scopes:
        - &quot;openid&quot;
        - &quot;profile&quot;
        - &quot;email&quot;
      user_mapping_provider:
        config:
          localpart_template: &quot;{% raw %}{{ user.preferred_username }}{% endraw %}&quot;
          display_name_template: &quot;{% raw%}{{ user.name }}{% endraw %}&quot;
          email_template: &quot;{% raw %}{{ user.email }}{% endraw %}&quot;</code></pre>
<p>Past this, we also had to port the small configurations we had in our
old homeserver.yaml to the ansible format.</p>
<p>Since most of these weren’t documented very well, we had to make
heavy use of the <a
href="https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/roles/custom/matrix-synapse/defaults/main.yml">defaults
file</a>.</p>
<pre><code>matrix_synapse_auto_join_rooms: [ &#39;#project-segfault:projectsegfau.lt&#39;, &#39;#support:projectsegfau.lt&#39;, &#39;#general:projectsegfau.lt&#39;, &#39;#announcements:projectsegfau.lt&#39; ]
matrix_synapse_max_upload_size_mb: 700
matrix_synapse_allow_public_rooms_without_auth: true
matrix_synapse_allow_public_rooms_over_federation: true
matrix_synapse_email_client_base_url: &quot;https://matrix.to&quot;
matrix_synapse_email_invite_client_location: &quot;https://chat.projectsegfau.lt&quot;
matrix_synapse_turn_uris: [&quot;turn:turn.projectsegfau.lt?transport=udp&quot;, &quot;turn:turn.projectsegfau.lt?transport=tcp&quot;]
matrix_synapse_turn_shared_secret: &quot;xxx&quot;
matrix_synapse_turn_allow_guests: true
matrix_coturn_enabled: false
matrix_client_element_enabled: false</code></pre>
<p>At this point we realized that we need to do a lot of weirder stuff
to get it to work reverse-proxied behind our main caddy instance.</p>
<p>We reverse-proxied the traefik instance behind our caddy instance, as
recommended by the <a
href="https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy">documentation</a>
with the instructions there:</p>
<pre><code># Ensure that public urls use https
matrix_playbook_ssl_enabled: true

# Disable the web-secure (port 443) endpoint, which also disables SSL certificate retrieval
devture_traefik_config_entrypoint_web_secure_enabled: false

# If your reverse-proxy runs on another machine, consider using `0.0.0.0:81`, just `81` or `SOME_IP_ADDRESS_OF_THIS_MACHINE:81`
devture_traefik_container_web_host_bind_port: &#39;0.0.0.0:81&#39;

# We bind to `127.0.0.1` by default (see above), so trusting `X-Forwarded-*` headers from
# a reverse-proxy running on the local machine is safe enough.
devture_traefik_config_entrypoint_web_forwardedHeaders_insecure: true
devture_traefik_additional_entrypoints_auto:
  - name: matrix-federation
    port: 8449
    host_bind_port: &#39;0.0.0.0:8449&#39;
    config: {}</code></pre>
<p>After all the configuration was done, we had to run it :P.</p>
<p>Firstly, we had to install ansible and <a
href="https://github.com/casey/just">just</a>, and run
<code>just roles</code> to initialize all the ansible stuff.</p>
<p>At this point, we shut down our old matrix instance in order to not
cause any issues.</p>
<p>Then, we ran
<code>ansible-playbook -i inventory/hosts setup.yml --tags=install-all</code>
to install all the files but not start the services.</p>
<p>Now came the most time consuming part, importing the old media repo.
Considering its size at over 85 gigabytes.</p>
<pre><code>ansible-playbook -i inventory/hosts setup.yml --extra-vars=&#39;server_path_media_store=/opt/docker/mtrx/files/media_store&#39; --tags=import-synapse-media-store</code></pre>
<p>This took almost 30 minutes, the majority of the downtime we
had..</p>
<p>After this was done, we were able to start the server:
<code>ansible-playbook -i inventory/hosts setup.yml --tags=start</code>.</p>
<p>The <a
href="https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/examples/nginx/matrix.conf">nginx
configuration</a> they recommended in the documentation for our
reverse-proxy setup was pretty self-explanatory and easy to convert, but
for the fact that till now our matrix instance used normal delegation
and did not make use of :8448.</p>
<p>Due to this, we had to waste a lot of time trying to figure out which
routes went to which ports. I wish the documentation explained this
better..</p>
<p>At the end, this was the caddy configuration we came up with for
this:</p>
<pre><code>matrix.projectsegfau.lt {
    reverse_proxy /_matrix/* 192.168.5.2:8449
    reverse_proxy /_matrix/client/* 192.168.5.2:81
    reverse_proxy /_synapse/* 192.168.5.2:81
}</code></pre>
<p>This configuration works right now, though we are still not
completely sure if other routes need to go somewhere else.</p>
<p>I do have some gripes with it though, such as the ages it takes for
restarts (–tags=setup-build and then –tags=restart for those wondering)
and the lack of documentation for what is the recommended upstream
delegation configuration.</p>
<p>At the end, matrix-docker-ansible-deploy simplified our config a lot
and relieved a lot of maintanence burden we would have had in case we
configured it manually and I am thankful for that.</p>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/02-mdad.html</guid>
  </item>
<item>
  <pubDate>Wed, 01 Mar 2023 14:44:26 +0000</pubDate>
  <category>2023/03/01/3</category>
  <title>Setting up Knot DNS - DNSSEC, GeoDNS, RFC2136,authenticated zonefile sync and more!</title>
  <link>https://aryak.me/blog/01-knot.html</link>
  <description><![CDATA[
<p><a href="https://knot-dns.cz">Knot DNS</a> is one of the easier to
setup authoritative dns servers out there, made by <a
href="https://nic.cz">NIC.CZ</a>.</p>
<p>In this tutorial I’ll show how to setup Knot with DNSSEC,
authenticated master -&gt; slave sync, RFC2136 (for automatic dns-based
certs in caddy and such) and GeoDNS, which makes the server give an IP
closest to the user.</p>
<p>I assume you have two Debian based systems, with port 53 (tcp+udp)
forwarded.</p>
<h2 id="installing-knot">Installing Knot</h2>
<p>This guide covers debian, but instructions for other distributions
can be found on the <a href="https://www.knot-dns.cz/download">download
page</a> Run the following on both the master and the slave:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">apt-get</span> <span class="at">-y</span> install apt-transport-https lsb-release ca-certificates wget</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">wget</span> <span class="at">-O</span> /usr/share/keyrings/knot.gpg https://deb.knot-dns.cz/apt.gpg</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="fu">sh</span> <span class="at">-c</span> <span class="st">&#39;echo &quot;deb [signed-by=/usr/share/keyrings/knot.gpg] https://deb.knot-dns.cz/knot-latest/ $(lsb_release -sc) main&quot; &gt; /etc/apt/sources.list.d/knot-latest.list&#39;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ex">apt-get</span> update</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ex">apt-get</span> install knot knot-dnsutils</span></code></pre></div>
<h2 id="basic-configuration">Basic Configuration</h2>
<h3 id="knot.conf">knot.conf</h3>
<p>Now, to add in the basic configuration, overwrite the
<code>/etc/knot/knot.conf</code> file on the master with the following
text:</p>
<pre><code>server:
    rundir: &quot;/run/knot&quot;
    user: knot:knot
    listen: 0.0.0.0@53
log:
  - target: syslog
    any: info
database:
    storage: &quot;/var/lib/knot&quot;
remote:
  - id: secondary
    address: your.other.servers.ip@53
acl:
  - id: acl_secondary
    address: your.other.servers.ip
    action: transfer
template:
  - id: default
    storage: &quot;/etc/knot/zones&quot;
    file: &quot;%s.zone&quot;
    semantic-checks: on
    # Don&#39;t override zonefile
    zonefile-sync: -1
    zonefile-load: difference-no-serial
    journal-content: all
zone:
  - domain: your.domain
    notify: secondary
    acl: acl_secondary</code></pre>
<p>On the slave, overwrite the same file with the following text:</p>
<pre><code>server:
    rundir: &quot;/run/knot&quot;
    user: knot:knot
    listen: 0.0.0.0@53
log:
  - target: syslog
    any: info
database:
    storage: &quot;/var/lib/knot&quot;
remote:
  - id: primary
    address: your.main.servers.ip@53
acl:
  - id: acl_primary
    address: your.main.servers.ip
    action: notify
template:
  - id: default
    storage: &quot;/etc/knot/zones&quot;
    file: &quot;%s.zone&quot;
zone:
  - domain: your.domain
    master: primary
    acl: acl_primary</code></pre>
<h3 id="zonefile">Zonefile</h3>
<p>At this point you need to create <code>/etc/knot/zones</code> on both
the master and slave as that is where the zonefiles will be stored. Now
create a file named your.domain.zone in the directory on the master
alone and add the following text to it:</p>
<pre><code>$ORIGIN your.domain. ; &#39;default&#39; domain as FQDN for this zone
$TTL 3600 ; default time-to-live for this zone

your.domain.   IN  SOA     ns1.your.domain. ns2.your.domain. (
        YYYYMMDD01  ;Serial
        14400       ;Refresh
        3600        ;Retry
        1209600     ;Expire
        3600        ;Negative response caching TTL
)
@   IN  NS  ns1.your.domain.
@   IN  NS  ns2.your.domain.
ns1 A   your.main.servers.ip
ns2 A   your.other.servers.ip
@   A   your.main.servers.ip

; PTR Records (for mailservers)
your.ip.in.reverse.in-addr.arpa.    PTR mail.your.domain.</code></pre>
<p>At this point, you can run <code>systemctl restart knot</code>
(restart since its a major change) on both nodes.</p>
<h2 id="updating-the-zonefile">Updating the zonefile</h2>
<p>Updating the zonefile is not hard.</p>
<ul>
<li>Since we set the <code>zonefile-load</code> to
<code>difference-no-serial</code>, we do not need to increment the
serial as it will automatically be computed when
<code>knotc reload</code> is run.</li>
<li>All records must be before the PTR in the zonefile.</li>
<li>Wildcards can be done with the hostname as <code>*</code></li>
<li>If the hostname ends with ., it must include your.domain, that is
something.your.domain will be <code>something.your.domain.</code></li>
<li>If the hostname does not end with a ., it is relative to the domain,
that is something.your.domain will just be <code>something</code>.</li>
<li>Always use tabs, not spaces.</li>
</ul>
<h2 id="token-based-zonefile-authentication">Token-based zonefile
authentication</h2>
<p>At the moment, the authentication for sending and receiving the
zonefile is completely based on the IP address, which is not very
secure.</p>
<p>To remediate this, we can use token-based authentication.</p>
<p>First, you need to generate a key with
<code>keymgr -t zonesync hmac-sha256</code></p>
<p>This is the key that will authenticate the zone transfers.</p>
<p>You can copy-paste the output it gives you into your knot.conf, above
the remote section on both master and slave.</p>
<p>Now, you need to add <code>key: zonesync</code> to the remote,
acl_primary/secondary sections on both master and slave.</p>
<p>At this point, you can run <code>systemctl restart knot</code>, and
all the syncs will be more secure!</p>
<h2 id="dnssec">DNSSEC</h2>
<p>DNSSEC is an extension to DNS designed to protect applications using
DNS from accepting forged or manipulated DNS data by using zone
signing.</p>
<p>Enabling DNSSEC on knot is as simple as adding the following line to
the template section:</p>
<pre><code>template:
    ...
    dnssec-signing: on
    ...</code></pre>
<p>At this point, you need to upload the DS record to your Registry.
This is usually done through your registrar’s WebUI.</p>
<p>The DNSSEC-enabled DNS servers use the DS record from your domain
registry to validate your records.</p>
<p>You can get your DS record with the following command:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">keymgr</span> your.domain ds</span></code></pre></div>
<p>The output will look something like this:</p>
<pre><code>54674 13 2 E28E3DB78E5517A577353A43799AD14EC044720BAE4906D134F5EA40 74AC0287</code></pre>
<p>In the example given:</p>
<ul>
<li>Key tag - 54674</li>
<li>Algorithm - 13</li>
<li>Digest Type - 2</li>
<li>Digest - E28E3…287 (omit space)</li>
</ul>
<p>On namecheap, you add this at Advanced DNS -&gt; DNSSEC</p>
<p>You can check if your DNSSEC is working properly at <a
href="https://dnsviz.net">DNSViz</a> and <a
href="https://dnssec-analyzer.verisignlabs.com">DNSSEC-Analyzer</a>.</p>
<h2 id="rfc2136">RFC2136</h2>
<p><a href="https://www.rfc-editor.org/rfc/rfc2136">RFC2136</a> is an
RFC that allows dynamic updates for DNS.</p>
<p>This works completely over DNS and does not require a special
API.</p>
<p>To set it up, you need to create an ACL as follows:</p>
<pre><code>acl:
    ...
    - id: acl_dynupdates
    address: [an.authorized.ip.addr, another.authorized.ip.addr]
    action: update
...
zone:
  - domain: your.domain
    notify: secondary
    acl: [acl_secondary, acl_dynupdates]</code></pre>
<p>You can also add token-based auth by generating another key with
<code>keymgr -t rfc2136 hmac-sha256</code></p>
<p>You can add it to the config as follows:</p>
<pre><code>key:
    ...
    - id: rfc2136
    algorithm: hmac-sha256
    secret: xxx
...
acl:
    ...
    - id: acl_dynupdates
    address: [an.authorized.ip.addr, another.authorized.ip.addr]
    action: update
    key: rfc2136</code></pre>
<p>After this, you can run <code>systemctl restart knot</code> to apply
the changes.</p>
<h3 id="caddy">Caddy</h3>
<p><a href="https://caddyserver.com">Caddy</a> is a modern webserver
which supports automatic cert generation from letsencrypt/zerossl with
acme.</p>
<p>It uses http-01 for the challenge by default, but can use a dns
challenge too.</p>
<p>For the DNS challenge, you first need to install the <a
href="https://github.com/caddy-dns/rfc2136">RFC2136 DNS plugin</a> with
the following command:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">xcaddy</span> build <span class="at">--with</span> github.com/caddy-dns/rfc2136@master</span></code></pre></div>
<p>Now, add the following lines to the top of your caddyfile</p>
<pre><code>{
    acme_dns rfc2136 {
        key_name &quot;rfc2136&quot;
        key_alg &quot;hmac-sha256&quot;
        key &quot;xxx&quot;
        server &quot;your.main.servers.ip:53&quot;
    }
    acme_ca https://acme-v02.api.letsencrypt.org/directory
}</code></pre>
<p>Now, all certs can be generated using the DNS challenge!</p>
<p>This is especially useful in a GeoDNS environment.</p>
<h2 id="geodns">GeoDNS</h2>
<p>GeoDNS allows geographical split horizon based on a GeoIP database,
such as Maxmind’s free GeoLite2.</p>
<p>Firstly, you need to procure the GeoLite2 database from Maxmind.</p>
<p>Due to policy changes, you now need to signup on Maxmind’s website in
order to get access.</p>
<p>However, older GeoIP DBs can still be found in many places, including
distribution package repositories.</p>
<p>Once you procure your copy of GeoLite2, you need to install the GeoIP
module for knot-dns on both master and slave.</p>
<p>On Debian, the package’s name is <code>knot-module-geoip</code></p>
<p>After installing the module, you can add it to the knot.conf (must be
before zone section however):</p>
<pre><code>mod-geoip:
  - id: geo 
    config-file: &quot;/etc/knot/geo.conf&quot;
    mode: geodb
    geodb-file: &quot;/var/lib/knot/GeoLite2-City.mmdb&quot;
    geodb-key: [ continent/code, country/iso_code, city/names/en ]</code></pre>
<p>You also need to include the GeoIP module for your domain. You can do
that by adding this line to your domain’s zone section:</p>
<pre><code>zone:
    - domain: your.domain
      ...
      module: mod-geoip/geo</code></pre>
<p>Now, you need to configure the GeoDNS.</p>
<p>To do so, create a file called <code>/etc/knot/geo.conf</code> with
the following:</p>
<pre><code>geodnsubdom.your.domain:
  - geo: &quot;*;*;*&quot; # Fallback incase DNS server doesn&#39;t send ECS
    A: your.main.servers.ip
    TXT: &quot;Worldwide&quot;
  - geo: &quot;EU;*;*&quot; # Europe
    A: your.europe.servers.ip
    TXT: &quot;Europe&quot;
    ...</code></pre>
<p>However, the file needs to be manually synced to the slave on every
update.</p>
<p>It is also painful to use if you have multiple root subdomains you
want to use GeoDNS with.</p>
<p>Due to these reasons, I made a kinda hacky script to remediate
this:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/usr/bin/env bash</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="va">geoconf</span><span class="op">=</span>/etc/knot/geo.conf</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="va">remote</span><span class="op">=</span><span class="st">&#39;geodns@other.servers.ip&#39;</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="bu">printf</span> <span class="st">&#39;&#39;</span> <span class="op">&gt;</span> <span class="va">$geoconf</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> i <span class="kw">in</span> <span class="va">$(</span><span class="op">&lt;</span>/etc/knot/geodnsdomains<span class="va">)</span><span class="kw">;</span> <span class="cf">do</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">cat</span> /etc/knot/geodnstemplate <span class="op">&gt;&gt;</span> <span class="va">$geoconf</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">sed</span> <span class="at">-i</span> <span class="st">&quot;s/REPLACEME/</span><span class="va">${i}</span><span class="st">/&quot;</span> <span class="va">$geoconf</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="cf">done</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="fu">scp</span> <span class="va">$geoconf</span> <span class="st">&quot;</span><span class="va">${remote}</span><span class="st">&quot;</span>:/var/geo.conf</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a><span class="fu">ssh</span> <span class="va">$remote</span> <span class="st">&quot;sudo systemctl restart knot&quot;</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a><span class="ex">systemctl</span> restart knot</span></code></pre></div>
<p>In order to allow the unprivileged user on the slave to restart knot,
I used a sudo ALLOW_CMDS flag:</p>
<pre><code>Cmnd_Alias KNOT_CMDS = /usr/bin/systemctl restart knot
geodns ALL=(ALL) NOPASSWD: KNOT_CMDS</code></pre>
<p>And thats it. Thanks for reading!</p>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/01-knot.html</guid>
  </item>
<item>
  <pubDate>Sat, 28 Jan 2023 14:44:26 +0000</pubDate>
  <category>2023/01/28/6</category>
  <title>Welcome to my new blog!</title>
  <link>https://aryak.me/blog/00-welcome.html</link>
  <description><![CDATA[
<p>Hello everybody.</p>
<p>Welcome to my new blog!</p>
<p>I created this along with my website redesign and conversion to
pandoc from static html.</p>
<p>I will try to write based content atleast once a month but no
promises :P</p>]]></description>
  <author>arya@projectsegfau.lt (Arya Kiran)</author>
  <guid>https://aryak.me/blog/00-welcome.html</guid>
  </item>
  </channel>
</rss>
