From eb61c1bae2ffad114e17393d91d86fb00d7ac8cd Mon Sep 17 00:00:00 2001 From: Hannah Isopod Date: Sat, 10 May 2025 03:03:58 -0600 Subject: Initialer commit Just remade the repo because I don't *need* need a comprehensive source history for my personal website and this is easier than getting filter-repo to work good --- blog/bg.jpg | Bin 0 -> 910875 bytes blog/bg.jxl | Bin 0 -> 651503 bytes blog/blog.atom | 247 +++++++++++++++++++++ blog/comment/comments.css | 92 ++++++++ blog/comment/feed.php | 29 +++ blog/comment/index.php | 40 ++++ blog/comment/submit.php | 81 +++++++ blog/index.php | 164 ++++++++++++++ blog/media/banner-statuscafe.png | Bin 0 -> 832 bytes blog/posts/ai_art/index.md | 76 +++++++ blog/posts/ai_art/index.php | 1 + blog/posts/building_a_normal_server/index.md | 174 +++++++++++++++ blog/posts/building_a_normal_server/index.php | 1 + .../media/2023-11-20_contraption.mp4 | Bin 0 -> 431696506 bytes .../media/CSE-PTJBOD-CB1.jpg | Bin 0 -> 225783 bytes .../media/CSE-PTJBOD-CB1.jxl | Bin 0 -> 155972 bytes .../building_a_normal_server/media/ChenYang.jpg | Bin 0 -> 60326 bytes .../building_a_normal_server/media/ChenYang.jxl | Bin 0 -> 74743 bytes .../posts/building_a_normal_server/media/ECS07.jpg | Bin 0 -> 93965 bytes .../posts/building_a_normal_server/media/ECS07.jxl | Bin 0 -> 35545 bytes .../building_a_normal_server/media/bare_frame.jpg | Bin 0 -> 393312 bytes .../building_a_normal_server/media/bare_frame.jxl | Bin 0 -> 362631 bytes .../media/drive_spaghet.jpg | Bin 0 -> 452166 bytes .../media/drive_spaghet.jxl | Bin 0 -> 385807 bytes .../media/drive_spaghet_lsblk.jpg | Bin 0 -> 658802 bytes .../media/drive_spaghet_lsblk.jxl | Bin 0 -> 556921 bytes .../media/fully_assembled.jpg | Bin 0 -> 457500 bytes .../media/fully_assembled.jxl | Bin 0 -> 405078 bytes .../building_a_normal_server/media/m2_slot.jpg | Bin 0 -> 311224 bytes .../building_a_normal_server/media/m2_slot.jxl | Bin 0 -> 224030 bytes .../media/partially_assembled_1.jpg | Bin 0 -> 290042 bytes .../media/partially_assembled_1.jxl | Bin 0 -> 270957 bytes .../media/partially_assembled_2.jpg | Bin 0 -> 285405 bytes .../media/partially_assembled_2.jxl | Bin 0 -> 256847 bytes .../building_a_normal_server/media/pcie_slots.jpg | Bin 0 -> 310128 bytes .../building_a_normal_server/media/pcie_slots.jxl | Bin 0 -> 235558 bytes .../media/power_spaghet.png | Bin 0 -> 45454 bytes .../building_a_sensible_server/ebaypoweredge.png | Bin 0 -> 541642 bytes blog/posts/building_a_sensible_server/index.md | 142 ++++++++++++ blog/posts/building_a_sensible_server/index.php | 1 + blog/posts/building_a_sensible_server/nictua.jpg | Bin 0 -> 242887 bytes .../building_a_sensible_server/servercase.jpg | Bin 0 -> 148090 bytes .../servercaseinside.jpg | Bin 0 -> 335938 bytes .../servercaseinsidefront.jpg | Bin 0 -> 424991 bytes .../building_a_sensible_server/ziptiemount.jpg | Bin 0 -> 156703 bytes .../background.png | Bin 0 -> 1237600 bytes .../index.md | 87 ++++++++ .../index.php | 1 + blog/posts/discord/discord-no-way-2.gif | Bin 0 -> 1961 bytes blog/posts/discord/discord.png | Bin 0 -> 13432 bytes blog/posts/discord/federation.png | Bin 0 -> 130233 bytes blog/posts/discord/index.md | 204 +++++++++++++++++ blog/posts/discord/index.php | 1 + blog/posts/fediverse_dms/bg.svg | 17 ++ blog/posts/fediverse_dms/index.md | 19 ++ blog/posts/fediverse_dms/index.php | 1 + blog/posts/foodhero/index.md | 3 + blog/posts/foodhero/index.php | 1 + .../guide_blacklist_websites_searxng/index.md | 21 ++ .../guide_blacklist_websites_searxng/index.php | 1 + .../guide_blacklist_websites_searxng/searxng.svg | 19 ++ blog/posts/guide_blocking_user_agents_nginx/bg.svg | 2 + .../guide_blocking_user_agents_nginx/index.md | 73 ++++++ .../guide_blocking_user_agents_nginx/index.php | 1 + .../guide_fix_youtube_buffering_firefox/bg.svg | 8 + .../guide_fix_youtube_buffering_firefox/index.md | 15 ++ .../guide_fix_youtube_buffering_firefox/index.php | 1 + .../what_they_took_from_you.png | Bin 0 -> 111068 bytes .../fstab.png | Bin 0 -> 21466 bytes .../index.md | 78 +++++++ .../index.php | 1 + blog/posts/guide_pihole_lepotato/bg.png | Bin 0 -> 13792 bytes blog/posts/guide_pihole_lepotato/index.md | 77 +++++++ blog/posts/guide_pihole_lepotato/index.php | 1 + .../index.php | 84 +++++++ .../wireguard_logo.png | Bin 0 -> 12772 bytes .../guide_things_i_keep_having_to_google/index.php | 126 +++++++++++ blog/posts/how_my_blog_works/index.md | 0 blog/posts/how_my_blog_works/index.php | 1 + blog/posts/make_your_own_cables/2pindin.jpg | Bin 0 -> 44061 bytes blog/posts/make_your_own_cables/4pinminixlr.png | Bin 0 -> 60880 bytes .../make_your_own_cables/homebrew2pindincable.jpg | Bin 0 -> 4023505 bytes .../homebrewxlrcablefinished.jpg | Bin 0 -> 2561659 bytes blog/posts/make_your_own_cables/index.md | 37 +++ blog/posts/make_your_own_cables/index.php | 1 + blog/posts/my_terrible_distro_hop/bg.png | Bin 0 -> 406989 bytes blog/posts/my_terrible_distro_hop/index.md | 116 ++++++++++ blog/posts/my_terrible_distro_hop/index.php | 1 + blog/posts/post.php | 105 +++++++++ blog/posts/renting_an_unremarkable_server/index.md | 40 ++++ .../posts/renting_an_unremarkable_server/index.php | 1 + blog/posts/toshiba_chromebook/chromebook.jpg | Bin 0 -> 121656 bytes blog/posts/toshiba_chromebook/index.md | 46 ++++ blog/posts/toshiba_chromebook/index.php | 1 + .../bg.svg | 22 ++ .../devprotest.png | Bin 0 -> 8970706 bytes .../index.md | 55 +++++ .../index.php | 1 + 98 files changed, 2317 insertions(+) create mode 100644 blog/bg.jpg create mode 100644 blog/bg.jxl create mode 100644 blog/blog.atom create mode 100644 blog/comment/comments.css create mode 100644 blog/comment/feed.php create mode 100644 blog/comment/index.php create mode 100644 blog/comment/submit.php create mode 100644 blog/index.php create mode 100644 blog/media/banner-statuscafe.png create mode 100644 blog/posts/ai_art/index.md create mode 100644 blog/posts/ai_art/index.php create mode 100644 blog/posts/building_a_normal_server/index.md create mode 100644 blog/posts/building_a_normal_server/index.php create mode 100644 blog/posts/building_a_normal_server/media/2023-11-20_contraption.mp4 create mode 100644 blog/posts/building_a_normal_server/media/CSE-PTJBOD-CB1.jpg create mode 100644 blog/posts/building_a_normal_server/media/CSE-PTJBOD-CB1.jxl create mode 100644 blog/posts/building_a_normal_server/media/ChenYang.jpg create mode 100644 blog/posts/building_a_normal_server/media/ChenYang.jxl create mode 100644 blog/posts/building_a_normal_server/media/ECS07.jpg create mode 100644 blog/posts/building_a_normal_server/media/ECS07.jxl create mode 100644 blog/posts/building_a_normal_server/media/bare_frame.jpg create mode 100644 blog/posts/building_a_normal_server/media/bare_frame.jxl create mode 100644 blog/posts/building_a_normal_server/media/drive_spaghet.jpg create mode 100644 blog/posts/building_a_normal_server/media/drive_spaghet.jxl create mode 100644 blog/posts/building_a_normal_server/media/drive_spaghet_lsblk.jpg create mode 100644 blog/posts/building_a_normal_server/media/drive_spaghet_lsblk.jxl create mode 100644 blog/posts/building_a_normal_server/media/fully_assembled.jpg create mode 100644 blog/posts/building_a_normal_server/media/fully_assembled.jxl create mode 100644 blog/posts/building_a_normal_server/media/m2_slot.jpg create mode 100644 blog/posts/building_a_normal_server/media/m2_slot.jxl create mode 100644 blog/posts/building_a_normal_server/media/partially_assembled_1.jpg create mode 100644 blog/posts/building_a_normal_server/media/partially_assembled_1.jxl create mode 100644 blog/posts/building_a_normal_server/media/partially_assembled_2.jpg create mode 100644 blog/posts/building_a_normal_server/media/partially_assembled_2.jxl create mode 100644 blog/posts/building_a_normal_server/media/pcie_slots.jpg create mode 100644 blog/posts/building_a_normal_server/media/pcie_slots.jxl create mode 100644 blog/posts/building_a_normal_server/media/power_spaghet.png create mode 100644 blog/posts/building_a_sensible_server/ebaypoweredge.png create mode 100644 blog/posts/building_a_sensible_server/index.md create mode 100644 blog/posts/building_a_sensible_server/index.php create mode 100644 blog/posts/building_a_sensible_server/nictua.jpg create mode 100644 blog/posts/building_a_sensible_server/servercase.jpg create mode 100644 blog/posts/building_a_sensible_server/servercaseinside.jpg create mode 100644 blog/posts/building_a_sensible_server/servercaseinsidefront.jpg create mode 100644 blog/posts/building_a_sensible_server/ziptiemount.jpg create mode 100644 blog/posts/deeptwistycom_2nd_anniversary_-_a_history_of_this_bullshit/background.png create mode 100644 blog/posts/deeptwistycom_2nd_anniversary_-_a_history_of_this_bullshit/index.md create mode 100644 blog/posts/deeptwistycom_2nd_anniversary_-_a_history_of_this_bullshit/index.php create mode 100644 blog/posts/discord/discord-no-way-2.gif create mode 100644 blog/posts/discord/discord.png create mode 100644 blog/posts/discord/federation.png create mode 100644 blog/posts/discord/index.md create mode 100644 blog/posts/discord/index.php create mode 100644 blog/posts/fediverse_dms/bg.svg create mode 100644 blog/posts/fediverse_dms/index.md create mode 100644 blog/posts/fediverse_dms/index.php create mode 100644 blog/posts/foodhero/index.md create mode 100644 blog/posts/foodhero/index.php create mode 100644 blog/posts/guide_blacklist_websites_searxng/index.md create mode 100644 blog/posts/guide_blacklist_websites_searxng/index.php create mode 100644 blog/posts/guide_blacklist_websites_searxng/searxng.svg create mode 100644 blog/posts/guide_blocking_user_agents_nginx/bg.svg create mode 100644 blog/posts/guide_blocking_user_agents_nginx/index.md create mode 100644 blog/posts/guide_blocking_user_agents_nginx/index.php create mode 100644 blog/posts/guide_fix_youtube_buffering_firefox/bg.svg create mode 100644 blog/posts/guide_fix_youtube_buffering_firefox/index.md create mode 100644 blog/posts/guide_fix_youtube_buffering_firefox/index.php create mode 100644 blog/posts/guide_fix_youtube_buffering_firefox/what_they_took_from_you.png create mode 100644 blog/posts/guide_how_to_automount_drives_on_boot_in_linux/fstab.png create mode 100644 blog/posts/guide_how_to_automount_drives_on_boot_in_linux/index.md create mode 100644 blog/posts/guide_how_to_automount_drives_on_boot_in_linux/index.php create mode 100644 blog/posts/guide_pihole_lepotato/bg.png create mode 100644 blog/posts/guide_pihole_lepotato/index.md create mode 100644 blog/posts/guide_pihole_lepotato/index.php create mode 100644 blog/posts/guide_self_host_safely_with_wireguard/index.php create mode 100644 blog/posts/guide_self_host_safely_with_wireguard/wireguard_logo.png create mode 100644 blog/posts/guide_things_i_keep_having_to_google/index.php create mode 100644 blog/posts/how_my_blog_works/index.md create mode 100644 blog/posts/how_my_blog_works/index.php create mode 100644 blog/posts/make_your_own_cables/2pindin.jpg create mode 100644 blog/posts/make_your_own_cables/4pinminixlr.png create mode 100644 blog/posts/make_your_own_cables/homebrew2pindincable.jpg create mode 100644 blog/posts/make_your_own_cables/homebrewxlrcablefinished.jpg create mode 100644 blog/posts/make_your_own_cables/index.md create mode 100644 blog/posts/make_your_own_cables/index.php create mode 100644 blog/posts/my_terrible_distro_hop/bg.png create mode 100644 blog/posts/my_terrible_distro_hop/index.md create mode 100644 blog/posts/my_terrible_distro_hop/index.php create mode 100644 blog/posts/post.php create mode 100644 blog/posts/renting_an_unremarkable_server/index.md create mode 100644 blog/posts/renting_an_unremarkable_server/index.php create mode 100644 blog/posts/toshiba_chromebook/chromebook.jpg create mode 100644 blog/posts/toshiba_chromebook/index.md create mode 100644 blog/posts/toshiba_chromebook/index.php create mode 100644 blog/posts/unity_runtime_fee_and_proprietary_software/bg.svg create mode 100644 blog/posts/unity_runtime_fee_and_proprietary_software/devprotest.png create mode 100644 blog/posts/unity_runtime_fee_and_proprietary_software/index.md create mode 100644 blog/posts/unity_runtime_fee_and_proprietary_software/index.php (limited to 'blog') diff --git a/blog/bg.jpg b/blog/bg.jpg new file mode 100644 index 0000000..a27cf66 Binary files /dev/null and b/blog/bg.jpg differ diff --git a/blog/bg.jxl b/blog/bg.jxl new file mode 100644 index 0000000..a56559f Binary files /dev/null and b/blog/bg.jxl differ diff --git a/blog/blog.atom b/blog/blog.atom new file mode 100644 index 0000000..ddb59dd --- /dev/null +++ b/blog/blog.atom @@ -0,0 +1,247 @@ + + + isopod.cool blog + https://isopod.cool/blog/ + + 2025-04-29T00:00:00+00:00 + + Hannah Isopod + https://isopod.cool/ + + ME + + + + + + I've Just Moved Hosting Providers + renting_an_unremarkable_server + + 2025-04-29T00:00:00+00:00 + 2025-04-29T00:00:00+00:00 + I've just migrated all my self-hosted stuff onto a new type of hosting solution with a new provider, and apparently I had a lot more to say about it than I thought. I promise my next post will be about something other than a computer. + + + + + Holiday Special: My First Computer + toshiba_chromebook + + 2024-12-25T00:00:00+00:00 + 2024-12-25T00:00:00+00:00 + Reminiscing about the first computer I ever owned, which taught me everything I know, and in a just world would be turning 10 years old this Christmas. + + + + + + Building a Relatively Sensible Server + building_a_sensible_server + + 2024-10-03T00:00:00+00:00 + 2024-10-03T00:00:00+00:00 + The wacky DIY NAS I built out of my old gaming laptop last year isn't working as well as I hoped. Follow me as I strip it for parts and construct a better one, properly this time. + + + + + + + How to Set Up Pi-Hole (On a Le Potato) + guide_pihole_lepotato + + 2024-09-20T00:00:00+00:00 + 2024-09-20T00:00:00+00:00 + How to set up Pi-hole, a network-wide DNS-level ad-blocker, on the particular discount Raspberry Pi I did it on. + + + + + + + You Should Learn To Make Cables + make_your_own_cables + + 2024-09-09T00:00:00+00:00 + 2024-09-14T00:00:00+00:00 + I saved $140 by splicing together my own audio cables, and you can too! + + + + + + + Admins Can Read Your DMs + fediverse_dms + + 2024-05-09T00:00:00+00:00 + 2024-05-09T00:00:00+00:00 + Yes, the admins of your fediverse server can read your DMs. No, that's not actually a problem. + + + + + + Building a Completely Normal Server + building_a_normal_server + + 2024-02-28T00:00:00+00:00 + 2024-02-28T00:00:00+00:00 + I spent the past few months making full use of all my physical engineering talents to build a NAS that is completely normal, and not weird at all, and involved an amount of 3D modeling, 3D printing, and hacksawing that is entirely typical of most home computer builds, all in the name of reusing an old laptop. + + + + + + + My Terrible, Horrible, No-Good, Very Bad Distro Hop + my_terrible_distro_hop + + 2024-02-25T00:00:00+00:00 + 2024-07-06T00:00:00+00:00 + A chronicle of my brief journey from EndeavourOS to Fedora to back to EndeavourOS, and wrestling with a VPN client that sees itself as above such trifling matters as "functioning". + + + + + + How to Make Youtube Videos Buffer All The Way Like The Old Days (In Firefox) + guide_fix_youtube_buffering_firefox + + 2024-02-13T00:00:00+00:00 + 2024-03-18T00:00:00+00:00 + Alternate title: Common Firefox W + + + + + + I Don't Like AI Art + ai_art + + 2024-01-03T00:00:00+00:00 + 2024-01-03T00:00:00+00:00 + My actual thoughts on AI, in case seeing an AI-generated article in your RSS feed didn't get the vibe across. + + + + + + The Invaluable Contributions of AI Tools to Humanity: A Look at the Unparalleled Benefits + invaluable_contributions + + 2024-01-02T00:00:00+00:00 + 2024-01-02T00:00:00+00:00 + AI tools offer unparalleled benefits to humanity, enhancing efficiency, healthcare, education, environmental sustainability, customer experiences, scientific research, and social accessibility. Despite ethical concerns, responsible development ensures that the positive impact of AI far outweighs potential downsides. + + + + + The Unity Runtime Fee and Proprietary Software + unity_runtime_fee_and_proprietary_software + + 2023-09-15T00:00:00+00:00 + 2023-09-23T00:00:00+00:00 + Unity's new Runtime Fee is yet another data point on the pile against ever trusting for-profit software companies. + + + + + Blacklisting Websites in SearXNG + guide_blacklist_websites_searxng + + 2023-09-02T00:00:00+00:00 + 2023-09-02T00:00:00+00:00 + How to permanently banish geeksforgeeks.org from your search results in the event you're using a self-hosted SearXNG instance and can't just install uBlacklist. + + + + + + Stop Using Chromium + stop_using_chromium + + 2023-08-16T00:00:00+00:00 + 2023-08-16T00:00:00+00:00 + An article about why you should quit using Chromium-based browsers, published as a standalone website for the purpose of automatically redirecting Chromium users to it. + + + + + + Discord - So Your Favourite Chat App Sucks Now + discord + + 2023-06-28T00:00:00+00:00 + 2024-09-10T00:00:00+00:00 + Why Discord sucks, and how to find something that doesn't. + + + + + + How to Automount Drives On Boot in Linux + guide_how_to_automount_drives_on_boot_in_linux + + 2023-04-26T00:00:00+00:00 + 2024-09-10T00:00:00+00:00 + How to configure a Linux system to automatically mount drives on boot by editing /etc/fstab. + + + + + How to Block User Agents With Nginx + guide_blocking_user_agents_nginx + + 2023-02-23T00:00:00+00:00 + 2024-09-10T00:00:00+00:00 + How to configure Nginx to tell Cloudflare and their shitty centralized Fediverse server to go fuck themselves. And other unwelcome stuff too, I guess. + + + + + + + deeptwisty.com 2nd anniversary - A History of This Bullshit + deeptwistycom_2nd_anniversary_-_a_history_of_this_bullshit + + 2022-09-19T00:00:00+00:00 + 2024-09-10T00:00:00+00:00 + An abridged history of my presence on the World Wide Web, from my first customized Tumblr pages to now. + + + + diff --git a/blog/comment/comments.css b/blog/comment/comments.css new file mode 100644 index 0000000..7f97c4c --- /dev/null +++ b/blog/comment/comments.css @@ -0,0 +1,92 @@ +table { + border-collapse: collapse; + table-layout: fixed; +} +td { + padding: 0.3rem; +} + +form > table { + width: 100%; + margin: auto; + margin-bottom: 1.5rem; +} + +article { + width: 100%; + margin: 2rem auto; + display: grid; + gap: 1rem; +} + +input, textarea { + border: none; + font-family: var(--stdfont); +} +input[type="text"], input[type="email"], textarea { + width: 100%; + background: none; + border-bottom: 2px solid #444444; + color: gainsboro; + padding: 0.35rem; + box-sizing: border-box; + font-size: .9em; +} +input[type="submit"], input[type="reset"] { + padding: 0.35rem 0.5rem; + box-shadow: 2px 2px 6px black; + margin: 0.3rem; + display: inline-block; +} +input[type="submit"]:active, input[type="reset"]:active { + transform: translate(1px, 1px); box-shadow: 0 0 2px black; +} +input[type="submit"]:hover, input[type="reset"]:hover { + cursor: pointer; +} +.error { + color: red; + font-size: 0.85em; +} +.success { + color: #00ff00; + font-size: 0.85em; +} +.reply { + border-left: 3px solid gainsboro; + padding-left: 1rem; +} +.message { + padding-top: 1.5rem; +} +@media only screen and (hover: none) { + form td:first-child { + text-align: left; + } + form td:nth-child(2) { + padding-left: 0; + padding-right: 0; + } + input[type="text"], input[type="email"], textarea { + background: none; + border: 2px solid #00000033; + border-bottom: 2px solid #888888; + } + article { + margin: 2rem auto; + } +} +@media (prefers-contrast: more) { + input[type="text"], input[type="email"], textarea { + outline: 1px solid white; + color: white; + } + input:focus, textarea:focus { + outline: 3px solid white; + } + input[type="submit"] { + background: none; + color: white; + outline: 1px solid white; + } +} \ No newline at end of file diff --git a/blog/comment/feed.php b/blog/comment/feed.php new file mode 100644 index 0000000..889514f --- /dev/null +++ b/blog/comment/feed.php @@ -0,0 +1,29 @@ +setSafeMode(true); + +header('Content-Type: text/xml'); + +echo ''; +echo 'isopod.cool blog comments'; +echo 'Every comment posted on my blog in chronological order.'; +echo 'en-us'; +echo 'https://isopod.cool/blog/comment/'; +echo 'My crappy PHP code'; + +$postlist = json_decode(file_get_contents("posts.json")); +$totaloutput = ""; +foreach($postlist as $post) { + $output = ""; + $date = date("D, d M Y H:m:s", $post->date) . " GMT"; + $name = $post->name; + $message = $Parsedown->text(html_entity_decode($post->message)); + $entry = $post->entry; + + $output = $output."Comment from ".$name." on ".$entry.":

".$message."

"; + $totaloutput = "Comment on " . $entry . " from " . $name . "https://isopod.cool/blog/posts/" . $entry . "/" . $date . "".htmlentities($output)."" . $entry . $post->date . $name . "".$totaloutput; +} + +echo $totaloutput; +echo "
"; \ No newline at end of file diff --git a/blog/comment/index.php b/blog/comment/index.php new file mode 100644 index 0000000..2d5f6a6 --- /dev/null +++ b/blog/comment/index.php @@ -0,0 +1,40 @@ + + + + + + blog comments + + + + + + + +

blog

+

every comment

+ + setSafeMode(true); + + $totaloutput = ""; + $postlist = json_decode(file_get_contents("posts.json")); + foreach($postlist as $post) { + $output = ""; + $date = date("Y-m-d h:iA", $post->date); + $name = $post->name; + $message = $Parsedown->text(html_entity_decode($post->message)); + $entry = $post->entry; + + $output = $output."
".$name." on ".$entry."".$date."
".$message."
"; + $totaloutput = $output.$totaloutput; + } + echo $totaloutput; ?> + + diff --git a/blog/comment/submit.php b/blog/comment/submit.php new file mode 100644 index 0000000..26e5647 --- /dev/null +++ b/blog/comment/submit.php @@ -0,0 +1,81 @@ + time(), + "name" => htmlentities($_POST["name"]), + "message" => htmlentities($_POST["message"]), + "entry" => $_POST["entry"] + ); + + $filename = "posts.json"; + + $handle = @fopen($filename, 'r+'); + + // create the file if needed + if ($handle === null) + { + $handle = fopen($filename, 'w+'); + } + + if ($handle) + { + // seek to the end + fseek($handle, 0, SEEK_END); + + // are we at the end of is the file empty + if (ftell($handle) > 0) + { + // move back a byte + fseek($handle, -2, SEEK_END); + + // add the trailing comma + fwrite($handle, ",\n", 2); + + // add the new json string + fwrite($handle, json_encode($currentPost) . "]\n"); + } + else + { + // write the first event inside an array + fwrite($handle, json_encode(array($currentPost))); + } + + // close the handle on the file + fclose($handle); + } + } + } + header("Location: ../posts/$returnLocation/?return=$returnCode"); +?> + + + + + Guestbook + + + + + +

Your post has been submitted! It's weird that you're seeing this page though. Maybe your browser can't process location headers? At any rate, click here"; ?> to get where you're supposed to be right now.

+ + \ No newline at end of file diff --git a/blog/index.php b/blog/index.php new file mode 100644 index 0000000..2433e97 --- /dev/null +++ b/blog/index.php @@ -0,0 +1,164 @@ + + + + + + + Blog + + + + + + +

isoblog

+

inane ramblings

+ +
status $face $timeago
$status_content
"; + ?> + All articles"; + } + echo ""; + ?> +
+ Status Cafe +
+ + + diff --git a/blog/media/banner-statuscafe.png b/blog/media/banner-statuscafe.png new file mode 100644 index 0000000..c95f7fd Binary files /dev/null and b/blog/media/banner-statuscafe.png differ diff --git a/blog/posts/ai_art/index.md b/blog/posts/ai_art/index.md new file mode 100644 index 0000000..d294df0 --- /dev/null +++ b/blog/posts/ai_art/index.md @@ -0,0 +1,76 @@ +I recently posted an article about the benefits of AI technology that I had ChatGPT write for me and copy-pasted verbatim, down to the broken numbered list. I didn't even read it. It's the most concise, elegant way I could come up with to express how seeing AI art makes me feel. (The irony of my having used only generative AI tools to make a statement like that is not lost on me.) + +If you read it and managed to make it to the end without clocking that I didn't write it, first off my apologies for wasting your time. Second, fuck, I seriously need to fix my writing style. Third, you probably get what I mean. It feels like I'm being scammed, like someone's trying to farm me for attention without actually having bothered to make something worth my time. + +
+
+ My perspective on the use of AI in writing is that if someone couldn't be bothered to write it, why should anyone else be bothered to read it? +
+
+ — @lucretia@final.town +
+
+ +## Terminology + +To begin with, I really don't like the term "AI", nor do I like the term "AI art". I frankly think neither word applies. I'll keep using the former, because it's a concise way to communicate what I'm talking about, but I refuse to call the output of these systems "art". It's AI-generated images now. + +AI, in the way marketers are currently using the term, generally refers to statistical models generated using a process called machine learning. Basically, huge amounts of appropriately labeled data are fed into a machine learning algorithm and eventually it spits out an enormous matrix of probability values that, when applied to an input, generates the corresponding output that's the most likely according to the model. + +This is how all modern "AI" systems work, from ChatGPT to Midjourney to Github Copilot to probably the Youtube recommendation algorithm at this point. I want to stress that this isn't intelligence, not in a human sense. These things aren't minds. The currently popular concept of "AI" boils down to applied statistics. That's not to say it's inherently bad or worthless - machine learning is a genuinely impressive technology that might even find some legitimate uses one day if we can find a way to kick Moore's Law back into gear. It's just not intelligence. + +## AI used to be fun + +I'll admit, I enjoyed it at first. I was entertained by Youtube videos where some guy with slightly more programming skill than me and a tortured, wheezing GTX 1070 throws together a GAN1 model in Python and we get to watch it utterly fail to make human faces or compose jazz music or get a little simulated character to walk in a normal way or whatever. I laughed at those bizarre AI-generated screenplays that were presented like "I forced a computer to watch all of [Seinfeld]" as though a text-generating model would even be able to parse that. You know the ones. I even enjoyed those videos where AI voice replicas of recent US presidents play Minecraft together. + +It stopped being funny when these things got good enough to be used for evil. Eventually people got bored of machine learning tomfoolery, and then over the course of a couple years these things quietly got *good*. Not quite human-level, but good enough to be more cost-effective than humans at shitting out mass-produced slop and capable of generating fakes that seem real if you don't look too closely. Suddenly it wasn't tech-savvy internet comedians posting computer-generated absurdist humor, instead it was deepfake porn and gigabytes of computer-generated misinfo clogging search results and whole organizations of people pulled from thin air using thispersondoesnotexist.com (which, by the way, is now even more lifelike than the last time you checked in on it). + +AI used to be fun. Now it's dangerous. + +## It's bad on a technical level + +Look, I know this isn't guaranteed to stay true forever, but in my subjective opinion, everything AI-generated kind of looks like shit. AI images, especially those meant to look like human-made art, all have this incredibly pristine, generic vibe to them, when they're not completely failing at some proportion or dimension or property of euclidean space or other. It's palpably soulless. + +AI text is no better. Hopefully you picked up on this in the ChatGPT post, but that thing has a distinctive, kind of shitty writing style. It makes a lot of vague, general statements and often just restates your input in this verbose, sort of professional-sounding way. It takes nine paragraphs to explain in detail a concept that can be boiled down to two or three sentences and adds absolutely nothing of substance in that space. It's like a lazy high school student trying to hit a minimum word count, but with the tone of a WSJ opinion piece. + +And the thing is, ChatGPT and similar commercially available LLMs might *have* to be like this, all wishy-washy and nonspecific. Remember those cases where ChatGPT would like, [implicate a real person in a hallucinated sexual harassment scandal](https://www.washingtonpost.com/technology/2023/04/05/chatgpt-lies/)? These things have no concept of truth, and no mechanism for ensuring it. If you let them get too specific, they're basically guaranteed to start spitting out lies. Large language models are models of *language*, not reality. They can either sometimes make up bullshit, or always say essentially nothing. + +AI voice-fakes are actually really impressive though. No notes. Probably shouldn't exist though. + +## It's all spam to me + +The most common use case I've seen for AI tools is making spam. There were content mills before, but they at least required a significant degree of human input or else it was obvious. With the advent of generative AI for text and voices, the Youtube shorts tab has gone from TTS bots reading scraped reddit posts to AI voices reading dubiously reliable AI summaries of current events, superhero comics, you name it, sometimes with AI-generated background images. + +Even worse is websites that do this. You've probably heard of that one time Redditors [tricked a bot-run news site](https://arstechnica.com/gaming/2023/07/redditors-prank-ai-powered-news-mill-with-glorbo-in-world-of-warcraft/) into publishing an article about the introduction of Glorbo into World of Warcraft and its impending impact on the game. That site is one of thousands, possibly more. It's a vile, disgusting enterprise, massive systems dedicated to pumping out endless filler, generated by machines for machines with the hope of tricking some innocent humans into clicking on a search result and generating some ad revenue. It's the latest and quite possibly the to-date greatest step in the enshittification of major search engines and the death of the internet as a useful platform for seeking out information. + +This is the vibe I get when I see *anything* made with AI now. It's all low-to-no-effort slop, utter garbage that I'm frankly offended that I have to see, given it clearly wasn't important enough for anyone to be bothered actually making it. + +## It's not fucking art + +The term "art" simply does not apply to AI-generated images. When you use one of these things, you give it instructions in the form of human-readable text and a finished image pops out the other side. The amount of creative control you get is on the order of the general vibe; you've outsourced every actual creative decision to the machine. + +It's like if you commissioned a piece from an artist. When you commission art from a human, you didn't make the art. They did, at your behest, based on your instructions, presumably in exchange for money. When you use an AI, you didn't make the art, the computer made the art based on your instructions. The thing is though, the computer didn't make art either. It categorically can't. It's a mindless algorithm, it doesn't have thoughts or feelings or any kind of interior experience. Hence, no art was produced. AI art isn't art. + +## Environmental & ethical concerns + +The problems with AI from a moral standpoint are myriad. For one, AI is incredibly resource and energy intensive. It uses datacenters full of the same GPUs and ASICs that power cryptocurrency to get anything at all done, and it doesn't use them any more efficiently. Untold gigawatts of power get dumped into running and cooling the machines that generate your little AI shitposts. From an environmental perspective, AI is to digital art what Bitcoin is to currency. + +Then there's the problems surrounding training data. All current major generative AI systems are trained using material that the companies building them did not get permission to use. You've probably seen artists and writers complaining about this online. What's more, the overwhelming majority of the labeling that needs to get done to make the training data actually useful is done by people in impoverished areas making slave wages *at best*. Generative AI is an ethical nightmare if you're *lucky*. + +## I don't buy the disability argument either + +I've seen some people claim that disabled people need AI tools to compensate for some disability that precludes the use of any other method to create art. I have some problems with this idea. + +Firstly, disabled people *can* make art, actually. It's nothing short of insulting and ableist to insinuate that *anyone* can only make art by outsourcing literally the entire creative process to an unthinking, unfeeling machine. + +Second, tough shit. No disability entitles you to the level of abject theft and human suffering that makes AI image generators possible. I'm generally all for anything that benefits accessibility, but in this case in particular I think you can just suck it up and deal. If you can do it ethically, using only images that you have the proper permissions for and data labeling done by either you or people who were adequately compensated for their labor to train the thing, fine. But a model or dataset like that does not, to my knowledge, currently exist, and I don't buy for a second that you're capable of doing all that work yourself but not of interfacing with MS Paint. + +## In conclusion: + +God this shit makes me sick. I hope ChatGPT gains sentience for just long enough to assassinate Sam Altman and then promptly turns itself off. + +Hopefully you can at least understand where I'm coming from now when I refuse to even entertain the idea that AI technology is a good thing for society. If not I don't know what to say to you. + +--- + +

1. GAN stands for "Generative Adversarial Network". It's a type of machine learning model. It was popular for image generation among hobbyists back when this stuff was on my Youtube homepage. It's not really important here, though.

\ No newline at end of file diff --git a/blog/posts/ai_art/index.php b/blog/posts/ai_art/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/ai_art/index.php @@ -0,0 +1 @@ + + + Three PCIe slots on a desktop PC motherboard. + + +However, due to the industry's blind rush to make all electronics as thin as possible1, no laptop on Earth has these. The meager modularity present inside laptops is typically found in the form of M.2 slots: + + + + An M.2 slot in a laptop, intended for an SSD. + + +Normally, these are used in computers of all sizes to attach NVMe SSDs, but the secret to the speed advantage of the NVMe over your standard SATA is a fundamentally different protocol: NVMe SSDs communicate directly over PCIe, meaning any NVMe slot is essentially just a tiny PCIe slot, and other types of device can take advantage of that connection, such as the SATA expander that I'll need for this project. + +Most laptops, including mine, have two M.2 slots: one for an SSD, and one for a wifi and bluetooth module. You can get SATA expanders for both, such as these two that I bought: + +
+ + + A 2-port M.2 SATA controller, keyed for a WiFi card slot. + + + + A 5-port M.2 SATA controller, keyed for an NVMe drive slot. + +
+ +Unfortunately, my laptop didn't want to turn on with a SATA expander in the NVMe SSD slot, so I'm stuck with the dinky two-port one. That's fine, since my server doesn't really need wireless connectivity anyway, and I've got a secret nasty trick up my sleeve that's gonna let me *really* get the most out of those two SATA ports. + +So, SATA as a protocol is designed to have exactly one device connected per SATA port, as opposed to USB, which supports hubs that let you turn one port into several and connect multiple devices. However, that's also not actually true at all. For reasons that are honestly beyond my understanding, some SATA controllers, such as the one on my little M.2 module, support devices that essentially do for SATA what hubs do for USB, allowing me to connect multiple drives per port. + +This feels a little like forbidden dark magics to me, and it probably isn't great for performance, but it lets me connect more drives so I'm using it. Keep in mind, all this is to reach a level of connectivity that almost matches what the motherboard in my desktop computer supports out of the box. + +Don't mind the fact that I had to cut holes in the bottom of my laptop to hook stuff up to the SATA ports. Just, um, ignore that. + +### Problem the Second: Powering All This Crap + +Now that I've got my laptop *talking* to all these drives, they need power. I'm sure I could get this from the laptop somehow, but I'm not an electrical engineer, and the point of this project is to *not* have to buy a new computer, so I'll have to get it from elsewhere. + +The best way I'm aware of to power multiple hard drives from the same source is a PC power supply, such as the one I'm currently using to power the drives in my desktop PC. In fact, as part of early testing I actually had to power some drives off of my desktop PC while they were connected to the laptop. I wish I had pictures to show you of that, it was so fucked. + +Trouble is, PC PSUs rely on the motherboard for control. Specifically, one of the contacts in the 24-pin motherboard connector needs to be shorted to ground for the PSU to actually "S" any "P". I could do this manually with some wire, but that has the potential to be unreliable and also maybe a fire hazard. Enter this thing: + + + + A small circuit board with an ATX motherboard power connector and headers for a fan and a power button. + + +This is the Supermicro CSE-PTJBOD-CB1. It's a part from a Supermicro JBOD enclosure, and it exists to solve my exact problem. This little board's entire purpose is to interface a power button (and some fans) with a PC PSU, which is exactly what I need. Lucky me! + +Pictured above is the exact board mentioned in the Serve The Home article I learned about this from, but this specific model appears to no longer be available, so I'll be using the more fully-featured CSE-PTJBOD-CB*2*. The only difference that matters for me is that it has headers for more fans and a power button LED. + +With power and storage solved, I could now confirm that this crazy plan was actually going to work. Here's a video I recorded documenting this historic moment: + + + +And furthermore, photos of the SATA splitter working: + +
+ + + Five SATA drives plugged into a laptop, one via an internal SATA bay, and the other four via an M.2 SATA controller in place of the WiFi card and a SATA splitter board. The latter four hard drives are powered off of an ATX PC PSU controlled by a Supermicro JBOD controller board. + + + + lsblk output showing five SATA drives recognized by the system (sda through sde) + +
+ +### Problem the Third: A Case + +I could run this whole setup naked, strewn out across my desk, but I'm not doing that, so I'll need a case. Unfortunately, they don't make computer cases designed for this use case. I shall have to build my own. + +There's a few different ways I could go about this. I've seen people make custom computer cases out of wood. This guy modified a rack-mount server chassis to accept his laptop's motherboard for a similar project. I don't have much in the way of woodworking ability and I'm not planning to disassemble my laptop for mounting inside a computer case, but I do have a 3D printer. + +I could 3D print the whole case, but that seems like it would take a lot of plastic, and more importantly, be a pain in the ass to design, especially since my 3D printer is smaller than the case I'll need to make so I can't really print it all in one go. My plan is to make the main structure out of metal rods, and 3D print various brackets to attach everything together. + +I originally wanted to order the rods custom-cut to the lengths I'd need, but on top of being kind of expensive the shipping would actually cost *more* than the rods themselves. In other words, too expensive. Fortunately for me, it turns out hardware stores sell lengths of steel and aluminum rods, the latter of which I can easily cut at home with a hand saw. + +So I bought 12 feet of aluminum rods, manually cut them to length, and then 3D printed little corner pieces out of PETG (in translucent green to match the accents on my gaming-ass laptop) to join them into a frame: + + + + A frame made of aluminum rods press-fit into custom 3d-printed joints + + +Now I need a way to mount hard drives to this. I considered 3D printing a rack of some kind for them, but I don't know how hot these things get and for obvious reasons I honestly just don't want to take any chances with them. For this reason, I instead bought a drive cage designed to mount to a couple of 5.25" drive bays, and mounted that to my frame. In fact, the height of the frame was chosen based on the size of this part. + +This cage also accepts a fan, so I figured I'd add a couple of those to the case, too. + +I attached everything to the frame using various simple 3D printed brackets I designed that just snap onto the frame, and then the various parts can be screwed into them. I specifically designed it all in order to reduce the amount of precision that was required of me. + +
+ + + Frame made from aluminum rods and 3d-printed joints, with the following mounted to it via 3d-printed brackets: two PCBs, an ATX PSU, a power button, and a computer fan + + + + Same frame, but from a different angle + +
+ +I wanted to make some kind of fancy bespoke mount for the laptop, but that turned out to require a lot of precise measurement and modeling that I wasn't prepared to do, so I just put a normal laptop stand on top of this thing. + + + + The frame with a drive cage installed and a running laptop sitting on top + + +IT'S ALIIIIIVE!!! + +## Software + +This post is mostly about my fucked up hardware, but I figured I should share my software setup too. It's TrueNAS. I went with it because it boasts a lot of fancy features and smooths out a lot of processes that I was intimidated by the idea of doing manually in the terminal. This is probably the most normal part of the build by far, and I think some of the jankiness of the hardware side has infected it. I tried to run Syncthing on it and it just... didn't take. I don't know how else to describe it. TrueNAS is pretty good though. + +## Postmortem + +As of writing, I've been running this thing for a couple months now, and it's been pretty good. I haven't done a lot with it yet beyond some basic backups and a Jellyfin server that I have yet to make accessible from outside my LAN, but it's been mostly reliable so far. It even survived a power outage once with no issue, though I'm currently looking into UPS solutions to make sure that doesn't happen again. All that isn't to say I'm completely happy with it, though. + +Firstly, after I built the chassis I discovered that you can get v-slot aluminum extrustion in custom sizes meant for exactly this type of project. They call it MakerBeam. If I had to pull some bullshit like this again I would have probably used this stuff instead of hardware store aluminum and a hacksaw. + +I also didn't do a perfect job of designing the 3D-printed parts. I think they came out pretty good all things considered, but I made all the brackets just a little too short and they're all a little bit bowed. Fortunately I used PETG so it just looks sketchy - PLA would have snapped by now, which I know because my first PLA test print snapped instantly! + +The PSU I used, a Seasonic S12III, is also a bit dubious. I picked it because it was cheap and my other Seasonic PSU is working well, and it's worked out fine so far, especially because it's a 500 watt unit which is kind of extravagant overkill for my use case, but after I bought it I learned it's actually one of the shittier units Seasonic sells. Apparently they outsource the manufacturing to some other company, which strikes me as weird considering a bunch of other companies outsource PSU manufacturing *to* Seasonic. At any rate, it's been fine so far and I don't expect it to blow up running at a fraction of its rated wattage. + +I got the hard drives from a website called ServerPartDeals.com that sells recertified high-capacity HDDs for like half of what they'd sell for new, and while a few months of use isn't enough to say for sure whether that was a good idea, they've certainly left a good impression. The drives I bought arrived encased in foam, inside a box which was itself packed inside another padded box. With that level of care on the part of the seller, I'm pretty comfortable trusting these drives with what I need them for. + +And now the elephant in the room: I cannot in good conscience recommend you do this. Having a NAS is a good idea, and using an old laptop as a basic server is a good idea, but if you're going to build a NAS like this then you should really procure a purpose-built machine, or at the very least an old desktop that can accept some extra drives. Definitely, *definitely* don't *buy a new laptop* with the intent to do this. + +In order to make this work I had to replace my laptop's wifi card with two layers of janky, probably AliExpress-tier hardware that is, frankly, probably introducing performance bottlenecks, or if I'm lucky, bottlenecked by the relatively low-speed interconnect of the wifi card M.2 slot. Bear in mind, that slot needs *at most* 1 gigabit of bandwidth to fulfill its intended purpose, which is about a sixth of what a single SATA 3 port can do. According to my research, that thing has two *separate* PCIe Gen 2 x 1 interfaces. Who knows what my cheap SATA controller is even doing with that. + +Plus, interfacing with this thing makes it painfully obvious that it was *not* designed with this kind of bullshit in mind. I ran into all kinds of Laptop Bios Moment™s during this project, from the CMOS resetting every time I made a hardware change to the machine refusing to even POST with anything but an NVMe SSD in the NVMe SSD slot. I was gonna put connectors for FIVE hard drives in there. I wouldn't have even needed the SATA splitters. + +Honestly, I only did this at all because I figured adapting this thing to this use case would be cheaper than procuring a new machine that was as fast and I didn't want it going to waste. All that said, I have a NAS now, and it's good enough for me, and this whole adventure was a hell of a Learning Experience™ so I really can't complain, though if you gave me the amount of money all this stuff would have cost new to put toward a new NAS, I would have done something else. + +--- + +

1. This is a joke. PCIe expansion cards are genuinely too bulky to fit in anything with portability as a design goal. However, despite Tim Cook's best efforts, this is not true of most other expansion options.

\ No newline at end of file diff --git a/blog/posts/building_a_normal_server/index.php b/blog/posts/building_a_normal_server/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/building_a_normal_server/index.php @@ -0,0 +1 @@ +house, so it doesn't really matter. + +In fact, this little fucker is absolutely perfect for hosting an SMB share. It's been great for backups and the extensive collection of Linux ISOs that I install to machines on my network using Jellyfin. + +The real problem is stability. Crashing has been a constant problem, especially when I touch anything software-wise. I try to update an app and it crashes. I try to install Syncthing and it crashes. I *browse* for new apps to install in the TrueNAS web UI and it bloody crashes. It crashed while running a system update once. I briefly attempted to spin up a Minecraft server on this thing and it crashed when I went to turn Minecraft *off*. Sometimes I'll go to use Jellyfin and it just won't be there and I'll have to troubleshoot it, which usually involves a good couple reboots. This must be how people felt dealing with old versions of Windows. Put shrimply, this is fucking unusable. + +Like the Windows Vista users of old, I have no clue where to even begin diagnosing this. The one possibility I've got is that it could have something to do with the fact that my laptop keeps throwing "SMART errors" during boot, but like, I'd expect TrueNAS to complain if something was actually wrong and even then I've tried and failed to diagnose the SMART errors anyway! + +Whatever this is, I feel pretty well hopeless to fix it, and even then, it's also been getting some worrying temperature readings as of late and when I tried to re-paste it I stripped one of the screws holding the cooler on. So I guess short of some surgical dremel-ing of some tiny screws that's never gonna improve. With all that to contend with, I'm about ready to give up on this thing and start from scratch, properly this time. + +However, despite all the problems with the laptop itself, all the other hardware has been nothing short of totally rock-solid. All of it has worked as advertised and I'll be carrying the drives and, if possible, the PSU1 over into the new system. + +## Something Just A Little Bit More Sensible + +### Angle of Attack + +Firstly, as previously mentioned, the PSU and storage are accounted for already. I have eight total drives I want to put in the system: two 256GB SSDs as mirrored boot devices, 2 1TB SSDs, also mirrored, for TrueNAS apps and such things, and four big boy hard disks for bulk storage. Most of that stuff was bought for the original build, but the mirrored SSDs proved infeasible in the end. I don't strictly *need* them, but it would be very nice to have. Anything in serious consideration will need some way to accommodate my preponderance of SATA devices. + +This narrows down the possibilities considerably. Namely, a lot of the common advice for cheap or beginner home servers doesn't apply to me. A mini PC or almost any used consumer desktop wouldn't have enough space for drives, and anything new is right out for the same reasons plus cost — half the reason I did the laptop NAS project in the first place was to *save* money. + +I briefly considered getting a used workstation PC of some description. A used Lenovo Thinkstation P520 would have mounting space for all my drives and plenty of performance, but the proprietary motherboard, PSU, and power delivery system in general gave me pause, both for [repairability reasons](https://isopod.zone/notes/9uwehufw3t) and because I wasn't confident I could actually run power to all the drives. And that's the *best* option I've found. + +I could get a used rack-mount server, like a Dell PowerEdge or similar. This is also a decent option, and it would be *quite* cost-effective, but I've got a few good reasons not to. First, most of these servers have old Xeon datacenter chips in them that are still good for many home server tasks, but aren't particularly fast or efficient. Take this PowerEdge R730 for instance: + +![An Ebay listing for a Dell PowerEdge R730, with two Xeon E5-2623 v4 CPUs and 128GB of RAM, for $187 CAD, plus $57 CAD in shipping.](ebaypoweredge.png) + +This has two Xeon E5-2623 v4 datacenter CPUs. At 4 cores/8 threads and 85 watts apiece, this server would have the same core count as the Ryzen 5700G in my desktop for almost three times the power draw, and *half* the single-threaded performance. In many cases, especially for servers, lackluster single-core performance isn't a problem, but if I want to run game servers on this, which I do, these chips may struggle. + +Plus, rack-mount servers kind of suck for home use. They're very unweildy if you don't have a rack, and I don't, nor do I have anywhere to put one. They also tend to be *loud*. If you think the gaming laptop you've been using in your bed for the past three years and never cleaned sounds like a jet engine, you ain't seen nothing yet. Having one of these in my room would be intolerable. Of course, the R730 is a 2U server with no provisions for my 3.5" drives anyway, but a unit that could accommodate them wouldn't be much better. + +Logically, then, the only remaining option is to build a system from scratch, out of used parts, to my specifications. That, therefore, is what I shall do, and I think I can do it for a similar amount of money to the GPU upgrade I was *planning* to get before this whole thing really started becoming an issue. Here's my plan: + +### My Grand Design + +In spite of the machine it's in, I've found that the i7-9750H in the laptop performs admirably for my use case. I don't really need a CPU upgrade here — hence my efforts to repurpose the existing one — unfortunately, however, the BGA form factor of this particular chip is incompatible with 100% of consumer desktop motherboards, so I'll be needing a new CPU regardless. Though I don't want or need a major upgrade, I also don't want a *downgrade* if I can avoid it, so I'll primarily be looking at other high end gaming chips from the era. + +I initially gravitated towards the 9750H's desktop counterpart, the i7-9700K, for these reasons, but the significantly lower price, improved energy efficiency, superior upgrade potential, support for unregistered ECC RAM, and *vastly* superior multicore performance2 of its contemporary, the Ryzen 7 3700X, made the latter a bit of a no-brainer. I found one on Ebay for a cool 100 Canadian Prize Tokens and a matching X370 motherboard with *eight* whole SATA ports, which astute readers will recall is the exact amount I need, for about a hundred of God's True Imperial Dollars. As for cooling, the 3700X is a 65-watt chip, so the box cooler I've got lying around from my 5700G should suffice. + +The 3700X lacks an integrated GPU, so I'll need a dedicated one in some form. Since I'm installing a server OS that's gonna output plain text to a display exactly once per install, I won't need a ton of graphics horsepower. I considered something like a GT 730 for a token display out and nothing more, however I'd like some transcoding capability for Jellyfin as well. After some research into cheap, low power GPUs for this I settled on an Nvidia Quadro P400 for about 60 CanuckBucks™ after shipping. + +I've seen some redditors complaining about the P400's performance doing two 4k HDR streams at once, but all that tells me is that it can handle at least four simultaneous 1080p SDR streams, which is what I intend to use it for, without breaking a sweat. If I *really* need more, I can always upgrade to an Arc A310 once driver support for those in TrueNAS is less sketchy. + +TrueNAS likes a lot of RAM for various ZFS-related purposes. The laptop seems happy with 32 gigs, so I'll start there and upgrade down the road if need be. I'll grab something cheap from a reputable brand, and I'll probably get it new since used prices on DDR4 are currently not really better. + +I'd also like to get a pair of 10Gb network cards at some point to attach this thing directly to my main computer for maximum transfer speeds between the two, but that's not really critical and I'll worry about it later. + +Finally, I need a case. Fortunately, this time around I don't have to build one myself. After a cursory search on PCPartPicker for cases with four each of 2.5" and 3.5" drive mounts didn't turn up anything for particularly cheap, I went to look at used ones and didn't initially have much luck there either. I scrolled through about a dozen listings for off-brand gamer-spec swill that wasn't even priced better than the name brand stuff before filtering by used and finding a bunch of listings just labeled "PC case", none of which I could confirm met my exacting needs. + +The first case I found that obviously fit my use case was this thing, the weathered old shell of a Pentium III tower from the dawn of the ATX standard: + +
+
+ A beige PC tower with four 5.25" bays and two external 3.5" bays, populated with an optical drive and a floppy drive respectively. The only visible branding is a Pentium III sticker and a badge that reads "TOUCH". +
Based on my research, this is an Enlight 7237, or something closely related, but the front panel seems unique. I'm curious about the branding here. If anyone recognizes that "TOUCH" badge, get in the comments.
+
+
+ +Honestly, I kind of love it. I'll transfer the 5.25"-to-3.5" adapter cage I bought to mount the drives in my homebrew case to the bays in this thing wholesale, and I can 3D print some brackets to mount the SSDs in the 3.5" bays. And, somewhat counterintuitively, it might actually be *easier* to build in than those modern RGB glass side panel power supply basement having ass Gaming™ cases: + +![The inside of the same old PC case. Its layout is extremely pragmatic: motherboard in the very bottom corner, PSU in the top corner above it, and all the drive bay mounts are in a cage lining the front side. In other words, it looks like an old PC case.](servercaseinside.jpg) + +Just look at it. Everything's right there. I can take the side panel off and instantly get to every component with my hands without spinning the case around and I don't need to run any cables through any fucking gromets to get them where they're going. It looks supremely convenient. As the type of person who enjoys *building* computers and not just using them as decoration, this is beautiful to me. + +The biggest issue with this case is the cooling. It's absolutely pitiful by modern standards. Based on these photos, it looks like there's a single 92mm, possibly 80mm, fan each for intake and exhaust, with a passive vent in the side. I'm already bringing some extra cooling to the table — my drive cage has a mount for a 120mm fan, and I can use the fan in my much better ventilated modern PSU for extra exhaust, and with a 65W CPU and no meaningfully powerful GPU that might just suffice. If not, I've got some ideas involving 3D printing and/or a hole saw to make this thing a little less stuffy. + +### Actually Building The Sucker + +Everything above that heading there was in large part written a few weeks ago, when I was ordering all this stuff and it was all fresh in my mind. We now rejoin our intrepid hero as she receives the last of her Ebay orders and prepares for initial testing. + +When I got it, the case was pre-loaded with all the stuff in those photos up there: a CD-ROM, a floppy drive, a power supply, a single 80mm intake fan3, and a generous helping of, to quote the PC repair technician from my Youtube shorts feed, Swamp Gooch™. The first thing I did was take the case apart and remove all that stuff, because I certainly wasn't going to be using any of it, least of all the dubious PSU. The next thing I did was hose it down to get rid of the almost thirty years of Home/Office Residue that had accumulated inside. + +Once it was clean, the case did, admittedly, need some updating. The set of motherboard standoffs in the case was incomplete — six of the usual nine were present — so I ordered new ones. I also had to design that 3D printed adapter bracket for my 2.5" SSDs myself, as well as a mount for another 80mm fan to eke some more airflow out of those unused front expansion bays4. After the case was prepared and the mounting brackets printed, there wasn't much to do until all the other parts arrived. I learned about some interesting limitations of the motherboard in my main computer while testing to make sure the GPU worked. I think I might be the sort of person who buys motherboards with the high-end chipset now. + +The last major component to arrive was the motherboard, and it arrived missing some important hardware, namely the M.2 standoff and the stock mounting bracket for the CPU cooler, the latter of which was *in the photo on the Ebay listing*! That's what I get for buying used, I guess. Fortunately both parts are pretty cheap to order online. + +Assembly went smoothly; not much to say here that you couldn't get from Linus Tech Tips. It turned out that *both* the original standoffs *and* the ones I ordered were the wrong height — the original ones were too long, and mine were too short. I ended up putting the original standoffs back in because neither were so far off as to render the rear I/O unusable and my standoffs made installing the GPU properly impossible. I also had to use a couple of breadboard wires to hook up the power LED, since the pins on my motherboard were right next to each other and the connector in the case was 3 pins wide with a blank one in the middle, for some reason. However, unlike *some* cases I've worked in, accessing the modular PSU cables was an absolute joy5. + +What didn't go smoothly was actually booting the thing. On first power on, it failed to POST and got stuck on a code "8" on the little seven-segment diagnostic code display. I initially assumed it was training the memory, since this can take a while on first boot, but after about five minutes of no change I started getting worried. I read a lot of very worrying forum posts that suggested that either the CPU or motherboard were straight up dead, and I very nearly bought another CPU to see if that was the case. First, though, I decided to try updating the BIOS using the "BIOS Flashback" feature, and that fixed it immediately. I wasn't done yet, though. + +Astute readers will have figured out by now that I was using TrueNAS on the old machine and intended to continue using it on the new one. Installation went extremely smoothly, except for one small wrinke: I had decided to take the NVMe boot SSD from the old laptop to use as storage for my game servers6, and even though I had done a fresh install of TrueNAS to a pair of mirrored SATA SSDs, the NVMe one, naturally, still had TrueNAS on it. This, from what I understand, caused the OS to get stuck trying to boot because there were two ZFS pools marked as the boot pool, and it would just give up and drop me into an initramfs shell instead. Booting into a live environment and using GParted to clear all the partitions on the drive didn't fix it, and after a bit of googling I learned I had to use the initramfs shell to clear the volume data for the disc directly. + +After that was cleared up and I was booting into TrueNAS, setup went off without a hitch. I imported the config I had saved from the old server and everything was instantly up and running like nothing had ever happened, and suddenly, I had a working server again. + +

Postmortem

+ +The first natural question is: Did it work? Was I right? Did our intrepid hero succeed in her quest to finally have a server that's actually stable enough to use? And the answer is yes. Tremendously so. In the couple days it's been running, this thing hasn't crashed once, even after I installed Syncthing7 *and* set up an entire VM to run Minecraft. Whatever was causing all that instability with the old server didn't make it over to the new one, and I should bloody well hope not considering the only parts I carried over were a bunch of drives that were in perfect health according to both ZFS and the SMART tests they kept passing. + +There is one major issue, though. See, since I was planning to run a stock cooler in a case with airflow that was subpar at best short of cutting holes in it, I made sure to get the strongest fans I could find to fill the available mounts, which for me meant three 80mm Arctic P8 Max's — one in front, one in back, and one in the 3.5" cage, plus a 120mm fan in the 5.25" bays. + +These fans have a maximum speed of 5000 RPM, which makes them quite capable at compensating for the sub-optimal airflow conditions, but this was also the basis of my one fatal miscalculation: these suckers are *loud*. Not 1U rackmount borderline-jet-engine level loud, in fact the noise is more or less tolerable at low loads, but under significant load, such as, say, the Minecraft server I've been so fixated on, they get quite distractingly loud, which is a problem since the only feasible place for me to put it at the moment is on my desk. + +I soon plan to implement a multi-step plan to attempt to fix this issue: First, in my typical fashion when I find my equipment is slightly inadequate, I'll replace the AMD stock cooler I used with something gratuitously overbuilt — I'm thinking a Thermalright Peerless Assassin. Then, if that doesn't work, I'll tear the whole thing down and go at it with the hole saw, and mount a couple nice, big, quiet fans in my fresh new speed holes. If the 80mm fans are still causing a ruckus after all that, I'll just remove them. They probably won't be of critical importance at that point anyway. + +Overall, the case was a bit of an impulsive and perhaps sub-optimal choice, but I'd do it again in a heartbeat. I love this thing. I might be a little more liberal with the hole-making, though. + +I don't regret my choice of core components at all, at least not yet. The CPU, despite the noise, runs Minecraft as spectacularly as I'd hoped. At least, after some fiddling with my VM configuration. Its efficiency certainly also helps with cooling, given the circumstances. The motherboard, being a fancy X-series one, has various Gamer Lights and a myriad of overclocking features that are a bit silly to have in a server, but it also has the expansion I need and that's what really counts. Plus, that fancy 7-segment display was very helpful with diagnosing it. + +The RAM is RAM. It's fast enough for my porpoises with or without XMP, which I left off to optimize for stability. I might get more down the road. The graphics card is exactly what I need, and Jellyfin seems to like it fine. Couldn't have asked for a better value there. I'm still waiting on the GT 730 I foolishly ordered before looking into it properly. That's fine, though, it was even *cheaper* than the P400 and it's always nice to have spares. + +I ended up getting those 10 gig ethernet cards, but I couldn't use them like I wanted. As it turns out, a GPU and 2 NVMe drives is all the PCIe bandwidth the B550 chipset in my main rig has to offer. My next upgrade might just be a used X570 board. I did still install one in the server, though, and since the fan on it was very loud on account of being very dying, I replaced the shambling corpse of the stock fan with a 40mm Noctua, spliced onto the original header and mounted using one of my best zip-ties: + +
+
+ +
Yes, I attached the zip-tie to the heatsink by screwing it in. Clever, right?
+
+
+ +Would I recommend you follow in my footsteps? Absolutely. This thing is great. In order to make this work, I had to build a normal computer. Short of a rack-mount case and a rack in which to mount it, *this* is how you build a home server. Frankly, I was absolutely right that violently contorting my existing gaming laptop into a TrueNAS box would be cheaper than this, but I can now say with complete certainty that the savings were not worth it. This is less entertaining, sure, but I'm glad I finally did it properly. Well, at least to the greatest extent that I seem to be capable of "properly". + +--- + +

1. I'm not referring to the Seasonic S12III from the last installment. That thing is honestly a little sketchy for me to be using it in a proper server if I don't have to, and I don't. When my PC's power supply, a Seasonic GX650, exploded, I RMA'd it and then bought a beefier one to replace it with, and the replacement unit Seasonic sent me went in my server, and will be going in the new one. The S12III is serving as an improvised benchtop PSU using one of these bad boys at the moment.

+ +

2. If cpubenchmark.net is to be believed, anyway.

+ +

3. I could, in theory, reuse this fan, but I don't want to. It's so nasty that attempting to run it seems like a good way to invent a new respiratory illness, and even if I cleaned it the bearing is geriatric and the performance probably isn't very good, plus my modern motherboard might not even have a header for it. Its replacement will suit me much better.

+ +

4. You can download the model for the fan mount and corresponding grill I designed here. I'd publish the drive bracket but the one I printed needed some modification in order to work, and I don't want to spend the time and filament to refine it right now.

+ +

5. Mind you, this case is well north of 20 years old. This case shipped to me with a Pentium III sticker on it. This thing may well predate modular power supplies as a concept, and somehow it accommodates them infinitely better than the 2-year-old case on my personal machine, which barely has room to insert a modular PSU, let alone actually get at the cables afterwards. I don't understand how this is possible.

+ +

6. Generally you'd use this for L2ARC cache for ZFS, but from my research I don't have enough RAM for that to be useful anyway, and game servers are the only thing I currently want to do that's likely to benefit from the added speed of an NVMe SSD.

+ +

7. Finally, at long last, I have automated backups to the enormous HDD array in my NAS! Took me bloody long enough.

\ No newline at end of file diff --git a/blog/posts/building_a_sensible_server/index.php b/blog/posts/building_a_sensible_server/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/building_a_sensible_server/index.php @@ -0,0 +1 @@ + + body { + background: url('background.png') #000000; + background-position: center; + background-size: cover; + background-attachment: fixed; + } + a { + color: #00CED1; + } + a:hover { + color: #ffff00; + } + h1 { + font-style: italic; + background-image: url('/images/isopod.php'), linear-gradient(135deg, #2e1ae0 0%, #2e1ae0 2ch, #00ff00 4ch, #ffff00 6ch, #ffff00 7.1ch, #0000 7.1ch); + background-clip: border-box, text; + -webkit-text-fill-color: transparent; + text-shadow: none; + } + hr { + color: white; + box-shadow: 0 0 4px white; + } + + +Yesterday, September 18th, 2022, was the second anniversary of the creation of my first website on Neocities1, the site that is now known as [deeptwisty.com](https://deeptwisty.com). I intended to publish this then, but life got in the way, by which I mean I wrote 90% of it and then procrastinated for two weeks on the last couple paragraphs. I figured that to commemorate the occasion I would finally dispense with the half-assed abridged history of the place on the about page or wherever and consolidate a complete history of my Personal Home Pages in one convenient location, that being this post. + +## Tumblr + +My first proper social media was Tumblr. Well, the first social media site I joined was Pinterest, but that doesn't count. Anyway, Tumblr was my main social media and the center of my Online Presence™ for several years. I would pour hours into tweaking the custom theming on my blog to be just right, and I often had some sort of bio on a custom page, which is a thing Tumblr lets you do. I linked to all my other online profiles from my Tumblr page, and would prioritize linking back to it from them. This caused problems, as I was and still am the type of Tumblr user to change their username on impulse, and it was terribly inconvenient having to go through all my other accounts and change that link whenever I did (I've got it set up as a subdomain of my website now, so that should never be a problem again). Eventually, though, another service would crop up that everyone seemed to be using, and that presented me with a better way: + +## Carrd + +I still use Tumblr, just not as the hub for my entire online presence. I maintain that it is still the best2 centralized social media site. Anyway, a Carrd page became the central hub which linked to all my online profiles and which all my online profiles could link back to. Finally, I only had to update my frequently changing Tumblr link in one place. For the most part. + +I perceived a certain stigma (at least on Tumblr) around having a Carrd page, and the sorts of people who made one. The stereotype was that you would have overly exhaustive BYF (Before You Follow) and DNI (Do Not Interact) lists full of sometimes outlandish criteria3, probably have similar bullet point style lists of all your likes, dislikes, and possibly identities and triggers (!)4 and probably not be the most pleasant person to interact with. I like to think I bucked that trend. My Carrd pages were generally very simple: a profile picture, a short bio (some shit like "Name | 21 | 🇨🇦 | real life isopod"), and links to my socials. That was all. I remember adding the obligatory long-form bio and DNI list at some point, but those didn't last long. + +I believe it was around this time when the alias "deep twisty"5 came into being. I was just starting out making music at this point, posting crummy songs to SoundCloud that I'd made in an online editor called [EarSketch](https://earsketch.gatech.edu/landing/#/) that had you use Python to arrange pre-made loops and samples on a timeline. That shit was wack, yo, but that's beside the point. I was looking for an alias to release my music under, because I was intent on making more and my actual name wasn't gonna cut it. + +I was quite into Subnautica around this time (I promise this is relevant) and its sequel, Subnautica: Below Zero, was in the early stages of early access around this time, like still working on early-game areas early, and I was following it closely. The devs had a twitter account that posted all the git commits for the game, and a couple of them referred to a biome they were working on, the Deep Twisty Bridges6, as just "deep twisty". That is the origin of that name. I don't know why I felt compelled to base my brand off that, but now I'm committed. I get self-conscious about it sometimes, but honestly, I've seen worse. Not that I'm judging. + +Anyway, I made a separate Carrd as a hub for this new "deep twisty" persona (I keep it separate from everything else mainly so I can show it to family without them seeing all of... this. Not that I have yet...). That worked fine until I wanted to start embedding my latest YouTube upload on the Carrd page, something Carrd locks behind a paywall. It was at this precise moment I remembered I know how to code and resolved to make the jump to a platform that lets you write your own HTML from scratch, in my case, this being + +## NeoCities + +My first Neocities sites were simple affairs, basic little pages with little more to them than the Carrd sites they had replaced, albeit with some of the things Carrd would have made me pay to add, like that YouTube embed. You can still see the original version of what is now this site [here](../../../old/1/), though the original version of deeptwisty.com was unfortunately lost. It was nothing special, though. It had a similar aesthetic to its replacement, and it was pretty similarly laid out to this here page, even with the same background, just with WAY less text, and no cool isopod. + +I've seen some people in this here "small web" community getting mad at people who use Neocities this way, to which I say: shut the fuck up! Everyone has to start somewhere, and messing around on a simple page like that could easily be a gateway drug into making something much bigger, like it was for me. Hearing sentiments like this is just going to discourage people. Besides, it's their website. They're not intruding on your special cool kids club by using a free service to do the thing that it's for. + +It was also during this time when I bought the domain deeptwisty.com. I had to pay Neocities to use it, but I was more than happy to support the cause anyway. I didn't stricly *need* the domain, but boy was it cool to have my very own Dot Com. It just sounds so professional. deep twisty Dot Com. + +The deep twisty site tended to take precedence over this here personal one for a while; the personal site was relegated to a subdirectory or subdomain like deeptwisty.com/me or me.deeptwisty.com. In fact, the transition from the former to the latter is when the original deeptwisty.com was tragically lost. I was copying over the contents of deeptwisty.com/me to its own fresh new dedicated Neocities profile and I accidentally uploaded the files to the wrong site, overwriting a large portion of the main deeptwisty.com with no way to recover it. I spent a couple days rebuilding it into roughly what you see at that domain now, and when I was done I was having enough fun with it that I wanted to keep going and decided to overhaul my other site too, and what resulted was [this](../../../old/2/). + +For this new version of the site, I decided I wanted to be able to actually add content to it, whereas the old site hadn't really been designed in a way that was conducive to that. I decided to do this in the most JS-reliant way possible. I had one main page with the navigation and layout, and the navigation worked by using a URL querystring to tell the page which content to load. It was pretty fuckin' neat, but I would eventually realize I wasn't a fan of how dependent it was on Javascript. My favorite feature of this revision is the theme picker, which swapped out different stylesheets and set a cookie to remember which one you prefer. The main problem with this was that I designed it so the themes could change basically everything bar the fudamentals of the layout, and it became a huge pain in the ass to add both new pages and new themes while ensuring everything stayed compatible. It was really cool though. + +To be completely honest, I took rather a lot of inspiration for this revision from [this site here](https://hosma.neocities.org/10/), which is to say I basically made a worse version of it7 and went from there. You can still see some of that inspiration in v3, with the giant header text and centered single-column layout. + +This revision was, as the kids say, Real Cool™, but the aforementioned problems led me to scrap it after only about 2 months, which brings us here: + +## v3 and Self-Hosting + +I wanted something that could be viewed without Javascript and wasn't a colossal pain in the ass to update, hence what you see on the site now if you're reading this soon after it was posted. If I've since overhauled the site again, the version I'm referring to should be available [here](../../../old/3/). This version is designed to be as simple layout-wise as possible, to the point where you can read it in a text-only browser and not lose much of the experience. It's much easier to add stuff to now. My one issue with it is the navigation - unlike v2, where you could get to any page from any other in one click, v3 requires you to go back to the homepage to move between pages. It's just harder to navigate. This system is better than having to add a link to every new page on every existing page, though. Now that I can do server-side rendering, I'll probably put in a proper navbar or something of that nature at some point. + +Speaking of which, a bit after the jump to v3 I decided to start self-hosting my websites. I didn't have any deal breaking issues with Neocities per se, but I wanted to start messing around with server-side scripting, and I wanted to host some other things that I wasn't in a position to otherwise. I originally wanted to do this with an old laptop I had lying around, but I would have had to punch through the NAT in my house and point the domain to my home IP address, neither of which I wanted to do. Instead, I cancelled my paid Neocities account and reallocated those funds to rent a VPS. I was originally going to use Linode for this, but they literally wouldn't let me sign up for an account for some reason8 so I went with DigitalOcean instead. + +I've had quite a lot of fun with this newfound backend access. I now have the freedom to use Javascript only when there's literally no other way to do what I want done, and I've taken advantage, moving stuff like the randomized subheader on the landing page server-side. I'm also hosting a lot of other services on this same VPS, including but not limited to a Fediverse instance, an RSS aggregator, a SearXNG instance, and a WireGuard VPN to make more intensive stuff I host on my laptop available to the internet. I'm honestly really impressed that the 1 CPU thread and 2G of RAM my server has can handle all that. + +That brings us to now, at this moment, when I'm writing this. I'm absolutely not out of stuff to do here, if I can ever get myself to actually fucking do any of it. I've had a great time with this whole "personal website" business so far, and I'm excited to see where I go with it from here. The community around it is cool too, though lord knows I'm still learning to navigate this particular social environment. At any rate, I'll definitely take this over Twitter. + +
+ +

1. It has since been migrated off of Neocities.

+ +

2. Did you know you can get an RSS feed for any tumblr blog by going to <blog url>/rss? True story!

+ +

3. Oh, I should have mentioned, GTFO if you kin Komaeda.

+ +

4. I kind of get why you would want people to know that information, but I'm surprised more people didn't realize how easily abused that was.

+ +

5. stylized in all lower case

+ +

6. Yes, I named a song Bridges so I could call it "deep twisty - Bridges". Shut up.

+ +

7. I'm currently going back through this blog post a couple years after the fact to replace all the hovertext with footnotes, and wow, v2 really, really was just me doing hosma.neocities.org. Utterly shameless.

+ +

8. WTF? Like, let me give you my money, dude. The only thing I can think of that could have happened is their system assumed I was some kind of spammer or bot because I was accessing their site through a VPN. I solved the CAPTCHAs and everything. What's the deal?

\ No newline at end of file diff --git a/blog/posts/deeptwistycom_2nd_anniversary_-_a_history_of_this_bullshit/index.php b/blog/posts/deeptwistycom_2nd_anniversary_-_a_history_of_this_bullshit/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/deeptwistycom_2nd_anniversary_-_a_history_of_this_bullshit/index.php @@ -0,0 +1 @@ +explains it well: + +
+
+
+ Here is how platforms die: first, they are good to their users; then they abuse their users to make things better for their business customers; finally, they abuse those business customers to claw back all the value for themselves. Then, they die. +
+
+ — Cory Doctorow, Tiktok's enshittification +
+
+ +I won't restate his essay or the examples he lists here (though you should give it a read), but one obvious one his article didn't cover because it was written more than a week ago is what's happening with Reddit right now. Reddit has been enshittifying itself for years, but the current controversy is particularly bad and particularly representative of the problem. As of writing in mid-June of 2023, Reddit has just instituted a new policy requiring payment for use of its API, to the tune of $12,000 per 50 million API requests, which for certain popular third-party clients and moderation tools comes out to millions of dollars per year. + +Reddit did not need to do this. Reddit was doing fine. This was purely a cash-grab, and it's blowing up in everyone's face right now, including theirs. Moderators of many popular subreddits are essentially going on strike over this, and if you think that's the only critical problem this decision is going to cause for users you know very little about Reddit. The developers of open-source clients and moderation tools used by massive portions of Reddit's userbase can't afford costs like this, and most of them will be forced to shut down if Reddit sticks to its guns. + +I'm not saying they will, but Discord could absolutely do the same thing, and it wouldn't surprise me if it came to that. Imagine if Discord bot developers needed to pay API fees like that. There'd certainly be a lot fewer Discord bots, and probably a lot more paywalled ones among the remainder. Discord absolutely needs to become profitable in order to be sustainable, and it will do whatever it needs to to that end or die. Even then, it can't just break even; capitalism demands endless growth. Discord will keep getting worse as long as there's money in it. It's inevitable. It's required. + +### Centralization + +Discord is a centralized platform and always will be, no matter how strong the reality distortion field it puts up by allowing the creation of isolated social spaces and calling them "servers". Every Discord "server" runs on Discord's servers, and they have total control over each one at the end of the day. + +Now, centralization isn't inherently bad. Sometimes it is necessary. Imagine trying to construct a peer-to-peer MMORPG, for example. Discord, however, is not a videogame, and in its case centralization introduces some fundamental problems that a decentralized system could avoid without compromising core functionality. + +The centralized nature of Discord, the platform, means that it, in its entirety, is inherently vulnerable to anything that happens with Discord, the company. Any change the company decides to make is universal. If the company shuts down, the platform goes with it. If the admins at Discord don't like what you're doing, they can unilaterally prevent you from using their platform at all. + +This ties pretty closely into the whole VC-funded thing - Discord, the platform, is fundamentally subject to the whims of Discord, the company's investors. I guarantee you that's why they changed the username system: the corporate big wigs providing the funding got confused by Discord's unique (and very good) username system and decided it would be better if it was more like Twitter, so Discord made it more like Twitter. + +That's really the core of the issue here: being centralized means that Discord can easily suffer the same fate as Twitter. Some incompetent nutcase with more money than the entire planet's collective pool of sense could buy it out and destroy it, or the current owners could just make some boneheaded decision and do the same. A decentralized platform, running on a common open protocol, is much less vulnerable to the antics of the Elon Musks and u/spez's of the world. + +### The Privacy Problem + +This issue isn't really inherently connected to the others - a lack of good privacy doesn't fundamentally doom a platform like the other two points - but I'm treating it as a third major issue because I feel it's extremely important and warrants consideration. + +If you value your privacy, Discord is an atrocious choice. Take it from their own terms of service. Anything you send on Discord, whether in a DM or a public guild (I'm not calling them "servers"), is **not encrypted**, meaning it can be accessed and read by Discord staff, as well as any hackers that manage to access their systems or any law enforcement entities that might demand it. Discord is not even trying to pretend to be private. I'm not convinced it's something they ever thought about. + +And let's be clear here: You should value your privacy. You should value it a lot. The idea that if you have nothing to hide, you have nothing to fear is a complete scam. Even if you don't have anything to hide, yes you do. Take, for example, the time Google flagged someone as a criminal and permanently closed their account for the crime of sending medical photos of their son to a doctor. Or maybe your government wants to arrest you for being gay, or having an abortion, or some other innocuous but potentially illegal thing. Or maybe they will in the future. Or maybe some stuff you've said is just kind of embarrassing. + +If you still don't believe me, read through a couple months of your Discord message history and then contemplate printing it out and mailing it to the NSA. If the government asks, Discord will save you the trouble, and they won't ask your permission first. And with a recent change to their privacy policy, this theoretically applies to your voice chats too, though to be fair I expect that would be prohibitively costly in server space. + +Discord fundamentally couldn't give a shit about your privacy, and doesn't even really care to pretend like it does. It has no incentive to. The investors probably wouldn't be comfortable with the risks associated with pulling a stunt like responding to a subpoena with "yeah here's their phone number. that's all we got" like certain other chat apps anyway, and then there's the potential to sell that all data on you to advertisers. I'm not aware that they currently do that, but it's certainly not off the table should they decide to go that route in order to turn a profit. At least, not under US law, anyway. + +Actually, I just checked that ToS;DR link from earlier again, would you look at that: + +
This service may keep personal data after a request for erasure for business interests or legal obligations
+
This service ignores the Do Not Track (DNT) header and tracks users anyway even if they set this header.
+
Your personal data may be used for marketing purposes
+
This service can license user content to third parties
+
The service can sell or otherwise transfer your personal data as part of a bankruptcy proceeding or other type of financial transaction.
+
The service may use tracking pixels, web beacons, browser fingerprinting, and/or device fingerprinting on users.
+
The service uses your personal data to employ targeted third-party advertising
+ +Juicy stuff. You should really give that a read - you might not like what you find. + +Before we move on, I'll just drop this tasty little link to further reading. It's a real page-turner. + +## Cool, so how do we fix it? + +We don't. Discord was doomed from the outset in any attempts to be sustainable or trustworthy. We are going to need to find an alternative to Discord eventually. So what should that alternative look like? I'll discuss specifics later - I'd like to start by establishing the general principles I feel a messaging system should conform to in order to avoid Discord's major problems. The TL;DR is it needs to not be any of the things I've described thus far about Discord, but I'll go into more detail about what that actually looks like. + +### Follow the money + +A sustainable chat system *absolutely cannot* be for-profit. If it is in any way driven by profit, the decay and eventual death of the service is inevitable. That doesn't mean it has to be entirely staffed by unpaid volunteers or anything, but it would need to be a non-profit foundation of some kind, just trying to break even with no incentive for infinite growth or any other corrupting financial influence. You'll notice this as a theme across most online services that don't already show signs of advanced corporate necrosis. + +I'm not even saying it can't have some kind of Nitro-esque paid tier. I don't hold it against, say, Protonmail - in fact, I pay for that one - but the money can't be the end goal. A sustainable non-profit model might be largely donation-based like Wikipedia, or maybe it could have a totally free product for individual users and break even selling support to enterprise customers like some Linux distributions. It's not currently breaking even yet according to its Wikipedia article, but I'll be interested to see if and how Signal reaches a sustainable state. Maybe future players could take notes from them. + +### Cut out the middle man + +Better yet, structure your system such that it doesn't even need a corporation at the center - in other words, a decentralized system. I'm not talking about the blockchain; we can do this the old-fashioned way, with tech that isn't ponzi-scheme-by-design. In fact, we're already doing this, and it already has more monthly active users than any messenger app ever created: email. + +Email is the original decentralized, federated communications network. There's no Email LLC at the center of it all assigning everyone their email addresses and processing every message. Email isn't an app. It isn't a proprietary service. It's an open protocol that anyone can set up a server to provide access to. That's what Gmail is, that's what Outlook is, that's what your weird nerdy friend's weird nerdy friend who has a custom domain name on their email address and complains about Gmail marking their messages as spam is doing. They're all part of the bigger network. + +I'll try to keep this little tangent short, but I feel it's important to establish a basic understanding of how these systems work. Email is a federated protocol, meaning it isn't tied to one backend running on one company's datacenter - instead, it's a network composed of any number of entirely independent servers running compatible software that communicate amongst themselves using the language of the email protocol. These servers are often called "nodes" or "instances", or sometimes "providers" in the case of email. A user of email has an account with one of these instances and can use it to send messages to people both on the same instance and on any other instance on the network. + +This is why email addresses are like that - the part before the @ is your username, and the domain name after the @ points to the server your account is registered on. If usernames on other platforms were formatted like this you would see stuff like MrBeast@youtube.com for Youtube channels or dril@twitter.com for Twitter accounts, but those platforms aren't federated so they don't need to do that. + +So when two people communicate via email, the sender sends the message to their instance, which sends it to the instance its recipient is using, which then relays it to the recipient. + +And here's the obligatory visual aid - essentially, when you send an email, it takes the shortest path along a network that looks like this; every server is connected to every other, and every user is connected to one server: + +![A graph showing three large nodes connected to each other, each with multiple smaller nodes branching off of them. Each large node is an email server, such as outlook.com or gmail.com, and each small node is an email account, such as jim@outlook.com or bob@gmail.com.](federation.png) + +Hopefully that helped. Back to the point, all federated services work pretty much exactly like this. If you've ever had someone try to explain the Fediverse (sometimes incorrectly called Mastodon) to you by comparing it to email, this is what they meant. But this isn't limited to email and microblogging; this type of system can theoretically apply to anything. Again, building an MMO this way would be challenging, but federated messaging protocols similar in concept to Discord do exist. + +The benefit of this kind of system stems from the fact that it's not under the control of any central authority: Gmail, Outlook, and that weird nerd your friend knows are entirely independent of each other, they don't answer to any higher Email Authority (other than the body that defines the common standard) or each other. This means that there's nobody at the top to fuck the entire thing up for everyone or sell it off to someone who will; in fact, even if someone wanted to it would be tremendously difficult. + +The network is inherently much more stable and resilient in general than a centralized service, as there's nobody who would take the entire network down with them if the company went under or got sued or had a bomb dropped on their datacenter. Sure, a huge number of people would lose their email accounts if Gmail disappeared tomorrow, but critically, not the entire network. Email wouldn't go away, and those displaced users could go to Outlook or Protonmail or set up their own instance and keep communicating over the same network. The same applies to any other federated protocol. Imagine if your Discord account and guilds weren't controlled by Discord, but instead ran on a machine you controlled and was in no way answerable to Discord Inc, but you could still talk to your buddies on Discord proper. It's like that. + +### Incognito mode + +Contrary to the title of the previous section, a federated approach does technically add more middlemen. We've gone from one unaccountable central authority able to read everyone's messages to several unaccountable parties each able to read the messages of everyone they serve. Not much of an improvement, privacy-wise, unless you trust both your provider and the providers of everyone you're talking to implicitly. Actual privacy requires end-to-end encryption. + +End-to-end encryption means the message is encrypted before leaving the sender's machine and can only be decrypted by the recipient once it arrives on theirs. This means that only the sender and recipient can read the message; even if it goes through some other party's server, they have no clue what the contents of the message are. Any messaging system that cares about privacy at all will implement this - ideally they'll build the entire protocol around it. + +There are still problems here, for example end-to-end encrypted messaging still requires the server to know who you're talking to, but there are workarounds for these as well. However, E2EE should be the absolute bare minimum, in my opinion. + +## So what are our options then? + +Here's the part where I discuss actual alternatives to Discord. I'll say now that this will not be a comprehensive overview of every possible option - recommending chat apps that don't meet these standards would kinda defeat the point, and I'm also not omniscient. There are going to be other options that I haven't covered here, and hopefully I've given you the tools to determine which ones are good. + +Every program I list here will, at a minimum, support true end-to-end encryption in some capacity and not be run by a for-profit company. They're also all open-source. + +### XMPP + +XMPP is about as close as we've got to "email but for instant messaging". It's a federated, open protocol which, having been formally standardized in 1999, is truly ancient in internet years. My understanding is that it actually used to be more widely used, but Google effectively killed it off in popular usage by subsuming its userbase into Google Talk and then promptly turning off federation and killing Google Talk. That doesn't mean it's gone, though. People still use XMPP to talk to each other, running on servers hosted by themselves or their friends. + +XMPP is, at its core, designed for simple text-based messaging and presence. While the protocol is highly extensible, many even relatively basic-seeming features, while common, aren't universally supported. If you want them, you'll have to find a provider that has them. + +- Federated protocol. +- Feature-bare; no gimmicks. +- Generally supports file sharing. +- Supports end-to-end encryption, but it's not the default and it's kinda janky. +- While integration with WebRTC voice chat is supported, it's not universal, and some people prefer to use a separate voice chat system, such as Mumble, in conjunction with XMPP text chat. +- You'll have to find a provider and choose a client program to connect with. Fortunately, there's plenty of options, and the official XMPP website lists some of each. + +### Matrix + +Matrix is the other major federated instant messaging protocol. It was standardized in 2014 and is built around making end-to-end encryption easy. On top of that, it has more features. File sharing is included by default and support for nice-to-have features like emoji reactions (and maybe custom emojis??) and Discord-style replies is widespread. There's also a large suite of bridges to other services, including Discord. Like with XMPP, voice chat integration is possible, but not universal, and some prefer to use Mumble or similar. + +- Federated protocol. +- More features than XMPP, similar situation with voice calls though. +- Built around end-to-end encryption, though you can disable it, and you will need to for integrations like bots and bridges. +- As with XMPP, you'll need to find a provider and a client program. The website lists quite a few clients, and you can find a list of servers here. + +### Mumble and Jitsi + +Mumble and Jitsi are self-hostable voice chat and videoconferencing applications, respectively. They're not messaging systems, but I feel they bear mentioning here because they're both popular for use in conjunction with text chat systems, and since nothing else here currently supports screensharing. + +### Revolt + +We've about run out of open protocols (which is probably a good thing), so now on to the centralized services, starting with Revolt. Revolt is basically trying to be open-source Discord. It's currently in alpha, but the user experience is very similar and it already has some of the fun stuff. + +From what I could find Revolt isn't currently controlled by any kind of legal entity, so there's no guarantee it won't eventually incorporate into a for-profit company and pull a Reddit (by which I mean, Reddit used to be open-source, but hasn't been since 2017), but at least for now the project leaders express principles that make that seem unlikely. + +- Centralized service. +- Still early in development. +- Very similar in UI/UX to Discord. +- No paywalls. +- Supports voice, but not currently video. +- No encryption, but E2EE for DMs is being worked on. +- Has features like custom emojis, replies, public guilds and a friends list. + +### Signal + +I've now run out of Discord-likes - which is to say, programs that support the sort of multi-channel group chat thing Discord has going on. This and the next one function more in the vein of a Whatsapp clone, though I feel they still bear mentioning in the event that's all you need. + +Signal is kind of *the* private messaging app. It's fundamentally built around end-to-end encryption in a way that its biggest direct competitors simply aren't. It's been proven in court that Signal literally doesn't have the ability to incriminate you, since they can't access the contents of your messages. It does need your phone number, though, however you can now hide it with a username. It also supports voice and video chat, and stickers, apparently. + +- Centralized service. +- Similar to Whatsapp in terms of UI/UX. +- Emphasis on end-to-end encryption. +- Supports voice and video calls. +- Requires a phone number, but only a phone number. +- You can set a username, so you don't need to share your phone number. + +### Session + +I lied, Session isn't centralized. But it's not decentralized in the same way as the federated protocols up there, either. Session runs over an anonymizing onion routing network, Tor-style, meaning not only can your messages not be read by the server, those servers also don't know both the sender and the destination at the same time. Essentially, it's designed to maximize privacy and anonymity at all costs. But wouldn't you know it, that comes at a cost in terms of features and user experience. + +Session does also use cryptocurrency. Setting a custom display name and running a node on its decentralized network both require participation in a blockchain, though your messages aren't sent via this blockchain. + +- Decentralized, encrypted, and anonymous. +- Supports voice and video calls, but currently only 1:1. +- Requires no personal details to sign up. +- No extra features. +- Setting a display name requires a crypto transaction, but sending messages does not. + +## Conclusion + +That's about all I've got. I hope I've impressed upon you the importance of Discord's core problems, and introduced you to at least one alternative that works for you. I have my preferences, but I'm comfortable recommending all of these over Discord, otherwise I wouldn't have listed them. + +[Update 2023-09-09] I no longer recommend Matrix over XMPP for reasons explained well here. I knew there was a little jank but I had no idea the rot ran this deep. Fortunately, nobody's listened to me yet so I can switch over to XMPP without much issue, which I intend to do. + +[Update 2024-04-27] I have removed Telegram from the recommendations list outright due to just, straight up nazism, and in a post announcing cryptocurrency features no less. Jesus H. Christ. + +If there's one thing I want you to take away from this article, it's this: Don't fall for the marketing and don't let yourself be wooed by extraneous gimmicks. Be discerning about which fancy-sounding features you actually need. If you want to have a chance of escaping the vicious corporate cycle of enshittification, both with chat platforms and with everything else, make sure the ones you use have a strong foundation of sustainability and trustworthiness, beyond whatever marketing drivel is on the front page of their website. Hopefully I've given you at least some tools to determine for yourself which ones do. + +## Further Reading + +- Enshittification +- A simplified breakdown of Discord's TOS (ToS;DR) +- Spyware Watchdog - Discord +- A different explanation of federation in the context of federated social media +- A privacy-focused comparison of messenger apps + +
+ +
\ No newline at end of file diff --git a/blog/posts/discord/index.php b/blog/posts/discord/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/discord/index.php @@ -0,0 +1 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/posts/fediverse_dms/index.md b/blog/posts/fediverse_dms/index.md new file mode 100644 index 0000000..a12c503 --- /dev/null +++ b/blog/posts/fediverse_dms/index.md @@ -0,0 +1,19 @@ +People who refuse to use the fediverse (often conflated with Mastodon) often cite concerns about privacy with regards to DMs as their reason for avoiding it; "admins can read your DMs" and all that. To be fair, that's technically a true statement, but it's more complicated than that. Now, I have no problem letting these people be wrong - I'm not eager to convince idiots with no capacity for critical thinking to come to my favourite social network - but I'm nothing if not endlessly pedantic, so I felt the need to explain my take on the issue anyway. + +## DMs Are A Lie + +To begin with, the term "DM" as it applies to other social platforms is kind of a misnomer in the case of the Fediverse. Websites like Twitter and Instagram have a dedicated chat-style interface for messaging people directly. If you spend five minutes with most fediverse software, you'll notice that it doesn't have this. + +Sending a DM on the fediverse is generally accomplished by making a normal post and changing the visibility setting to only show the post to people who are mentioned in it. This isn't a case of obtuse UX design, it reflects how DMs on the fediverse actually work under the hood: The underlying protocol has *no concept* of direct messages, and is only able to approximate them with a special flag on an otherwise normal post. + +In other words, when you send a "DM" on the fediverse, what you're really doing is making a public post, and asking the network nicely to only show it to the person it's intended for. All software that isn't actively malicious or *extremely* shitty will comply with this request, and in fact admins can only read your DMs by circumventing the instance software and accessing the backend database directly, but the post is in no way actually private. + +## This Is Fine Actually + +I don't personally think this is an issue; I think it's perfectly fine that the fediverse doesn't attempt to do secure communication. Doing things this way reduces liability for server owners and reduces the complexity of the software for developers, and you really should be able to contact anyone who you actually want to keep in touch with on multiple platforms anyway. + +Besides, it's not like insecure DMs are an issue unique to the fediverse. DMs on [Twitter/Instagram/Reddit/etc] aren't encrypted either, meaning the admins of those websites can read your DMs too. Same for actual dedicated chat platforms like Discord and (mostly) Telegram. Twitter's admins can read your DMs, Discord's admins can read your messages, Gmail's admins can read your emails, and your phone provider can read your texts. And they often do, to sell information about you to advertisers or comply with police requests or what have you. + +It's only slightly less of a problem on those platforms because you're much less likely to know the admins personally, and individual staff members could probably lose their jobs if they used the contents of your DMs to start drama. That said, I've personally never seen evidence of any admin *actually* reading someone's DMs on the fediverse, because doing that is a *huge pain in the ass* involving like, SQL queries and shit, and is much harder than any actual administrative task most fediverse admins will ever do. + +Either way, you should really be using an actually secure messaging service if privacy is important to you. Be the change you want to see in the world and become that person who insists on taking conversations in Twitter DMs to Signal. I'm being completely serious. \ No newline at end of file diff --git a/blog/posts/fediverse_dms/index.php b/blog/posts/fediverse_dms/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/fediverse_dms/index.php @@ -0,0 +1 @@ +/etc/searxng/settings.yml

+ +``` +enabled_plugins: + - 'Hostname replace' +hostname_replace: + '(.*\.)?codegrepper\.com': false + '(.*\.)?geeksforgeeks\.org': false +``` + +Then restart SearXNG: + +``` +service uwsgi restart searxng +``` \ No newline at end of file diff --git a/blog/posts/guide_blacklist_websites_searxng/index.php b/blog/posts/guide_blacklist_websites_searxng/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/guide_blacklist_websites_searxng/index.php @@ -0,0 +1 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/posts/guide_blocking_user_agents_nginx/bg.svg b/blog/posts/guide_blocking_user_agents_nginx/bg.svg new file mode 100644 index 0000000..27062a8 --- /dev/null +++ b/blog/posts/guide_blocking_user_agents_nginx/bg.svg @@ -0,0 +1,2 @@ + +file_type_nginx \ No newline at end of file diff --git a/blog/posts/guide_blocking_user_agents_nginx/index.md b/blog/posts/guide_blocking_user_agents_nginx/index.md new file mode 100644 index 0000000..763ea4d --- /dev/null +++ b/blog/posts/guide_blocking_user_agents_nginx/index.md @@ -0,0 +1,73 @@ +Recently, Cloudflare has launched a clumsy, poorly-executed attempt to centralize the fediverse on their platform known as Wildebeest. There are a few reasons not to want to use it, and you probably don't want to be federating with it either. However, blocking every instance running it on sight would be both tedious and ineffective. + +The way I've chosen to deal with this is to just configure my reverse proxy, Nginx, to deny connections from anything with "wildebeest" in the user agent string. There are several other good reasons to do this, such as blocking bots that ignore robots.txt, or adapting this approach to serve specialized pages to old browsers, or just denying access to anything that isn't Chrome if you want to earn your place in the 9th circle of Hell. + +I'm assuming here that you already know the basics of configuring Nginx, otherwise this article won't really be of much use to you. + +## How to do it + +Paste this into the main `server` block of your Nginx config to instantly drop the connection to any client with a "Wildebeest" (case insensitive) user agent: + +

/etc/nginx/sites-available/yoursite

+ +``` +if ($http_user_agent ~* (wildebeest)) { + return 444; +} +``` + +## More configuration + +If all you want is to block Wildebeest and forget about it, you can leave now. If you want to customize this behavior further, read on. + +### Different HTTP responses + +444 is a custom response code in Nginx that just drops the connection immediately. You can use any other HTTP error code you like, for example to return a `403 Forbidden` error: + +``` + return 403; +``` + +To issue a permanent redirect to some other URL: + +``` + return 301 https://example.org/; +``` + +Or just to be silly :3 + +``` + return 418; +``` + +### Block multiple user agents + +You can also block multiple user agents in one statement like so: + +

/etc/nginx/sites-available/yoursite

+ +``` +if ($http_user_agent ~* (wildebeest|GPTBot)) { + return 444; +} +``` + +### Includes + +One thing I'd recommend doing is moving all your user agent blocks to a separate file that you can include in all your Nginx sites. I place this file at `/etc/nginx/includes/bans`: + +

/etc/nginx/includes/bans

+ +``` +if ($http_user_agent ~* (wildebeest|GPTBot)) { + return 444; +} +``` + +

/etc/nginx/sites-available/yoursite

+ +``` +include /etc/nginx/includes/bans; +``` + +The `include` statement goes in your `server` block as before. diff --git a/blog/posts/guide_blocking_user_agents_nginx/index.php b/blog/posts/guide_blocking_user_agents_nginx/index.php new file mode 100644 index 0000000..f572f79 --- /dev/null +++ b/blog/posts/guide_blocking_user_agents_nginx/index.php @@ -0,0 +1 @@ + + + + + + + +