- Scan-ID:
- ed34c212-a800-47f4-b4cd-a704b1be151fBeendet
- Eingereichte URL:
- https://blog.myhro.info/
- Bericht beendet:
Links · 31 gefunden
Die von der Seite ausgehenden identifizierten Links
Link | Text |
---|---|
https://notes.myhro.info/ | Notes |
https://talks.myhro.info/ | Talks |
https://github.com/gorhill/uBlock | uBlock Origin |
https://github.com/uBlockOrigin/uBlock-issues/wiki/About-Google-Chrome's-%22This-extension-may-soon-no-longer-be-supported%22 | This extension may soon no longer be supported |
https://developer.chrome.com/docs/extensions/develop/migrate/mv2-deprecation-timeline | ongoing deprecation of Manifest V2 |
https://www.osnews.com/story/140947/googles-ad-blocking-crackdown-underway/ | Some articles suggest that there’s no hope |
https://github.com/uBlockOrigin/uBOL-home | uBlock Origin Lite |
https://adguard.com/ | AdGuard |
https://adguard-dns.io/en/public-dns.html | block via DNS |
https://www.dropbox.com/ | Dropbox |
JavaScript-Variablen · 3 gefunden
Globale JavaScript-Variablen, die in das Window Object einer Seite geladen werden, sind Variablen, die außerhalb von Funktionen deklariert werden und von jeder Stelle des Codes innerhalb des aktuellen Bereichs zugänglich sind
Name | Typ |
---|---|
onbeforetoggle | object |
documentPictureInPicture | object |
onscrollend | object |
Konsolenprotokoll-Meldungen · 1 gefunden
In der Web-Konsole protokollierte Meldungen
Typ | Kategorie | Protokoll |
---|---|---|
error | network |
|
HTML
Der HTML-Rohtext der Seite
<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 -->
<title>Myhro Blog</title>
<meta name="generator" content="Jekyll v3.9.5">
<meta property="og:title" content="Myhro Blog">
<meta name="author" content="Tiago Ilieve">
<meta property="og:locale" content="en_US">
<link rel="canonical" href="/">
<meta property="og:url" content="/">
<meta property="og:site_name" content="Myhro Blog">
<meta property="og:type" content="website">
<link rel="next" href="/page/2">
<meta name="twitter:card" content="summary">
<meta property="twitter:title" content="Myhro Blog">
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"WebSite","author":{"@type":"Person","name":"Tiago Ilieve"},"headline":"Myhro Blog","name":"Myhro Blog","url":"/"}</script>
<!-- End Jekyll SEO tag -->
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="/feed.xml" title="Myhro Blog"></head>
<body><header class="site-header" role="banner">
<div class="wrapper"><a class="site-title" rel="author" href="/">Myhro Blog</a><nav class="site-nav">
<input type="checkbox" id="nav-trigger" class="nav-trigger">
<label for="nav-trigger">
<span class="menu-icon">
<svg viewBox="0 0 18 15" width="18px" height="15px">
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
</svg>
</span>
</label>
<div class="trigger"><a class="page-link" href="/about/">About</a><a class="page-link" href="/archives/">Archives</a><a class="page-link" href="https://notes.myhro.info/">Notes</a>
<a class="page-link" href="https://talks.myhro.info/">Talks</a>
</div>
</nav></div>
</header>
<main class="page-content" aria-label="Content">
<div class="wrapper">
<div class="home">
<h1 class="page-heading">Posts</h1>
<ul class="post-list">
<li>
<span class="post-meta">Oct 20, 2024</span>
<h2>
<a class="post-link post-title" href="/2024/10/ad-blocking-in-a-manifest-v3-world">Ad-blocking in a Manifest V3 world</a>
</h2>
<article class="post-content">
<p>I started receiving warnings on Chrome about <a href="https://github.com/gorhill/uBlock">uBlock Origin</a>, stating, “<a href="https://github.com/uBlockOrigin/uBlock-issues/wiki/About-Google-Chrome's-%22This-extension-may-soon-no-longer-be-supported%22">This extension may soon no longer be supported</a>”, after I set it up on a new computer nearly three months ago. These warnings are related to the <a href="https://developer.chrome.com/docs/extensions/develop/migrate/mv2-deprecation-timeline">ongoing deprecation of Manifest V2</a>, which has been going on for a few years and is expected to be finalized by June next year. I can’t even imagine using the internet without an ad blocker, so I decided to explore the current alternatives.</p>
<p>To be honest, the process was a bit daunting. <a href="https://www.osnews.com/story/140947/googles-ad-blocking-crackdown-underway/">Some articles suggest that there’s no hope</a> unless you switch to a browser supported by a company that doesn’t rely on ads - something that doesn’t really exist. In situations like this, I tend to try the simplest, most straightforward solution first before diving into more complex, over-the-top options. In this case, I decided to switch to the Manifest V3-based extension from the same developers: <a href="https://github.com/uBlockOrigin/uBOL-home">uBlock Origin Lite</a>.</p>
<p>The experience was actually better than I expected. Even in “Basic” mode, which doesn’t require permission to read or change data on all sites, it worked quite well with the default filters. I did notice some empty ad boxes, as the page layouts aren’t reworked, but that’s something I’m already used to when visiting sites on mobile with <a href="https://adguard.com/">AdGuard</a> (doing the <a href="https://adguard-dns.io/en/public-dns.html">block via DNS</a>). No need to change to the “Optimal” mode for now.</p>
<p>In fact, enabling the “Overlay Notices” and “Other Annoyances” filter lists made the experience even more pleasant than before. There are no more “please disable your ad-block” or “please donate to this site using Google” overlays to disrupt my browsing. So while the transition from V2 to V3 may have been a hassle for extension developers, as an end-user, I can’t say I’m unhappy with it. I’m still experiencing the (mostly) ad-free internet I was used to.</p>
</article>
</li>
<li>
<span class="post-meta">Aug 18, 2024</span>
<h2>
<a class="post-link post-title" href="/2024/08/the-cloud-won-again">The cloud won, again</a>
</h2>
<article class="post-content">
<p><a href="/2018/03/how-i-finally-migrated-my-whole-website-to-the-cloud">Since 2018</a> (and <a href="/2020/01/the-cloud-computing-era-is-now">again in 2020</a>), I’ve been writing about how defaulting to cloud-based solutions instead of self-hosting everything has changed my life for the better. Even knowing that for years, I still made the wrong decision to self-host a service I needed and almost doubled down on doing it again. This was until I stopped and figured out an easier way to achieve the same goal.</p>
<p>I’ve been a <a href="https://www.dropbox.com/">Dropbox</a> user for nearly 15 years. It really simplified my approach to backups for personal stuff: a cloud-synced folder on my laptop where I put everything that’s not already on a cloud service. Accidentally deleted something? I can just go to their web app and restore it. The problem is that I don’t want it offering a read-write version of this folder on every device I have. Sometimes I just need a temporary folder to drop a screenshot from my Windows gaming machine so I can access it from my phone.</p>
<p><a href="https://www.resilio.com/sync/">Resilio Sync</a> (previously known as BitTorrent Sync) is what I was using for that. It has a few problems, including being super slow even after configuring everything possible to bypass its relay servers (spoiler: it doesn’t). Plus, it doesn’t have cloud-backed storage, so I ran an instance of it on a server to have an always-on copy of the files there. Not exactly a drop-in replacement for Dropbox, but it was still useful until I realized I was completely unhappy with its performance.</p>
<p>Things were reaching a point where I was considering self-hosting <a href="https://nextcloud.com/">Nextcloud</a> (fork of the original ownCloud) just for its file-syncing feature or even writing my own cloud-folder synchronization tool backed by S3-compatible storage. That’s when it clicked: I realized I don’t need real-time syncing for the simple use case of easily sharing single files from a computer to my phone. I just needed a way to access a Cloudflare R2 bucket from a mobile app.</p>
<p>After looking around, asking <a href="https://chatgpt.com/">ChatGPT</a> and <a href="https://www.perplexity.ai/">Perplexity</a>, I settled on <a href="https://apps.apple.com/us/app/s3-files-bucket-storage/id6447647340">S3 Files</a>. I can upload a file from Windows using <a href="https://winscp.net/">WinSCP</a> or from a macOS/Linux terminal using <a href="https://s3tools.org/s3cmd">s3cmd</a>. Each machine uses a fine-grained access key I can revoke if needed. The S3 API is ubiquitous. I just needed a mobile app to access it when I’m away from my computer. It offered me the ease, speed, availability, and robustness of the cloud, which are miles ahead compared to self-hosting anything.</p>
</article>
</li>
<li>
<span class="post-meta">Jul 24, 2024</span>
<h2>
<a class="post-link post-title" href="/2024/07/introducing-myhro-notes">Introducing Myhro Notes</a>
</h2>
<article class="post-content">
<p>Writing is hard. I’ve been writing in this blog since 2011, when posts were still written in Portuguese - those have since been deleted. It hasn’t gotten any easier after nearly 15 years. Posts still take hours to be written, proofread and double-checked before being published. On top of that, much of the energy I have to write longer chunks of text is spent on project documentation, issues and pull request descriptions, both in and out of work-related duties. The result is that posts on this blog are becoming rare - this is the first one for the entire year.</p>
<p>But it doesn’t need to always be like that. Not every piece of advice or knowledge I’d like to share needs to be in a long blog article format. Sometimes I discover something useful, either through my own exploration or based on someone else’s experience, and I share it with close friends with a small comment of a few sentences. This happens on Slack workspaces, WhatsApp groups or even in direct messages. In the end, I thought: what if I write this for the wider internet and share the link with the same people, instead of writing directly to them?</p>
<p>Based on the concept of “blogmarks”, where small blog posts are used to share links that, in a distant past, would be bookmarked to <a href="https://en.wikipedia.org/wiki/Delicious_(website)">del.icio.us</a>, I started <a href="https://notes.myhro.info/">Myhro Notes</a>. There’s usually one or two short paragraphs adding context, explaining why the link is interesting. They are listed by date, like a blog, but only the title is visible on the home page. The posts themselves will eventually be available on search engines. I expect my future self to be one of its users looking for content posted there.</p>
</article>
</li>
<li>
<span class="post-meta">Dec 23, 2023</span>
<h2>
<a class="post-link post-title" href="/2023/12/managing-podman-containers-with-systemd">Managing Podman containers with systemd</a>
</h2>
<article class="post-content">
<p>Since my early days in programming, I’ve always worried about isolated development environments. Of course, this wasn’t relevant when developing C applications with no external dependencies in <a href="https://www.codeblocks.org/">Code::Blocks</a>, but it soon became a necessity when I had to deal with Python packages through <a href="https://virtualenv.pypa.io/">virtualenv</a>. The same happened with Ruby versions using <a href="https://github.com/rbenv/rbenv">rbenv</a>. Later I settled on <a href="https://asdf-vm.com/">asdf</a> to do that with multiple Go/Node.js versions, which basically solved the problem for good for many programming languages and even some CLI tools that are sensible to versioning, like <code class="language-plaintext highlighter-rouge">kubectl</code>.</p>
<p>But dealing with multiple runtimes or packages is just one piece of the equation in the grand schema of cleanly handling dependencies. Sometimes you have to worry about the versions of the external services a project makes use of, like a database or cache system. This is also a solved problem since <a href="https://en.wikipedia.org/wiki/Docker_(software)">Docker</a> came into the picture over 10 years ago. I remember that the Docker Compose mantra when it launched (<a href="https://web.archive.org/web/20140802222736/http://www.fig.sh/">still called Fig</a>) was: “<em>no more installing Postgres on your laptop!</em>”. This is just a bit more complicated when you don’t use the original Docker implementation, but another container management system, like <a href="https://podman.io/">Podman</a>.</p>
<p>Podman offers several advantages over Docker. It can run containers without requiring <code class="language-plaintext highlighter-rouge">root</code> access; it doesn’t depend on a service daemon running all the time; and it doesn’t require <a href="https://www.docker.com/pricing/">a paid subscription depending on the usage</a>. It’s a simpler tool, with an almost 1:1 compatible UI overall. The main difference is that it doesn’t seamlessly handle containers with <code class="language-plaintext highlighter-rouge">--restart</code> flags. I mean, of course it does restart containers when their processes are interrupted, but they won’t be brought up after a host reboot - which tends to happen from time to time in a workstation.</p>
<p>When looking into how to solve this problem, I realised that the <code class="language-plaintext highlighter-rouge">podman generate</code> command can create <a href="https://systemd.io/">systemd</a> service unit files. So instead of tinkering about how to integrate the two tools, figuring the file syntax and functionality, it’s possible to just create a new systemd service of the desired container as if it were any other program/process. And the best part is that we can still do that without <code class="language-plaintext highlighter-rouge">root</code>, thanks to <a href="https://wiki.archlinux.org/title/systemd/User">systemd user services</a>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ podman create --name redis -p 6379:6379 docker.io/redis:7
Trying to pull docker.io/library/redis:7...
(...)
$ mkdir -p ~/.config/systemd/user/
$ podman generate systemd --name redis > ~/.config/systemd/user/redis.service
</code></pre></div></div>
<p>To increase the service’s reliability, it’s preferable to drop the <code class="language-plaintext highlighter-rouge">PIDFile</code> line from the configuration file. It typically looks like:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PIDFile=/run/user/1000/containers/vfs-containers/c1b1c3e5dba5368c29ada52a638378e5fec74e1a62e913919528b9c3846c14bb/userdata/conmon.pid
</code></pre></div></div>
<p>This ensures that even if the container is recreated, like when updating its image, systemd won’t be referencing its older ID, as it will only care about its name. This can be done programmatically with <code class="language-plaintext highlighter-rouge">sed</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sed -i '/PIDFile/d' ~/.config/systemd/user/redis.service
</code></pre></div></div>
<p>The generated file should be similar to:</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># container-redis.service
# autogenerated by Podman 4.3.1
# Sat Dec 23 17:18:01 -03 2023
</span>
<span class="nn">[Unit]</span>
<span class="py">Description</span><span class="p">=</span><span class="s">Podman container-redis.service</span>
<span class="py">Documentation</span><span class="p">=</span><span class="s">man:podman-generate-systemd(1)</span>
<span class="py">Wants</span><span class="p">=</span><span class="s">network-online.target</span>
<span class="py">After</span><span class="p">=</span><span class="s">network-online.target</span>
<span class="py">RequiresMountsFor</span><span class="p">=</span><span class="s">/run/user/1000/containers</span>
<span class="nn">[Service]</span>
<span class="py">Environment</span><span class="p">=</span><span class="s">PODMAN_SYSTEMD_UNIT=%n</span>
<span class="py">Restart</span><span class="p">=</span><span class="s">on-failure</span>
<span class="py">TimeoutStopSec</span><span class="p">=</span><span class="s">70</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/podman start redis</span>
<span class="py">ExecStop</span><span class="p">=</span><span class="s">/usr/bin/podman stop </span><span class="se">\
</span> <span class="s">-t 10 redis</span>
<span class="py">ExecStopPost</span><span class="p">=</span><span class="s">/usr/bin/podman stop </span><span class="se">\
</span> <span class="s">-t 10 redis</span>
<span class="py">Type</span><span class="p">=</span><span class="s">forking</span>
<span class="nn">[Install]</span>
<span class="py">WantedBy</span><span class="p">=</span><span class="s">default.target</span>
</code></pre></div></div>
<p>The final step consists in starting the service and enabling it to launch on boot:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ systemctl --user start redis
$ systemctl --user enable redis
Created symlink /home/myhro/.config/systemd/user/default.target.wants/redis.service → /home/myhro/.config/systemd/user/redis.service.
$ systemctl --user status redis
● redis.service - Podman container-redis.service
Loaded: loaded (/home/myhro/.config/systemd/user/redis.service; enabled; preset: enabled)
Active: active (running) since Sat 2023-12-23 17:25:40 -03; 13s ago
Docs: man:podman-generate-systemd(1)
Tasks: 17 (limit: 37077)
Memory: 11.1M
CPU: 60ms
CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/redis.service
├─46851 /usr/bin/slirp4netns --disable-host-loopback --mtu=65520 --enable-sandbox --enable-seccomp --enable-ipv6 -c -e 3 -r 4 --netns-type=path /run/user/1000/netns/netns-102ff957-157c-adcb-bd4a-45e7e0d2a50f tap0
├─46853 rootlessport
├─46859 rootlessport-child
└─46869 /usr/bin/conmon --api-version 1 -c c1b1c3e5dba5368c29ada52a638378e5fec74e1a62e913919528b9c3846c14bb -u c1b1c3e5dba5368c29ada52a638378e5fec74e1a62e913919528b9c3846c14bb -r /usr/bin/crun -b /home/myhro/.local/share/(...)
Dec 23 17:25:40 leptok redis[46869]: 1:C 23 Dec 2023 20:25:40.071 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * monotonic clock: POSIX clock_gettime
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * Running mode=standalone, port=6379.
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * Server initialized
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * Loading RDB produced by version 7.2.3
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * RDB age 18 seconds
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * RDB memory usage when created 0.83 Mb
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * Done loading RDB, keys loaded: 0, keys expired: 0.
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * DB loaded from disk: 0.000 seconds
Dec 23 17:25:40 leptok redis[46869]: 1:M 23 Dec 2023 20:25:40.072 * Ready to accept connections tcp
</code></pre></div></div>
<p>In summary, I quite liked how easy it was to leverage the strengths of both the Podman and systemd in their integration. Being able to do that in a rootless way is definitely a huge plus. Before doing that, I always believed that managing Linux services was a root-only thing. But now that I think about it, I realize that when Docker was the only game in town, managing containers also required elevated privileges. I’m glad that we are moving away from this idea, piece by piece.</p>
</article>
</li>
<li>
<span class="post-meta">May 4, 2023</span>
<h2>
<a class="post-link post-title" href="/2023/05/mikrotik-hap-ac3-review">MikroTik hAP ac3 Review</a>
</h2>
<article class="post-content">
<p>As I <a href="/2022/01/mikrotik-hex-rb750gr3-review">mentioned in the previous review</a>, my experience with the MikroTik router that only supported wired networking encouraged me to look for a Wi-Fi one. After browsing the available models, the slogan of a particular one, the <a href="https://mikrotik.com/product/hap_ac3">hAP ac3</a>, caught my attention:</p>
<blockquote>
<p>Forget about endless searching for the perfect router and scrolling through an eternity of reviews and specifications! We have created a single affordable home access point that has all the features you might need for years to come.</p>
</blockquote>
<p>A highly configurable router, with gigabit wired networking and dual-band 2.4 and 5 GHz Wi-Fi at an affordable price (abroad, where it costs US$ 99, not here where it costs R$ 800)? It seemed like exactly what I was looking for.</p>
<h1 id="findings">Findings</h1>
<p>After spending 3 hours configuring the wired router, I thought to myself: “Ah, now that I know how MikroTik works, it’ll be easy. 15 or 20 minutes and everything will be working.” What a mistake. The interface is literally the same with an additional <code class="language-plaintext highlighter-rouge">Wireless</code> option in the menu, but even setting a password on the unprotected Wi-Fi network was challenging. I really scratched my head trying to understand how things worked and spent another 2 hours configuring it in the way I wanted.</p>
<p>Configuring the 5 GHz Wi-Fi transmission, in particular, was quite difficult. It has a “radar detection” system to use higher frequencies (5.5-5.6 GHz) that takes literally 10 minutes (!) on each boot to decide which one to use, time in which the wireless network remains unavailable during this process. To avoid frustration, I manually chose a lower frequency option (5.1-5.2 GHz).</p>
<p>After everything was configured, I noticed that the 5 GHz Wi-Fi signal was weaker in other rooms than it used to be with my TP-Link router. Weak enough for iOS to automatically fall back to 4G. Along with the weaker signal came a drop in connection speed. On my MacBook, it fell from 400 to 200 Mbps, and on my iPhone from 200 to 100 Mbps, both measured at <a href="https://fast.com/">Fast.com</a> in other rooms, compared to the TP-Link router I intended to replace. Although that would be sufficient bandwidth to cover most of my use cases, it seemed unacceptable to downgrade the speed I was used to, given the price and quality I expected from the device.</p>
<p>The solution was to go back to a setup identical to the wired MikroTik: connecting the TP-Link router to the new MikroTik and using only the Wi-Fi from the former. In router mode, the speed loss was the same. In access point mode, I achieved the same speed as before when connecting the TP-Link directly to the modem or the wired MikroTik.</p>
<h1 id="conclusion">Conclusion</h1>
<p>It wasn’t a very wise decision to buy a more expensive model because of Wi-Fi and ultimately not use it, but the experience was valuable. It still solves my Dual WAN support issue, albeit in a less than ideal way, and I could return the borrowed MikroTik. I couldn’t exactly pinpoint why its 5 GHz network was so much slower than the TP-Link, but I’ve encountered similar situations caused by software (as the same has happened to me with DD-WRT) in a not-so distant past. It’s not what I expected from MikroTik, a device whose software is precisely its selling point, but who knows. Today, if I were to set up the same system without having the TP-Link router available, I would get a simpler wired MikroTik and connect a Unifi AP to it. It would be the best of both worlds and the cost would be virtually the same.</p>
</article>
</li>
</ul>
<div>
<div style="width: 50%; float: left;">
<p><a href="/page/2" class="next">« Older</a></p>
</div>
<div style="width: 50%; float: right;">
</div>
</div>
<div style="clear: both"></div>
</div>
</div>
</main><footer class="site-footer">
<div class="wrapper">
<div class="footer-col-wrapper" style="margin-left: 0;">
<div style="width: 50%; float: left;">
<p>Copyright © 2024 - Tiago Ilieve</p>
</div>
<div style="width: 50%; float: right;">
<p style="text-align: right;">
Powered by <a href="https://jekyllrb.com/">Jekyll</a>
</p>
</div>
</div>
</div>
</footer>
</body></html>