Feuerfest

Just the private blog of a Linux sysadmin

trustscope.app corrects the Google reviews situation in Germany at least a little bit

If you ever reviewed a business on Google in Germany you may be familiar with this mail:

In Germany it is pretty easy to get rid of bad, but honest, reviews. The business owner just needs to claim the review is defamatory and Google has to remove it. Shifting the burden of prove towards the reviewer. Often this includes lengthy discussions with lawyers as many business use the services of specialised law-firms.

Which also creates a scenario of financial ruin for people as legal battles can be costly and mistakes are easily made..

As I wrote recently Google now started to display the approximately number of deleted reviews due to defamation. Creating a crucial metric which enables Google Map users to reach an informed decision.

And it didn't take long for someone to scrape that data and take it into account when calculating the "real" score of a business. Of course these numbers are just an approximation, and we have no data on rightfully vs. wrongfully deleted reviews. After all, it is still a nice project: https://trustscope.app/

Comments

Using PowerShell to get the size of folders (Get-FolderSize function)

On my gaming PC Windows complained that C:\ had only 10GB of free space left. Time to free up some space! In WindowsXP times I used a separate Program called GetFolderSize for this, but nowadays with PowerShell I was like: "Hey, I bet I can do this with PowerShell alone."

After a bit of back & forth I came up with the following function:

function Get-FolderSize {
    param([string]$Path = ".")
    Get-ChildItem $Path -Directory -Force | ForEach-Object {
        $bytes = (Get-ChildItem $_.FullName -Recurse -File -Force -ErrorAction SilentlyContinue |
                  Measure-Object Length -Sum).Sum
        [PSCustomObject]@{ Folder = $_.Name; Bytes = [long]$bytes }
    } | Sort-Object Bytes -Descending |
      Format-Table Folder,
        @{n='Size(MB)';e={'{0:N2}' -f ($_.Bytes/1MB)}},
        @{n='Size(GB)';e={'{0:N2}' -f ($_.Bytes/1GB)}} -AutoSize
}

It worked fine. However I always needed to copy & paste it into the current PowerShell window to have the function available. Hence I had a new question: How do I make this function available for my local Windows? How do I add this function to the PowerShell equivalent of a .bashrc?

I myself was surprised I didn't know how to do this. Never needed it before apparently. And at customers PowerShell and/or UserProfiles are always locked down so that I can't do such stuff.

Making a PowerShell function constantly available

Microsoft has some documentation available about the $PROFILE variable: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-7.6

First I tested if I already have a $PROFILE for the current user on the current host. This turned out to be false:

PS C:\Users\USER> Test-Path $PROFILE
False

Hence I simply create the $PROFILE:

PS C:\Users\USER> New-Item -ItemType File -Path $PROFILE -Force


    Verzeichnis: C:\Users\USER\Documents\WindowsPowerShell


Mode        LastWriteTime         Length  Name
----        -------------         ------  ----
-a----      8/8/2026   4:44 PM         0  Microsoft.PowerShell_profile.ps1

Now I can edit my $PROFILE and the Get-FolderSize function:

PS C:\Users\USER> notepad $PROFILE

Then just copy&paste the function in the Microsoft.PowerShell_profile.ps1 file:
(Note the screenshot shows an older version of the code.)

After that we need to source the $PROFILE again to have it available. Just like on Linux:

PS C:\Users\USER> . $PROFILE

And it works just fine:

PS C:\Users\USER\AppData> Get-FolderSize .

Folder   Size(MB)  Size(GB)
------   --------  --------
Local    53,609.24 52.35
Roaming  10,956.81 10.70
LocalLow 9,207.82  8.99

Alternatives

PowerShell Gallery

Only later did I learn of the site https://www.powershellgallery.com/, they collect scripts from the community and make them available. There seems to be a good script here, however I didn't use it.

Microsoft SysInternal DiskUsage Utility

There is a du tool from SysInternals available here: https://learn.microsoft.com/en-us/sysinternals/downloads/du. Downloading that and putting the binary in the $PATH should do the trick to. However I did not check if the output matches my desired format.

Comments

How to counter enshittyfication in consumer products

The start: Knockoff browser extension

A few weeks ago I wrote a post about the Knockoff browser extension which helps consumers to filter out cheap and bogus brands from the Amazon search results. Now I found two websites which help me even more in a) filtering out/recognising bad brands and b) find good brands that still produce quality products which are worth their price.

Discovering: Worse on Purpose.com

It all started when I noticed that the WMF Clip&Close ice cube box is similar to the one produced by EMSA. And both had the same worse reviews as the plastic doesn't seem to be made for storing in freezes as it breaks easily and constantly. Naturally I was curious why WMF sells such crappy products.

And I found the solution on a webpage called Worse on Purpose. In the article Your Cookware Got Worse On Purpose author Keyana Sapp writes in detail about how family-owned companies are bought by international conglomerates who just seek to own the established brand name known for it's high quality products, to sell their cheap & crappy stuff.

The solution to this curiosity was rather boring. Under the headline Six companies, eighty-one brands we learn that both companies are owned by Groupe SEB (Wikipedia) who bought WMF & EMSA in 2016 and is, according to Wikipedia, the world's largest manufacturer of cookware.

Great, that will definitely not have any impace on the quality of WMF products rights? Oh wait.. There have been numerous factories closed since 2025...

The Brand Legder

Worse on Purpose operates The Brand Ledge where you can search for brands and companies names to get a small overview and can now decided for yourself if you still trust that brand. Takes this example for WMF: https://ledger.worseonpurpose.com/brands/wmf

Neat! And very handy!

BuyItForLife.com, the Chef'n Juicer & WMF

I don't really know what to make out of buyitforlife.com. It's a website seemingly vetting products the website owner has used/is using himself.

He states and the frontpage:

Browse 500+ Buy It For Life products I've personally vetted for quality and longevity. Compare where they're made, warranty, category, and price in seconds.
Source: https://buyitforlife.com/

And on the about page:

This list isn't sponsored or biased. It's just me, someone who likes well-built products, going down a rabbit hole to find things that are actually built to last.
Source: https://buyitforlife.com/about

Why I am experiencing such an uneasy feeling when reading that site?

Well, I found the site today. I was search for a manually operated lemon/citrus squeezer/press. The WMF one looked nice at first for 38,99€ but luckily the  Chef'n PalmZester (22,79€) was displayed right next to it.. And.. Well look for yourself:

First the Chef'n model in yellow, than the WMF one in black. They are exactly the same model, just different colours. And apparently black is 16€ more expensive.. Yeah, are you kidding me!?

     

Amazon reviews on both products state, that it breaks after just 1 year of regular usage. As apparently the plastic can't deal with the stress and breaks at some point. Wow.

What is even more interesting: Chef'n is owned by Lifetime Brands Inc.

And that is a totally different company which as nothing to do with Group SEB who owns WMF. This proves, again, that the brand WMF now stands for nothing. Just a shell used to sell cheap products for a higher price.

Good job capitalism!

BuyItForLife however has this product listed on it's site. Among many other products from companies which Worse on Purpose has on it's Watchlist or where people on Reddit say for years that the products became shittier over the time. I think this is my problem with that site. BuyItForLife is just a single person without any special knowledge. Just recommending products he finds useful. That's fair. Nothing against that, but it isn't as objective as it claims to be. It's just a single persons opinion - marketed as something more...

Nowhere on the site can I read a detailed review about a product. All links point directly to Amazon. No "This is why I recommend that item", nothing. For me, personally, this simply doesn't add up. So no, I'm not going to recommend that site.

Comments

TinyMCE: Configure iframe sandboxing to allow YouTube domains

In TinyMCE 6.8.1 (the WYSIWYG editor used by Bludit) iframe sandboxing was introduced. This automatically added the sandbox="false" attribute to all inserted <iframe>-tags. Starting with version 7 it was changed to sandbox="" and this blocks all embedded videos from playing, even when the CSP-Headers are correct.

As I just wanted to write a short blogpost about a YouTube video which discusses why we Germans are able to eat raw pork ("Mett") and suddenly the video wasn't displayed in the editor-view. Browser console showed no problems with CSP-Headers and so I was left to searching..

YouTube gave me the following <iframe> block for embedding the video:

<iframe width="560" height="315"
 src="https://www.youtube-nocookie.com/embed/azdV7EzP0v4?si=sKj7zfe0OkVNxjsi" title="YouTube video player"
 frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
 referrerpolicy="strict-origin-when-cross-origin"
 allowfullscreen>
</iframe>

However, after copy&pasting that into the TinyMCE in Bludit and saving the article, it changed to:

<iframe width="560" height="315"
 src="https://www.youtube-nocookie.com/embed/azdV7EzP0v4?si=sKj7zfe0OkVNxjsi" title="YouTube video player"
 frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
 referrerpolicy="strict-origin-when-cross-origin"
 allowfullscreen="allowfullscreen"
 sandbox="">
</iframe>

And the added sandbox-attribute triggers the following error in the browser console:

GET https://www.youtube-nocookie.com/img/meh7.png NS_BINDING_ABORTED
A resource is blocked by OpaqueResponseBlocking, please check browser console for details.

Of to the search engine I went and luckily the TineMCE folks wrote so in their release notes:

Note: sandbox_iframes: is set to false by default, which is the existing behavior. This is because enabling sandbox_iframes may break existing media embeds such as YouTube, Vimeo, and Codepen, as actions such as scripting and same-origin access are prevented.
Source: https://www.tiny.cloud/docs/tinymce/6/6.8.1-release-notes/#new-sandbox_iframes-option-that-controls-whether-iframe-elements-will-be-added-a-sandbox-attribute-to-mitigate-malicious-intent

Which is why I was able to find it so quickly.

When the youtube-nocookie.com domain is missing in TinyMCE

I later learned that TinyMCE already includes a list of pre-defined exclusions for iFrame sandboxing: https://www.tiny.cloud/docs/tinymce/latest/content-filtering/#example-using-sandbox_iframes_exclusions-option

However youtube-nocookie.com is missing here, as can be seen in the code: https://github.com/tinymce/tinymce/blob/main/modules/tinymce/src/core/main/ts/api/Options.ts#L907

There is an older ticket to fix this but it contained no pull request: https://github.com/tinymce/tinymce/issues/9617

So I took the liberty and created one: https://github.com/tinymce/tinymce/pull/11260 let's hope this will do it.

The fix

I fixed it, by adding the YouTube domains to the iframe-exclusion tag inside the File bludit-folder/bl-plugins/tinymce/plugins.php.

  1. Add the sandbox_iframes: true, line
  2. The exclusions are defined for the three most used YouTube-domains: youtube.com, youtube-nocookie.com, youtu.be
    • Yes, this will overwrite the default TinyMCE list and effectively remove all other entries, but for me it works 😄

        tinymce.init({
                selector: "#jseditor",
                auto_focus: "jseditor",
[...]
                link_default_target: '_blank',
                sandbox_iframes: true,
                sandbox_iframes_exclusions: [
                        'youtube.com',
                        'youtube-nocookie.com',
                        'youtu.be'
                ]
        });

Now your TinyMCE behaves like before and embedding videos works again.

Comments

Why we Germans can eat Mett (aka: raw pork)

Everything I ever wanted to know about Mett. Honestly I was just bored when I clicked on that video, thought of it to have a bit of over-promising/misleading title.

But that turned out to be wrong. Oliver Kim or Microbehunter explains in detail why we Germans are able to eat Mett. Which is somewhat of a oddity, given that raw pork can be dangerous and is frowned upon in many cultures and countries.

He explains the bacteria involved and also the system Germany has in place to ensure the meat is healthy. And this was really something new for me. I know that Germany is often praised for it's good infrastructure, however never had I considered uninterrupted cold-chains and strict meat controls to be a part of that. Turns out, Oliver is right, to offer raw pork at any butchery or even bread rolls with Mett as ready-to-eat items in bakeries is quite an achievement.

Source: https://www.youtube.com/watch?v=azdV7EzP0v4

Comments

Booting an Ubuntu LTS cloud-init QEMU VM inside a Proxmox VM

I needed a quick throwaway Ubuntu VM for some testing, so I reached for the classic combo: an Ubuntu cloud image, a local cloud-init NoCloud datasource served over HTTP, and a bare qemu-system-x86_64 invocation. Nothing fancy, I've done this a dozen times before - just that the last time was ages ago..

My first attempt looked like this:

root@vm:~# qemu-system-x86_64 -net nic \
    -net user -machine accel=kvm:tcg -m 512 \
    -nographic -hda noble-server-cloudimg-amd64.img \
    -smbios type=1,serial=ds='nocloud;s=http://127.0.0.1:8000/'

And of course, it didn't just work. Last time I did was ages ago and directly on the hardware of my rootserver, not my local Proxmox server. As it turned out, I had two separate problems in this command, and to make things even more interesting: Everything is executed inside a Debian 13 VM, which itself lives on top of Proxmox. A VM inside a VM. So every weirdness I hit had to be checked twice. Once for "Is this a QEMU problem?" and once for "Is this a nested-virtualization problem?".

Preface

I created the directory /root/temp and but the files there according to the cloud-init QEMU tutorial. Then I started a webserver via the http.server Python module.

Have a look at https://docs.cloud-init.io/en/latest/tutorial/qemu.html#define-the-configuration-data-files regarding the files and the content.

Problem 1: Stuck at "Booting from Hard Disk..."

The VM wouldn't get past the SeaBIOS boot message "Booting from Hard Disk...". It became stuck there, forever. Additionally I saw no request to the local webserver on port 8000/tcp.

Turns out this is entirely expected, once you know why. Ubuntu's released Noble Numbat (LTS) cloud image is built for UEFI boot. SeaBIOS, the legacy BIOS QEMU uses by default, has no idea what to do with the GPT-partitioned disk and just... stops. No error, no hint, just sitting at "Booting from Hard Disk...".

EDIT October 2026: This turned out to be wrong. Ubuntu themselves document booting the image with SeaBIOS and UEFI here: https://ubuntu.com/docs/public-images/public-images-how-to/launch-qcow-with-qemu/

Hence the OVMF stuff shouldn't be necessary. I suspect that my TCG fallback was to blame for this error, but this is speculation as so far I couldn't be bothered to try and reproduce the error. If you do, please let me know via the comments!

EDIT END

The fix is to hand the VM the proper UEFI firmware via the Open Virtual Machine Firmware (OVMF) package instead of relying on SeaBIOS:

apt-get install ovmf

If you find older posts, they mention the /usr/share/OVMF/OVMF_VARS.fd file, but on Debian 13 there's a small surprise waiting here too, the package no longer ships the plain OVMF_CODE.fd or OVMF_VARS.fd files I was used to. Instead you get the 4M variants:

root@vm:~# ls /usr/share/OVMF/OVMF_VARS_4M.*
/usr/share/OVMF/OVMF_VARS_4M.fd  /usr/share/OVMF/OVMF_VARS_4M.ms.fd  /usr/share/OVMF/OVMF_VARS_4M.snakeoil.fd

The .ms.fd variant ships with Microsoft's Secure Boot certificates pre-enrolled, and .snakeoil.fd is pre-signed with a test certificate for Secure Boot development. Neither is what I wanted, so plain OVMF_VARS_4M.fd it is, paired with the matching OVMF_CODE_4M.fd. CODE and VARS need to come from the same "generation" (2M vs. 4M), mixing them doesn't end well.

You also don't want to point QEMU directly at the VARS file in /usr/share/OVMF/, copy it locally first, since QEMU will write to it (that's where your EFI variables actually live):

root@vm:~# cp /usr/share/OVMF/OVMF_VARS_4M.fd .

Problem 2: Wrong IP for the webserver

While I was at it, I remembered that the datasource URL is used inside the guest and therefore refers to the guest itself, not my Proxmox VM serving the cloud-init files. With QEMU's user-mode networking -net user, the host is reachable from inside the guest at the fixed address 10.0.2.2. And since I'm serving the metadata over HTTP rather than a local path, nocloud-net is the correct datasource identifier, not nocloud.

Putting it together:

root@vm:~# qemu-system-x86_64 \
  -machine q35,accel=kvm:tcg \
  -m 512 \
  -nographic \
  -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \
  -drive if=pflash,format=raw,file=./OVMF_VARS_4M.fd \
  -drive file=noble-server-cloudimg-amd64.img,if=virtio,format=qcow2 \
  -net nic -net user \
  -smbios type=1,serial=ds='nocloud-net;s=http://10.0.2.2:8000/'

That got me past the boot prompt. Progress.

NOTE: Confusingly this changed with cloud-init 24(?) nocloud is solely used and depending on if file:// or http:// is used it automatically detects how to work.

Problem 3: It boots, but agonizingly slowly

The VM eventually made it into the kernel, but everything crawled. The console was full of entries like this:

[  116.771971] workqueue: drm_fb_helper_damage_work hogged CPU for >10000us 32 times, consider switching to WQ_UNBOUND
Starting systemd-udevd version 255.4-1ubuntu8.16
[  148.409180] workqueue: drm_fb_helper_damage_work hogged CPU for >10000us 64 times, consider switching to WQ_UNBOUND
[  226.621365] workqueue: drm_fb_helper_damage_work hogged CPU for >10000us 128 times, consider switching to WQ_UNBOUND

These particular messages are a symptom, not the disease. What's actually going on: accel=kvm:tcg tells QEMU "Use KVM if you can, otherwise silently fall back to TCG (software emulation)". If, for whatever reason, KVM isn't available inside the nested VM, QEMU just quietly emulates the entire CPU in software which is orders of magnitude slower and explains why a workqueue would get starved for 10ms stretches and longer.

Since this whole setup is a VM inside a VM, the first suspect is always nested virtualization. So, checks on the Proxmox-hosted Debian VM:

root@vm:~# ls -la /dev/kvm
ls: cannot access '/dev/kvm': No such file or directory
root@vm:~# lscpu | grep -i virtualization
Virtualization type:                     full

As the /dev/kvm device isn't present, we now have confirmed that QEMU falls back to software emulation for the CPU.

The solution? Changing the CPU for the VM in Proxmox from x86-64-v2-AES (or whatever is configured) to host. This enables the VM to directly use the CPU of my Proxmox host.

This can be done comfortably in the WebUI of Proxmox. Just power down the VM.

Before:

And after:

After a reboot we have a /dev/kvm device and full support for Intel VT-x virtualisation. This confirms Proxmox is passing VT-x through cleanly to the nested VM. So KVM should be usable in principle, meaning if the inner QEMU VM is still falling back to TCG, it's not because nested virt is broken at the Proxmox level.

root@vm:~# ls -la /dev/kvm
crw-rw---- 1 root kvm 10, 232 Jul 27 00:48 /dev/kvm
root@vm:~# lscpu | grep -i virtualization
Virtualization:                          VT-x
Virtualization type:                     full

To actually find out, instead of trusting the silent kvm:tcg fallback, it's better to force KVM explicitly and let it fail loudly if something's wrong:

root@vm:~# qemu-system-x86_64 \
  -machine q35,accel=kvm \
  -cpu host \
  -m 512 \
  -nographic \
  -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \
  -drive if=pflash,format=raw,file=./OVMF_VARS_4M.fd \
  -drive file=noble-server-cloudimg-amd64.img,if=virtio,format=qcow2 \
  -net nic -net user \
  -smbios type=1,serial=ds='nocloud-net;s=http://10.0.2.2:8000/'

Removing the :tcg fallback means any KVM problem (permissions, missing nested virt on the Proxmox host CPU type, whatever) surfaces immediately as a hard error instead of a mysteriously slow VM. The parameter -cpu host on top makes sure the guest actually sees the hosts CPU features rather than a generic, lowest-common-denominator CPU model.

And the command worked, however, as we are still booting a VM inside a VM expect it to take some time. 😅

My learnings

For anyone hitting the same wall on their own Proxmox nested-VM setup, the checklist is:

  1. Is /dev/kvm present on the outer (Proxmox) VM at all?
  2. Is nested virtualization actually enabled on the Proxmox host itself?
    • # For Intel-CPUs - prints Y if enabled/available
      root@proxmox:~# cat /sys/module/kvm_intel/parameters/nested
      Y
      # For AMD-CPUs - prints Y if enabled/available
      root@proxmox:~# cat /sys/module/kvm_amd/parameters/nested
      Y
  3. Is the outer VM's CPU type set to host in the Proxmox config? So VMX/SVM flags get passed through
    • Check in the Hardware tab of the VM inside Proxmox's WebUI, or: 
    • Check with qm config VM-ID and verify the cpu line says host
      root@proxmox:~# qm config 100
      [...]
      cores: 1
      cpu: host
      [...]
  4. Does the inner QEMU call use accel=kvm (not kvm:tcg) plus -cpu host, so a broken KVM path fails loudly instead of silently degrading to software emulation?
  5. Is the /dev/kvm device present on the VM where you want to start the QEMU VM?
  6. Is CPU virtualization supported?

Nothing here is exotic once you know to look for it, but "silent TCG fallback" combined with "one VM inside another" is a pretty effective way to make a simple performance problem look mysterious for a while.

Comments