<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://dofahy.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://dofahy.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-07-01T09:41:41+00:00</updated><id>https://dofahy.github.io/feed.xml</id><title type="html">Donal Fahy</title><subtitle>Donal Fahy is an IT consultant based in Ireland specialising in cybersecurity, software, networking and infrastructure.</subtitle><entry><title type="html">IrishVPN vs NordVPN in China</title><link href="https://dofahy.github.io/2026/06/29/post4.html" rel="alternate" type="text/html" title="IrishVPN vs NordVPN in China" /><published>2026-06-29T00:00:00+00:00</published><updated>2026-06-30T13:44:28+00:00</updated><id>https://dofahy.github.io/2026/06/29/post4</id><content type="html" xml:base="https://dofahy.github.io/2026/06/29/post4.html"><![CDATA[<h2 id="testing-the-two-vpn-providers">Testing the two VPN providers</h2>

<p>In this real world OpenWrt router test from China, IrishVPN and NordVPN produced very different outcomes under the same practical conditions. IrishVPN connected successfully and provided a stable, usable tunnel, while repeated NordVPN tests using their Seoul, Ireland, and Hong Kong servers showed different failures: TLS handshake timeout, unstable low-quality connection, and stalled TCP connection attempt.</p>

<p>One issue is that NordVPN does not offer WireGuard config files as mentioned on their site:</p>

<p>https://nordvpn.com/blog/nordvpn-config-files/</p>

<p>IrishVPN does provide WireGuard connection files which can be imported to any device (router, mobile, laptop, etc) that supports WireGuard.</p>

<p>The first NordVPN attempt used Seoul based servers. In this case, the connection failed during the TLS negotiation stage and did not establish a working tunnel.
That outcome suggests the router could reach the remote endpoint well enough to begin the process, but the session never completed. In practical terms, the Seoul test was a connection failure.</p>

<p>The next NordVPN test used an Ireland-based server over OpenVPN with UDP. This attempt did connect, but the connection quality was extremely poor.
Observed performance was effectively unusable for normal browsing. Throughput was extremely low, sites would begin to connect, and page elements such as static content often failed to load. The session also proved unstable, connecting successfully and then dropping a few minutes later before restarting.</p>

<p>A further NordVPN test was carried out using Hong Kong-based servers over TCP. This attempt did not produce a working connection. In this case, the router log showed repeated attempts to establish the TCP connection, but the process stalled before a usable VPN session was created. So while changing both region and transport method altered the failure mode, it did not solve the underlying usability problem.</p>

<p>These tests do not claim that one service will outperform another in every location or on every network. Note that since at least 2024, NordVPN has not worked effectively in China.</p>

<p>Now in 2026, the only scenario in which NordVPN appeared to perform properly was when it used NordLynx rather than OpenVPN. NordLynx is NordVPN’s WireGuard based protocol. An attempt was made to use the token generation method availble on NordVPN’s admin console, but that failed to work on the router with the error:</p>

<p>“get information from provider server failed [20001214]”</p>

<p>A mobile comparison was carried out where IrishVPN proved to be faster. It connected quickly and delivered between 50mbs to 80mbs, whereas NordVPN often started at only kilobyte speeds before gradually improving to 30mbs to 40mbs.</p>

<h2 id="logs-from-router-testing">Logs from router testing:</h2>

<p>1) IrishVPN success</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Mon Jun 29 21:43:26 2026 daemon.notice netifd: Interface 'wgclient1' is setting up now
Mon Jun 29 21:43:27 2026 daemon.info dnsmasq[xxxxx]: reading /tmp/resolv.conf.d/resolv.conf.wgclient1
Mon Jun 29 21:43:27 2026 daemon.info dnsmasq[xxxxx]: read /tmp/hosts/dhcp.wgclient1 - 4 names
Mon Jun 29 21:43:29 2026 daemon.notice netifd: Interface 'wgclient1' is now up
Mon Jun 29 21:43:29 2026 daemon.notice netifd: Network device 'wgclient1' link is up
Mon Jun 29 21:43:29 2026 user.notice vpn-failover-watcher: action=exit iface=wgclient1 source=setup-timeout reason=startup-connecting-timeout result=connected
Mon Jun 29 21:43:29 2026 user.notice firewall: Reloading firewall due to ifup of wgclient1 (wgclient1)
Mon Jun 29 21:44:05 2026 daemon.info dnsmasq[xxxxx]: reading /tmp/resolv.conf.d/resolv.conf.wgclient1
Mon Jun 29 21:44:05 2026 daemon.info dnsmasq[xxxxx]: read /tmp/hosts/dhcp.wgclient1 - 4 names
</code></pre></div></div>

<p>2) NordVPN fail: TLS negotiation timeout</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Mon Jun 29 21:44:34 2026 user.notice vpn-failover-trigger: action=schedule iface=ovpnclient1 source=setup-timeout reason=startup-connecting-timeout delay=0s
Mon Jun 29 21:44:42 2026 user.info tunnel-switch: interface ovpnclient1 still down after 8s, proceeding with failover
Mon Jun 29 21:45:04 2026 daemon.err ovpnclient1[xxxxx]: TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Mon Jun 29 21:45:04 2026 daemon.notice ovpnclient1[xxxxx]: SIGHUP[soft,tls-error] received, process restarting
Mon Jun 29 21:45:05 2026 daemon.notice ovpnclient1[xxxxx]: UDPv4 link remote: [AF_INET][REDACTED]:[REDACTED]
</code></pre></div></div>
<p>3) NordVPN unstable: connects, then drops and restarts</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Mon Jun 29 21:58:51 2026 daemon.notice netifd: Network device 'ovpnclient1' link is up
Mon Jun 29 21:58:51 2026 daemon.notice netifd: Interface 'ovpnclient1' is now up
Mon Jun 29 21:58:53 2026 daemon.notice ovpnclient1[xxxxx]: Data Channel: cipher 'AES-256-GCM', peer-id: [REDACTED], compression: 'stub'
Mon Jun 29 21:58:55 2026 daemon.notice ovpnclient1[xxxxx]: Initialization Sequence Completed
Mon Jun 29 22:02:43 2026 daemon.notice netifd: Interface 'ovpnclient1' has lost the connection
Mon Jun 29 22:02:43 2026 user.notice firewall: Reloading firewall due to ifdown of ovpnclient1 ()
Mon Jun 29 22:02:44 2026 daemon.notice ovpnclient1[xxxxx]: SIGHUP[soft,ping-restart] received, process restarting
Mon Jun 29 22:02:45 2026 daemon.notice ovpnclient1[xxxxx]: UDPv4 link remote: [AF_INET][REDACTED]:[REDACTED]
Mon Jun 29 22:02:46 2026 daemon.notice ovpnclient1[xxxxx]: TLS: Initial packet from [AF_INET][REDACTED]:[REDACTED], sid=[REDACTED]
</code></pre></div></div>
<p>4) NordVPN fail: TCP attempt stalls</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Mon Jun 29 22:17:12 2026 daemon.notice netifd: Interface 'ovpnclient1' is setting up now
Mon Jun 29 22:17:13 2026 daemon.notice ovpnclient1[xxxxx]: NOTE: --fast-io is disabled since we are not using UDP
Mon Jun 29 22:17:13 2026 daemon.notice ovpnclient1[xxxxx]: TCP/UDP: Preserving recently used remote address: [AF_INET][REDACTED]:[REDACTED]
Mon Jun 29 22:17:13 2026 daemon.notice ovpnclient1[xxxxx]: Attempting to establish TCP connection with [AF_INET][REDACTED]:[REDACTED]
</code></pre></div></div>]]></content><author><name>Donal Fahy</name></author><category term="vpn" /><summary type="html"><![CDATA[Comparison between IrishVPN and NordVPN for a connection from China]]></summary></entry><entry><title type="html">Firmware mod CN to US - GL.iNet Beryl 7</title><link href="https://dofahy.github.io/2026/06/11/post3.html" rel="alternate" type="text/html" title="Firmware mod CN to US - GL.iNet Beryl 7" /><published>2026-06-11T00:00:00+00:00</published><updated>2026-06-11T06:11:22+00:00</updated><id>https://dofahy.github.io/2026/06/11/post3</id><content type="html" xml:base="https://dofahy.github.io/2026/06/11/post3.html"><![CDATA[<p>The GL-MT3600BE router is available in CN and global markets.
The CN version is about half the price, but has certain features blocked.
For example, the VPN features are blocked on the CN version.
These can be unblocked by modifying the firmware.</p>

<p>(11/06/2026, Amazon UK €135 vs 淘寶 TaoBao €55)</p>

<p>If done correctly the process does not take long.
The device will be functionally the exact same as the global version.
There is a small risk of damaging the device from user error during this process.</p>

<h2 id="steps-to-modify-and-write-firmware">Steps to modify and write firmware</h2>

<p>The process involves connecting to the router over ssh, making a bin of the factory mtd,
copying this back to your laptop, make the modification, copy the modified bin back to 
the router and then write it to the mtd. After a reboot, configuration that relies on this 
marker will read US instead of CN.</p>

<p>To begin, in a web browser navigate to the router page http://192.168.8.1
Login and in the Security &gt; Admin Access, enable ssh.
Open terminal or powershell and continue:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@192.168.8.1
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M

root@GL-MT3600BE:~# 

cat /proc/mtd
Identify the partition named "Factory", 
on this device it was mtd3

copy the content of mtd3 to a bin file
dd if=/dev/mtd3 of=/tmp/factory.bin
8192+0 records in
8192+0 records out

transfer file to laptop 
use the compatible -O flag as router does not have sftp
ash: /usr/libexec/sftp-server: not found
or install openssh sftp

scp -O root@192.168.8.1:/tmp/factory.bin .
md5sum factory.bin 
9352af94d1ec6fd012b22a3259fc5a8e

now search for the marker we want to modify
grep -oba 'CN' factory.bin

The output was 16520, 
search around that value to confirm it is the correct marker

xxd -s 16496 -l 48 factory.bin
00004080: ffff ffff ffff ffff 434E ffff ffff ffff  ........CN......

xxd -s 23199 -l 48 factory.bin 
This was unrelated data that happened to contain CN

make a backup
cp factory.bin factory.bin.orig

modify CN to US:
printf 'US' | dd of=factory.bin bs=1 seek=16520 conv=notrunc

Confirm write success:
xxd -s 16512 -l 16 factory.bin
00004080: ffff ffff ffff ffff 5553 ffff ffff ffff  ........US......

md5sum factory.bin 
ad406453d33fa680c7f7343b357ba49e

Copy the modified image back to the router.
scp -O factory.bin root@192.168.8.1:/tmp/

ssh into the router and write the image
mtd write /tmp/factory.bin Factory

Reboot and the router is now in US (global) mode.
</code></pre></div></div>
<h2 id="enabling-unlocked-features">Enabling unlocked features</h2>

<p>With the router now in global mode, a flash of the router image will enable all features.
Download it from the GL.iNet site, grab the latest beta or stable image.
Flash whichever one you prefer by going to:</p>

<p>System &gt; Upgrade &gt; Firmware Local Upgrade</p>

<p>After the flash all router functionality is working.</p>

<p>You may also wish to go to the openwrt page and download the latest supported image.
As of writing GL.iNet ships images with openwrt version 21.
The latest supported openwrt version for the beryl7 is 25.
The process to flash is the same.
I recommend doing this as version 21 is EOL. 
It does mean that GL.iNets UI will be replaced by openwrts LuCI.</p>

<h2 id="links">Links</h2>

<p>When buying a router, check that it is compatible with OpenWrt to keep it updated and secure.
https://toh.openwrt.org/?view=normal
https://openwrt.org/toh/gl.inet/gl-mt3600be</p>

<p>Merge of 25.12 is pending for MediaTek chip GL-MT3600BE (as of 11/06/2026) 
https://github.com/openwrt/openwrt/pull/23368
Going to wait for release instead of compiling OpenWrt with the patch applied.</p>

<h2 id="background-info-on-router-design">Background info on router design</h2>

<p>The GL-MT3600BE device follows a standard modern embedded router architecture based on a MediaTek SoC paired with large capacity NAND flash.
The persistent storage is not treated as a single filesystem like a PC disk.
Instead it is a structured flash layout exposed through the Linux MTD subsystem. 
The underlying storage is SPI-NAND flash 512mb, much larger than earlier router generations that used 4–16 MB SPI NOR flash.</p>

<p>At the lowest level, the flash chip is divided into MTD partitions defined by the bootloader and device tree. 
These partitions represent fixed functional regions rather than flexible filesystems. 
These include bootloader stages (BL2, FIP, U-Boot), a factory/ calibration region, and a large firmware region. 
The factory partition is used to store immutable data like MAC addresses, wireless calibration values, and regulatory identifiers. 
This avoids duplicating data inside firmware images and allows it to persist across firmware upgrades.</p>

<p>The main firmware area is implemented using UBI (Unsorted Block Images), which is a flash translation layer designed for NAND. 
NAND flash requires block erasure and has bad-block management, so raw filesystems are not suitable. 
UBI abstracts these details and allows logical volumes to be created on top of the raw flash partition. 
Inside the UBI, OpenWrt creates two logical volumes: a read-only squashfs root filesystem and a writable data volume.</p>

<p>The read-only portion, often mounted as /rom, contains the compressed base system image. 
This is the actual OpenWrt firmware image provided by the vendor or build system. 
It includes the kernel, base utilities, init system, and default configuration templates. 
This image is immutable at runtime and is effectively what would be considered the “factory firmware” in traditional embedded systems.
The writable overlay filesystem is mounted on /overlay using overlayfs, which merges changes on top of the read-only base system. 
This design allows package installation, configuration changes, and system modifications without altering the underlying firmware image.</p>

<p>This layered filesystem approach is common for OpenWrt devices and many Linux embedded systems.
It differs from simpler router designs where firmware is a single squashfs partition with minimal or no overlay separation. 
In more constrained legacy devices, updates often replaced the entire flash region or used dual partition A/B schemes. 
UBI based OpenWrt systems provide greater flexibility, wear leveling, and resilience against power loss during writes.</p>]]></content><author><name>Donal Fahy</name></author><category term="router" /><summary type="html"><![CDATA[Flashing a Beryl 7 with modified firmware]]></summary></entry><entry><title type="html">World Cup 2026 Fixtures</title><link href="https://dofahy.github.io/2026/06/09/post2.html" rel="alternate" type="text/html" title="World Cup 2026 Fixtures" /><published>2026-06-09T00:00:00+00:00</published><updated>2026-06-09T04:31:50+00:00</updated><id>https://dofahy.github.io/2026/06/09/post2</id><content type="html" xml:base="https://dofahy.github.io/2026/06/09/post2.html"><![CDATA[<h2 id="fifa-world-cup-2026-group-stage-fixtures">FIFA World Cup 2026 Group Stage fixtures</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Thursday, 11 June 2026

Mexico v South Africa - Group A – Mexico City Stadium
Korea Republic v Czechia – Group A - Estadio Guadalajara

Friday, 12 June 2026

Canada v Bosnia and Herzegovina - Group B – Toronto Stadium
USA v Paraguay - Group D – Los Angeles Stadium

Saturday, 13 June 2026

Haiti v Scotland – Group C - Boston Stadium
Australia v Türkiye – Group D - BC Place Vancouver
Brazil v Morocco – Group C - New York New Jersey Stadium
Qatar v Switzerland – Group B - San Francisco Bay Area Stadium

Sunday, 14 June 2026

Côte d'Ivoire v Ecuador – Group E - Philadelphia Stadium
Germany v Curaçao  – Group E - Houston Stadium
Netherlands v Japan – Group F - Dallas Stadium
Sweden v Tunisia – Group F - Estadio Monterrey

Monday, 15 June 2026

Saudi Arabia v Uruguay – Group H - Miami Stadium
Spain v Cabo Verde  – Group H - Atlanta Stadium
IR Iran v New Zealand – Group G - Los Angeles Stadium
Belgium v Egypt  – Group G - Seattle Stadium

Tuesday, 16 June 2026

France v Senegal – Group I - New York New Jersey Stadium
Iraq v Norway – Group I - Boston Stadium
Argentina v Algeria – Group J - Kansas City Stadium
Austria v Jordan – Group J - San Francisco Bay Area Stadium

Wednesday, 17 June 2026

Ghana v Panama – Group L - Toronto Stadium
England v Croatia – Group L - Dallas Stadium
Portugal v Congo DR – Group K - Houston Stadium
Uzbekistan v Colombia – Group K - Mexico City Stadium

Thursday, 18 June 2026

Czechia v South Africa – Group A - Atlanta Stadium
Switzerland v Bosnia and Herzegovina – Group B - Los Angeles Stadium
Canada v Qatar - Group B – BC Place Vancouver
Mexico v Korea Republic - Group A - Estadio Guadalajara

Friday, 19 June 2026

Brazil v Haiti – Group C - Philadelphia Stadium
Scotland v Morocco – Group C - Boston Stadium
Türkiye v Paraguay – Group D - San Francisco Bay Area Stadium
USA v Australia - Group D – Seattle Stadium 

Saturday, 20 June 2026

Germany v Côte d'Ivoire – Group E - Toronto Stadium
Ecuador v Curaçao – Group E - Kansas City Stadium
Netherlands v Sweden – Group F - Houston Stadium
Tunisia v Japan – Group F - Estadio Monterrey

Sunday, 21 June 2026

Uruguay v Cabo Verde – Group H - Miami Stadium
Spain v Saudi Arabia – Group H - Atlanta Stadium
Belgium v IR Iran – Group G - Los Angeles Stadium
New Zealand v Egypt – Group G - BC Place Vancouver

Monday, 22 June 2026

Norway v Senegal – Group I - New York New Jersey Stadium
France v Iraq – Group I - Philadelphia Stadium
Argentina v Austria – Group J - Dallas Stadium
Jordan v Algeria – Group J - San Francisco Bay Area Stadium

Tuesday, 23 June 2026

England v Ghana – Group L - Boston Stadium
Panama v Croatia – Group L - Toronto Stadium
Portugal v Uzbekistan – Group K - Houston Stadium
Colombia v Congo DR – Group K - Estadio Guadalajara

Wednesday, 24 June 2026

Scotland v Brazil – Group C - Miami Stadium
Morocco v Haiti – Group C - Atlanta Stadium
Switzerland v Canada - Group B – BC Place Vancouver
Bosnia and Herzegovina v Qatar – Group B - Seattle Stadium
Czechia v Mexico - Group A – Mexico City Stadium
South Africa v Korea Republic – Group A - Estadio Monterrey

Thursday, 25 June 2026

Curaçao v Côte d'Ivoire  – Group E - Philadelphia Stadium
Ecuador v Germany – Group E - New York New Jersey Stadium
Japan v Sweden – Group F - Dallas Stadium
Tunisia v Netherlands – Group F - Kansas City Stadium
Türkiye v USA - Group D – Los Angeles Stadium
Paraguay v Australia – Group D - San Francisco Bay Area Stadium

Friday, 26 June 2026

Norway v France – Group I - Boston Stadium
Senegal v Iraq – Group I - Toronto Stadium
Egypt v IR Iran – Group G - Seattle Stadium
New Zealand v Belgium – Group G - BC Place Vancouver
Cabo Verde v Saudi Arabia – Group H - Houston Stadium
Uruguay v Spain – Group H - Estadio Guadalajara

Saturday, 27 June 2026

Panama v England – Group L - New York New Jersey Stadium
Croatia v Ghana – Group L - Philadelphia Stadium
Algeria v Austria – Group J - Kansas City Stadium
Jordan v Argentina – Group J - Dallas Stadium
Colombia v Portugal – Group K - Miami Stadium
Congo DR v Uzbekistan – Group K - Atlanta Stadium 

</code></pre></div></div>
<h2 id="fifa-world-cup-2026--round-of-32-fixtures">FIFA World Cup 2026 – Round of 32 fixtures</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Sunday, 28 June 2026

Match 73 – Group A runners-up v Group B runners-up - Los Angeles Stadium

Monday, 29 June 2026

Match 74 – Group E winners v  Group A/B/C/D/F third place - Boston Stadium
Match 75 – Group F winners v Group C runners-up - Estadio Monterrey
Match 76 – Group C winners v Group F runners-up - Houston Stadium

Tuesday, 30 June 2026

Match 77 – Group I winners v Group C/D/F/G/H third place - New York New Jersey Stadium
Match 78 – Group E runners up v Group I runners-up - Dallas Stadium
Match 79 – Group A winners v Group C/E/F/H/I third place - Mexico City Stadium

Wednesday, 1 July 2026

Match 80 – Group L winners v Group E/H/I/J/K third place - Atlanta Stadium
Match 81 – Group D winners v Group B/E/F/I/J third place - San Francisco Bay Area Stadium
Match 82 – Group G winners v  Group A/E/H/I/J third place - Seattle Stadium

Thursday, 2 July 2026

Match 83 – Group K runners-up v Group L runners-up - Toronto Stadium
Match 84 – Group H winners v Group J runners-up - Los Angeles Stadium
Match 85 – Group B winners v Group E/F/G/I/J third place - BC Place Vancouver

Friday, 3 July 2026

Match 86 – Group J winners v Group H runners-up - Miami Stadium
Match 87 – Group K winners v Group D/E/I/J/L third place - Kansas City Stadium
Match 88 – Group D runners-up v Group G runners-up - Dallas Stadium

</code></pre></div></div>
<h2 id="fifa-world-cup-2026-round-of-16-fixtures">FIFA World Cup 2026 Round of 16 fixtures</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Saturday, 4 July 2026

Match 89 – Winner match 74 v Winner match 77 - Philadelphia Stadium
Match 90 – Winner match 73 v Winner match 75 - Houston Stadium
Sunday, 5 July 2026

Match 91 – Winner match 76 v Winner match 78 - New York New Jersey Stadium
Match 92 – Winner match 79 v Winner match 80 - Mexico City Stadium
Monday, 6 July 2026

Match 93 – Winner match 83 v Winner match 84 - Dallas Stadium
Match 94 – Winner match 81 v Winner match 82 - Seattle Stadium
Tuesday, 7 July 2026

Match 95 – Winner match 86 v Winner match 88 - Atlanta Stadium
Match 96 – Winner match 85 v Winner match 87 - BC Place Vancouver
</code></pre></div></div>
<h2 id="fifa-world-cup-2026-quarter-final-fixtures">FIFA World Cup 2026 quarter-final fixtures</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Thursday, 9 July 2026

Match 97 – Winner match 89 v Winner match 90 - Boston Stadium
Friday, 10 July 2026

Match 98 – Winner match 93 v Winner match 94 - Los Angeles Stadium
Saturday, 11 July 2026

Match 99 – Winner match 91 v Winner match 92 - Miami Stadium
Match 100 – Winner match 95 v Winner match 96 - Kansas City Stadium
</code></pre></div></div>
<h2 id="fifa-world-cup-2026-semi-final-fixtures">FIFA World Cup 2026 semi-final fixtures</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Tuesday, 14 July 2026

Match 101 – Winner match 97 v Winner match 98 - Dallas Stadium
Wednesday, 15 July 2026

Match 102 – Winner match 99 v Winner match 100 - Atlanta Stadium
FIFA World Cup 2026 bronze final
Saturday, 18 July 2026

Match 103 – Runner-up match 101 v Runner-up match 102 - Miami Stadium
</code></pre></div></div>
<h2 id="fifa-world-cup-2026-final">FIFA World Cup 2026 Final</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Sunday, 19 July 2026

Match 104 – Winner match 101 v Winner match 102 - New York New Jersey Stadium
</code></pre></div></div>]]></content><author><name>Donal Fahy</name></author><category term="football" /><summary type="html"><![CDATA[The list of fixtures taken from FIFA site]]></summary></entry><entry><title type="html">Notes April to June 2026</title><link href="https://dofahy.github.io/2026/06/01/post1.html" rel="alternate" type="text/html" title="Notes April to June 2026" /><published>2026-06-01T00:00:00+00:00</published><updated>2026-06-07T23:17:29+00:00</updated><id>https://dofahy.github.io/2026/06/01/post1</id><content type="html" xml:base="https://dofahy.github.io/2026/06/01/post1.html"><![CDATA[<h2 id="github-pages">Github Pages</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>getting familiar with github pages
https://docs.github.com/en/pages
    created this blog
    
read up on creative commons license
https://creativecommons.org/licenses/

blog and github profile updated
    adding some features to blog
        search - done
        rss feed - done
        pagination - done
        giscus comments - maybe later
        
reviewing https://xmonader.github.io/nimdays/day12_resp.html
    
    this is mostly a nim tutorial - day 1 demidecode parser
    man dmidecode - interesting tool, shame its output is "unreliable"
    sudo dmidecode -q
    
installed a fedora 43 vm with kde
    going to use this for trying nim code
    
    sudo dnf group install c-development development-tools
    curl https://nim-lang.org/choosenim/init.sh -sSf | sh
    
    (optional) sudo dnf install --nogpgcheck --repofrompath '
    terra,https://repos.fyralabs.com/terra$releasever' terra-release
    
    sudo dnf install file-devel
    nim c -r main.nim
    
opentofu - an open source alternative to terraform (which was open source until 2023)
    https://github.com/opentofu/opentofu
    iac templates for azure
    https://github.com/infra-at-scale/organization-template
    
setup scrcpy
    https://github.com/genymobile/scrcpy
</code></pre></div></div>
<h2 id="trying-nim">trying nim</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>published my first nim program, more to follow
    https://github.com/dofahy/nim-explore

getting kate setup for nim
    enabled plugins
    nimble install nimlsp
    nimble install nph 
        run formatting in cli
    kate defaults to python indentation for nim
        change to none
        settings &gt; editing &gt; indentation - set none and untick auto detect
    
    formatting in kate
        create external tool
        Name: Format Nim
        Exec: nph
        Args: %{Document:FileName}
        
        create shortcut for tool
        ctrl+alt+f
        
add markdown preview to kate
    sudo apt install markdownpart

bencode (bee-encode)
    the encoding use by torrent files as part of bittorrent spec
    https://en.wikipedia.org/wiki/Bencode
    
    integers, byte strings, lists and dictionaries
    a couple drawbacks:
        not human-readable encoding format. values often contain binary data, 
        so decoding by hand may be error prone. a hex editor or bencode editor is needed.
        does not store any metadata about the size of list or dictionary, 
        requiring all elements to be read sequentially. not be suitable for 
        large data where random access is required. 
        
nim - parsing bencode
    create nim-bencode, a library to encode/decode bencode torrent files
    
pushed code for nim-bencode
    can create more tests and improve bencode.nim to be closer to spec
    encoding and decoding are not robust

pushed code for nim-dmidecode
    nim c main.nim
    sudo dmidecode &gt; dmi.txt
    ./main dmi.txt

    output
    Physical Memory Array =&gt; 6
    End Of Table =&gt; 0
    System Information =&gt; 8
    Processor Information =&gt; 22
    System Boot Information =&gt; 1
    Memory Array Mapped Address =&gt; 5
    Chassis Information =&gt; 15
    Memory Device =&gt; 21
    BIOS Information =&gt; 10
    
pushed code for nim-linkschecker
    a simple http utility using sequential or async
    
installed markdown preview for kate
    https://apps.kde.org/markdownpart/

viewing debian iputils package
    https://salsa.debian.org/debian/iputils/-/tree/master/ping?ref_type=heads

came across sourcehut, a lightweight alternative to github
    https://sourcehut.org/
    https://news.ycombinator.com/item?id=33607098

nim has a robust config file parser module parsecfg
    https://nim-lang.org/docs/parsecfg.html
    https://github.com/nim-lang/Nim/blob/devel/lib/pure/parsecfg.nim

created a smaller version that works on an ini file taken from wiki's ini article
    https://en.wikipedia.org/wiki/INI_file
    
    pushed code for nim-configparser
    
pushed code for nim-urlshort
    a simple url shortener
curl -X POST http://localhost:5000/short -H "Content-Type: application/json" -d '{"url":"example.com"}'
    {"id":"tzjgq"}
</code></pre></div></div>
<h2 id="mythos-model">mythos model</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SANS NewsBites email
    discussions on soon to be released mythos model - powerful but high token cost

watched dave's take on mythos
    https://www.youtube.com/watch?v=vELETrEp27k
    concern over malicious use - "offence moves at machine 
    speed while defence moves at corporate speed"
    cybersecurity areas that are now more important - asset inventory, 
    patch discipline, logging, lease privilege, dependency hygiene 
    and supply chain security."
</code></pre></div></div>
<h2 id="irishvpn-dev">irishvpn dev</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>installed mailpit
    sudo sh &lt; &lt;(curl -sL https://raw.githubusercontent.com/axllent/mailpit/develop/install.sh)

installed stripe-cli
    https://github.com/stripe/stripe-cli/releases
    
    stripe login
    if using gpg signing
        gpg --full-generate-key
    auth is good for 90 days
    
setup mariadb-10.11.16

used sdkman to get java 21

installed latest nvm and node
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
    
fixed bug in temp password generation
    code did not gaurantee at least one letter, number and special
    
</code></pre></div></div>
<h2 id="python-interview-prep">python interview prep</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>revise relevant topics for interview
    python, azure, saas, devops ci/cd, linux, postgresql, sqlalchemy
    webapp/api for authenticated to access content
    
authentication for api
    api keys
    basic auth with https
    bearer token (jwt)
    oauth
    digest authentication
    hmac

api vulnerabilities
    private resource leak
    predictable serial number attack
    session hijacking

python questions
    meta class

    decorators
        dataclass

    horizontal inheritance
    https://www.geeksforgeeks.org/python/multiple-inheritance-in-python/

    list comprehension

    generator function
    https://www.geeksforgeeks.org/python/generators-in-python/

    context manager
    https://www.geeksforgeeks.org/python/context-manager-in-python/

    concurrency
    threads
    asyncio

    the threads within each python process cannot truly run in parallel
    for parallelism you have to create multiple processes
    multiprocessing module

    containers
    sockets
    queues

</code></pre></div></div>
<h2 id="regulations-api">regulations api</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>installed latest postgresql
/postgresql-18.3/bin/initdb -D ~/databases/data/pg18.3-casino-reg-ie --encoding=UTF8 --locale=en_IE.UTF-8
    
pushed code for regulations app
    working example for basic post and get
    can refactor main.py to fill in the be

added helpers to the casino regulations api
    commit checks
    test coverage
    ruff - linting and formatting

coverage in README is static
    can make it dynamic (later)
    codecov.io

need to use --no-verify until the imports are sorted

need to use underscores for python and postgres 
    dashes cause issues but they are only needed for 
        the apps name and cmd line starting
            everywhere else in code should be underscores

desktop froze twice - gpu gtx 1070 issue - driver (nvidia 580.126.09) or wayland
    audio was still playing
    alt+prt screen+b to force reboot
    see if it goes away with x11
        sudo apt install plasma-session-x11

added logging, can switch to json format when needed
    toggle sqlalchemy

</code></pre></div></div>
<h2 id="network-changes-and-kate-support">network changes and kate support</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>made network changes
    removed ISP device. it is not needed
    set owned device to PPPoE
        vodafone@vodafone.ie
        broadband
    set vlan 10
    speeds tests are similar but stability has noticeably improved 
    
added additional support in kate
    https://github.com/python-lsp/python-lsp-server
    pip install python-lsp-server
    
    https://github.com/redhat-developer/yaml-language-server
    npm install -g yaml-language-server
    yaml-language-server --version =&gt; 1.22.0

    https://github.com/artempyanykh/marksman
        mv marksman-linux-x64 ~/.local/bin/marksman
        chmod +x ~/.local/bin/marksman
        echo 'export PATH="$HOME/.local/bin:$PATH"' &gt;&gt; ~/.bashrc
        source ~/.bashrc
        marksman --version =&gt; release 2026-02-08
        
Also, Tools &gt; Spelling &gt; Auto spell check
</code></pre></div></div>
<h2 id="matrix-protocol-and-sqlalchemy">matrix protocol and sqlalchemy</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>matrix protocol
    https://en.wikipedia.org/wiki/Matrix_(protocol)
    A communications protocol that can bridge instant messaging apps into a single app. 
    The messaging app developed by the matrix team is called Element.

gerrit - free web-based team code collaboration tool.

renamed app to regulate-ie
    created github action for a production ci workflow
    may use poetry 
    can install with pipx
    
reading docs for version 2
    https://docs.sqlalchemy.org/en/20/tutorial/dbapi_transactions.html
    
</code></pre></div></div>
<h2 id="pip-fortune-and-rogue">pip, fortune and rogue</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Went with pip-tools instead of poetry
    note on poetry setup:
        sudo apt install pipx
        pipx install poetry
        pipx upgrade poetry
        poetry completions bash &gt;&gt; ~/.bash_completion
        generate a project -&gt; poetry init
        
sudo apt install fortunes
pipx install cowsay -&gt; v6.1 original is 1999 perl program
(https://github.com/VaasuDevanS/cowsay-python)
cowsay -t "$(fortune)" -c "tux"
        
    pip-tools -&gt; https://pypi.org/project/pip-tools/
    can install it in project venv or using pipx
    pip install pip-tools
    pip-compile --version
        pip-compile, version 7.5.3
    pip-compile -o requirements.txt pyproject.toml --strip-extras
    pip-compile --extra dev -o requirements-dev.txt pyproject.toml --strip-extras

1980 text game
    https://en.wikipedia.org/wiki/Rogue_(video_game)
    https://en.wikipedia.org/wiki/Roguelike
    
</code></pre></div></div>
<h2 id="openwrt-router">openwrt router</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>firmware version: OpenWrt 21.02
kernel version: 5.4.238

OpenWrt - Linux operating system targeting embedded devices
    https://openwrt.org/

LuCI - OpenWrt Configuration Interface 
    https://github.com/openwrt/luci/wiki/
    
ddns config
    https://openwrt.org/docs/guide-user/services/ddns/client
    
to configure ddns
    from router home page go to LuCI
    click System &gt; software
    update list
    filter for ddns
    install  ddns-scripts and luci-app-ddns
    optional wget-ssl and ca-certificates, or curl and ca-bundle for SSL
    ddns-scripts-noip ddns-scripts-cloudflare 
    full reload page
    go to services &gt; ddns
    delete defaults
    add new connections
    ca cert path -&gt; /etc/ssl/certs
    for cloudflare the username is Bearer and pw is api key
    logs are auto truncated

create backup of current config
    system &gt; backup &gt; generate archive
    
setup ssh key only from lan
    use vpn to lan
   
ash
    https://en.wikipedia.org/wiki/Almquist_shell
    
opkg
    https://openwrt.org/docs/guide-user/additional-software/opkg
    
created layer 3 segmentation
    the web server is on its own network
    it can be accessed from the management network
    the firewall restricts it to reject input and forward
    custom input for dhcp and dns
    port forwarding setup 
</code></pre></div></div>
<h2 id="updating-dependencies-and-depracted-code">updating dependencies and depracted code</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn dependency:tree
mvn versions:display-dependency-updates

in addition to stable release this also shows candidate, milestone, snapshot, beta, alpha versions
only go with stable or milestone for production

This is too heavy but could run it as part of CI
https://dependency-check.github.io/DependencyCheck/dependency-check-maven/index.html

pom.xml updated with 
    org.springframework.boot 
    version 3.5.13
    
    jsonwebtoken
    https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api
    latest 0.13.0
    
    stripe 32.0.0
        reverted to 30 as major version upgrade introduced breaking changes in 
        how objects are deserialized or how the Session object is constructed.
    
updating jjwt depracted code
    https://github.com/jwtk/jjwt#installation
    https://javadoc.io/doc/io.jsonwebtoken/jjwt-api/latest/io/jsonwebtoken/package-summary.html
    
    the JwtService class now has cleaner and more readable code.
    added issuer validation
    The "iss" (issuer) claim identifies the principal that issued the
    JWT.  The processing of this claim is generally application specific.
    The "iss" value is a case-sensitive string containing a StringOrURI
    value.  Use of this claim is OPTIONAL.
    https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.1
    
</code></pre></div></div>
<h2 id="netbeans-and-dependency-artifacts">netbeans and dependency artifacts</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>netbeans has an option to auto download the source and javadoc for dependencies.
however this can cause slow startup times.

better to use maven
mvn dependency:sources
mvn dependency:resolve -Dclassifier=javadoc

they are needed for IDE features like code navigation, refactoring, and doc lookup.

</code></pre></div></div>
<h2 id="network-tester-and-kvm">network tester and KVM</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>network tester
    Bufferbloat and Internet Speed Test
    https://www.waveform.com/tools/bufferbloat

shopping list
    Remote KVM
        https://www.gl-inet.com/campaign/kvm/
    
kde tips
    can copy the clock in plasma to get a timestamp, useful for jekyll date requirements.

</code></pre></div></div>
<h2 id="setting-up-local-build-system">setting up local build system</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>setting up a local build system
    https://about.gitea.com/
    https://github.com/go-gitea/gitea
    
    can set up so that i push to it and github
        it will run tests and local repo
        github will just store private for remote acccess and as backup
        
    it's also called a forge
        https://en.wikipedia.org/wiki/Forge_(software)
        
setting up a forgejo system

    using a pi 5 as a prototype
    writing iac instructions as project progresses
    
    using:
        podman
        cockpit, cockipit-podman
        forgejo, forgejo-runner
        postgres
        caddy
        
    the container files specify config to run as systemd services
        systemd manages lifecycle/restarts
        podman exec for entering and running commands inside
        folders on the host persist and provide access to pod data
        like
            mkdir -p /srv/forge/data/caddy/{config,data,site}
        
    creating a rootful version first then try rootless.
</code></pre></div></div>

<h2 id="caddy">caddy</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://en.wikipedia.org/wiki/Caddy_(web_server)
setup involved making a container, creating a Caddyfile and copying the cert to client 
devices then importing the authority cert in browser.
result is i can navigate to forge.home.arpa with no browser warnings.

</code></pre></div></div>
<h2 id="pi-eeprom">pi EEPROM</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://en.wikipedia.org/wiki/EEPROM
electrically erasable programmable read-only memory is a type of non-volatile memory. 
It is used in computers, usually integrated in microcontrollers such as smart cards 
and remote keyless systems, or as a separate chip device, to store relatively small 
amounts of data by allowing individual bytes to be erased and reprogrammed.

Raspberry Pi EEPROM stores critical bootloader firmware on Pi 4/5 models, non-volatilely 
maintaining data without power.
https://github.com/raspberrypi/rpi-eeprom

sudo rpi-eeprom-update -a

</code></pre></div></div>
<h2 id="ubuntu-2604">ubuntu 26.04</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>steps to update
    logout
    ctrl+alt+f3
    sudo systemctl stop sddm
    cp .config backup-config
    rm -r .config
    sudo do-release-upgrade
        follow prompts
    reboot
        restore any config
        clean up any startup services
    systemd-analyze blame
    sudo systemctl disable NetworkManager-wait-online.service
    sudo systemctl disable qemu-kvm.service
    
    add to nextcloud service
    [Service]
    ExecStartPre=/bin/sleep 5
    systemctl --user daemon-reload
    systemctl --user restart com.nextcloud.desktopclient.nextcloud.servic
</code></pre></div></div>]]></content><author><name>Donal Fahy</name></author><category term="notes" /><summary type="html"><![CDATA[A collection of notes from early April to start of June 2026]]></summary></entry></feed>