Initial public git commit

This commit is contained in:
Laura Hausmann 2022-03-17 17:22:29 +01:00
commit ac9498f42a
Signed by: zotan
GPG key ID: D044E84C5BE01605
14 changed files with 3199 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
travelynx.txt
.bearer_token
.DS_Store

1
.well-known/pronouns Normal file
View file

@ -0,0 +1 @@
she/her

BIN
blog/img/adhd-and-notes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

37
blog/index.php Normal file
View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="zotan's blog"/>
<meta name="twitter:description" content="The blog of a disabled neurodivergent queer person unhappy with the state of the world."/>
<link rel="stylesheet" href="/style.css">
<title>zotan's blog</title>
</head>
<body>
<header>
<div class="container">
<h1><a href="/blog">zotan's blog</a></h1>
<?php if($_SERVER['HTTP_HOST'] === "zotan.pw" || $_SERVER['HTTP_HOST'] === "zotan.pw.dev"): ?>
<h2 style="margin-bottom: 0px;">Welcome internet user.</h2>
<?php else: ?>
<h2 style="margin-bottom: 0px;">Welcome <?php echo($_SERVER['SERVER_PROTOCOL'])?> internet user.</h2>
<?php endif; ?>
<small><a href="/">Back to main site</a></small>
</div>
</header>
<div class="container">
<section id="main_content">
<p>Hey there, welcome to the blog of a disabled neurodivergent queer person unhappy with the state of the world.</p>
<p>This is where I post about things that make it somewhat fun, things that help me with life in general or just things I felt like sharing.</p>
<h1 id="posts">Posts</h1>
<ul>
<!--<li><strong>2021-08-11</strong> <a href="/blog/posts/disability-identity-living">Disability, Identity & Living situations</a></li>-->
<li><strong>2021-08-23</strong> <a href="/blog/posts/ipv6-networking">IPv6-native networking: a project report</a></li>
<li><strong>2021-08-07</strong> <a href="/blog/posts/adhd-and-notes">ADHD & Notetaking: an autistic perspective</a></li>
</ul>
<p style="color: #666666"><i>This request was served by <?php echo gethostname() ?> in <?php echo(round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"])*1000, 2)) ?> ms<i></p>
</div>
</body>
</html>

View file

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="zotan's blog"/>
<meta name="twitter:description" content="ADHD & Notetaking: an autistic perspective"/>
<link rel="stylesheet" href="/style.css">
<title>zotan's blog</title>
</head>
<body>
<header>
<div class="container">
<h1><a href="/blog">zotan's blog</a></h1>
<?php if($_SERVER['HTTP_HOST'] === "zotan.pw" || $_SERVER['HTTP_HOST'] === "zotan.pw.dev"): ?>
<h2 style="margin-bottom: 0px;">Welcome internet user.</h2>
<?php else: ?>
<h2 style="margin-bottom: 0px;">Welcome <?php echo($_SERVER['SERVER_PROTOCOL'])?> internet user.</h2>
<?php endif; ?>
<small><a href="/blog">Back to blog overview</a></small>
</div>
</header>
<div class="container">
<section id="main_content">
<b>2021-08-07</b> - an 8 minute read (150 wpm)
<h1 id="post">ADHD & Notetaking: an autistic perspective</h1>
<div align="justify">
<p>
If you are living with ADHD, diagnosed or not, the following things might sound familiar: <i>"I forgot to write that down"</i>, <i>"I forgot to do that"</i>, <i>"I don't remember that"</i>.
</p>
<p>
If you ask neurotypical people what they do to resolve that, they will probably give you answers ranging from "Oh I just have it all in my head" to "Just use a todo list / GTD system / bullet journal", both equally unhelpful to most neurodiverse folks I know.
</p>
<p>
Reading <a href="https://christine.website/blog/gtd-on-paper-2021-06-13" target="_blank">this article</a> by Xe inspired me to tackle this problem for myself. (I highly encourage you to read the linked post along with the rest of their blog)
</p>
<p>
Now, back to the topic at hand. As mentioned, there are many common strategies for managing tasks and notes, many of which simply do not work for me, but let's go through the why and try to find something that works from there.
</p>
<p>
<h3>Journals, paper and other physical ways of notetaking</h3>
The most immediate problem with this one is something many ADHD folks will know very well - keeping track of the physical thing. Many times have I lost track of notebooks, journals, diaries or anything related, often times not finding them again to this day. For something I have to rely on (physical extension of my brain, my memories, my thoughts), that's bad. It's hard to forget your head, after all - even though a certain figure of speech might suggest otherwise.
</p>
<p>
Another issue, that links more into the <i>autistic perspective</i> part of the title, is the thing that many people like about paper - its append-only nature. I have very specific ideas about how I want things structured - and those ideas and needs vary with time and with the contents of the page. You just can't (easily and realistically) re-write the entire page every time those change, which makes paper inconvenient at best and irritating at worst.
</p>
<p>
But there are also some wonderful things about paper, some even come as a direct consequence of the problems I just described. You can just start writing, there are no creative restrictions on what you can and can't write, draw or otherwise do with the page, there is no fixed set of design choices, style guidelines and whatnot. The append-only nature also forces you to stop worrying about mistakes, and ideally should let you be in full control of writing out thoughts.
</p>
<p>
To summarize: Paper is problematic because of the physical and append-only nature, but can also great because of the freedom and implicit restrictions it brings onto the table. What I then set out to do is translating those concepts into the digital world, as closely adhering to those concepts (and other things my brain likes that I didn't cover in this post) as possible.
</p>
<p>
<h3>Markdown and the digital world</h3>
Once you dabble with digital notetaking for more than a few minutes, there's no way not to stumble upon Markdown. And there's good reason for that, being an easy to understand, simple and human-readable (in contrast to programmer-readable) markup language.
</p>
<p>
Those things also bring caveats with them, however. Simplicity inherently means limitation, and that's also true here. There isn't that much most Markdown renderers can do. Even worse, there is fragmentation in the Markdown space, with plain Markdown, GitHub-flavored Markdown (GFM) and MultiMarkdown as examples, not to speak of the variety of ways different renderers for the same specification actually interpret things.
</p>
<p>
Where does that leave us, then? I think Markdown is great, just not the full story we need here. It's a great starting point, and that's why my personal solution builds upon Markdown. So what is it that I currently (and thus far successfully, i.e. there when I need it, how I need it, as I want it) use?
</p>
<p>
It's a combination of <a href="https://obsidian.md" target="_blank">Obsidian</a> (a fancy Markdown editor, self-proclaimed "second brain"), some plugins, a custom theme, and most importantly, <i>not using the Markdown <b>renderer</b></i>. You might wonder how that works, isn't markdown supposed to be rendered? To which I say - yes, but we can do better. The one thing you are losing with that click of a button is control. Suddenly you have the version of what you wrote in front of you that the renderer decided on, not how you wanted it to look and feel. Which defeats the entire purpose of this project, to get something that offers creative freedom close to physical paper, without being convoluted to use.
</p>
<p>
<h3>Putting it all together</h3>
So how does my setup look like exactly? Like <a href="/blog/img/adhd-and-notes.png" target="_blank">this</a>. Let me explain what you are looking at here. On the left there is a tree view of the directory structure that is currently open in Obsidian.
</p>
<p>
From top to bottom: <i>Events</i> are things like conferences and similar, <i>Journal</i> is where the daily notes go, <i>Knowledge</i> is a categorized map of information and trivia that might be useful again in the future, <i>Meta</i> is stuff relevant for debugging Obsidian itself, <i>Notes</i> are uncategorized but titled notes, <i>People</i> is for keeping track of people I know (for the non-ADHD people reading this, yes, this is necessary, I regularly forget basic things about people very close to me), <i>Places</i> is the same thing but for Places like restaurants and stuff (important to keep track of what I eat and where to get it and stuff), <i>Projects</i> is pretty self-explanatory, <i>Vault</i> is the "system folder" where all the templates and attachments go, and <i>Zettelkasten</i> is for untitled notes. I have a shortcut configured that will create one of those untitled notes so I can just type out a thought and figure out what it's about later.
</p>
<p>
The file that's open is the daily journal template. This is used to automatically generate the daily journal entry when I click on a date in the calendar applet you can see on the top right. I then type out basic info about the day (where I was when I woke up, when I woke up) and move over incomplete TODOs from yesterday's daily note. You will also notice the text editor is, well, in edit mode, with a nice monospace font. This allows me to customize the spacing of individual elements in the documents however I want (just like paper), which would all get lost when rendering to HTML.
</p>
<p>
<h3>Summary and conclusion</h3>
This setup allows me to write freely, structure everything the same way my brain is structured, keep track of what I've been doing, keep track of things that still need to be done, and much more. Have I forgotten about it? Yes - two times over the past month. In comparison to previous methods, this is great! It's also fairly easy to reconstruct the past day or two, so I think I'm doing okay.
</p>
<p>
I won't pretend that this system will work for everyone, but I do hope that you will find some useful information in this writeup. If you have any questions (or want me to help you with Markdown, Obsidian or any other part of this setup), feel free to contact me. (Links for that are on the <a href="/#contact">main site</a>)
</p>
<p>
I hope this post was interesting for you, being the first time I've ever written one like it. If you have any comments on the blog or my writing style or just this post in general, please contact me as well. In any case, thanks for reading and have a wonderful day!
</p>
</div>
<p style="color: #666666"><i>This request was served by <?php echo gethostname() ?> in <?php echo(round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"])*1000, 2)) ?> ms<i></p>
</div>
</body>
</html>

View file

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="zotan's blog"/>
<meta name="twitter:description" content="IPv6-native networking: a project report"/>
<link rel="stylesheet" href="/style.css">
<title>zotan's blog</title>
</head>
<body>
<header>
<div class="container">
<h1><a href="/blog">zotan's blog</a></h1>
<?php if($_SERVER['HTTP_HOST'] === "zotan.pw" || $_SERVER['HTTP_HOST'] === "zotan.pw.dev"): ?>
<h2 style="margin-bottom: 0px;">Welcome internet user.</h2>
<?php else: ?>
<h2 style="margin-bottom: 0px;">Welcome <?php echo($_SERVER['SERVER_PROTOCOL'])?> internet user.</h2>
<?php endif; ?>
<small><a href="/blog">Back to blog overview</a></small>
</div>
</header>
<div class="container">
<section id="main_content">
<b>2021-08-23</b> - a 10 minute read (150 wpm)
<h1 id="post">IPv6-native networking: a project report</h1>
<div align="justify">
<p>
If you have reached this post, chances are you already know my <a href="https://as211579.net" target="_blank">AS211579</a> project. This post serves as a summary of the things I learnt and the roadblocks I had to overcome on the way to get the network to its current state.
</p>
<p>
<h3>Goals and setup</h3>
For those who don't know the project, here's a quick recap. After having dabbled a bit with <a href="https://dn42.eu" target="_blank">DN42</a> last year during the first lockdown, I wanted to do the real thing, in the same global routing system your ISP is using to reach this very web server. While this sounds unnecessarily convoluted and complicated to accomplish, it was actually pretty easy and not that expensive. The easy part is almost completely due to my knowledge gained by interacting with DN42 and the awesome people in #dn42 on the <a href="https://hackint.org" target="_blank">hackint</a> IRC, who have helped me with debugging the stupidest of mistakes. If you're interested in any of the things I'm about to talk about, be sure to check out the community behind it, it's seriously amazing.
</p>
<p>
Alright, we've established the goals, where do we go from here? I quickly found a sponsoring AS (something you need for the <i>cheap</i> part) and had all the documents on the way to RIPE (the regional internet registry responsible for, among others, Europe and Asia). Once all that was processed, a nice person from one of the many network group chats I'm in (Wim, if you are reading this, thank you so much), hooked me up with a free /40 IPv6 subnet for all my routing needs. Next, I got BGP VMs. Good places to get them are either <a href="https://vultr.com" target="_blank">Vultr</a> (cloud provider) or various smaller providers like <a href="https://ifog.ch" target="_blank">iFog</a>. Peering mostly happened on <a href="https://locix.online" target="_blank">LocIX</a>. From there, I provided connectivity to home routers, laptops and other computer-y devices via WireGuard.
</p>
<p>
<h3>Going a step further</h3>
Once my projects (mostly RPKI) eclipsed the performance level provided by the VMs, I contacted the nice people at <a href="https://meerfarbig.net" target="_blank">Meerfarbig</a> for a dedicated machine. That one is the primary server running the network to this day. If you are trying to set up a similar thing and are looking for specifics, feel free to <a href="/#contact">contact me</a> and I will give you appropriate resources.
</p>
<p>
<h3>The trials and tribulations of networking without IPv4</h3>
Now for the fun part, and the likely reason you are here in the first place: all the things that broke along the way. You see, as you might be able to tell from the title, my project goal was to set up an IPv6-native network. That implies NAT64, DNS64, 464XLAT and a whole bag of other fun things. But let's start at the beginning.
</p>
<p>
When you have IPv6-only networks, especially when talking about eyeball networks (the kind mostly used for content consumption, e.g. viewing webpages and their content), you will want a way to reach IPv4-only servers. Many popular websites still presently don't support IPv6. At time of writing, this includes GitHub, which is fairly important for developing things. A less important (but still relevant) example is Reddit. For now, we can't reach those websites. What do we do from here?
</p>
<p>
Our (first) solution is called NAT64, which translates packets between IPv6 and IPv4, hence the name. The software I chose for this task is <a href="https://jool.mx" target="_blank">Jool</a>. Setting it up was fairly trivial, and I quickly set up three redundant NAT64-gateways that announce the NAT64-WKP (well-known prefix, <span class="highlight-bg">64:ff9b::/96</span>). So far so good, but how do we get our systems to actually <i>use</i> those gateways?
</p>
<p>
For that, we need to look at DNS, which is responsible for translating our domain names (e.g. <span class="highlight-bg">github.com</span>) to an address we can connect to (e.g. <span class="highlight-bg">140.82.121.3</span>). If we configure the resolver that does that lookup to synthesize an AAAA record for our IPv4-only domain, we can connect to it! And that's what I'm doing. Using <a href="https://www.nlnetlabs.nl/projects/unbound/about/" target="_blank">unbound</a>, the address <span class="highlight-bg">140.82.121.3</span> (from the real A record) is translated to <span class="highlight-bg">64:ff9b::140.82.121.3</span>, or <span class="highlight-bg">64:ff9b::8c52:7903</span> in encoded form, and returned as a synthesized AAAA record. Once we configure our system to use this resolver, <i>most</i> IPv4-only sites work perfectly! If you are asking why I said most there, I hope you are in for a ride.
</p>
<p>
<h3>464XLAT and questioning whether connecting computers together was a good idea</h3>
The answer to that question is no, obviously. And it keeps chipping away at <a href="https://xkcd.com/2259/" target="_blank">my sanity</a>. But since we're here, I might as well roll with it. So, what does 464XLAT even mean? It's a specific combination of systems in place to ensure connectivity to IPv4 hosts from IPv6-only networks. Namely, in addition to DNS64 and the NAT64 gateway (called PLAT in this setup, provider-side address translator), we need a second piece of software, the CLAT (client/customer-side address translator).
</p>
<p>
Why, you ask? Because lots of rather popular software (for example, Skype and Spotify) not only use IPv4, but hardcoded IPv4 literals. That means that instead of connecting to <span class="highlight-bg">somedomain.tld</span>, the software tries to connect to <span class="highlight-bg">192.0.2.255</span>, which will fail without a CLAT, since we are only capturing (and synthesizing AAAA records for) DNS queries. A CLAT will take that packet and translate it to an IPv6 packet destined for the DNS64-synthesized address of the target host, the same one the resolver would have synthesized, had we not used literals.
</p>
<p>
Okay, sounds simple enough, how do we do this? Most mobile operating systems (Android and iOS) and some desktop operating systems (Windows) support this natively, though support outside of cellular connections is limited to non-existent. Since we are working with WireGuard here, this won't help us. The solution I used here is giving all clients a private IPv4 address, and instead running the CLAT on the router the tunnel terminates on. For compatibility reasons I use addresses from the prefix <span class="highlight-bg">100.64.0.0/10</span> meant for CGNAT (which is almost what we are doing here) for this purpose.
</p>
<p>
<h3>Trying to get it all to work</h3>
After the configuration part, getting NAT64 to run was fairly easy, despite some initial issues with routing the NAT64-WKP. Once I turned on 464XLAT however, everything broke. <span class="highlight-bg">::1</span> (the IPv6 loopback address) was unreachable. Traceroutes that shouldn't even have gone through the 464XLAT stopped working. I ran into bugs in Jool. Two fairly major ones, to be exact. However, the developers were very helpful in debugging the problems, and got both of them resolved within about two months (shoutouts to ydahhrk!). If you intend on deploying a similar setup, I recommend going for the -git version, since those bugs are fixed there already.
</p>
<p>
<h3>One more thing</h3>
One last roadblock was wireguard-quick for macOS. For those unfamiliar with these issues, I'm glad you didn't go through that debugging rabbit hole. To start with, if you are tunneling all of your traffic and your WiFi or Ethernet connection doesn't support IPv6 while your tunnel does, macOS will sometimes decide to be smart and not attempt to request AAAA records at all, thereby making the IPv6 connectivity of the tunnel redundant. To work around this issue I created a very dodgy-looking script that is run post-up by wireguard-quick, which creates a custom network service for the tunnel interface. If you have this problem and want this script, please <a href="/#contact">contact me</a> directly as I don't feel comfortable publishing something that terrible on my website.
</p>
<p>
Back to wireguard-quick, though. It turns out that the macOS version is particularly dodgy, since the bypass for the "we only have one routing table to work with" problem the devs went for is adding a more specific override route for the tunnel endpoint, which depends on parsing unchecked output of commands that print the routing table to determine the default gateway. For reasons I can't explain, this breaks when you create a custom network service as mentioned above, and it tries to set the default gateway to <span class="highlight-bg">link#32</span> or similar. This fails, and therefore the tunnel breaks, as tunnel traffic is then routed back through the tunnel in an infinite loop. After contacting the devs in the #wireguard channel on <a href="https://libera.chat" target="_blank">libera.chat</a>, my patch was accepted and this specific problem shouldn't occur anymore, though that doesn't change the bodge that is the route monitor code of wg-quick.
</p>
<p>
<h3>Epilogue</h3>
That concludes the network setup. Everything is running smoothly and thus far, no further bugs were found. I provide IPv6-tunnels for a few friends who haven't reported any problems either, so at least for now I think that this project is complete.
</p>
<p>
I have already removed IPv4 addresses from a few services I run, and I hope to do so for the entirety of my online presence by the end of 2021, maybe with a few exceptions for critical services used by friends from Austria where major telcos still don't support IPv6.
</p>
<p>
Maybe the end of IPv4 is actually near, at least in my small corner of the internet. Thanks for reading, and have a wonderful day.
</p>
</div>
<p style="color: #666666"><i>This request was served by <?php echo gethostname() ?> in <?php echo(round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"])*1000, 2)) ?> ms<i></p>
</div>
</body>
</html>

BIN
files/SmartHome.pdf Normal file

Binary file not shown.

BIN
files/StreamingCrypto.pdf Normal file

Binary file not shown.

2421
files/help.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2 MiB

111
index.php Normal file
View file

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="zotan.pw"/>
<meta name="twitter:description" content="Website of a queer software, systems, and network engineer."/>
<link rel="stylesheet" href="/style.css">
<title>zotan.pw</title>
</head>
<body>
<header>
<div class="container">
<h1><a href="/">zotan.pw</a></h1>
<?php if($_SERVER['HTTP_HOST'] === "zotan.pw" || $_SERVER['HTTP_HOST'] === "zotan.pw.dev"): ?>
<h2 style="margin-bottom: 0px;">Welcome internet user.</h2>
<small style="color:#aaa">An experimental http3 + v6o version of this page is available <a href="https://h3.zotan.pw">here</a>.</small>
<?php else: ?>
<h2 style="margin-bottom: 0px;">Welcome <?php echo($_SERVER['SERVER_PROTOCOL'])?> internet user.</h2>
<small style="color:#aaa">Too experimental? <a href="https://zotan.pw">Go back</a>.</small>
<?php endif; ?>
</div>
</header>
<div class="container">
<section id="main_content">
<h1 id="about">About me</h1>
<p>Hey there, I'm <span style="color: #D291BC;">Laura</span> (~<span style="color: #957DAD">zotan</span>, she/her), and I'm a queer, anarchist & antifascist network engineer, system administrator and software developer.</p>
<p>You can find me in hackerspaces across Germany, primarily in Berlin and Karlsruhe. <?php echo file_get_contents("travelynx.txt") ?></p>
<p>Here you can find my contact info, crypto keys, projects, and a few links.</p>
<?php if(strpos($_SERVER['REMOTE_ADDR'], ':') === false && $_SERVER['HTTP_HOST'] === "zotan.pw"): ?>
<p>Many of my services are IPv6-only, and more are soon to follow. Your browser preferred IPv4 while connecting to this website, so please <a href="https://ip6.biz" target="_blank">check your connection</a> for IPv6 support before contacting me if your browser displays a network error.</p>
<?php endif; ?>
<h2 id="contact">Contact</h1>
<p>You can contact me via the following services:</p>
<ul>
<li><strong>Telegram:</strong> <a href="https://t.me/zotan" target="_blank">@zotan</a></li>
<li><strong>Threema:&nbsp;</strong> <a href="https://threema.id/S59S9U8J" target="_blank">S59S9U8J</a></li>
<li><strong>Matrix:&nbsp;&nbsp;</strong> <a href="https://matrix.to/#/@zotan:161.rocks" target="_blank">@zotan:161.rocks</a></li>
<li><strong>Email:&nbsp;&nbsp;&nbsp;</strong> <a href="mailto:zotan@zotan.pw" target="_blank">zotan@zotan.pw</a> (for GPG see below)<br />
</li>
</ul>
<h2 id="social">Profiles</h2>
<ul>
<li><a href="/blog">Blog</a></li>
<li><a href="https://estrogen.network/@zotan" target="_blank">Fediverse</a></li>
<li><a href="https://chaos.stream/profile/zotan" target="_blank">Live streaming</a> (occasional gaming and photo editing streams)</li>
</ul>
<ul>
<li><a href="https://git.ztn.sh/zotan" target="_blank">Gitea</a></li>
<li><a href="https://github.com/zotanmew" target="_blank">GitHub</a></li>
</ul>
<h2 id="links">Network</h2>
<ul>
<li><a href="https://status.zotan.network" target="_blank">Network status</a></li>
<li><a href="https://status.zotan.services" target="_blank">Service status</a></li>
<li><a href="https://vnstat.zotan.services" target="_blank">Network load</a></li>
</ul>
<h2 id="photo">Photography</h2>
<ul>
<li><a href="https://zotan.photos" target="_blank">Portfolio</a> (my favourite shots)</li>
<li><a href="https://t.me/photolaura" target="_blank">Main photo channel</a> (all of my photos)</li>
<li><a href="https://t.me/photolaura_nofood" target="_blank">Secondary photo channel</a> (all of my photos that don't contain food)</li>
</ul>
<h2 id="projects-net">Projects - Networking</h2>
<ul>
<li><a href="https://zotan.network" target="_blank">AS211579</a> ~ zotan experimental networks</li>
</ul>
<h2 id="projects-web">Projects - Webservices</h2>
<ul>
<li><a href="https://chaos.stream" target="_blank">chaos.stream</a> - a chaos-community centric live streaming platform</li>
<li><a href="https://c3stream.de" target="_blank">c3stream.de</a> &nbsp;- a media.ccc.de mirror with added functionality</li>
<li><a href="https://ip6.biz" target="_blank">ip6.biz</a> &nbsp;&nbsp;&nbsp;&nbsp; - IPv6 (and IPv4) address info and connection test</li>
<br/>
<li><a href="https://git.ztn.sh" target="_blank">Gitea instance</a> (signups closed due to spam, <a href="#contact">contact me</a> if you want an account)</li>
<li><a href="https://pad.ztn.sh" target="_blank">Hedgedoc instance</a> (signups closed due to spam, see above)</li>
<li><a href="https://hc.ztn.sh" target="_blank">Healthchecks.io instance</a> (free, open signups)</li>
<li><a href="https://öv.ztn.sh" target="_blank">Öffisearch instance</a></li>
<li><a href="https://paste.zotan.services" target="_blank">PrivateBin instance</a></li>
<li><a href="https://t.zotan.services" target="_blank">Nitter instance</a></li>
<li><a href="https://meet.ztn.sh" target="_blank">Jitsi instance</a></li>
</ul>
<h2 id="projects-web">Projects - Software</h2>
<ul>
<li><a href="https://git.ztn.sh/zotan/nginx-mod-rtmp" target="_blank">nginx-mod-rtmp</a> - fork of the original with fixed bugs and added functionality</li>
<li><a href="https://git.ztn.sh/zotan/rtmpdash" target="_blank">RTMPdash</a> - the software powering <a href="https://chaos.stream">chaos.stream</a></li>
<li><a href="https://git.ztn.sh/zotan/ip6.biz" target="_blank">ip6.biz</a>&nbsp; - the source code for the IPv6 toolbox mentioned above</li>
<li><a href="https://git.ztn.sh/zotan/monithor" target="_blank">monithor</a> - alerting and status page generator for InfluxDB</li>
<li><a href="https://git.ztn.sh/zotan/webmusic" target="_blank">webmusic</a> - a simple web player for your music</li>
<li><a href="https://git.ztn.sh/zotan/bahnplan" target="_blank">bahnplan</a> - experimental DB Navigator replacement</li>
<li><a href="https://git.ztn.sh/zotan/repomgr" target="_blank">repomgr</a> &nbsp;- experimental AUR buildserver and repo manager</li>
<li><a href="https://git.ztn.sh/zotan/autotag" target="_blank">autotag</a> &nbsp;- experimental music tag normalizer</li>
</ul>
<h2 id="papers">Papers</h2>
<ul>
<li>2019 - Comparison of music streaming services encryption concepts <a href="/files/StreamingCrypto.pdf" target="_blank">Download</a></li>
<li>2020 - Programming a modular Smart-Home-System (prescientific paper) <a href="/files/SmartHome.pdf" target="_blank">Download</a></li>
</ul>
<h2 id="crypto">Crypto</h2>
<p>I use the following PGP keys:</p>
<ul>
<li><strong>Primary (ECC):</strong> F8A5 DAC0 0E43 5119 2089 42F9 D044 E84C 5BE0 1605 <a href="primary.gpg">Pubkey</a></li>
</ul>
</div>
<center>
Source code (commits are PGP-signed): <a href="https://git.ztn.sh/zotan/zotan.pw-web" target="_blank">Gitea</a>
<p style="color: #666666">----- This request was served by <?php echo gethostname() ?> in <?php echo(round((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"])*1000, 2)) ?> ms -----</p>
<img src="/files/help.svg" height=450rem title="Designed by someone I love, ~fr2">
</center>
</body>
</html>

38
primary.gpg Normal file
View file

@ -0,0 +1,38 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
EncJ1pW/NjYaSExm7R02mtcWM91dzBML
=RAbj
-----END PGP PUBLIC KEY BLOCK-----

333
style.css Normal file
View file

@ -0,0 +1,333 @@
/*
generated by rouge http://rouge.jneen.net/
original base16 by Chris Kempson (https://github.com/chriskempson/base16)
*/
.highlight table td {
padding: 5px; }
.highlight table pre {
margin: 0; }
.highlight, .highlight .w {
color: #d0d0d0; }
.highlight .err {
color: #151515;
background-color: #ac4142; }
.highlight .c, .highlight .cd, .highlight .cm, .highlight .c1, .highlight .cs {
color: #888; }
.highlight .cp {
color: #f4bf75; }
.highlight .nt {
color: #f4bf75; }
.highlight .o, .highlight .ow {
color: #d0d0d0; }
.highlight .p, .highlight .pi {
color: #d0d0d0; }
.highlight .gi {
color: #90a959; }
.highlight .gd {
color: #ac4142; }
.highlight .gh {
color: #6a9fb5;
font-weight: bold; }
.highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv {
color: #aa759f; }
.highlight .kc {
color: #d28445; }
.highlight .kt {
color: #d28445; }
.highlight .kd {
color: #d28445; }
.highlight .s, .highlight .sb, .highlight .sc, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 {
color: #90a959; }
.highlight .sr {
color: #75b5aa; }
.highlight .si {
color: #8f5536; }
.highlight .se {
color: #8f5536; }
.highlight .nn {
color: #f4bf75; }
.highlight .nc {
color: #f4bf75; }
.highlight .no {
color: #f4bf75; }
.highlight .na {
color: #6a9fb5; }
.highlight .m, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mb, .highlight .mx {
color: #90a959; }
.highlight .ss {
color: #90a959; }
body {
margin: 0;
padding: 0;
background: #151515 0 0;
color: #eaeaea;
font-size: 16px;
line-height: 1.5;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; }
/* General & 'Reset' Stuff */
.container {
width: 90%;
max-width: 800px;
margin: 0 auto; }
section {
display: block;
margin: 20px 0 0 0; }
h1, h2, h3, h4, h5, h6 {
margin: 20px 0 0 0; }
header h2 {
margin: 0 0 0 0 !important;
}
li {
line-height: 1.4; }
/* Header, <header>
header - container
h1 - project name
h2 - project description
*/
header {
background: rgba(0, 0, 0, 0.1);
width: 100%;
border-bottom: 1px dashed #b5e853;
padding: 20px 0;
margin: 0 0 40px 0; }
header h1 {
font-size: 30px;
line-height: 1.5;
margin: 0 0 0 -40px;
font-weight: bold;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
color: #b5e853;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(181, 232, 83, 0.1), 0 0 10px rgba(181, 232, 83, 0.1);
letter-spacing: -1px;
-webkit-font-smoothing: antialiased; }
header h1:before {
content: "./ ";
font-size: 24px; }
header h2 {
font-size: 18px;
font-weight: 300;
color: #666; }
#downloads .btn {
display: inline-block;
text-align: center;
margin: 0; }
#tor-url {
font-size: smaller; }
/* Main Content
*/
#main_content {
width: 100%;
-webkit-font-smoothing: antialiased; }
section img {
max-width: 100%; }
h1, h2, h3, h4, h5, h6 {
font-weight: normal;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
color: #b5e853;
letter-spacing: -0.03em;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(181, 232, 83, 0.1), 0 0 10px rgba(181, 232, 83, 0.1); }
#main_content h1 {
font-size: 30px; }
#main_content h2 {
font-size: 24px; }
#main_content h3 {
font-size: 18px; }
#main_content h4 {
font-size: 14px; }
#main_content h5 {
font-size: 12px;
text-transform: uppercase;
margin: 0 0 5px 0; }
#main_content h6 {
font-size: 12px;
text-transform: uppercase;
color: #999;
margin: 0 0 5px 0; }
dt {
font-style: italic;
font-weight: bold; }
ul, p {
margin-top: 5px;
}
ul li {
list-style: none; }
ul li:before {
content: ">>";
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
font-size: 13px;
color: #b5e853;
margin-left: -37px;
margin-right: 21px;
line-height: 16px; }
blockquote {
color: #aaa;
padding-left: 10px;
border-left: 1px dotted #666; }
pre {
background: rgba(0, 0, 0, 0.9);
border: 1px solid rgba(255, 255, 255, 0.15);
padding: 10px;
font-size: 16px;
color: #b5e853;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
text-wrap: normal;
overflow: auto;
overflow-y: hidden; }
table {
width: 100%;
margin: 0 0 20px 0; }
th {
text-align: left;
border-bottom: 1px dashed #b5e853;
padding: 5px 10px; }
td {
padding: 5px 10px; }
hr {
height: 0;
border: 0;
border-bottom: 1px dashed #b5e853;
color: #b5e853; }
/* Buttons
*/
.btn {
display: inline-block;
background: -webkit-linear-gradient(top, rgba(40, 40, 40, 0.3), rgba(35, 35, 35, 0.3) 50%, rgba(10, 10, 10, 0.3) 50%, rgba(0, 0, 0, 0.3));
padding: 8px 18px;
border-radius: 50px;
border: 2px solid rgba(0, 0, 0, 0.7);
border-bottom: 2px solid rgba(0, 0, 0, 0.7);
border-top: 2px solid black;
color: rgba(255, 255, 255, 0.8);
font-family: Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 13px;
text-decoration: none;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.75);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05); }
.btn:hover {
background: -webkit-linear-gradient(top, rgba(40, 40, 40, 0.6), rgba(35, 35, 35, 0.6) 50%, rgba(10, 10, 10, 0.8) 50%, rgba(0, 0, 0, 0.8)); }
.btn .icon {
display: inline-block;
width: 16px;
height: 16px;
margin: 1px 8px 0 0;
float: left; }
.btn-github .icon {
opacity: 0.6;
background: url("../images/blacktocat.png") 0 0 no-repeat; }
/* Links
a, a:hover, a:visited
*/
a {
color: #63c0f5;
text-shadow: 0 0 5px rgba(104, 182, 255, 0.5);
text-underline-offset: 1px;
}
/* Clearfix */
.cf:before, .cf:after {
content: "";
display: table; }
.cf:after {
clear: both; }
.cf {
zoom: 1; }
header h1 a {
text-decoration: none; }
/* Scrollbar colors */
/* Works on Firefox */
* {
scrollbar-width: thin;
scrollbar-color: grey #151515;
}
/* Works on Chrome, Edge, and Safari */
*::-webkit-scrollbar {
width: 6px;
}
*::-webkit-scrollbar-track {
background: #151515;
}
*::-webkit-scrollbar-thumb {
background-color: grey;
border-radius: 20px;
}
h1#post {
margin-top: 5px;
margin-bottom: 5px;
}
.highlight-bg {
background-color: #333;
padding: 1px 4px;
}

2
sync.sh Executable file
View file

@ -0,0 +1,2 @@
ssh destiny "bash -c 'cd /var/www/sites/zotan.pw && git pull'"
ssh atlantis "bash -c 'sudo nixos-rebuild switch --option tarball-ttl 0'"

69
travelynx.php Normal file
View file

@ -0,0 +1,69 @@
<?php
if (getBearerToken() !== trim(file_get_contents(".bearer_token"))) {
http_response_code(403);
die('Forbidden');
}
$rq = json_decode(file_get_contents('php://input'));
$output="Most recently, I was seen ";
if ($rq->status->checkedIn === true){
if (is_null($rq->status->toStation->name)) {
$output = $output . 'in <span style="color: #D291BC;">' . $rq->status->train->type . " " . $rq->status->train->no . "</span>.";
}
else {
$output = $output . 'in <span style="color: #D291BC;">' . $rq->status->train->type . " " . $rq->status->train->no . '</span> on the way to <span style="color: #b295cf">' . $rq->status->toStation->name . "</span>.";
}
}
else {
if (is_null($rq->status->toStation->name)) {
$output = $output . 'at <span style="color: #D291BC;">an unknon train station in Germany</span>.';
}
else {
$output = $output . 'at <span style="color: #b295cf;">' . $rq->status->toStation->name . "</span>.";
}
}
atomic_put_contents("travelynx.txt", $output);
echo ($output);
function atomic_put_contents($filename, $data)
{
// Copied largely from http://php.net/manual/en/function.flock.php
$fp = fopen($filename, "w+");
if (flock($fp, LOCK_EX)) {
fwrite($fp, $data);
flock($fp, LOCK_UN);
}
fclose($fp);
}
function getAuthorizationHeader(){
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER["Authorization"]);
}
else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
} elseif (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
// Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
//print_r($requestHeaders);
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
return $headers;
}
function getBearerToken() {
$headers = getAuthorizationHeader();
// HEADER: Get the access token from the header
if (!empty($headers)) {
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
return $matches[1];
}
}
return null;
}