My wiki



Eating sure is nice, so if you find my existence helpful, consider starting to toss me some cash on Ko-Fi, or with extra fees through PayPal or with also some extra fees on my Patreon page.


This wiki is supposed to document my knowledge and setup so I don't have to look things up twice. Since you stumbled upon it, I hope it helps you!

Keep in mind that the wiki is permanently under construction. Information might be wrong, incomplete, ... I'm not exactly getting paid to keep it up to date.

List of all pages

Contact me

If you wish to contact me, you can do so at following places:

You will get the fastest response via Telegram and email.

SSH pubkeys (these are here mostly for myself):

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB23ddI/axXRkPe6WJ/8Vl1AHVrPOkMmaKfZ5Tt/Pd0y [2023-01-07]|ansible
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR3/QA/+Kq1txg/APGQcpa3UradYnaaxSomDQamFDpH [2023-01-07]|c0rn3j
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIqnWQRCGgb6YDcbENshr2ElhDa82aGqYGT9kZ+EHqkc u0_a184@Xiaomi12




My name is Martin Rys and I am a Linux systems administrator born and currently living in Czechia.

My hobbies are reverse engineering, embedded electronics, creating and self-hosting various services.
My hobby projects are mostly available on Gitlab.

Work experience:

Technical background:






This page is a list of software I use.

I denote the license in brackets, I try to stick with software that is free and open-source, if a piece of software is not FOSS, source, I mark it red, as I do not want to recommend such, but it is what I am stuck with.


Windows only

Linux only


Browser addons



If you wish to contact me, you can do so at following places:

You will get the fastest response via Telegram and email.

SSH pubkeys (these are here mostly for myself):

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB23ddI/axXRkPe6WJ/8Vl1AHVrPOkMmaKfZ5Tt/Pd0y [2023-01-07]|ansible
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR3/QA/+Kq1txg/APGQcpa3UradYnaaxSomDQamFDpH [2023-01-07]|c0rn3j
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIqnWQRCGgb6YDcbENshr2ElhDa82aGqYGT9kZ+EHqkc u0_a184@Xiaomi12


List of all the hardware I'm using and what I'm using it for.

Also has stuff of others that I want to keep track of.



Peripherals and Other





Phones & Tablets

Raspberry Pi 5 8GB



3D Printers

Ender 3 V2

Cura settings

Start G-code:

; Ender 3 Custom Start G-code
; Heat up the bed and extruder at the same time, saves time, the power supply can handle it
M104 S{material_print_temperature_layer_0} ; Start heating extruder
M140 S{material_bed_temperature_layer_0}   ; Start heating bed
M109 S{material_print_temperature_layer_0} ; Wait for extruder to reach temp before proceeding
M190 S{material_bed_temperature_layer_0}   ; Wait for bed to reach temp before proceeding
G92 E0                                     ; Reset Extruder
G28                                        ; Home all axes
;G29                                        ; Mesh leveling (takes a while)
;M500                                       ; Save mesh
M420 S1                                    ; Load saved mesh
G1 Z2.0 F3000                              ; Move Z Axis up little to prevent scratching of Heat Bed
G1 X0.1 Y20 Z0.3 F5000.0                   ; Move to start position
G1 X0.1 Y200.0 Z0.3 F1500.0 E15            ; Draw the first line
G1 X0.4 Y200.0 Z0.3 F5000.0                ; Move to side a little
G1 X0.4 Y20 Z0.3 F1500.0 E30               ; Draw the second line
G92 E0                                     ; Reset Extruder
G1 Z2.0 F3000                              ; Move Z Axis up little to prevent scratching of Heat Bed
G1 X5 Y20 Z0.3 F5000.0                     ; Move over to prevent blob squish

End G-Code:

G91               ; Relative positioning
G1 E-2 F2700      ; Retract a bit
G1 E-2 Z0.2 F2400 ; Retract and raise Z
G1 X5 Y5 F3000    ; Wipe out
G1 Z10            ; Raise Z more
G90               ; Absolute positioning

G1 X0 Y{machine_depth} ; Present print
M106 S0                ; Turn-off fan
M104 S0                ; Turn-off hotend
M140 S0                ; Turn-off bed

M84 X Y E         ; Disable all steppers but Z
Filament specific settings

Printer itself

v4.2.2 mainboard




Marlin build instructions

Grab latest stable or latest bugfix (see what's usually recommended at the time of flash), unzip and open its config folder, read that to download configurations too.

Relevant config for the Ender is in config/examples/Creality/Ender-3 V2/CrealityV422 - copy the two header files from the MarlinUI subfolder to the main firmware folder under Marlin subfolder, overwriting the defaults.

Screen FW needs to be in sync with printer FW, update from 4096 sector VFAT fs mkfs.vfat -S 4096 /dev/sdg, see Marlin config folder for instructions.

Printer FW won't update from a 4096 sector FS, use defaults (16k).

Elegoo Saturn

On the way!









This is a list of my feeds on that serves as a backup



Monitoring commands for

'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Enter output'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Sign in - Matomo'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Keycloak' '--url=/'
'/usr/lib/monitoring-plugins/check_http' '' '--string=V2020.0930' '--timeout=30' '--url=/en/download.php?id=6'
'/usr/lib/monitoring-plugins/check_http' '--expect=403' '' '--ssl=1.2+' '--string=Keycloak'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=a safe home for all your data' '--url=/login'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Duplicate & Edit'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Your IPv4'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Roundcube Webmail' '--url=/webmail/'
'/usr/lib/monitoring-plugins/check_tcp' '--hostname' '' '--port' '64738'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=zero knowledge'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Network Latency'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Matomo'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Main stream · FreshRSS' '--url=/i/'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=Hardware'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=LibreSpeed'
'/usr/lib/monitoring-plugins/check_tcp' '--hostname' '' '--port' '8999'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=AGPL'
'/usr/lib/monitoring-plugins/check_http' '' '--ssl=1.2+' '--string=meteor_js'


Arch Linux

I use Arch Linux (or the spinoff ARM version) on practically all my machines.


You can download Arch here

Basic commands and usage

Before going through the install guide you really should know these.

Lower/upper case is important in linux.

You can use arrow keys to navigate through your previous commands.

CTRL+ALT+F1-F12 - key combination for switching between terminals

cd DIRECTORY - for example cd /home/baf/Downloads - chooses directory

nano FILE - edit a text file

CTRL + C - break from a command, for example a ping

lsblk - lists all your drives and their partitions.

irssi - IRC in the CLI in case you get lost, #archlinux on Libera should help you out if you ask nicely.

Installing GPU proprietary drivers


sudo nano /etc/pacman.conf - uncomment [multilib] and the line below it. This is required for 32bit applications.

sudo pacman -Syu - synchronize the repository databases and update the system's packages

sudo pacman -S nvidia nvidia-libgl lib32-nvidia-libgl nvidia-settings



Do not use Catalyst. If you think you have to, rather get another GPU.

Table of hardware with needed drivers is here.

Installing packages from AUR

You can download user created PKGBUILDs from the AUR.

Package managers


Usage: tldr pacman + the rest of this page:

-S has a useful --ignore packagename flag, which lets you ignore a broken package when doing a full update for example. Use multiple times when you want to avoid installing more packages. There's also a --noconfirm flag, which ignores confirmation of actions.

pacman -Qm - List packages installed locally.(that includes AUR)

You can get to the package cache via this command cd /var/cache/pacman/pkg/ and then use pacman -U packagename to downgrade/reinstall a package.

Converting Wii's Bluetooth module to a USB dongle

Original thread on Dolphin forums


This page assumes no previous soldering knowledge whatsoever.

If you want perfect connection of real Wii motes to the Dolphin emulator, you want to pass-through one of the original chips to Dolphin.

There are two chips, the older 4250A-WML-C43 and the newer J27H002. The only difference between those seems to be that the newer version has slightly smaller test pads, but they're pretty small on both versions, so it's not going to make your job too much easier by choosing one over the other.


Both chips go for about $1.3 a pop on Aliexpress.

List of things you'll need for this -

When you're done and you get the USB dongle to show up when connected, follow the Bluetooth Passthrough wiki page.

I will not be wiring the sync button as you can just use the software button in Dolphin when connecting the Wii motes, so essentially just ignore the button on the following schematic. If you want it there you're free to wire it up of course.




  1. Solder the 4 wires to the USB-A connector and pull the cables through the plastic cover. Red for +, black for -, green for Data+ and white for Data-
  2. Continuity test - make sure none of the 4 pins is connected to its nearby pin(s) and that all pins are connected to the wires
  3. Pull the plastic cover onto the USB connector hard so it stays in place
  4. Put a shrink tube on USB(-) and pull another black wire through it, solder both to regulator GND. You should twist the wire ends together when soldering two at the same time
  5. Take two red wires and solder them to regulator output, put a shrink tube on them
  6. Put a shrink tube on USB(+) red wire and solder the wire to regulator input
  7. Continuity test the 2 pairs of wires on the regulator
  8. Pull the shrink tubes up and heat them under fire
  9. If you're using liquid flux like I am, pour it on the pads , let it be the for a short while then dry it up (or don't dry it if your flux doesn't turn into charcoal when heated up like mine does)
  10. If you don't have properly colored wires for Data+ and -, tontinuity test which wire is which and solder them onto the BT chip
  11. The 2 output red wires are because there's 3 output pads total (orange) - you need to connect all 3 together. One wire goes to the singular left pad, and other wire goes between the 2 right pads and you bridge those together
  12. Solder the remaining GND and you're done soldering
  13. Clean your iron on the damp sponge, put some solder on the tip and turn it off. this prevents degrading the tip.
  14. Test the dongle you made in a computer
  15. Finally hot glue the connections on the BT chip so they don't come off in case they get tugged on hard
  16. Put the connector on the USB dongle and hot glue it, hot glue the regulator from the other side
  17. With a working adapter, follow Dolphin's BT passthrough page

Creating a bootable flashdrive


Nowadays, just use Ventoy.

To create a bootable flashdrive for Windows you'll need an 8GB+ flash drive. For Linux, it depends on the distribution. You should be fine with 1GB for Arch, but hey, 16GB flash drives are like $5 today.

Keep in mind that the flash drive can either be (U)EFI bootable, BIOS bootable(often named legacy in UEFI options) or both.

To actually boot from the flash drive, go into your UEFI/BIOS settings and either find the option to boot directly from the flash drive, or rearrange your boot order to boot from flash drive first.

On Windows

Linux or Windows images

Rufus - Rufus usually has no problem working with Linux and Windows ISOs and is easy to work with. The only negative thing is that I didn't figure out how to make ISOs that boot both under BIOS and UEFI, only one or the other, which is selected under the "Partition scheme" label.

You want to use "GPT for UEFI" partition scheme unless your hardware is years and years old.

unetbootin - Sometimes certain Linux distributions fail to be used by Rufus

On Linux and macOS

macOS has some command name differences not mentioned here, but the general idea works still.

Linux images

Unebootin or dd can be used for this purpose, I chose to use dd because it's preinstalled and straightforward.

Make sure to run lsblk to know what device you should be dealing with.

umount /dev/sde1 - Unmount the device in case it's mounted

sudo dd if=/path/to/file.iso of=/dev/sde bs=4M status=progress && sync

You should now be able to boot the distribution in both BIOS and UEFI, if the distribution supports it.

Windows images

Below is a description of the manual process, however you can use WoeUSB for an automated one.

[1] [2]

This handy script does the below-described process:

Format the flash drive with Gparted - Device > Create partition table - Set partition table to msdos. Afterwards create a FAT32 partition, remember to label it, labeling it is optional if you only want to keep only one OS on the flash drive but probably required for more.

Right click the partition you created > Manage flags > tick the 'boot' flag. Exit gparted.

Mount the ISO you want to use to some already existing folder

sudo mount -o loop ~/Downloads/Win8.1_English_x64.iso /mnt/iso

and copy all files from it to the mounted flash drive. The exclude is there to support Win10 1809+ images which have over 4GB install.wim which needs to be split:

rsync -rv --progress --exclude=install.wim /mnt/iso/ /run/media/c0rn3j/WINDOWS/

wimsplit /mnt/iso/sources/install.wim /run/media/c0rn3j/WINDOWS/sources/install.swm 3000

At this point the flash drive should be UEFI bootable. You're likely done here, but if you have a very old machine, the rest is needed to also enable BIOS booting.

Also you should create a file ei.cfg in the sources folder with following content(it makes sure you can actually select the edition):


sudo grub-install --target=i386-pc --boot-directory=/run/media/c0rn3j/WINDOWS/boot /dev/sdd - This command will install GRUB bootloader on the flash drive.

Last thing you'll need to do is create a config file for GRUB.

gedit /run/media/c0rn3j/WINDOWS/boot/grub/grub.cfg - This command will run gedit, paste the following text block in it and save it. Remove the label part if you didn't set one.

menuentry "Start Windows Installation" {
    insmod ntfs
    insmod search_label
    search --no-floppy --set=root --label WINDOWS --hint hd0,msdos1
    ntldr /bootmgr

The flash drive should now be bootable by both UEFI and BIOS.

KON-BOOT images

Format the flash drive with Gparted - Device > Create partition table - Set partition table to msdos. Afterwards create a FAT32 partition, remember to label it.

Copy the EFI folder onto the new partition.(you may need to rename it to lowercase efi?) Copy the files in USBFILES folder onto the new partition.

sudo grub-install --target=i386-pc --boot-directory=/run/media/c0rn3j/KONBOOT/boot /dev/sdd - This command will install GRUB bootloader on the flash drive.

sudo cp /usr/lib/syslinux/bios/memdisk /run/media/c0rn3j/KONBOOT/boot/grub/ - copies memdisk onto the flashdrive - needed for BIOS booting.

gedit /run/media/c0rn3j/KONBOOT/boot/grub/grub.cfg - create the following grub entry

 menuentry "Konboot" {
 linux16 /boot/grub/memdisk
 initrd16 /konboot.img

Note: Konboot v2.5 does not seem to work on anything past the first W10 RTM build.

Using Android to emulate mass storage

You can boot images straight off your phone if you've root permissions.

Usb Mountr was one of the FOSS solutions, but it was dropped by the maintainer.

DriveDroid is supported but proprietary.

Your kernel might support emulating USB, emulating CD drive or both.



Dolphin is an emulator, community/dolphin-emu on Arch.

If you have real Wii motes: Dolphin uses its own drivers so do not install xwiimote or anything similar, do not use bluetooth GUI or anything, simply connect a bluetooth dongle and start the BT service via

sudo systemctl start bluetooth

if it isn't on already. Go to Controllers in dolphin-emu, set at least one Real Wiimote and check continuous scanning. On pressing 1+2 or the red sync button the controller should connect and vibrate.

All chinese BT dongles will likely not work properly, throwing various errors at you when you try to use them with Dolphin.

Note: The wii motes can glitch out - you will need to take out the batteries for a second to get them to connect again.

You need to add ISO directory with your game ISO files to do so go to Config > Paths > Add... and select the directory.

You may want to go to Graphics > Enhancements and set the resolution to auto and use some AA and/or Anisotropics Filtering.

You should also go to controllers and check that the GC/Wii controllers are configured(You can always reset them to default).

Dolphin-emu has an awesome feature called Netplay, allowing you to play the games with your friends over the internet even though the games were meant to be played locally only! For that you'll need to have the exact same Dolphin-emu version, exact same ISO file(check file hash to know you do) and same Memory card save if you intend to use that.

Sadly Netplay doesn't work with real Wiimotes(yet...).

BT dongles

From my experience: some just don't work, some work weirdly, I'll try to list what I bought and where and how it works. None store-bought work truly well.

Dongle #1 - Works weirdly but after messing around with it for a bit I got both my wii motes to connect. Would not recommend.

Dongle #2 - Does not work with Dolphin.

Dongle #3 - works perfectly but I don't have an exact link, looks exactly like Dongle #2 but without any text on it or "golden" connector. Seems like it's USB 2.0 V2.0 BT dongle.

The only really functional option is to make your own from a Wii BT chip




Figuring out wallbangs n stuff:

mp_buy_anywhere 1;mp_buytime 60000 
mp_maxmoney 65535;mp_startmoney 65535;mp_afterroundmoney 65535
mp_roundtime_defuse 60;mp_roundtime_hostage 60;mp_roundtime 60;mp_restartgame 1 

Danger zone bunny hop practice:

game_mode 0; game_type 2; map dz_sirocco
sv_cheats 1; sv_infinite_ammo 1; sv_regeneration_force_on 1
mp_autokick 0; mp_disable_autokick; bot_kick all
# MP (use changelevel instead of map above)
mp_respawn_on_death_ct 1; mp_respawn_on_death_t 1

exojump; give weapon_bumpmine; give weapon_knife



Interesting resources

Punycode attack on browser URLs - https://www.аррӏе.com/

From 0x90 to 0x4c454554, a journey into exploitation

Email spoofing


Stolen from a Reddit comment somewhere:

  1. Test - before starting any topic, make sure your student has a grasp of the prerequisites by giving them simple tasks. Just because you have taught them the prerequisites a week ago does not mean that they didn't forget.

  2. When you are teaching them, talk as little as possible. The only thing you should be saying is the concepts.

  3. Ask lots of questions. I.e.: What is an object (expect them to repeat what you told them); What happens if (insert 10x different cases). Teach by asking.
    I can't emphasize this enough. When I teach, I never say more than 2 sentences without asking a question. Because you quickly realize that people have a hard time retaining more than 2-3 sentences at a time.

  4. Set 0 expectations. If you get frustrated it's because you have expectations. Many people have self confidence issues. Being disappointed will cause your students emotional stress and they will not be able to learn. They might start to avoid asking you questions...

  5. Listen. Many times, your students could be saying what you wanted to hear, but worded differently. Their analogy could have the same concept as yours but very different. Learn to recognize what students are saying.


From time to time I host a server for myself and a few friends, but new people are welcome too!

It's down most of the time.




Clear all items on the ground - /kill @e[type=Item]

Where to get Forge

Main place to get mods rarely, some mods won't use Curseforge but a build server or a webpage (IC2 for example)

-Xms is startup memory and -Xmx is maximum allowed memory. -Xms8G -Xmx8G - makes minecraft start with 8GB and will let allocate memory up to 8GB as needed... This is useful as reallocation is costly so let's just go with max.

# Will install/update server + forge in the current directory.
java -jar forge-*-installer.jar --installServer


Server setup


Rubber Ducky

Screw the $45~ thing, we're making our own for $1.15~.

Open Arduino IDE; File -> Preferences -> Additional Boards Manager URLs

Tools -> Board -> Boards Manager -> Digistump AVR Boards - install it.

# cat > /etc/udev/rules.d/49-micronucleus.rules << EOF
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1"


You can now flash stuff to the board by selecting it as 'Digispark Default 16.5mhz'.

Do not plug the board before compiling process, do it after when you'll be prompted.

## This seems not needed anymore as the AVR package ships up to date micronucleus, and the project stopped providing precompiled linux library?
#git clone
#cp ~/micronucleus/commandline/micronucleus /home/c0rn3j/.arduino15/packages/digistump/tools/micronucleus



Hashcat is a tool to crack various hashes, passwords and other formats. Hashcat is now merged into one OpenCL version(used to have a CUDA version for nvidia GPUs- CudaHashcat, the new hashcat only supports OpenCL).

For WPA2 it uses a new(2017) format called hccapx.

Attacking 802.11

[1] [2] [3]


Packages: aircrack-ng wireshark-qt macchanger reaver-wps-fork-t6x

Kill your network manager service to avoid it interfering.

I am using NetworkManager.

sudo systemctl stop NetworkManager - sometimes it starts again so just try this twice...

Then use sudo airmon-ng to find out your interface name for the wireless card you want to use. If it is not listed, you are either lacking drivers or it is not compatible.

After finding out your interface name, turn your WLAN card into monitor mode with sudo airmon-ng start yourInterface, you will then have a _yourInterface_mon interface you can use. You can use the –verbose flag with the command to diagnose possible issues if it is not working as intended. You can use stop instead of start to make the interface go back to managed mode and use wi-fi as usual.

Since the default interface tends to be wlp8s0, that is what I am going to use for this page.

Change your MAC:

macchanger -r wlp8s0 - randomize MAC address completely. Alternatively use -m option and supply an address starting with 68:5D:43 or any other vendor specific address, as some routers and networks will not allow MAC that is not assigned to any vendor. (MAC is in this format XX:XX:XX:YY:YY:YY where XXXXXX is vendor specific and YYYYYY is random)


There is a script called wifite that can do most of these attacks even if the attacker doesn't understand them. It fails in some more complicated cases.

git clone

cd wifite/

sudo python2.7 ./

Scan your surroundings

sudo airodump-ng wlp8s0mon

MAC address filtering

Use airodump to look for an active client and change your MAC address to theirs.

Hidden SSID

aireplay-ng -0 0 -a 00:1F:1F:1F:1F:1F -c 00:1F:1F:1F:1F:1F --ignore-negative-one wlp8s0mon

while running airodump. Successfully deauthing a client will make them broadcast the SSID in the clear because they'll have to reconnect.


airmon-ng start wlp8s0

airodump-ng wlp8s0mon

airodump-ng -w wep -c CHANNEL --bssid BSSID wlp8s0mon

aireplay-ng -1 0 -a BSSID wlp8s0mon

aireplay-ng -3 -b BSSID wlp8s0mon

aircrack-ng filename.cap


airmon-ng start wlp8s0

airodump-ng wlp8s0mon

airodump-ng -c CHANNEL -w filename --bssid BSSID wlp8s0mon

aireplay-ng -0 0 -a BSSID wlp8s0mon

After obtaining 4-way handshake:

aircrack-ng –w WORDLIST -b BSSID filename.cap



Scan for WPS enabled APs

sudo wash -i wlp8s0mon

For Bruteforcing and logging for possible pixie attack. Use -K 1 parameter to try pixiewps while reaver is running. The plain bruteforce attack might take minutes to days, but usually it's max 10 hours.

sudo reaver -i wlp8s0mon -b BSSID -c channel -f -S -vvv -H

After obtaining at least one response you can use pixiewps to try the offline pixie attack. Whole pixiewps command will be saved in a text file if you supplied the -H command. Pixie attack takes anywhere from a second to 30 minutes, and only works if the router is vulnerable to it.

Cracking a handshake/capture file

Using GPU

Converting .cap to .hccapx

Use cap2hccapx (from the hashcat-utils package)

cap2hccapx capture.cap capture.hccapx

HCCAP to password

hashcat -m 2500 -w 1 filename.hccapx wordlist.txt

Using CPU

IVS file crack aircrack-ng -a2 -b F8:8E:88:AA:FF:BB -w wordlist-final.txt ivsfile.ivs

Other stuff

Find out default gateway route -n

Obtaining wordlists have awesome leaked lists, so I'm going with a bunch these. You can find different lists on torrent trackers.

7z x xxx_found.7z -owordlists - extract file into a folder called 'wordlists'

cat xxx_found_sorted.txt xxx_found_sorted.txt xxx_found_sorted.txt > mywordlist.txt - join all lists into one

sed -r '/^.{,7}$/d' mywordlist.txt > WPAwordlist.txt - remove everything that is 7 characters or less from the file and write that to a new file. WPA/2 does not accept less than 8 characters.

sort -T ~ -u WPAwordlist.txt > WPAwordlist_sorted.txt - change temporary directory to the home directory(sort would fail on a big file if /tmp is too small) and sort into a new file


Packages: openssh

Client config: /etc/ssh/ssh_config

Server config: /etc/ssh/sshd_config

What is SSH?

Notable config options:

Port # default port(22) is sometimes blocked on networks X11Forwarding # Lets you connect to the X server(forward GUI apps) Banner # Display a message before logging in(warning messages are required in some countries), file /etc/ is usually used for that. Alternatively you can show a message after login, simply edit /etc/motd for that. PasswordAuthentication no # Force use of SSH keys ChallengeResponseAuthentication no # Force use of SSH keys(default set to no?)

sudo systemctl enable --now sshd - Enable sshd service and start it, this is required if you want to host a SSH server so it starts at boot.

By default SSH server accepts user logins(root is disabled by default), but you might want to generate and use SSH keys instead.

Default crypto used is 2048 bit RSA. This is a sane default, you could possibly use 4096 bit RSA(or higher), which has diminishing returns. It takes about 8x more resources to decrypt 4096 RSA than 2048 RSA.

Consider using the newer Ed25519 cipher. Ed25519 is supposedly the best current option. There is no need to set the key size, as all Ed25519 keys are 256 bits. The only problem should be compatibility with old openssh versions.

ssh-keygen -t ed25519 - Generate a keypair - you'll be prompted for a filepath and a password] to secure the key. The passphrase uses AES-128 for encryption. You probably don't want to use a passphrase though, so just leave it empty.

ssh-copy-id -i ~/ -p 1234 - Copy the public key to the server via SSH. In the example there is specified file path, port and hostname/IP.

By default the public keys allowed to connect to your machine are saved per line in ~/.ssh/authorized_keys

Cool thing that SSH can do is port forwarding:

Let's say I'm running a webserver on - this command would forward the port 80 to port 20123, only for, so you could look at the website via http://localhost:20123 from the host machine you executed the ssh command on! You can of course replace the host( with whatever and forward your traffic through just for that website.

ssh -L :20123: username@

This is remote mapping instead - executing this would forward the host's port 22 to the remote server's port 20123 - useful if ISP is blocking ports and you want to forward something through another server!

ssh -R :20123:

System Administration


Some tips


Example Client config

PrivateKey = <censored>
Address =

PublicKey = aHcw4mjbI0md5VwQSJovvASLs0bkd0Dkwa1Ma4y6yW0=
AllowedIPs =
Endpoint =

Example Server config

Address =
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens2 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens2 -j MASQUERADE
ListenPort = 51820
PrivateKey = {{ wireguard_private_key }}

PublicKey = 766tBrNv7iinsbd9wMP3yM2ksnIprdT9mgfM9VtFcRM=
AllowedIPs =

PublicKey = SoFi/vC8IOhBYEMqnFzzuz9umlgDKoo3yytbuIMvizg=
AllowedIPs =


GRUB on Arch wiki

Get grub to ignore bad devices and install properly:

blockdev --flushbufs /dev/sde && blockdev --flushbufs /dev/sda && grub-mkdevicemap -n




Dependencies: wine wine_gecko wine-mono winetricks

Wine is used to run Windows only executables on other operating systems. More information about Wine

You can have multiple Windows "installations" which are called prefixes. In fact it is suggested that you use a new prefix for each application you use.

~/.wine is the default wineprefix (a.k.a. "configuration directory" or "bottle"). You can change which prefix Wine uses by changing the WINEPREFIX environment variable (outside Wine). To do this, run the following in a terminal:

export WINEPREFIX=~/.wine-new wine winecfg

Alternatively, you can specify the wine prefix in each command, e.g.

WINEPREFIX=path_to_wineprefix wine winecfg

you can create a new 32 bit wineprefix using the WINEARCH environment variable(note: you can also export WINEARCH). In a terminal, type:

WINEARCH=win32 WINEPREFIX=~/.wine32bit winecfg

Do not use an existing directory for the new wineprefix: Wine must create it.

Once a 32 bit wineprefix is created, you no longer have to specify WINEARCH in the command line to use it, as the architecture of an existing wineprefix cannot be changed.

You can use wine64 instead of wine to force 64bit.

There are three Direct3D backends for Wine. Which one you use depends on what features your card supports.

wined3d - The D3D backend included with Wine upstream. It is a translation layer that converts Direct3D calls to OpenGL and then sends them to your OpenGL GPU driver. Usable on all GPUs, but has the worst performance.

wined3d with CSMT - A multi threaded, more optimized version of wined3d. It has the same support as wined3d but is much faster. It still incurs a high CPU overhead but if your CPU is good it can help give you better FPS.

Gallium Nine - A native D3D9 implementation that skips the OpenGL translation entirely, requires less CPU overhead, but requires you use a GPU driver which has the GPU side support built in, which are all the Gallium mesa drivers (radeonsi, r600g, nouveau). Nouveau is the open source nVidia driver, but it lacks performance due to reclocking issues and it does not support the GTX10 series because they haven't released signed binaries to support it.

winecfg - > Drives > Autodetect - binds your home folder

Make AppDB reports, it helps the community!

How to install SVP on Arch Linux to play interpolated movies

Dependencies: qt5-3d, mpv-git(AUR), svp(AUR)

Pre-requisites(optional): proprietary GPU drivers already installed.

Download and install mpv-git from AUR

Set up mpv socket - cat > ~/.config/mpv/mpv.conf << EOF input-ipc-server=/tmp/mpvsocket # Receives input from SVP hr-seek-framedrop=no # Fixes audio desync resume-playback=no # Not compatible with SVP EOF

Note: There's currently a small bug in SVP causing video stuttering - go to SVP control panel > Utilities > Application settings; and play with the number of "threads" which are set to 0 by default. Setting it to 15 fixed the stuttering issues for me.

That's it, running movies through mpv while having SVP manager turned on will play them smoothly!

Additionally you can install SMplayer, because MPV alone has almost no GUI and relies heavily on CLI commands.

Dependencies: smplayer

Launch SMplayer > open Preferences > Advanced > Options for MPlayer/mpv and add this to Options --input-ipc-server=/tmp/mpvsocket


Packages: rsync

Needs to be installed on both computers.

Using rsync over SSH and custom port:

rsync -avz -e "ssh -p PORT" path/to/folder/or/file

-z flag for compression, -r flag for recursive, but that is already implied with -a, which preserves file permissions and such. (-a equals -rlptgoD (no -H,-A,-X))

Use destructive syncing – “rsync --del” – This will delete any items on the destination that are not present on the source.







Virtualization under QEMU/KVM

virt-manager - start the interface. Make sure to do so after you're already connected to the internet, else it might use the wrong interface and you'll have no internet connectivity on the VMs.

virt-manager --no-fork - virtmanager will let you type passwords in the terminal instead of openssh-askpass or something like that

Create a new Virtual Machine using an .ISO image and default settings.

Now you should have a working BIOS VM. To create a UEFI one make sure to check customize install and select UEFI for firmware when creating a new VM.

Bi-directional copy pasting and drag-n-dropping files to a Windows KVM is possible by simply installing spice-guest-tools on the KVM(default virt-manager setup uses Spice for display, so it works out of the box)

To enlarge .qcow2 image, use command qemu-img resize ubuntu-server.qcow2 +5G Remember it'll end up as unallocated space

Using LXC/LXD containers

Virtualization under VirtualBox

Packages: virtualbox linux-headers virtualbox-host-dkms

GPU Passthrough

More stuff

Webserver in current folder

You can instantly create a webserver hosting contents of the folder you're currently in via python:

python -m http.server 8080


Tmux is a terminal multiplexer, meaning you can SSH somewhere, run tmux there and disconnect without killing whatever you were running, or just have multiple terminal tabs without actually launching more terminals.

Full cheatsheet:

Tip: tmux running a session but list-sessions doesn't show it? This might help killall -s SIGUSR1 tmux

If you're running nested tmux sessions, explanation and tips how to do it efficiently. (CTRL+B twice to get into the second level session, thrice to get into third level etc)

Command to detach all other sessions(in case the window is small and other session is blocking resizing): attach -d

Basic usage:

tmux - start new tmux session

tmux ls - list active sessions

tmux a -t sessionName - attach to specific session

tmux kill-session -t sessionName - kill specific session

Inside of tmux:

CTRL+B d - detach session

CTRL+B % - split current pane vertically

CTRL+B " - split current pane horizontally

CTRL+B ARROW_KEY - move between panes

CTRL+B+ARROW_KEY - resize current pane

CTRL+B z - toggle current pane fullscreen state

CTRL+B x - kill current pane

CTRL+B c - create a new window

CTRL+B n - next window

CTRL+B p - previous window


Packages: apache php php-apache(why?) nghttp2

Sources:Arch wiki

Configuration files are located in the folder /etc/httpd/conf , the main configuration file is httpd.conf

sudo systemctl enable --now httpd - Enable and start the httpd service, you should now be able to access the Apache server via localhost:80

PHP7 >

in **httpd.conf**

comment **#LoadModule mpm_event_module modules/**

uncomment **LoadModule mpm_prefork_module modules/**

place **LoadModule php7_module modules/** at the end of the LoadModule list

and **Include conf/extra/php7_module.conf** at the end of the Include list

sudo systemctl restart httpd


DocumentRoot in the config sets the folder for the website, default is /srv/http/

nginx + PHP

Packages: php nginx-mainline php-fpm openssl

systemctl enable --now php-fpm

sudo nano /etc/nginx/nginx.conf - Example config of the server blocks

 server {
        listen; # listen on IPv4
        listen       [::]:80 # listen on IPv6
        server_name  *; #Redirect all port 80 requests to HTTPS(443)
        return 301 https://$host$request_uri;
 server {
         listen ssl http2; #listen for TLS IPv4 connections and enable HTTP2
         listen       [::]:443 ssl http2; #listen for TLS IPv6 connections and enable HTTP2
         root /usr/share/webapps/mediawiki;
         index index.php;
         location ~ \.php$ { # serve .php files via php-fpm
                 fastcgi_pass   unix:/run/php-fpm/php-fpm.sock;
                 fastcgi_index  index.php;
                 include        fastcgi.conf;
         location / {
                 index  index.html index.htm index.php;

 server { #forward traffic going to to another server - useful if you need more servers running.
          listen ssl http2; #listen for TLS IPv4 connections and enable HTTP2
          listen       [::]:443 ssl http2; #listen for TLS IPv6 connections and enable HTTP2
          location / {
                 proxy_redirect     default;
                 proxy_set_header   X-Real-IP  $remote_addr;
                 proxy_set_header   Host       $host;
                 proxy_set_header   X-Forwarded-Proto https;
                 proxy_set_header   X-Forwarded-Ssl on;

You can check if your config is valid via nginx -t, and then reload the server config via nginx -s reload, instead of restarting the daemon.

systemctl enable --now nginx - enable and start nginx

TLS(used to be SSL)

TLS 1.0 being deprecated 30th June 20181

All versions of nginx as of 1.4.4 rely on OpenSSL for input parameters to Diffie-Hellman (DH). Unfortunately, this means that Ephemeral Diffie-Hellman (DHE) will use OpenSSL's defaults, which include a 1024-bit key for the key-exchange.

cd /etc/ssl/certs && sudo openssl dhparam -out dhparam.pem 4096 - This takes time depending on your single core performance as it's not multithreated.(few mins on i7-4790K, 42~ mins on Raspberry Pi 3B) You can use 2048 but it's weaker, create the stronger file at a later date if you just want to get it running for now.

sudo nano /etc/nginx/nginx.conf - place these outside of the server blocks so it applies to all servers.


ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.3; # Keep in mind this will break software that is way past it's end of life.
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
#resolver $DNS-IP-1 $DNS-IP-2 valid=300s; # I do not understand those so I disabled them
#resolver_timeout 5s;
#RESOLVERS: if you don't specify any, nginx will resolve HTTP upstream server hostnames when starting up, and will never attempt to re-resolve them. This is a problem if later the IP addresses of these upstream servers change. But if you define resolvers in nginx.conf, it will honor the TTL of DNS records, and re-resolve the hostnames periodically.
#Make sure you correctly respond to this or the issue is fixed before defining the resolver.
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; # You can add your domain to Chromium's source code for automatic preloading
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
#add_header Content-Security-Policy "default-src 'self';"; # if you require no scripting.. likely not the case.
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; child-src 'self'; connect-src 'self'; object-src 'none' ";

SSL certs - you'll need to use letsencrypt to get these

ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;

Add a block that redirects all HTTP requests to HTTPS

server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;

Additionally use listen 443 ssl http2; listen [::]:443 ssl http2; in every other server block to force TLS and support HTTP2 protocol.


Packages: mariadb

sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql

sudo nano /etc/php/php.ini - uncomment

sudo systemctl restart php-fpm

sudo systemctl enable --now mysqld

**sudo /usr/bin/mysql_secure_installation **


mysqldump --single-transaction --flush-logs --master-data=2 --all-databases -u root -p | gzip > all_databases.sql.gz


gunzip all_databases.sql.gz | mysql -u root -p

mysqldump --defaults-file=/path-to-file/SQLcreds.txt --all-databases > my_db.sql

nano SQLcreds.txt


sudo chown root:root SQLcreds.txt

sudo chmod 700 SQLcreds.txt


Packages: phpmyadmin php-mcrypt

sudo nano /etc/nginx/nginx.conf - add a whole new server block for phpmyadmin

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name phpmyadmin.localhost;
    root /usr/share/webapps/phpMyAdmin;
    index index.php;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        include fastcgi.conf;


Packages: murmur

Port: TCP/UDP 64738

Config: /etc/murmur.ini

Setting valid TLS(SSL) certificate:

uncomment and set these two lines in the config


Let's Encrypt

Packages: certbot certbot-apache/certbot-nginx

sudo systemctl stop nginx - Stop your webserver. In case of apache you want to stop httpd

sudo certbot certonly --standalone -d -d -d -d -d -d -d -d -d --email --rsa-key-size 4096 --agree-tos

sudo systemctl start nginx

To non-interactively renew all of your certificates, run **certbot renew --rsa-key-size 4096 **.


?Final setup - TODO - postfix+dovecot+roundcube+postfixadmin?

Order of importance of records:


Packages: postfix #dovecot roundcubemail postfixadmin php-imap

First set up DNS records. I will be using, so I set MX record of @ pointed to, which is in turn pointed at my VPS.

systemctl enable --now postfix

This will likely land in your spam folder. echo "Message" | mailx -s "important mail"

Edit /etc/postfix/

myhostname =

postfix reload

Now you should be able to resend the test email and see it came from your domain.

Edit /etc/postfix/aliases

root: c0rn3j

change to your user account, reading email as root is bad

postalias /etc/postfix/aliases

For later changes run newaliases

Now you should be able to read mail coming from the internet(only for users that exist on the system) and the services on the box.

less /var/mail/c0rn3j

Access point (WIP)

Packages: hostapd dnsmasq

sudo nano /etc/hostapd/hostapd.conf

ssid=myWifi # SSID of the network
wpa_passphrase=MySuperSecurewifi123 # password for the network
interface=wlan0 # Interface it'll run on
auth_algs=1 # 1=wpa, 2=wep, 3=both
channel=6 # Channel it'll broadcast on
hw_mode=g # 2.4GHz, 'a' for 5GHz
wpa=2 # WPA2 only
#In addition to these, RPi3 seems to require those
ieee80211n=1 # nothing would work without this
#wmm_enabled=1 # QoS support
#ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40] #I did not actually need this

sudo nano /etc/sysctl.conf # is this an outdated way to set ipv4 forward on a systemd distro?

net.ipv4.ip_forward = 1

sudo sysctl -p

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT

sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT

sudo sh -c "iptables-save > /etc/iptables.rules"

sudo iptables-restore /etc/iptables.rules # This needs to be executed after boot

sudo nano /ect/dnsmasq

port = 0

sudo ip addr add broadcast dev wlan0

sudo ip route add default via

Samba(file sharing)

Packages: samba

sudo cp /etc/samba/smb.conf.default /etc/samba/smb.conf - copy the default config file to the default config path

sudo systemctl enable --now smb

sudo nano /etc/samba/smb.conf

workgroup = WORKGROUP #change to WORKGROUP so it's the same as default windows WG.

valid users = %S # - add this to [homes] to allow users login to their home directories(?)

Example block

comment = dolphin ISOs
read only = yes
valid users = c0rn3j
 Samba requires a Linux user account - you may use an existing user account or create a new one.
 Although the user name is shared with Linux system, Samba uses a password separate from that of the Linux user accounts.

sudo smbpasswd -a c0rn3j - change samba password of the user

testparm -s - will show you the current config

sudo smbstatus - list connections to the shares on the server

sudo systemctl restart smb - restart samba service to apply new config

Now on the client side...

smbclient -L // -U% - list public shares on a server

sudo mount // /mnt/dolphin/ -o user=c0rn3j - example: Mount the home of user c0rn3j to /mnt/dolphin/

Mounting every time is tedious though, let's add an entry to fstab to mount it on boot. First we'll need to store the credentials safely though.

sudo nano /mnt/credentials


sudo chmod 600 /mnt/credentials - secure it so it's not readable by anyone but root or owner.

sudo nano /etc/fstab - and add this line at the bottom

// /mnt/dolphin cifs auto,x-systemd.automount,_netdev,credentials=/mnt/credentials 0 0

mount -v - list all mountpoints

mount -t cifs - list mountpoints by fs

GPG Encryption

-c specifies to encrypt symmetrically(symmetrical is harder to crack than asymmetrical), defaults to AES-128 which should be secure enough for now and the near future. AES-256 seems to be noted as 30-40% slower, so if you don't mind taking that performance hit feel free to use that instead(but I do suggest reading why you'd want to do that first as AES-128 is possibly enough for you).

Encryption with a password and AES-256:

gpg --batch --cipher-algo AES256 --passphrase password -c file

Decryption with a password:

gpg --batch --passphrase password -o file -d file.gpg

If you are not going to be using an automatic script for encryption/decryption, you can simply omit --passphrase password and you will be asked to enter it manually.

The above example is not secure because any user can execute ps aux and see the whole command, including the password.

Now let's do it better!

nano password.txt - write your super secret password there

sudo chown root:root password.txt

sudo chmod 700 password.txt

Encryption with a password in a restricted file:

sudo gpg --batch --passphrase-file password.txt -c file

Decryption with a password in a restricted file:

sudo gpg --batch --passphrase-file password.txt -o file -d file.gpg


Check if your password is correct and list slots:

cryptsetup luksOpen --test-passphrase --verbose /dev/sda

Add a key file for automatic unlocking via /etc/crypttab:

cryptsetup luksAddKey /dev/nvme1n1p1 /etc/adatapass


Encrypt a file:

ansible-vault encrypt --vault-id C0rn3j/configs@~/C0rn3j_configs-vaultpass.txt id_ed25519

Encrypt a string for use in playbooks/templates:

ansible-vault encrypt_string --vault-id C0rn3j/configs@~/C0rn3j_configs-vaultpass.txt 'supersecretpassword' --name 'bree_matomo_db_password'


Since there's 2 LG TVs in the household, I figured I might as well make a separate page for them.

  1. 55UH605V-ZC - 3.10.19-p.45.dharug.k2lp.2 - FW 05.30.60 - webOS 3.3.4
  2. 55UK6200PLA - 4.4.84-p.84.gomolsha.lm18a.1 - OTA ID HE_DTV_W18A_AFADABAA - FW 05.50.15 - webOS 4.4.2

There's some ways to jailbreak some LG TVs - XDA, RU forum

You can get SSH access by following instructions here.

cat /var/run/nyx/device_info.json - has mac addresses and TV model name among other things

cat /var/run/nyx/os_info.json - webOS version. The version the TV displays is FW version, not webOS version!

Code this as Base64 file called 'query" and execute the curl command to test connection to the update server

curl -X POST -A "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" -d @query

If query is wrong, server cuts connection - curl: (56) Recv failure: Connection reset by peer

Server also times out very often.

Queries and responses are Base64 encoded.

# Force ezAdjust menu open as per
# Password is 0413
luna-send -n 1 -f luna://com.webos.service.applicationManager/launch '{"id":"","params":{"id":"executeFactory","irKey":"ezAdjust"}}'


Powershell setup scripts

Install modern PowerShell

Windows ships with Windows PowerShell which is stuck at v5.1, so install latest PowerShell

winget install --silent --id Microsoft.Powershell --source winget

Post-install script

Dead Windows:

# W10 22H2
# Take Cortana off the taskbar
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v ShowCortanaButton /t REG_DWORD /d 0 /f
# Hide People button
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People /v PeopleBand /t REG_DWORD /d 0 /f
# Delete Windows Defender tray from startup
reg delete HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v SecurityHealth /f
# Disable Skype from startup
reg add "HKCU\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\SystemAppData\Microsoft.SkypeApp_kzf8qxf38zg5c\SkypeStartup" /v State /t REG_DWORD /d 0 /f
# Do not hide tray items when they get cluttered
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer /v EnableAutoTray /t REG_DWORD /d 0 /f

Windows 11 21H2 and later:

# W11 21H2
# Disable Teams+Edge from autostartup
# Disable Widgets icon from Taskbar
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v TaskbarDa /t REG_DWORD /d 0 /f
# Disable Chat icon from Taskbar
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v TaskbarMn /t REG_DWORD /d 0 /f
# Align Taskbar to the left
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v TaskbarAl /t REG_DWORD /d 0 /f

# W11 21H2 + W10 22H2
# Enable Hyper-V on Pro or Edu
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All -NoReboot
# Ignore CPU freshness check and downgrade minimum TPM version from 2.0 to 1.2 for upgrades
reg add HKLM\SYSTEM\Setup\MoSetup /v AllowUpgradesWithUnsupportedTPMOrCPU /t REG_DWORD /d 1 /f
# Disable Automatic Install of Suggested Apps 
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v SilentInstalledAppsEnabled /t REG_DWORD /d 0 /f
# Disable App Suggestions in Start menu
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v SystemPaneSuggestionsEnabled /t REG_DWORD /d 0 /f
# Disable popup "tips" about Windows
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v SoftLandingEnabled /t REG_DWORD /d 0 /f
# Disable Windows Welcome Experience
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v SubscribedContent-310093Enabled /t REG_DWORD /d 0 /f
# Disable xbox game DVR capture
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR /v AppCaptureEnabled /t REG_DWORD /d 0 /f
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR /v HistoricalCaptureEnabled /t REG_DWORD /d 0 /f
# Show file extensions
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v HideFileExt /t REG_DWORD /d 0 /f
# Opening explorer opens in THIS PC rather than RECENT FILES
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v LaunchTo /t REG_DWORD /d 1 /f
# Take Search off the taskbar
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Search /v SearchboxTaskbarMode /t REG_DWORD /d 0 /f
# Hide Task View button
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v ShowTaskViewButton /t REG_DWORD /d 0 /f
# Show hidden files
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v Hidden /t REG_DWORD /d 1 /f
# Show hidden system files
#reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v ShowSuperHidden /t REG_DWORD /d 1 /f
# Disable lock screen window when using password, saving one extra click
reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization /v NoLockScreen /t REG_DWORD /d 1 /f
# Enable Dark Mode for apps
reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize /v AppsUseLightTheme /t REG_DWORD /d 0 /f
# Enable Dark Mode for system
reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize /v SystemUsesLightTheme /t REG_DWORD /d 0 /f
# Disable new context menu, always show the old one
reg.exe add 'HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32' /f /ve
# To revert the above:
#reg.exe delete "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}" /f
# Disable UAC prompts
reg add HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f
# Delete OneDrive from startup
reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v OneDrive /f
# Delete all taskbar shorcuts to get rid of Edge, Store and more
reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband /v Favorites /f
# Disable hibernation to get rid of hiberfile.sys
#powercfg.exe -h off
# Kill and restart explorer.exe to apply most changes right now
taskkill /f /im explorer.exe
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(''))

# Reopen powershell

# Minimal install
choco install -y 7zip-zstd everything googlechrome hashcheck notepadplusplus nomacs smplayer ventoy windirstat vcredist-all
# Remove Chrome from DB, it has its own autoupdater
choco uninstall -n --skipautouninstaller googlechrome
# Further Bloat
choco install -y crystaldiskmark crystaldiskinfo hwinfo mumble keepassxc libreoffice-fresh sharex telegram vscode qbittorrent

Activate Windows

First install vlmcsd and OpenVPN's tap driver for a tunnel, as Windows will refuse to authenticate against a KMS server running on localhost

choco install -y tapwindows
# Download the vlmcsd binaries archive and extract binaries/binaries/Windows/intel/vlmcsd-Windows-x64.exe to C:\install\vlmcsd.exe
New-Item -ItemType Directory -Force -Path C:\install
Invoke-WebRequest -Uri -OutFile C:\install\vlmcsd.exe
# Install the service
C:\install\vlmcsd.exe -s -U /n -O .
netsh advfirewall firewall add rule name="vlmcsd" dir=in action=allow program=C:\install\vlmcsd.exe enable=yes
# Start the service (it's enabled, reboot would also start it)
net start vlmcsd
# If you do not have Home(Core) installed, you can switch between different editions (not Home)
# You can get a popup with available editions via 'slmgr /dlv all'. 
# Get just the editions by copypasting the box and running 'grep Name boxtext.txt | sort | uniq'
# Note: Windows 11 KMS keys seem to match W10 ones

# Switch edition to Edu
Cscript.exe c:\windows\system32\slmgr.vbs /ipk NW6C2-QMPVW-D7KKK-3GKT6-VCFB2

# W11 Edu 
slmgr /ipk NW6C2-QMPVW-D7KKK-3GKT6-VCFB2
# Set KMS server to a LAN one
#slmgr /skms
slmgr /skms
# Force activation now
slmgr /ato
# You should get a box in a few seconds that the activation passed. You can see the license info with
slmgr /dli

Activate Office

# Convert Retail to VL first if Office is Retail

cd 'C:\Program Files\Microsoft Office\Office16'
# Office 2019 Pro Plus
#cscript ospp.vbs /inpkey:NMMKJ-6RK4F-KMJVX-8D9MJ-6MWKP
# Office 2021 Pro Plus
cscript ospp.vbs /inpkey:FXYTK-NJJ8C-GB6DW-3DYQT-6F7TH
cscript ospp.vbs /sethst:
cscript ospp.vbs /act

Force W10 to W11 upgrade

# Source for some of these:
# Can also be done by doing SHIFT+F10 from an unmodified booted W11 installer -> regedit and adding the LabConfig values

## Upgrade W10 to W11 with at least TPM 1.2
# Ignore CPU freshness check and downgrade minimum TPM version from 2.0 to 1.2 for upgrades
reg add HKLM\SYSTEM\Setup\MoSetup /v AllowUpgradesWithUnsupportedTPMOrCPU /t REG_DWORD /d 1 /f

## Clean install W11 with possibly no TPM, <4GB RAM and on BIOS/UEFI with no Secure Boot
# Bypass TPM check in booted image
reg add HKLM\SYSTEM\Setup\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1 /f
# Bypass 4GB+ RAM check in booted image
reg add HKLM\SYSTEM\Setup\LabConfig /v BypassRAMCheck /t REG_DWORD /d 1 /f
# Bypass SecureBoot check (UEFI check pretty much) in booted image
reg add HKLM\SYSTEM\Setup\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1 /f
# Bypass Storage Check... is this even required?
reg add HKLM\SYSTEM\Setup\LabConfig /v BypassStorageCheck /t REG_DWORD /d 1 /f


You can download .ISO of Windows 10 or Windows 11 versions directly from Microsoft's servers. Note that you'll have to spoof the user agent if you're on Windows, as you'll get redirected to the Media creator tool otherwise.

The ISOs provided by MS contain all the editions (sans enterprise pretty much), but you might have to add.../sources/ei.cfg file to show them all.

You can download older versions of windows and different versions of W10 through this method

If you want Enterprise, one way to get it is to install Pro/Edu and then switch the license, as per the powershell example above.

Reboot into UEFI

Open admin cmd.exe and run: shutdown /r /fw /t 0

Windows 11 Installation

[[Creating a bootable flashdrive|Boot from the flash drive]]. Remember to always select "Custom" where applicable. You can skip creating a Microsoft account by trying to login with a nonexistent email.

Windows usually gets all the drivers itself, but if something doesn't work as it should you might need to visit your motherboard or device manufacturer's website and download drivers/update firmware.

Windows usually downloads an outdated GPU driver so head over to AMD's or Nvidia's website depending on what GPU you have.

If you already have or had a Windows license, then your hardware ID combination(should be motherboard+CPU) is stored on Microsoft's servers and your license will be obtained automatically when you connect to the internet, provided you installed the same Windows version.

If you don't have a W11 license you can either:

  1. Buy a license key from official source. Buying from unofficial sources/grey markets is exactly as illegal as cracking it. You'd be literally giving your money away to thieves. The keys are from hacked MSDN accounts, credit card frauds etc.

  2. If you're in college or some sort of academic institute, they might have MSDN licenses, see if you can find a copy from their IT department.

  3. Not activate Windows - you will not be able to use Personalization features and it'll nag you

  4. Activate Windows with KMSpico. Defender will complain about it, allow it manually in Defender after installing it. Alternatively you can use vlmcsd if you want an open source, more hardcore solution.

Upgrade from Home edition

Use a generic key - W10 or W11 - to upgrade to the needed edition.

This is not a valid key for activation, it only allows for the upgrade.

Setting up OpenSSH

Due to this, to connect to an admin user, one needs to use


instead of

$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR3/QA/+Kq1txg/APGQcpa3UradYnaaxSomDQamFDpH' > 'C:\ProgramData\ssh\administrators_authorized_keys'
# Check that the resulting file is(file is not preinstalled):
#   Unicode text, UTF-8 (with BOM) text, with CRLF line terminators
# And not this or anything else:
#   Unicode text, UTF-16, little-endian text, with CRLF line terminators
file 'C:\ProgramData\ssh\administrators_authorized_keys'

To use sshd, first install it via Optional Features as per the docs;

To start it, run services.msc and configure OpenSSH Server to start Automatic and also Start it.

Disable password authentication in the config and then restart the server to apply it. Optionally also disable forcing the key path for admins.


If you can't connect to an admin account and you kept the forced key path, permissions are probably wrong, run the following to set them correctly

icacls C:\ProgramData\ssh\administrators_authorized_keys /remove "NT AUTHORITY\Authenticated Users"
icacls C:\ProgramData\ssh\administrators_authorized_keys /inheritance:r
get-acl C:\ProgramData\ssh\ssh_host_dsa_key | set-acl C:\ProgramData\ssh\administrators_authorized_keys

VM setup

Install spice-guest-tools on KVM with Spice for better experience.


Since I was forced to make an eIdentity with my government, mostly due to new laws about customs, I noted down everything needed from the view of someone who had absolutely no eGovernment account before.




Current is a gateway drug to magic smoke.

A list of basic stuff to buy when starting out


You might've noticed that some things are super easy to solder, some are super hard.

That's because you may be using a ruined tip(it's supposed to be shiny, not black), low-power iron or solder without lead(Pb). The last possible annoying cause is that the contacts you are soldering on are lead-free. For those I've had to use minimum 370°C and half of the connections I made were garbage.

How to not ruin a tip

Do not leave the iron on when you are not using it.

Clean the tip by applying solder, wiping it clean on a sponge or steel wool and then coat it with a thin layer of solder to prevent oxidation before you turn it off and leave it, or coat it right after turning it off.

If you use a sponge, make sure it's damp but not soaked.



LED strips

LED strips from "best" to "worst". Price is according to that.

SK9822 =~ APA102 > APA102C > WS2812B


If you overvolt a capacitor it will fail in moments, if you go above 50-70% of the voltage limit it will fail in months, or years. All electrolytic caps will fail eventually though, even if idle



Alkaline typically doesn't have a mAh rating because it's so current dependant


To measure voltage just put multimeter to voltage mode and connect leads to positive and negative of the batteries. If the battery is non-rechargeable and way below it's supposed voltage (think <1V for 1.5V battery) it's pretty much dead.

Laws and equations

Ohm's law

The law stating that the direct current flowing in a conductor is directly proportional to the potential difference between its ends. It is usually formulated as V = IR, where V is the potential difference, or voltage, I is the current, and R is the resistance of the conductor.

To explain that in a more useful way - You can calculate for a third variable if you know the other two.

That means if you wanted to know what resistor to use if you had an LED that drops 3.3V, works at 20mA and your power source was 5V - Since the current is the same across the circuit, you'd calculate the voltage drop of the resistor divided by the current, which is 1.7V in this circuit as 3.3V is already being dropped by the LED - (5-3.3)/0.02 and would end up knowing you need to use a resistor that is 85Ω or close to that value.


Keep in mind these projects assume you have the parts kit linked at the top of the page.



Assuming Linux your user needs to be in the lock and uucp groups.

Get the Arduino IDE and setup ESP8266 in it according to this github readme.

Connect the board via the microUSB connector and in Arduino>Tools>Port select the ttyUSB0 port. Under Board select the NodeMCU 1.0 one.

Pulling the D0 pin up makes one of the integrated LEDs light up, so it's a quick way to test everything is running, so let's do just that and blink it.

You can use the number notation (GPIO10 is defined as '10') or the pin notation, like D0.

  void setup() {
    pinMode(D0, OUTPUT);
  void loop() {
    digitalWrite(D0, HIGH);  // turn the LED on.
    delay(1000);             // wait for 1 second.
    digitalWrite(D0, LOW);  // turn the LED off.
    delay(1000);            // wait for 1 second.

Upload it to the board, it should boot up and the blue LED should start blinking.

Now let's try with an actual LED, grab a red 5mm one. If you'd read the specs sheet you'd know it has a 2V voltage drop and is rated for 20mA of forward current. You need a resistor unless you want to fry the LED with current, so according to Ohm's law a resistor for the remaining 1.3V voltage drop needs to be (3.3-2)/0.02, so around 65 Ohms.


Connect them like so and now you should have the LED permanently glowing. Quite boring, let's make it blink.

Re-connect the resistor from the 3v3 pin to the SD3 one (GPIO10) and replace the code with this:

  const short int LED1 = 10; 
  void setup() {
    pinMode(LED1, OUTPUT);
  void loop() {
    digitalWrite(LED1, HIGH);  // turn the LED on.
    Serial.println("Turned LED1 on");
    delay(1000);             // wait for 1 second.
    digitalWrite(LED1, LOW);  // turn the LED off.
    Serial.println("Turned LED1 off");
    delay(1000);            // wait for 1 second.

Now it should blink! And since we added serial connection and some debugging output, we should be able to connect to it via some software that can read serial, for example 'screen'. Note that 115200 is the baud rate, affecting how fast you can send/receive data.

screen /dev/ttyUSB0 115200

If you see output every second with on/off sentence, great! You can do ^A and then K to kill the window.

Now let's make the LED Wi-Fi controllable! Same physical setup, different code. Just change the SSID and password in the example:

#include <ESP8266WiFi.h>

const short int LED1 = 10;

const char* ssid = "ssid";
const char* password = "password";
WiFiServer server(80);

void setup() {
	pinMode(LED1, OUTPUT);
	// WiFi.mode(m): set mode to WIFI_AP, WIFI_STA, or WIFI_AP_STA.
	WiFi.begin(ssid, password);

	while (WiFi.status() != WL_CONNECTED) {
		Serial.println("Wi-Fi not connected, retrying... ");
		delay(500); // Do not use this delay in SoftAP mode
	// Start the wifi server

	Serial.println("IP address: ");

void loop() {
	if(WiFi.status() != WL_CONNECTED) {
		Serial.println("Wi-Fi not connected, retrying... ");
		delay(500); // Do not use this delay in SoftAP mode
	WiFiClient client = server.available();
	if (!client) {
		//Serial.println("No client connected, suiciding.");

	int insanity = 0;
	// Wait until the client sends some data
	while (!client.available()) {
		if (insanity == 1000) {
			Serial.println("And nobody came...");
		Serial.println("Waiting for client to send data.");
		//client = server.available(); // Check if the connection didn't break, if yes, kill it.
		//if (!client) {
	Serial.println("Client available, receiving data...");

	// Read the first line of the request
	String request = client.readStringUntil('\r');

	// Match the request
	if (request.indexOf("/OFF") != -1) {
		digitalWrite(LED1, LOW);
	if (request.indexOf("/ON") != -1) {
		digitalWrite(LED1, HIGH);
	// Return the response
	String html = String("HTTP/1.1 200 OK\r\n") +
                "Content-Type: text/html\r\n" +
                "\r\n" +
                "<!DOCTYPE HTML>" +
                "<html>" +
                "<head>" +
                "<style media=\"screen\" type=\"text/css\">" +
                "   .button {" +
                "        background-color: #000000;" +
                "        color: #FFFFFF;" +
                "        padding: 10px;" +
                "        border-radius: 10px;" +
                "        -moz-border-radius: 10px;" +
                "        -webkit-border-radius: 10px;" +
                "        margin:10px" +
                "    }"
                "    .small-btn {" +
                "        width: 50px;" +
                "        height: 25px;" +
                "    }" +
                "    .medium-btn {" +
                "        width: 70px;" +
                "        height: 30px;" +
                "    }" +
                "    .big-btn {" +
                "        width: 90px;" +
                "        height: 40px;" +
                "    }" +
                "</style>" +
                "</head>" +
                "<body>" +
                "<a href=\"/ON\"><div class=\"button big-btn\">ON</div></a>" +
                "<a href=\"/OFF\"><div class=\"button big-btn\">OFF</div></a>" +
                "</body>" +

Get the IP either from serial or your DHCP server list. Open it in your browser and you should see two buttons that turn the LED off and on.


Now that you know enough to get going, time to dive into something fun, IR. Let's make a thing that can both receive and send.

You'll need a 2-pin IR LED, 3-pin 1838 IR receiver, 2N2222 NPN transistor, 100 Ohm resistor and some wires.


You will need to setup the IR library for ESP8266

Keep in mind that at least on the NodeMCU board linked in the doc with stuff to buy you can't use GPIO 1,3,9,10,15,16 for IR receive(and possibly send), the limitations are mostly explained here.

I used this code to test which GPIOs I can use for receiving:

#include <ESP8266WiFi.h>

#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRsend.h>
#include <IRtimer.h>
#include <IRutils.h>
#include <ir_Argo.h>
#include <ir_Daikin.h>
#include <ir_Fujitsu.h>
#include <ir_Kelvinator.h>
#include <ir_LG.h>
#include <ir_Magiquest.h>
#include <ir_Midea.h>
#include <ir_Mitsubishi.h>
#include <ir_Toshiba.h>
#include <ir_Trotec.h>

const char* ssid = "ssid";
const char* password = "password";
WiFiServer server(80);

int RECV_PIN = 0; //IR IN
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {

	// WiFi.mode(m): set mode to WIFI_AP, WIFI_STA, or WIFI_AP_STA.
	WiFi.begin(ssid, password);

	while (WiFi.status() != WL_CONNECTED) {
		Serial.println("Wi-Fi not connected, retrying... ");
		delay(500); // Do not use this delay in SoftAP mode
	// Start the wifi server
	Serial.println("IP address: ");

	Serial.print("RECV_PIN now: ");
void loop() {
	if (irrecv.decode(&results)) {
		Serial.println((long int)results.value, HEX);
		irrecv.resume(); // Receive the next value
		return; // Kill the cycle
	if(WiFi.status() != WL_CONNECTED) {
		Serial.println("Wi-Fi not connected, retrying... ");
		delay(500); // Do not use this delay in SoftAP mode
	WiFiClient client = server.available();
	if (!client) {
//		Serial.println("No client connected, suiciding.");

	int insanity = 0;
	// Wait until the client sends some data
	while (!client.available()) {
		if (insanity == 1000) {
			Serial.println("And nobody came...");
		Serial.println("Waiting for client to send data.");
	Serial.println("Client available, receiving data...");

	// Read the first line of the request
	String request = client.readStringUntil('\r');

	// Match the request
	if (request.indexOf("/NEXT_PIN") != -1) {
	// Return the response
	String html = String("HTTP/1.1 200 OK\r\n") +
                "Content-Type: text/html\r\n" +
                "\r\n" +
                "<!DOCTYPE HTML>" +
                "<html>" +
                "<head>" +
                "<style media=\"screen\" type=\"text/css\">" +
                "   .button {" +
                "        background-color: #000000;" +
                "        color: #FFFFFF;" +
                "        padding: 10px;" +
                "        border-radius: 10px;" +
                "        -moz-border-radius: 10px;" +
                "        -webkit-border-radius: 10px;" +
                "        margin:10px" +
                "    }"
                "    .small-btn {" +
                "        width: 50px;" +
                "        height: 25px;" +
                "    }" +
                "    .medium-btn {" +
                "        width: 70px;" +
                "        height: 30px;" +
                "    }" +
                "    .big-btn {" +
                "        width: 90px;" +
                "        height: 40px;" +
                "    }" +
                "</style>" +
                "</head>" +
                "<body>" +
                "<a href=\"/NEXT_PIN\"><div class=\"button big-btn\">NEXT_PIN</div></a>" +
                "</body>" +

void nextPin() {
	Serial.print("RECV_PIN now: ");
	IRrecv irrecv(RECV_PIN);
	decode_results results;
	irrecv.enableIRIn(); // Start the receiver


Lots of services give you different prices depending on which region you appear to be from.
Here is a handy wiki page explaining the concept.

This page documents the various services I use and their caveats.

Keep in mind that trying to cheat this system breaks TOS of practically all services.


Bandcamp charges you VAT if your IP is from a country where VAT is collected, as opposed to for example Israel.


Geopricing sheet

Netflix has not only different pricing but the service they offer can differ. For example, in Turkey they offer a plan not available anywhere else, a very low-cost mobile plan.

You should be able to set up payments via any debit card for any region as long as your IP is from that region. For example you could use a Turkish proxy to have the service for half the price, you only ever need to appear from TL IP while you set up the payment method.

Netflix's library content is based on your current IP.


Steam store's regional pricing is set by game publishers and can vary a lot, but places with bad economy generally have cheap games, with Turkey being the best as of writing due to Turkish Lira crashing a lot.

Currently, at first payment after your account's creation your account's geolocation is decided. You can change it once per 3 months, and you need an IP and payment method of the country you're changing to, simply change the country checkout when you're buying something.

You can only charge up or pay for a game through a valid payment method in the region you're buying the game in.

You should always shop from the same country's IP, as of 2022-08 Valve has apparently taken notice of this trick and started soft-changing the region of the account.

Around 2023-07, Valve has stopped providing gift cards to Turkey, Argentina and possibly others.

You can, however, activate a digital or physical* steam gift card from any region**, currency will autoconvert.

* Digital cards can only be sent to people you've been friends for 3+ days with
** Any region as long as the currency gap is not too large(?), gifting from EUR to Turkey or Argentina will give a There seems to have been an error initializing or updating your transaction. Please wait a minute and try again or contact support for assistance. error for example

To activate a georestricted game:

To make a purchase with a debit/credit card, it must not have been used on 4 other accounts previously, it seems.

Some games change their language availability depending on your region. Such is always noted in a warning on the store page for the game however.


Looks like Mexico is one of the cheapest regions to get membership through.

Regional IP only needed for payment. Takes any debit card if I recall correctly.

You can have a US, EU or RU account on Battle.Net(possibly more). This is decided at account creation time and changing this seems to require a valid ID and contacting support.

RU has most things for half the price, including World of Warcraft expansions and subscriptions.

While Battle.Net will actually let you use a debit card from any region, it will be declined and your payment refunded after a few hours. If you intend to have a RU account, you need to charge it up via a valid russian payment method or... game cards. Shady sites like have resellers that sell such cards with next to no profit.


Patreon charges you VAT if your account is set to a country where VAT is collected, as opposed to for example Israel.

Just use a russian proxy and your own debit card...

Youtube Premium Family

One of the cheapest regions for Premium is Turkey, as of writing it is priced at 116 TL/mo for a family plan for 6 people.

You will need a debit card from any region, a proxy/VPN that is actually good and the premium page will show you that the plan is available.

People you invite to share the family plan with need to be joining from the same geolocation as your account's address. If you have trouble with Alphabet thinking you're still located in a different country, you'll need to make sure that your Google Pay account is set to the same country as the host's address. If you have multiple Pay profiles, you may have to close the other ones. You can add them back afterwards.

Family groups aren't available for G Suite accounts.


Sending money via PayPal is tricky - sending as a product has less fees than sending as friends&family.

This calculator has worked for me in the past -


Turkey seems to be cheapest at 350TL/year

You will need a non-VPN (or at least not flagged) Turkish IP and the easiest way seems to be to get a Turkish Google account and pay via G2A prepaid cards through Play Store.

Raspberry Pi as fake mass storage

Disclaimer: Since the advent of Ventoy, this is much less useful, but a fun project nevertheless.


Ever wanted a Multiboot drive but realized turning a flash drive into one is impossible with some images(Windows in particular), and commercial solutions start at 50 EUR?

Let's use the 10 EUR Pi Zero W instead.

The board uses MiniHDMI. You can find Mini+MicroHDMI to HDMI connectors for under 1 EUR on Aliexpress. However video output is technically not needed, especially if you have the W version of the board.

The 5 EUR Pi Zero without Wi-Fi can also be used, but is less comfortable for my use, pushing images over the internet into it via rsync is comfy.


Benefits over a simple flash drive:





<C0rn3j> I want to power a raspberry pi zero from a power bank, while also use it for data connection with a PC. This is an issue because as the PC reboots, so does the Pi sometimes, pretty sure its trying to take power through the PC instead of the power bank
<C0rn3j> how do I prevent it trying to power itself off of the second USB port?
<DocScrutinizer05> you get a USB Y-cable and connect the "middle" plug to PC, the "extension" plug to powerbankand obviously the other end to SBC, then you hope your PC won't barf up when external USB VBUS during reboot
<DocScrutinizer05> smarter approach is to add two schottky or ideal diodes from powerbank and from PC to SBC VBUS in
<DocScrutinizer05> a third solution is to use a cheap externally powered USB hub that's powered by your powerbank. The cheap USB hubs simply feed through external power to downstream USB VBUS
<DocScrutinizer05> hope I explained it sufficiently obscure to question all answers ;-)
<DocScrutinizer05> the hub simply feeds through the external power barrel jack to the downstream USB ports
<DocScrutinizer05> it however sometimes (not all do) has a diode preventing 5V power to go back from hub to PC
<DocScrutinizer05> the expensive high-quality hubs *might* have a transistor switch between external 5V in and each downstream port, and control those transistors via software. Rarely ever to be found but you should keep in mind those exist, when you encounter strange behavior
<DocScrutinizer05> then, USB also knows of a "software" suspend command that your SBC obviously should ignore if the PC actually does send it during reboot


My OS of choice is Archlinux ARM for the board, Pi Zero is essentially Pi 1. Follow the install guide for it. Stop before step 7 if you have to W version to setup Wi-Fi first.


If you have the W version of the board, you will want to setup Wi-Fi:

cat << EOF >> root/etc/systemd/network/


wpa_passphrase yourSSID yourPassword > root/etc/wpa_supplicant/wpa_supplicant-wlan0.conf

ln -s /usr/lib/systemd/system/wpa_supplicant@.service root/etc/systemd/system/

USB Gadget

Now we setup the USB Gadget which will let us use all the fun features.

Edit /boot/config.txt and add a new line to it to use the needed driver:


Create /etc/modules-load.d/usbgadget.conf with the following content:


Add max_loop=256 to the end of /boot/cmdline.txt. This raises amount of max loop devices from 8 to 256.

We're only interested in g_mass_storage for this use case. There is many more uses for this driver, check out this gist if you're interested.

Additional OS setup

If you're using the W version, install rsync, openssh, enable sshd on boot, disable password auth in sshd_config and throw your pubkey in root's authorized_key file.

W or non-W, reboot the board.


You have two ways to host your images - either via emulated mass storage or emulated USB CD-ROM.

Power the board on by connecting the PWR IN port to a power source. A power bank or another PC will do.

You will have to connect the board through the other USB port to a turned-off PC and cold boot it after you attach the image. Restarting the PC will also restart the board, see Problems in [[#Intro]].

If you want to mount another image after already mounting one, you have to remove the following first:

rmmod g_mass_storage

Emulated mass storage

The following approach works for most sane bootable ISOs. Default Windows ISOs are a snowflake and need to be remastered into an image with a FAT32 partition with the files copied over. Look up loopback devices if you need Windows, or implement emulated DVD-ROM as per Problems in [[#Intro]] and use the approach below.

modprobe g_mass_storage file=/archlinux.iso stall=0

You can also specify up to 8 images at once, although you don't want to do this since there's no way to distinguish them in UEFI/BIOS since the module does not give the emulated devices a name.

modprobe g_mass_storage file=/archlinux.iso,/anotherimage.iso,/guttedwindows.iso stall=0

Emulated USB CD-ROM

This approach does not work with ISOs over 2.4GB, see Problems in [[#Intro]].

modprobe g_mass_storage file=/archlinux.iso stall=0 cdrom=y

Emulated CD drive shows up as /dev/sr*

Additional setup

Tip: While this guide is for loading ISO images, you can load any image, including simple storage, or read only storage etc.


An acrylic case is some $1.7 from Aliexpress.

TODO - picture

Display and buttons

TODO - Here goes additional software and hardware setup

Sources <- why is the formatting broken? Same link as above

Linux-sunxi has a bit of info not present on this page, I recommend you give it a read.

Video Encoding

My TV does not play some video files, this is an attempt to document why and how to reencode things.

mediainfo is a handy tool, running it against a file gives you handy info, such as that the encoding settings of the video stream are ref=10 ... bframes=10, which is more than my TV can handle, so let's re-encode this.

I've tried using nvenc (hevc_nvenc for x265) to encode, but then it ignores the crf setting and produces garbage quality output, so am stuck rendering on a CPU.

The -map 0 option needs to be there, or only one audio track will be copied.

The -y option is to overwrite the output file without asking.

The -crf 18 option is there to set quality. You can play around with this if you're not satisfied with the image or think you can save space.

ffmpeg -y -i original.mkv -c:v libx264 -crf 18 -preset slow -c:a copy -map 0 reencodedx264.mkv
ffmpeg -y -i original.mkv -c:v libx265 -crf 18 -preset slow -c:a copy -map 0 reencodedx265.mkv

System Basics

Hi! This page is supposed to explain phones/laptops/desktops/technology in general. It's obviously completely incomplete.

Monitors, displays etc

Frame rate and Sync technologies

Standard for monitors is 60Hz. That means the monitor can display 60 frames per second. In games you might still want your PC to produce more frames than your monitor's refresh rate can physically display, because you will see a newer frame, which means less latency.12


144Hz monitor - 1000/144 = 6.944ms per frame draw

144Hz G-Sync worst result - 38ms

144Hz No sync worst - 26ms

G-Sync effectively adds about 12ms of input lag over having no sync on 144Hz. That's almost 2 whole frames, which was really noticeable for me when I was testing it on CS:GO.

Having no sync can cause screen tearing . However, while screen tearing is really noticeable on a 60Hz panel, on a 144Hz one it's much less noticeable and not a problem for me, so I play with no sync.

Keep in mind that Windows doesn't seem to like having two or more monitors connected with different refresh rates. It seems to slow down the other monitors to the frequency of the lower monitor when there's a redraw on it, which makes everything stutter/freeze for a little while.

Linux doesn't seem to have that problem.


Unless you're using a password manager, your passwords are most likely insecure.

Take the LinkedIn database breach - over 96% passwords were bruteforced already. That means that less than 4% people are probably using decent passwords. Why probably? Because they could still be using one strong password for all sites, but the moment there's a database leak where passwords are in plain text is the moment when their system becomes useless.

Go read the XKCD about bit entropy. Sounds like good advice? It isn't. If we agree that safe password length is 15 characters, and you just used "correct horse battery staple" as a password, you've just effectively made a "4 character" password to someone who has a script that uses whole dictionary words to bruteforce it_(taking in account that the number of commonly used words is much larger than the number of characters in the alphabet(26))_. Even if you start adding numbers here and there, it's still not good as someone could use modified version of that script so it tries replacing letters with numbers, and you also end up having the problem the XKCD itself talks about. Think that any word or any sequence of characters counts as one character.

I've hopefully convinced you that remembering 15 completely different passwords is impossible and using the same or similar password on those 15 sites is stupid. What's the solution then? A password manager.

You should also expect certain things from the password manager.

I've found KeePassXC to satisfy those needs(Android implementation). You only need to make one strong password for the database file and you're set. Remember to have multiple backups of the database file. Setting a timeout on the clipboard and database to 30~ seconds should be a good idea.

Keep in mind that if you follow all the advice here, you will lose access to your accounts if you lose access to your password database backup. It would be a good idea to encrypt it with 256-bit AES and keep it with someone you trust or somewhere safe offsite. Imagine some very unlikely event like tornado/flood passing through your house, you probably won't have access to anything in it afterwards, so plan ahead.

2 Factor Authentication

2FA is an awesome thing which adds another layer of security. Service you're using has to obviously support 2FA.

There is a lot of implementations since most 2FA is based on an open standard.

2FA works like following: Site gives you a secret key(sometimes in a form of QR code with a small button that reveals it in plain text), which you will supply into your 2FA app on your device(s), and the application on the device(s) will give you a generated code which works for a short time, you will need that code to login to the service after supplying your username and password. '''Remember to backup the secret key.'''

Your time on the device needs to be correct otherwise you will receive invalid codes.

2FA does not only mean that you have an app with a secret key and timed codes, but can also be a device, or SMS/call codes...

You cannot trust your cell provider, SO DO NOT use SMS/call authentication if you can avoid it.

Using an open source authenticator app is highly recommended, it is a layer of your security, you should be able to look at the source code.

Personally I use WinAuth for desktop. It is an open source app made for Windows, with support not only for the traditional Google Authenticator algorithm but also services like or Steam. It also works well on Linux with WINE.

For phone I use FreeOTP. Google Authenticator is not open source anymore, so I'd advise against using it.

Remember that 2FA is a Two Factor Authentication, having your password and 2FA system saved on the same computer effectively makes 2FA useless.


Hard drives fail, flash drives fail, DVDs/BDs deteriorate, solid state drives fail, accounts get hacked and the data wiped, data corruption happens... You need a good backup system.

Security through encryption

Wi-fi security

Use WPA2-PSK with AES encryption, disable WPS and use a password that you would not find in a dictionary nor one that can be bruteforced.

That means you shouldn't use WPA/WPA2, just pure WPA2, you should not use TKIP, only AES.

For WPA2 Enterprise networks, do not use MSCHAPv2 protocol.

Here's why


File encryption



Why? I have nothing to hide

Privacy is a human right. People should have control over and access to the data they produce. If this right is not granted, people give significant power to those who have the access to and control over information. Even though they might be trusted now, no one can predict who will have the access and control in the future. Data about you is a leverage point for predicting and influencing your future actions. It is power over you.[1]

Instant messaging


Also known as "Give me 5 digits to reset an account and gain control over it"


Operating systems and everything around them

There's tons of operating systems and tons of their variations. I'll list some of the most used ones.


You can backup and restore android appdata without root.

adb backup -apk -shared -all -f backup-file.adb
adb restore backup-file.adb

With root apps should be in /data/app/APPNAME/base.apk and appdata should be in /data/data


Runs on x86(Windows 11 dropped support) and x64 and ARM CPU architectures.

You can either buy a retail or OEM license, retail is transferable between devices and OEM is tied to one device(unique motheboard and CPU) only. Retail home edition costs 119$.

The main editions that are still supported are 8.1(2023) and new builds of 10. The number in brackets is the year when the system becomes End Of Life, which means it will stop receiving support and should not connected to the internet at that point.

W10 has following editions:

In addition to that, each version can be either N or KN(Korean version of N), which removes software like Windows media player and a bunch of other mostly useless software.

There are also Server versions




Partition Tables, BIOS and UEFI

Motherboard has firmware, which used to be IBM BIOS, but is nowadays UEFI. Almost everyone incorrectly refers to UEFI as BIOS, including motherboard manufacturers.

Most UEFI implementations have backwards compatibility with how the old BIOS firmwares used to boot, known as CSM (and sometimes as Legacy or simply BIOS). This mode should not be used and is going to be discontinued on Intel hardware post 2020.

BIOS booting works by loading the first 1024~ bytes (it varied) from a drive. This was never standardized. UEFI booting works by either directly booting an entry off a partition(almost never implemented), or by booting off entries in /boot partition(called ESP or EFI) which is standardized, should be FAT32 (FAT16 also works if your OS supports it, and Apple has added in their FS support into their UEFI implementation).

Using the EFI partition allows for multiple installed operating systems without deleting each other's bootloaders, as it used to be during the BIOS times.

MBR - Obsolete drive partitioning standard. It does not support more than 4 partitions per drive or drives larger than 2TB. Whole MBR is located on 512 bytes on the first sector of a drive, it contains the bootloader and information about partitions. Since this size is extremely small for any modern bootloader, it usually contains enough code to load a bootloader stored on an actual partition. For example if you have a Linux/Windows dual-boot, GRUB as a boot manager, and decide to wipe the partition with Linux, you will not be able to boot properly since GRUB can't load.

GPT - Current partitioning standard, use it if you have the option.

BIOS - First thing that loads when you start up you PC. Obsolete, only supports MBR(or rather, Windows will refuse to work using BIOS+GPT or UEFI+MBR).

UEFI(previously EFI) - Successor of BIOS, supports GPT, usually has backwards compatibility to allow BIOS booting(and you can use GPT partitioning with that).

Motherboards with UEFI firmware have been the standard for years now, so unless you're working with hardware that's more than few years old it's likely using UEFI.

To update BIOS or UEFI go to your motherboard/laptop manufacturer's website. Looking in the downloads section should give you downloads and documentation on how to update. 1

If you want to read more about this, here's a handy site.

CPU architectures

ARM - weaker CPU architecture used in smartphones and such. It is not capable of running x86/x64 code

x86 - 32 bit architecture - obsolete, 32bit desktop CPUs were last made a decade ago. Cannot run x64/ARM code

x64 - 64 bit architecture - current standard for desktop PCs. Can run x86 code, cannot run ARM.

Creating a bootable flashdrive

Instructions here

Installing an OS





Find some wattage calculator, get a PSU that has higher wattage than that and make sure it is not shit by getting a Tier 1 PSU from this post.


CPU cooler



How to check for failure

Under Arch Linux EFI install:

$ trizen -S memtest86-efi
# memtest86-efi --install

Storage Drives



S.M.A.R.T and Badblocks

S.M.A.R.T - is a monitoring system included in computer hard disk drives (HDDs) and solid-state drives (SSDs) that detects and reports on various indicators of drive reliability, with the intent of enabling the anticipation of hardware failures.

Windows: CrystalDiskInfo - open source tool

Linux: Arch Wiki

Badblocks is a program to test storage devices for bad blocks.

sudo badblocks -wsv /dev/$drive - Perform a DESTRUCTIVE test on the device. Tests with 4 patterns, so 4 passes which can take a while on an HDD. Useful for new drives or drives which have useless data on them.

sudo badblocks -nsv /dev/$drive - Perform a NON-DESTRUCTIVE test on the device. Single pass test.






Today's widely used formats waste a crap ton of space - it is the reason why Dropbox made the lossless Lepton format for JPGs(saves about 22% space on average).

One of the formats you can convert your images to is WebP.

You can use a simple script and ImageMagick to mass convert files - It is not perfect (images will end up being named image.jpg.webp) but it does the job.

for file in *; do; convert $file $file.webp; done


One of the formats you can convert your videos/GIFs/whatever is WebM.

You can use a simple script and ffmpeg to mass convert files - It is not perfect (images will end up being named image.''mp4''.webm, usually only runs on a single thread) but it does the job.

for file in *; do; ffmpeg -i $file $file.webm; done

Mouse Polling rate

Max mouse polling rate is 1000Hz, as in 1ms response time. Surprisingly I'm having a hard time finding mice that actually do have 1ms response time even though it says so on the spec sheet.

How to check your polling rate:

Windows: Download

Linux : #TODO

List of mice I've tried so far:

A4 Tech XL-750BK - says 1000Hz, actually is 1000Hz 3600 DPI laser mouse. I'm using this one.

SteelSeries Sensei RAW NaVi Edition - says 1000Hz, is actually 500Hz~.


My list of issues on Wayland -

3D Printing


According to this (backup) selection guide - you need A1 protection for the resin fumes and (FF)P2 or (FF)P3 for the particles from sanding resin.

What I ended up getting was the

Lenovo Legion 5 Pro touchpad zones

MSFT0001:00 04F3:31AD Touchpad zones for the Lenovo Legion series and possibly others, painstakingly obtained from Lenovo Support.


Martin Rys

My name is Martin Rys and I am a Linux systems administrator born and currently living in Czechia.

My hobbies are reverse engineering, embedded electronics, creating and self-hosting various services.
My hobby projects are mostly available on Gitlab.

Work experience:

Technical background:





Eating sure is nice, so if you find my existence helpful, consider starting to toss me some cash on Ko-Fi, or with extra fees through PayPal or with also some extra fees on my Patreon page.

Raspberry Pi 5, NVMe and USB woes

If you have not bought an enclosure/SSD yet, PLEASE make triple sure that what you're buying is compatible between each other and it's not the same cursed enclosure chip I bought. Ideally buy an M.2 hat instead to save yourself some of the issues. You still have to verify compatibility with the SSD if you'll choose a HAT.

After buying a Raspberry Pi 5 8GB, Orico NVMe USB enclosure and ADATA XPG SX8200 Pro 2TB for an SSD, I had an awesome time debugging it for hours, here's some things for you to check to save time.

This thread is linked on GitHub and several other places that I found where people struggled to get this working.


# JPEG/JFIF - lossless
jpegoptim "${filepath}"

# PNG (and ICO that is PNG) - lossless
# zopfli makes the entire thing MUCH slower, but saves more space - question is whether it's worth it inflating compress time by 80x (decompress is the same)
# --strip all or --strip safe options may be of interest if EXIF cleanup is desired, but EXIFtool should suffice for that
# --preserve is of interest if saving timestamp is necessary, and --fast is necessary for --zopfli unless you have a lot of CPU or a lot of time
oxipng --zopfli --opt max "${filepath}"

# SVG - might lose data that other scripts may rely on if the SVG is somehow parsed
#   see `plasma/breeze:.../` where name metadata is fed to inkscape
# Verification that result is smaller is necessary as svgo may actually be
#  adding data necessary for correct rendering everywhere.
#  That may or may not be desirable, bad for filesize, good for compatibility.
# Corrupt output is possible, take care
svgo --multipass --input "${filepath}" --output "${tempDir}/svgo-$$.temp"

# BMP -> PNG - lossless, but probably requires editing other things that link to BMP
convert "${filepath}" "${filepathWithoutExtension}.png"

# PDF - lossless recompression
# Corrupt output is possible, take care
pdftk "${filepath}" output "${filepath}.tmp" uncompress
pdftk "${filepath}.tmp" output "${filepath}.packie" compress

# GIF - lossless optimization
gifsicle "${filepath}" --output "${tempDir}/gifsicle-$$.temp"

# TTF - Converting to ttx and back with fonttools can gain a little bit of savings
fonttools ttx -q -o "${tempDir}/fonttools-$$.ttx" "${filepath}"
fonttools ttx -q -o "${tempDir}/fonttools-$$.ttf" "${tempDir}/fonttools-$$.ttx"

# Delete ALL EXIF data, might be dangerous and remove useful things like color profiles
exiftool -v -preserve -overwrite_original -All= "${filepath}"
# Delete old hostcomputer watermark, anything related to thumbnails and Software used for creation
exiftool -v -preserve -overwrite_original -HostComputer= -ifd1:all= -Software= "${filepath}"

A lot of files scattered around the internet have pointlessly large file sizes, which modern software can optimize out, or they weren't meant to be there in the first place.

The above commands try to do so without losing any data. Further file size savings can be achieved by means of exiftool and removing extra unnecessary EXIF information, but that is entering lossy territory, as it can often carry useful or necessary information.