<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0">
	<title type="text">hakthepla.net</title>

	<updated>2026-02-26T23:23:15.464628Z</updated>

	<link rel="alternate" type="text/html" href="https://hakthepla.net/" />
	<id>https://hakthepla.net/</id>
	<link rel="self" type="application/atom+xml" href="https://hakthepla.net/atom.xml" />
        <entry>
          <author><name>madcap</name><uri>https://hakthepla.net</uri></author>
          <title type="html">Hacking the URL schema</title>
          <link rel="alternate" type="text/html" href="https://hakthepla.net/blog/2025-11-20-hacking-the-url-schema.html" />
          <id>https://hakthepla.net/blog/2025-11-20-hacking-the-url-schema.html</id>
          <published>2025-11-20T00:00:00Z</published>
          <updated>2025-11-20T00:00:00Z</updated>
          <content type="html">
            &lt;h1&gt;Hacking the URL schema&lt;/h1&gt;
            &lt;p&gt;A while ago I submitted an article to the 2600 magazine. It was published in the Autumn issue of 2024. For those who don&amp;#x27;t know the 2600 magazine (2600 - The Hacker Quarterly), it&amp;#x27;s a publication about hacking and technology that has been around for 41 years. Check it out:&lt;/p&gt;
&lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;https://2600.com&quot;&gt;https://2600.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since it&amp;#x27;s been a year since my article has been published, I thought it was time to release online. So, here it is (with some minor corrections and updates). I hope you enjoy it.&lt;/p&gt;
&lt;h2&gt;Let&amp;#x27;s hack&lt;/h2&gt;
&lt;p&gt;Let&amp;#x27;s talk a little about the ancient art of generating URL&amp;#x27;s that look legit and similar to some address that you may know. There are several ways to do it. &lt;/p&gt;
&lt;p&gt;The most common technique is called typosquatting and relies on the typos that we make when typing an address on the address bar.  Like goggle.com or paypall.com. Although we get to those malicious sites by mistyping a website address, many people would also click on a link with that URL not really noticing the typo.&lt;/p&gt;
&lt;p&gt;There are also homograph attacks which rely on the fact that different characters can look very similar, like the capital I and the lower case L. Also there are different alphabets (latin, greek, cyrillic) that have very similar symbols.&lt;/p&gt;
&lt;p&gt;But in this article I&amp;#x27;m going to focus on a different kind of attack called &amp;quot;URL Schema Obfuscation&amp;quot;. It&amp;#x27;s so good that it allows you to create a fake URL that looks pretty normal and you don&amp;#x27;t even have to register a fake domain.&lt;/p&gt;
&lt;p&gt;Let&amp;#x27;s say that you receive a legitimate looking link to a supposedly enraging tweet by some billionaire that you love to hate:&lt;/p&gt;
&lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;http://twitter.com∕elonmusk∕status∕@2672109077&quot;&gt;http://twitter.com∕elonmusk∕status∕@2672109077&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You click on it. But instead, you&amp;#x27;re taken somewhere else. In this case, you would be taken to a homepage with a video you may have see before.&lt;/p&gt;
&lt;p&gt;How did this happen? Let&amp;#x27;s split the above address in parts and start by the end.&lt;/p&gt;
&lt;p&gt;The 2672109077 part, which looks like the id of a tweet, is indeed a disguised IP address in decimal format. This is a valid format, although most people don&amp;#x27;t know. An IP address is, in fact, a 32 bit number. It&amp;#x27;s easier to represent it in the normal dotted notation, separating it in 4 parts, each part having 8 bits, like we usually do. But we can as well use it in decimal format.&lt;/p&gt;
&lt;p&gt;Let&amp;#x27;s say that we want our victims to be redirected to a prank website, which in this case has the IP address 159.69.38.21. First, start by converting each part of that address into binary format:&lt;/p&gt;
&lt;p&gt;10011111.01000101.00100110.00010101&lt;/p&gt;
&lt;p&gt;Remove the dots, obtaining a 32 bit value, and then convert it to a decimal number:&lt;/p&gt;
&lt;p&gt;binary 10011111010001010010011000010101 = decimal 2672109077&lt;/p&gt;
&lt;p&gt;Now, if you paste that decimal number into your browser&amp;#x27;s address bar, preceding it with http://, you will be taken to the prank website. Try it: &lt;/p&gt;
&lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;http://2672109077&quot;&gt;http://2672109077&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But what about the rest of the URL (twitter.com/elonmusk/status/@)? Well, this part also has some tricks in it. &lt;/p&gt;
&lt;p&gt;First there&amp;#x27;s the at sign (@). That character, when placed before a domain name, means that you want to authenticate to that site using some username. Let&amp;#x27;s say you wanted to sign as user jaime at the site joana-blog.net. You would type http://jaime@joana-blog.net. This is not a very common means of authentication (nor a secure one), but it&amp;#x27;s a valid one. It was common in the old days to authenticate to FTP servers.&lt;/p&gt;
&lt;p&gt;So, at the example given above, you would be authenticating at http://2672109077 with the username &amp;quot;twitter.com/elonmusk/status/&amp;quot;.&lt;/p&gt;
&lt;p&gt;Kind of. If you type that manually on your address bar, the browser it will see those slashes and invalidate all that I&amp;#x27;ve been saying. But instead of using regular forward slashes we can use a unicode character that looks like a slash but is instead interpreted as a regular character. In my example I&amp;#x27;m using the unicode character U+2215 (division slash). You can see more details about it here:&lt;/p&gt;
&lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;https://codepoints.net/U+2215&quot;&gt;https://codepoints.net/U+2215&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, after these small manipulations, you end up with a normal looking URL that will trick anyone because it looks like a valid address. That teaches us that we should be very careful when clicking random links even when they look legit (don&amp;#x27;t click links on suspicious emails, remember?) &lt;/p&gt;
&lt;p&gt;Since this method only works when using http (instead of https), if you see a link that starts with http:// you should probably avoid it. If in doubt, try typing the address manually into your browser. &lt;/p&gt;
&lt;p&gt;Another thing you should do is use Firefox as your main browser. Firefox shows a warning saying that you&amp;#x27;re trying to login to a website that doesn&amp;#x27;t request authentication. Something like this:&lt;/p&gt;
&lt;p&gt;You are about to log in to the site &amp;quot;159.69.38.21&amp;quot; with the username &amp;quot;twitter.com&amp;quot;. &lt;/p&gt;
&lt;p&gt;(I wonder how many people will still click &amp;quot;OK&amp;quot; after this message, anyway)&lt;/p&gt;
&lt;p&gt;Unfortunately Google Chrome doesn&amp;#x27;t show that warning. And you know what? 7 out of 10 people use Google Chrome or some variant of it, which makes an attack like this pretty efficient.&lt;/p&gt;
&lt;p&gt;This is not a complicated method, but I created a python script to make the creation of these URL&amp;#x27;s easier:&lt;/p&gt;
&lt;pre&gt;#!/bin/python3

import sys

URL_TEMPLATE = &amp;quot;http://{}@{}&amp;quot;

if len(sys.argv) != 3:
    print(&amp;quot;Usage: ./obfuscate_url.py &amp;lt;fake_address&amp;gt; &amp;lt;real_ip_address&amp;gt;\n&amp;quot; \
    &amp;quot;Example: ./url_schema_obfuscation.py twitter.com/elonmusk 194.150.169.131&amp;quot;)
    exit(-1)

fake_addr = sys.argv[1]
real_ip_addr = sys.argv[2]

username_part = (
    fake_addr.replace(&amp;quot;http://&amp;quot;, &amp;quot;&amp;quot;)
    .replace(&amp;quot;https://&amp;quot;, &amp;quot;&amp;quot;)
    .replace(&amp;quot;/&amp;quot;, &amp;quot;\u2215&amp;quot;)
)

ip_parts = real_ip_addr.split(&amp;quot;.&amp;quot;)
binary_string = &amp;quot;&amp;quot;

for part in ip_parts:
    binary_string += &amp;quot;{0:08b}&amp;quot;.format(int(part))

print(URL_TEMPLATE.format(username_part, int(binary_string, 2)))
&lt;/pre&gt;
&lt;p&gt;Be safe and beware of any links with an at sign!&lt;/p&gt;

          </content>
        </entry>
        <entry>
          <author><name>madcap</name><uri>https://hakthepla.net</uri></author>
          <title type="html">Prevent M$ Teams from changing your status to Away</title>
          <link rel="alternate" type="text/html" href="https://hakthepla.net/blog/2025-11-03-prevent-teams-away-status.html" />
          <id>https://hakthepla.net/blog/2025-11-03-prevent-teams-away-status.html</id>
          <published>2025-11-03T00:00:00Z</published>
          <updated>2025-11-03T00:00:00Z</updated>
          <content type="html">
            &lt;h1&gt;Prevent M$ Teams from changing your status to Away&lt;/h1&gt;
            &lt;p&gt;If, like me, you are a Linux user and have to use M$ Teams because of your $dayjob, you may be confused by the fact that your status keeps changing to Away, even when you&amp;#x27;re using your computer. Only when you hover your mouse pointer over Teams does it decide to wake up and change your status back to Available.&lt;/p&gt;
&lt;p&gt;To prevent this from happening, you just have to trick it into thinking that you&amp;#x27;re periodically hovering your mouse pointer over it.&lt;/p&gt;
&lt;p&gt;M$ Teams, on Linux, runs in the browser or as a progressive web app (PWA), which allows us to easily inject javascript code and change its behavior:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Open Teams, press F12 to access the browser&amp;#x27;s DevTools&lt;/li&gt;
&lt;li&gt;Click on Console&lt;/li&gt;
&lt;li&gt;Run this script to simulate a `mousemove` event:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;function moveMouse() {
    const event = new MouseEvent(&amp;#x27;mousemove&amp;#x27;, { clientX: 0, clientY: 0 });
    window.dispatchEvent(event);
}

setInterval(moveMouse, 30000);

&lt;/pre&gt;
&lt;p&gt;You can run this every time you open the application or automate its execution. There are several add-ons that allow you to do this. I&amp;#x27;m not going to compare them, so choose the one you like best.&lt;/p&gt;

          </content>
        </entry>
        <entry>
          <author><name>madcap</name><uri>https://hakthepla.net</uri></author>
          <title type="html">My magazine scanning workflow</title>
          <link rel="alternate" type="text/html" href="https://hakthepla.net/blog/2025-04-22-my-magazine-scanning-workflow.html" />
          <id>https://hakthepla.net/blog/2025-04-22-my-magazine-scanning-workflow.html</id>
          <published>2025-04-22T00:00:00Z</published>
          <updated>2025-04-22T00:00:00Z</updated>
          <content type="html">
            &lt;h1&gt;My magazine scanning workflow&lt;/h1&gt;
            &lt;p&gt;As you may have noticed, I&amp;#x27;ve been scanning my complete collection of Cyber.net magazines. This post serves as a mental note of the steps I use to scan and publish each issue.&lt;/p&gt;
&lt;h2&gt;Step 1 - Scan&lt;/h2&gt;
&lt;p&gt;First I scan the magazine using my flatbed scanner (a CanoScan 9000F) at 300DPI, using the following software:&lt;/p&gt;
&lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;https://gitlab.com/sane-project/frontend/xsane&quot;&gt;XSane for Linux&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;#x27;s say the output is a file named magazine_original.pdf.&lt;/p&gt;
&lt;h2&gt;Step 2 - resize file&lt;/h2&gt;
&lt;p&gt;Since the generated file is too big, I usually resize it, using ghostscript:&lt;/p&gt;
&lt;pre&gt;gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress -dNOPAUSE -dQUIET -dBATCH -sOutputFile=magazine.pdf magazine_original.pdf
&lt;/pre&gt;
&lt;p&gt;Instead of /prepress, we can use /printer to obtain a smaller file, but I think image quality is too low.&lt;/p&gt;
&lt;h2&gt;Step 3 - Set metadata info&lt;/h2&gt;
&lt;p&gt;Now, set the metadata of the PDF to whatever you desire, using exiftool. Eg:&lt;/p&gt;
&lt;pre&gt;exiftool -Title=&amp;quot;Cyber.net #25 (1997)&amp;quot; -Producer=&amp;quot;Your name&amp;quot; -Keywords=&amp;quot;revista internet portugal cyber net&amp;quot; -Subject=&amp;quot;Revista portuguesa dedicada à Internet (1995-1998)&amp;quot; cybernet_25.pdf
&lt;/pre&gt;
&lt;h2&gt;Step 4 - Upload to Internet Archive&lt;/h2&gt;
&lt;p&gt;There are likely effective tools available for OCRing the PDF, but my approach is:&lt;/p&gt;
&lt;p&gt;1. Upload file to Internet Archive&lt;/p&gt;
&lt;p&gt;2. Let Internet Archive generate a copy with OCR&lt;/p&gt;
&lt;p&gt;You have to wait a few minutes or hours between step 1 and 2.&lt;/p&gt;
&lt;p&gt;After that long wait, go to the page of your uploaded file in the Internet Archive, and you should find a file named PDF WITH TEXT in the &amp;quot;DOWNLOAD OPTIONS&amp;quot; section.&lt;/p&gt;
&lt;p&gt;3. Download that file&lt;/p&gt;
&lt;p&gt;The file is usually much smaller than the file you uploaded.&lt;/p&gt;
&lt;h2&gt;Step 5 - Merge PDF OCR and PDF hi-res&lt;/h2&gt;
&lt;p&gt;Now you should have 2 files:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;magazine.pdf - the file you uploaded to the Archive&lt;/li&gt;
&lt;li&gt;magazine_text.pdf - the file you downloaded from the Archive (with OCR).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this step we want to merge both files, resulting in a file that has the quality of the first file and the OCR text of the second.&lt;/p&gt;
&lt;p&gt;1. Create a bash script named pdf-merge-text.sh with the following content:&lt;/p&gt;
&lt;pre&gt;#!/usr/bin/env bash

set -eu

pdf_merge_text() {
    local txtpdf; txtpdf=&amp;quot;$1&amp;quot;
    local imgpdf; imgpdf=&amp;quot;$2&amp;quot;
    local outpdf; outpdf=&amp;quot;${3--}&amp;quot;
    if [ &amp;quot;-&amp;quot; != &amp;quot;${txtpdf}&amp;quot; ] &amp;amp;&amp;amp; [ ! -f &amp;quot;${txtpdf}&amp;quot; ]; then echo &amp;quot;error: text PDF does not exist: ${txtpdf}&amp;quot; 1&amp;gt;&amp;amp;2; return 1; fi
    if [ &amp;quot;-&amp;quot; != &amp;quot;${imgpdf}&amp;quot; ] &amp;amp;&amp;amp; [ ! -f &amp;quot;${imgpdf}&amp;quot; ]; then echo &amp;quot;error: image PDF does not exist: ${imgpdf}&amp;quot; 1&amp;gt;&amp;amp;2; return 1; fi
    if [ &amp;quot;-&amp;quot; != &amp;quot;${outpdf}&amp;quot; ] &amp;amp;&amp;amp; [ -e &amp;quot;${outpdf}&amp;quot; ]; then echo &amp;quot;error: not overwriting existing output file: ${outpdf}&amp;quot; 1&amp;gt;&amp;amp;2; return 1; fi
    (
        local txtonlypdf; txtonlypdf=&amp;quot;$(TMPDIR=. mktemp --suffix=.pdf)&amp;quot;
        trap &amp;quot;rm -f -- &amp;#x27;${txtonlypdf//&amp;#x27;/&amp;#x27;\\&amp;#x27;&amp;#x27;}&amp;#x27;&amp;quot; EXIT
        gs -o &amp;quot;${txtonlypdf}&amp;quot; -sDEVICE=pdfwrite -dFILTERIMAGE &amp;quot;${txtpdf}&amp;quot;
        pdftk &amp;quot;${txtonlypdf}&amp;quot; multistamp &amp;quot;${imgpdf}&amp;quot; output &amp;quot;${outpdf}&amp;quot;
    )
}

pdf_merge_text &amp;quot;$@&amp;quot;
&lt;/pre&gt;
&lt;p&gt;2. Make it executable:&lt;/p&gt;
&lt;pre&gt;chmod u+x pdf-merge-text.sh
&lt;/pre&gt;
&lt;p&gt;3. Finally, execute the script to merge both files. Example:&lt;/p&gt;
&lt;pre&gt;~/pdf-merge-text.sh magazine_text.pdf magazine.pdf magazine_final.pdf
&lt;/pre&gt;
&lt;p&gt;4. A file named magazine_final.pdf is created. Publish it, store it, do whatever you want with it.&lt;/p&gt;

          </content>
        </entry>
        <entry>
          <author><name>madcap</name><uri>https://hakthepla.net</uri></author>
          <title type="html">Blocking big instances might save the Fediverse</title>
          <link rel="alternate" type="text/html" href="https://hakthepla.net/blog/2023-12-21-blocking-huge-instances-might-save-the-fediverse.html" />
          <id>https://hakthepla.net/blog/2023-12-21-blocking-huge-instances-might-save-the-fediverse.html</id>
          <published>2023-12-21T00:00:00Z</published>
          <updated>2023-12-21T00:00:00Z</updated>
          <content type="html">
            &lt;h1&gt;Blocking big instances might save the Fediverse&lt;/h1&gt;
            &lt;p&gt;A few days ago, the new social network Threads fulfilled the promise it made a few months ago. It started testing the implementation of ActivityPub, the protocol responsible for the interoperability between all the instances of Mastodon, Pleroma, Lemmy, PixelFed (what we like to call the Fediverse).&lt;/p&gt;
&lt;p&gt;Back in July, when it was announced that this new social network was planning to implement ActivityPub, the Fediverse was divided over whether to allow or to block federation with it. Now we&amp;#x27;re back in this debate, but now we know they&amp;#x27;re really doing it.&lt;/p&gt;
&lt;p&gt;This whole discussion centers on the fact that Threads is yet another product of Meta, the tech giant that owns Facebook, Instagram and Whastapp. In fact, to use Threads you must have an Instagram account.&lt;/p&gt;
&lt;p&gt;Many of us who lurk in the Fediverse view this move by Meta with suspicion. Tech giants have a long history of adopting open protocols when they are favorable to their business and abandoning them when they have already built a big user base and don&amp;#x27;t want those to flee to other platforms. Examples abound. The most famous are those of the RSS protocol, abandoned by Google Reader, and the XMPP/Jabber protocol, abandoned by Google Talk and Facebook Messenger.&lt;/p&gt;
&lt;p&gt;There&amp;#x27;s little doubt that the same could happen with ActivityPub. If Meta is currently considering adopting it, it&amp;#x27;s because they think they can get some commercial benefit from it. But if this strategy doesn&amp;#x27;t work, if they reach the conclusion that it is in fact detrimental to their financial health, the protocol will certainly be abandoned.&lt;/p&gt;
&lt;p&gt;Many fear that this could happen, that the Fediverse will become too dependent on a single instance where most of the users host their accounts.&lt;/p&gt;
&lt;p&gt;Many even think that that is in fact Meta&amp;#x27;s big evil plan. They will enter the Fediverse, build a big user base and abandon it, leaving all the other users wishing they were on Threads so they can continue to interact with the majority of their contacts. But does that make any sense? Just a few hours after Threads was launched, it already had more users than the entire Fediverse. Why would they want to extinguish something that can&amp;#x27;t stand up to them?&lt;/p&gt;
&lt;p&gt;We all know in fact who their main rival is: Twitter, the social network that launched the concept of microblogging but has become a nightmare after being acquired by its new billionaire last year . And yes, there is also another potential competitor: BlueSky, the new social network launched by the former billionaire of Twitter, Jack Dorsey. It was supposedly designed from the start to be decentralized, but so far this has been nothing more than promises.&lt;/p&gt;
&lt;p&gt;Maybe this whole adoption of ActivityPub thing is some kind of plan to win this space. I have no idea. But I know they&amp;#x27;re not doing it just because they believe in decentralization. If they did believe, why haven&amp;#x27;t they implemented it on Facebook or Instagram? Why do we even need an account to read posts from those platforms? Why don&amp;#x27;t they make their users&amp;#x27; posts available via RSS so that we can follow them without accessing their platform, like Mastodon has done from the beginning?&lt;/p&gt;
&lt;p&gt;A very interesting feature of Mastodon is the ease with which you can migrate an account from one server to another, bringing all the followers from the old account to the new one. According to Eugen Rochko (Gargron), Mastodon&amp;#x27;s creator, his &amp;quot;wife is looking forward to deleting her Instagram account once she can connect with the same folks from her Mastodon account. Being able to remain in touch with over 100M people who still use Meta products out of the comfort of an ad-free, privacy-friendly platform like Mastodon is a game changer&amp;quot;.&lt;/p&gt;
&lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;https://mastodon.social/@Gargron/111591822065763831&quot;&gt;Read Gargron&amp;#x27;s post here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What Gargron doesn&amp;#x27;t tell us is how he expects that to happen. First of all, ActivityPub is being tested on Threads, not Instagram. But let&amp;#x27;s imagine that Instagram goes down that road too. Can you imagine Instagram implementing an account migration feature that allows its users to move away to a Mastodon instance? I can see it happening in the opposite direction, sure. But believing that Meta will allow any celebrity to leave its platform while keeping their millions of followers, is totally naive.&lt;/p&gt;
&lt;p&gt;Even if they did allow it, and if they somehow managed to monetize posts from other servers, it would still be a huge risk if those celebrities&amp;#x27; followers also decided to migrate to the same server where the &amp;quot;cool people&amp;quot; are now.&lt;/p&gt;
&lt;p&gt;But wait a minute. Why am I so critical of Meta&amp;#x27;s plan, when I&amp;#x27;ve always been and advocate for interoperability? And, like me, why are so many other defenders of open protocols wary of federation with Threads? Isn&amp;#x27;t it contradictory that, now that this platform is going to adopt one of those protocols, we are so suspicious and thinking of blocking it in our accounts and on our servers? Aren&amp;#x27;t we the ones who compare ActivityPub with SMTP, the successful protocol that allows email to also be a decentralized and federated system?&lt;/p&gt;
&lt;p&gt;Well, when we advocate the adoption of open protocols, what we&amp;#x27;re really saying is that anyone with some technical ability can create and manage a server. If so many people can do it, then the existence of servers that hold a majority of users is completely unnecessary. There are currently thousands of Mastodon servers (instances.social currently lists almost 17,000). Most of those only have a few dozen users. This is what we call decentralization. It&amp;#x27;s the possibility for a community to have its own corner of the Internet, free and independent of the big tech infrastructure. On the other hand, if a majority of users are centered on a single server, can we really call that decentralization? Multiple servers orbiting a massive server, resembles a centralized system more than the opposite.&lt;/p&gt;
&lt;p&gt;I&amp;#x27;ve thought about this a lot and I believe that the way forward is to block any instance that becomes a threat to the existence of the Fediverse by accumulating a significant percentage of users. I&amp;#x27;m not only talking about Threads, Instagram, Twitter, Tik Tok, etc. I&amp;#x27;m saying that we should also block any instance of Mastodon that grows beyond a reasonable size. Yes, Gargron, we&amp;#x27;re keeping an eye on your instance, too. Just like we block instances with hateful content, we should block any instance that may be toxic to the environment. That means blocking ones that are, or have become, bigger than they should be.&lt;/p&gt;
&lt;p&gt;Basically, and going back to the email analogy, we don&amp;#x27;t want another Gmail. We want diversity.&lt;/p&gt;
&lt;p&gt;But, unfortunately, not everyone agrees with blocking these platforms, which means that the Fediverse is split between blocking and non-blocking instances. In the latter, users will be able to interact with those trapped in Threads. In the former, this won&amp;#x27;t be possible.&lt;/p&gt;
&lt;p&gt;Perhaps some users will migrate from the blocking instances to permissive ones where they will be able to follow Cristiano Ronaldo or Kim Kardashian&amp;#x27;s posts. I&amp;#x27;d rather look at the bright side of it and enjoy that some other people will choose to delete their big tech social accounts and move to smaller instances where they will be able to interact with the many interesting people and communities who have chosen to keep control of their own data and posts.&lt;/p&gt;
&lt;p&gt;Blocking is taking care of our space. It means keeping it healthy and free from manipulative algorithms, targeted advertising and dark patterns. Blocking is the best way to send out the message that we&amp;#x27;re fine as we are and don&amp;#x27;t need Zuckerbergs or Musks to get what, after all, we already have.&lt;/p&gt;

          </content>
        </entry>
        <entry>
          <author><name>madcap</name><uri>https://hakthepla.net</uri></author>
          <title type="html">Hacking a custom homepage for your Mastodon instance</title>
          <link rel="alternate" type="text/html" href="https://hakthepla.net/blog/2023-01-19-hacking-a-custom-homepage-for-your-mastodon-instance.html" />
          <id>https://hakthepla.net/blog/2023-01-19-hacking-a-custom-homepage-for-your-mastodon-instance.html</id>
          <published>2023-01-19T00:00:00Z</published>
          <updated>2023-01-19T00:00:00Z</updated>
          <content type="html">
            &lt;h1&gt;Hacking a custom homepage for your Mastodon instance&lt;/h1&gt;
            &lt;p&gt;Starting with version 4.0.0, Mastodon&amp;#x27;s homepage is not that great. It defaults to the &amp;quot;explore&amp;quot; page that basically shows the public timeline of that instance. If you want to know more you have to click on the &amp;quot;Learn more&amp;quot; button and then you&amp;#x27;re presented with the about page that shows the long description of the instance, the rules and the list of moderated servers. And it all shows up in a column centered on the page, which is kinda limiting.&lt;/p&gt;
&lt;p&gt;You can add some html tags to the description of the instance. That is good. But you can&amp;#x27;t do it in the rules section, where you can&amp;#x27;t even add hyperlinks.&lt;/p&gt;
&lt;p&gt;In our instance, Ciberlândia, we decided to hack a custom homepage:&lt;/p&gt;
&lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;https://ciberlandia.pt&quot;&gt;https://ciberlandia.pt&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Looks good, doesn&amp;#x27;t it? aiscarvalho and rlafuente did a great work with the design of the page.&lt;/p&gt;
&lt;p&gt;We didn&amp;#x27;t want to mess with the Mastodon source code, so we did it all by hacking a few rules in the NGINX config.&lt;/p&gt;
&lt;h2&gt;Step 1: Create your homepage html&lt;/h2&gt;
&lt;p&gt;SSH to your server as the mastodon user (or sudo - mastodon if you&amp;#x27;re already logged in as root).&lt;/p&gt;
&lt;p&gt;Create the directory where your html will be. We used /home/mastodon/live/custom-index/. Put your index.html, images and css files in there.&lt;/p&gt;
&lt;h2&gt;Step 2: Add rules to NGINX config&lt;/h2&gt;
&lt;p&gt;In this step you have to be logged in as root.&lt;/p&gt;
&lt;p&gt;Edit the file /etc/nginx/sites-available/mastodon and add these lines (don&amp;#x27;t forget to change you Content-Security-Policy according to your needs):&lt;/p&gt;
&lt;pre&gt;# START CUSTOM HOMEPAGE

location /welcome {
  rewrite ^ /welcome/ redirect;
}

location /welcome/ {
  alias /home/mastodon/live/custom-index/;
  add_header Content-Security-Policy &amp;quot;default-src &amp;#x27;none&amp;#x27;; font-src &amp;#x27;self&amp;#x27;; img-src &amp;#x27;self&amp;#x27; data:; script-src &amp;#x27;self&amp;#x27;; style-src &amp;#x27;self&amp;#x27;; frame-ancestors &amp;#x27;none&amp;#x27;; base-uri &amp;#x27;none&amp;#x27;; form-action &amp;#x27;none&amp;#x27;&amp;quot;;
  add_header X-XSS-Protection &amp;quot;1; mode=block&amp;quot;;
  add_header Strict-Transport-Security &amp;#x27;max-age=31536000; includeSubDomains; preload&amp;#x27;;
  add_header X-Frame-Options &amp;quot;SAMEORIGIN&amp;quot;;
  add_header X-Content-Type-Options nosniff;
}

location = / {                                                             
  if ($cookie__session_id = &amp;quot;&amp;quot;) {
    rewrite ^/$ https://&amp;lt;**your instance url in here**&amp;gt;/welcome/ redirect;
  }                                                                                                                                                      
  try_files $uri @proxy;                                                   
}                                   

# END CUSTOM HOMEPAGE
&lt;/pre&gt;
&lt;h2&gt;Step 3: restart NGINX&lt;/h2&gt;
&lt;p&gt;Run this:&lt;/p&gt;
&lt;pre&gt;systemctl restart nginx
&lt;/pre&gt;
&lt;p&gt;Now when a user tries to access the root of your site, NGINX will check if the user is logged in (checking the value of the cookie session_id) and redirect them to your custom page which is located at the /welcome/ path.&lt;/p&gt;
&lt;p&gt;If the user is logged in, they will of course be served the default Mastodon interface.&lt;/p&gt;
&lt;p&gt;[EDIT 2023-03-12] Added security headers&lt;/p&gt;

          </content>
        </entry>

</feed>

