[{"content":"Practical exam (ECF) of the Titre Professionnel Technicien Supérieur Systèmes et Réseaux (TSSR, RNCP level 5), January 2026.\nA fictional company, seven missions, and timestamped proof for each step. The brief # The exam describes a fictional design studio, CreativeFusion Studios. Its problems are very ordinary ones: every application has its own passwords, support requests get lost between emails and phone calls, and all departments share one flat network. My job was to fix that, then prove every step with timestamped screenshots.\nThe original exam report isn\u0026rsquo;t published. Every screenshot on this page comes from it, and every command or configuration file is transcribed from those screenshots, with nothing added. When I corrected something afterwards, I say so.\n# Mission Tools 1 Create the company domain Windows Server 2022, AD DS, DNS 2 One DHCP scope per department Windows DHCP 3 Ticketing server for user support Debian 13, Apache, PHP-FPM 8.4, MariaDB, GLPI 11 4 Log in to GLPI with domain accounts LDAP, AD service account 5 Segment the network, route between VLANs Cisco Packet Tracer, 2960 + 2901 6 Back up switch and router configs IOS copy running-config ftp: 7 Stop users from setting static IPs GPO, PowerShell startup script Machines and network # RFC 1178 recommends naming machines after a theme rather than their role. I picked Norse mythology: for someone heading north, it seemed fitting.\nHost Role OS IP MIDGARD Domain controller, DNS, DHCP Windows Server 2022 10.0.60.1 (static) YGGDRASIL GLPI server (no GUI) Debian 13 10.0.60.2 (static) THOR Test workstation joined to the domain Windows 10 DHCP Missions 1–4 and 7 ran on VMware virtual machines, missions 5–6 in Cisco Packet Tracer.\nSix departments, one VLAN and one /24 each. The gateway is always the last usable address (.254), and every scope hands out MIDGARD as DNS server.\nVLAN Department Network Gateway 10 RH (HR) 10.0.10.0/24 10.0.10.254 20 Comptabilité (Accounting) 10.0.20.0/24 10.0.20.254 30 Informatique (IT) 10.0.30.0/24 10.0.30.254 40 Direction (Management) 10.0.40.0/24 10.0.40.254 50 Design 10.0.50.0/24 10.0.50.254 60 Serveurs (Servers) 10.0.60.0/24 10.0.60.254 flowchart LR R[\"Router0 · Cisco 2901Gi0/0.10 … Gi0/0.60gateways .254 + ip helper\"] S[\"Switch0 · Cisco 2960\"] R ---|\"802.1Q trunkGi0/0 ↔ Fa0/1\"| S S ---|\"Fa0/2 · VLAN 50\"| D[\"PC0 · Design\"] S ---|\"Fa0/3 · VLAN 40\"| DG[\"PC1 · Direction\"] S ---|\"Fa0/4 · VLAN 30\"| I[\"PC2 · Informatique\"] S ---|\"Fa0/5 · VLAN 20\"| C[\"PC3 · Comptabilité\"] S ---|\"Fa0/6 · VLAN 10\"| H[\"PC4 · RH\"] S ---|\"Fa0/7 · VLAN 60\"| M[\"MIDGARD · 10.0.60.1DHCP + FTP\"] 1 · Active Directory domain # Need. One place to manage accounts and access: a new domain, CreativeFusion-Studios.eu, on Windows Server 2022, with a server name that follows RFC 1178.\nWhat I did\nInstalled Windows Server 2022 and renamed it MIDGARD. Gave it a static address: 10.0.60.1/24, gateway 10.0.60.254. Added the AD DS role, then promoted the server to domain controller of a new forest, CreativeFusion-Studios.eu, with the integrated DNS server. Organised the directory before creating anything, following the company org chart: CreativeFusion-Studios.eu ├── 00_GROUPES ├── 01_ADMIN │ └── Comptes_techniques ← Sync_GLPI, service account used by GLPI (mission 4) ├── 02_COMPTABILITE ├── 03_DESIGN_ANIMATION │ ├── PERSONNEL │ └── POSTES ← THOR lives here, target of the GPO (mission 7) ├── 04_DIRECTION │ ├── PERSONNEL │ └── POSTES ├── 05_INFORMATIQUE │ ├── PERSONNEL │ └── POSTES ├── 06_RH │ ├── PERSONNEL │ └── POSTES └── 07_SERVEURS Keeping people (PERSONNEL) and computers (POSTES) apart in each department pays off later: a GPO for computers can be linked to a POSTES OU without touching user accounts.\nHow I checked it. nslookup midgard resolves midgard.CreativeFusion-Studios.eu to 10.0.60.1. The Windows 10 client THOR joined the domain, and the domain administrator account opens a session on it.\n2 · DHCP scopes # Need. Each department gets its own network and DHCP scope. The gateway is the last usable address of each network, the AD server keeps a static address, and every scope hands out the AD/DNS server as DNS.\nWhat I did. Added the DHCP role on MIDGARD, completed its post-install configuration, then created six scopes:\nScope Network Router (option 003) DNS (option 006) Etendue_RH 10.0.10.0/24 10.0.10.254 10.0.60.1 Etendue_Comptabilité 10.0.20.0/24 10.0.20.254 10.0.60.1 Etendue_Informatique 10.0.30.0/24 10.0.30.254 10.0.60.1 Etendue_Direction_Générale 10.0.40.0/24 10.0.40.254 10.0.60.1 Etendue_Design_Animation 10.0.50.0/24 10.0.50.254 10.0.60.1 Etendue_Serveurs 10.0.60.0/24 10.0.60.254 10.0.60.1 Example range, for accounting: 10.0.20.1 → 10.0.20.253. .254 stays out because it belongs to the gateway.\nHow I checked it. On THOR, ipconfig /all shows a lease from MIDGARD with the right gateway and DNS. THOR sits in the servers network, so its lease comes from Etendue_Serveurs. Clients in the other departments only reach the server through a DHCP relay across VLANs: that part is done in mission 5.\n3 · GLPI ticketing server # Need. Support requests arrive by email and phone: nothing is tracked, and there are no resolution-time metrics. The company chose GLPI, on a Debian server without a graphical interface, in the servers network.\nServer. Debian 13 \u0026ldquo;trixie\u0026rdquo; (the brief asked for Debian 12, but 13 was the current stable release), hostname YGGDRASIL, static address 10.0.60.2/24.\nWeb stack — commands as typed, in order:\nsudo apt update \u0026amp;\u0026amp; sudo apt upgrade -y sudo apt install apache2 -y sudo apt install php -y sudo apt-get install php-fpm mariadb-server sudo apt-get install php-{curl,gd,intl,mysql,zip,bcmath,mbstring,xml,bz2} sudo apt install php-ldap # needed later for AD authentication Database. A dedicated account limited to the GLPI database, rather than root:\nsudo mariadb-secure-installation # switched root to unix_socket authentication sudo mysql -u root -p CREATE DATABASE db1_glpi; GRANT ALL PRIVILEGES ON db1_glpi.* TO glpi_adm@localhost IDENTIFIED BY \u0026#39;********\u0026#39;; FLUSH PRIVILEGES; GLPI 11.0.4. The brief asked for 10.0.10 minimum. I took the current release, which runs on the PHP 8.4 shipped with Debian 13.\ncd /tmp wget https://github.com/glpi-project/glpi/releases/download/11.0.4/glpi-11.0.4.tgz sudo tar -xzvf glpi-11.0.4.tgz -C /var/www/ Config, data and logs out of the web root. By default they sit under /var/www/glpi. Moving them means a misconfiguration can never expose them over HTTP.\nsudo chown www-data /var/www/glpi/ -R sudo mkdir /etc/glpi sudo chown www-data /etc/glpi/ sudo mv /var/www/glpi/config /etc/glpi sudo mkdir /var/lib/glpi sudo chown www-data /var/lib/glpi/ sudo mv /var/www/glpi/files/ /var/lib/glpi sudo mkdir /var/log/glpi sudo chown www-data /var/log/glpi GLPI is then told where to look:\n\u0026lt;?php // /var/www/glpi/inc/downstream.php define(\u0026#39;GLPI_CONFIG_DIR\u0026#39;, \u0026#39;/etc/glpi/\u0026#39;); if (file_exists(GLPI_CONFIG_DIR . \u0026#39;/local_define.php\u0026#39;)) { require_once GLPI_CONFIG_DIR . \u0026#39;/local_define.php\u0026#39;; } \u0026lt;?php // /etc/glpi/local_define.php define(\u0026#39;GLPI_VAR_DIR\u0026#39;, \u0026#39;/var/lib/glpi/files\u0026#39;); define(\u0026#39;GLPI_LOG_DIR\u0026#39;, \u0026#39;/var/log/glpi\u0026#39;); Apache + PHP-FPM. A dedicated virtual host whose document root is only /var/www/glpi/public:\n/etc/apache2/sites-available/support-creative-fusion-studios.eu.conf \u0026lt;VirtualHost *:80\u0026gt; ServerName support-creative-fusion-studios.eu DocumentRoot /var/www/glpi/public \u0026lt;Directory /var/www/glpi/public\u0026gt; Require all granted RewriteEngine On #ensure authorization headers are passed to PHP. #Some apache configurations may filter them and break usage of API, CalDAV... RewriteCond %{HTTP:Authorization} ^(.+)$ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] #redirect all request to GLPI router, unless file exists. RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] \u0026lt;/Directory\u0026gt; \u0026lt;FilesMatch \\.php$\u0026gt; SetHandler \u0026#34;proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost/\u0026#34; \u0026lt;/FilesMatch\u0026gt; \u0026lt;/VirtualHost\u0026gt; sudo a2ensite support-creative-fusion-studios.eu.conf sudo a2dissite 000-default.conf sudo a2enmod proxy_fcgi setenvif sudo a2enconf php8.4-fpm sudo systemctl restart apache2 PHP session hardening, in /etc/php/8.4/fpm/php.ini:\nsession.cookie_httponly = on ; cookie not readable by JavaScript (limits session theft through XSS) session.cookie_samesite = Lax ; cookie not sent on cross-site sub-requests (CSRF mitigation) Web installer, run from a browser on the network (http://10.0.60.2), then:\nsudo rm /var/www/glpi/install/install.php Last step: changed the password of the default glpi super-admin account.\nHow I checked it. systemctl status apache2 → active (running) after each change, ip a → 10.0.60.2/24, and the GLPI dashboard reachable from the network.\nThe orange banner is GLPI warning that the other default accounts (post-only, tech, normal) still had their default passwords. See what I would harden. 4 · GLPI authentication against Active Directory # Need. Users log in to GLPI with their domain account, not a separate GLPI password.\nWhat I did. A service account in AD, Sync_GLPI, in 01_ADMIN/Comptes_techniques. GLPI only uses it to read the directory, so no administrator credentials are stored on the GLPI server. Then a new LDAP directory in GLPI (Setup → Authentication → LDAP directories):\nField Value Server / port 10.0.60.1 / 389 Connection filter (\u0026amp;(objectCategory=person)(objectClass=user)) BaseDN DC=creativefusion-studios,DC=eu Bind account CN=Sync_GLPI,OU=Comptes_techniques,OU=01_ADMIN,DC=creativefusion-studios,DC=eu Login field samaccountname Synchronisation field objectguid objectguid rather than the login: if a user is renamed in AD, GLPI still recognises the same person.\nHow I checked it. GLPI\u0026rsquo;s built-in test: TCP connection, BaseDN, bind and search all succeed (8 entries found).\nThen I created test users in AD, opened a session on THOR to set their password, and logged in to GLPI with the Active Directory source. The AD users then appear in GLPI\u0026rsquo;s user list.\n5 · VLAN segmentation and inter-VLAN routing # Need. Segment the network by department, while every workstation gets its address from the DHCP server and can still ping every other machine. That means routing between VLANs.\nBuilt in Cisco Packet Tracer from the topology given in the brief: one 2960 switch, one 2901 router, one PC per department and the server.\nSwitch. VLANs 10 to 60 named after the departments, one access port per VLAN (Fa0/2 → Fa0/7), and Fa0/1 as an 802.1Q trunk towards the router, allowing only VLANs 10–60.\nRouter. Router-on-a-stick: one physical link, one sub-interface per VLAN, each one being the gateway (.254) of its network.\ninterface gigabitEthernet 0/0.10 encapsulation dot1Q 10 ip address 10.0.10.254 255.255.255.0 DHCP across VLANs. DHCP requests are broadcasts and don\u0026rsquo;t cross a router. On each client sub-interface, ip helper-address 10.0.60.1 turns the broadcast into a unicast towards the server. VLAN 60 doesn\u0026rsquo;t need it: the server is already there.\nServer (MIDGARD in Packet Tracer). Static 10.0.60.1, gateway 10.0.60.254, one DHCP pool per client VLAN (start .1, gateway .254, DNS 10.0.60.1). Every PC set to DHCP.\nSwitch0 — full command list enable configure terminal vlan 10 name RH exit vlan 20 name COMPTABILITE exit vlan 30 name INFORMATIQUE exit vlan 40 name DIRECTION exit vlan 50 name DESIGN exit vlan 60 name SERVEURS exit interface fa0/2 switchport mode access switchport access vlan 50 exit interface fa0/3 switchport mode access switchport access vlan 40 exit interface fa0/4 switchport mode access switchport access vlan 30 exit interface fa0/5 switchport mode access switchport access vlan 20 exit interface fa0/6 switchport mode access switchport access vlan 10 interface fa0/7 switchport mode access switchport access vlan 60 exit interface fa0/1 switchport mode trunk switchport trunk allowed vlan 10,20,30,40,50,60 no shutdown exit Router0 — full command list enable configure terminal interface gigabitEthernet 0/0 no shutdown exit interface gigabitEthernet 0/0.10 encapsulation dot1Q 10 ip address 10.0.10.254 255.255.255.0 ip helper-address 10.0.60.1 exit interface gigabitEthernet 0/0.20 encapsulation dot1Q 20 ip address 10.0.20.254 255.255.255.0 ip helper-address 10.0.60.1 exit interface gigabitEthernet 0/0.30 encapsulation dot1Q 30 ip address 10.0.30.254 255.255.255.0 ip helper-address 10.0.60.1 exit interface gigabitEthernet 0/0.40 encapsulation dot1Q 40 ip address 10.0.40.254 255.255.255.0 ip helper-address 10.0.60.1 exit interface gigabitEthernet 0/0.50 encapsulation dot1Q 50 ip address 10.0.50.254 255.255.255.0 ip helper-address 10.0.60.1 exit interface gigabitEthernet 0/0.60 encapsulation dot1Q 60 ip address 10.0.60.254 255.255.255.0 exit Grouped by sub-interface for readability: during the exam, the helper addresses were added in a second pass.\nVerification — show vlan brief / show ip interface brief Switch#show vlan brief VLAN Name Status Ports ---- -------------------------------- --------- ------------------------------ 1 default active Fa0/1, Fa0/8, Fa0/9, Fa0/10 … 10 RH active Fa0/6 20 COMPTABILITE active Fa0/5 30 INFORMATIQUE active Fa0/4 40 DIRECTION active Fa0/3 50 DESIGN active Fa0/2 60 SERVEURS active Fa0/7 Router#show ip interface brief Interface IP-Address OK? Method Status Protocol GigabitEthernet0/0 unassigned YES unset up up GigabitEthernet0/0.10 10.0.10.254 YES manual up up GigabitEthernet0/0.20 10.0.20.254 YES manual up up GigabitEthernet0/0.30 10.0.30.254 YES manual up up GigabitEthernet0/0.40 10.0.40.254 YES manual up up GigabitEthernet0/0.50 10.0.50.254 YES manual up up GigabitEthernet0/0.60 10.0.60.254 YES manual up up How I checked it. From each PC, one ping to every network (ping -n 1, to fit on one screenshot). From PC4 (HR), the TTL tells the story: 128 for the address in its own VLAN, 127 everywhere else, one hop through the router.\n6 · Backing up network configs to FTP # Need. Test saving the switch and router configurations to the FTP server, with the admin / Cisco account given in the brief.\nRouter. My first attempt put the credentials in the URL:\nRouter#copy running-config ftp://admin:Cisco@10.0.60.1/router_backup.cfg % Invalid input detected at \u0026#39;^\u0026#39; marker. Packet Tracer\u0026rsquo;s IOS doesn\u0026rsquo;t accept that syntax: the credentials have to be declared in the configuration first.\nRouter(config)#ip ftp username admin Router(config)#ip ftp password Cisco Router#copy running-config ftp: Address or name of remote host []? 10.0.60.1 Destination filename [Router-confg]? router_backup.cfg [OK - 1367 bytes] Switch. Same commands, but the first copy failed:\n%Error opening ftp://.../switch_backup.cfg (Timed out) A layer-2 switch has no IP address by default, so it couldn\u0026rsquo;t reach the FTP server at all. The fix: a management interface in the servers VLAN and a default gateway.\ninterface vlan 60 ip address 10.0.60.2 255.255.255.0 no shutdown ip default-gateway 10.0.60.254 After that: [OK - 1592 bytes].\nHow I checked it. Both files are on the FTP server.\n7 · GPO forcing DHCP at startup # Need. A recurring ticket: users can\u0026rsquo;t log in with their domain account because some of them typed a static IP. The brief asks for a GPO that runs a PowerShell script at computer startup to put the network card back in DHCP mode.\nWhat I did\nA security group, G_DHCP_POSTES, with THOR as member. The script, stored in SYSVOL so every domain computer can read it (\\\\CreativeFusion-Studios.eu\\SYSVOL\\CreativeFusion-Studios.eu\\scripts\\): # force_dhcp.ps1 — for every active adapter: DHCP on, manual DNS servers removed Get-NetAdapter | Where-Object {$_.Status -eq \u0026#34;Up\u0026#34;} | ForEach-Object { Set-NetIPInterface -InterfaceIndex $_.InterfaceIndex -Dhcp Enabled Set-DnsClientServerAddress -InterfaceIndex $_.InterfaceIndex -ResetServerAddresses } :: force_dhcp.bat — launcher @echo off powershell.exe -NoProfile -ExecutionPolicy Bypass -File \u0026#34;\\\\CreativeFusion-Studios.eu\\SYSVOL\\CreativeFusion-Studios.eu\\scripts\\force_dhcp.ps1\u0026#34; exit /b 0 The GPO GPO_FORCE_DHCP_STARTUP, linked to 03_DESIGN_ANIMATION/POSTES, where THOR is: Computer Configuration → Policies → Windows Settings → Scripts → Startup → the .bat launcher; security filtering on G_DHCP_POSTES instead of Authenticated Users; Always wait for the network at computer startup and logon → Enabled, so the script doesn\u0026rsquo;t run before the network is ready. How I checked it. On THOR, gpupdate /force, then gpresult /r /scope computer as administrator: GPO_FORCE_DHCP_STARTUP is among the applied policies, and THOR is a member of G_DHCP_POSTES.\nCorrected afterwards. Re-reading my screenshots for this page, I found two typos in the DNS line of the script written during the exam: - InterfaceIndex (with a space) and -ResetServerAdresses. The script above is the corrected version. gpresult proves the GPO was applied, not that every line succeeded: the DHCP line was correct, the DNS line would have failed. Looking back # The exam was about making things work. Looking back with a security mindset, here is what I would do differently.\nMy mistakes, kept on purpose\nA typo in the GPO script: the GPO applied, but one line would have failed. Lesson learned: a script gets tested by hand on one machine before a GPO pushes it to all of them. A wrong subnet mask on a router sub-interface (255.255.255.255), caught by IOS: Bad mask /32 for address 10.0.40.254. A reminder to read the console output instead of firing commands blindly. A switch backup that timed out, because the switch had no management IP. Obvious once understood: a layer-2 device needs an address to talk to anything. What I would harden on a production network\nPoint In the exam In production LDAP between GLPI and AD port 389, unencrypted LDAPS (636) or StartTLS, so the service account password never crosses the network in clear text GLPI default accounts post-only, tech, normal still had default passwords change or disable them right after installation GLPI over HTTP http://10.0.60.2 HTTPS with a certificate from an internal CA Config backups FTP with clear-text credentials, required by the brief SCP/SFTP, a dedicated account, versioned backups Script launcher -ExecutionPolicy Bypass a signed script and an AllSigned policy AD domain name CreativeFusion-Studios.eu, a public TLD, imposed by the brief a subdomain the company actually owns (e.g. ad.example.com), to avoid DNS conflicts with the real internet Treating the symptom a GPO resets static IPs at every boot also remove standard users\u0026rsquo; right to change network settings Tech stack # Windows Server 2022 · Active Directory · DNS · DHCP · GPO · PowerShell · Debian 13 · Apache · PHP-FPM · MariaDB · GLPI 11 · LDAP · Cisco IOS · Packet Tracer\nConfig files on GitHub ","date":"14 January 2026","externalUrl":null,"permalink":"/projects/tssr-infrastructure/","section":"Projects","summary":"The practical exam of my systems and networks diploma: a Windows domain, GLPI authenticated against Active Directory, inter-VLAN routing and a startup GPO.","title":"TSSR infrastructure — Active Directory, GLPI and VLANs","type":"projects"},{"content":"A travel agency hacked in peak season. A key partner ready to walk away. One admin to rebuild everything.\nNorrøn Voyages is a fictional company, created as the scenario for this lab.\nThe company # Norrøn Voyages is a French travel agency founded in 2012. Its 15 employees run small-group adventure trips to Iceland, the Faroe Islands and Norway: hiking, trekking, northern lights.\nHélène Marchand, the founder, is a former hiking guide. Pragmatic and not technical, she wants concrete results and to understand what\u0026rsquo;s at stake. Bjarni, the guide and coordinator, works from Reykjavik and needs remote access to the internal tools. The sales team travels a lot and uses the website and booking tools on the move. The agency handles sensitive data: travellers\u0026rsquo; identities, passport copies, medical information for the treks, payments — all subject to GDPR.\nThe starting point # Like many small companies, the agency\u0026rsquo;s IT grew without a plan:\na single old server doing everything; a flat network: every computer and server can reach every other one; shared passwords between colleagues; a WordPress site edited directly in production, with plugins rarely updated. The incident # Last spring, in the middle of the booking season, the WordPress website was defaced through an outdated plugin. It stayed offline for several days.\nIt wasn\u0026rsquo;t bad luck: it was the logical result of the setup above. On a flat network with no updates and shared passwords, one weakness is enough.\nThe trigger # The agency\u0026rsquo;s main Norwegian partner, bound by the NIS2 directive, now requires security guarantees from its suppliers. Without them, the contract won\u0026rsquo;t be renewed.\nMy role # Hélène hires a DevOps systems administrator: me. The only technician, reporting directly to her. The mission: rebuild the infrastructure properly, automate it, then be able to defend it.\nNext article: the plan.\n","date":"11 October 2026","externalUrl":null,"permalink":"/heading-north-lab/scenario/","section":"Heading North Lab","summary":"A travel agency hacked in peak season, a partner bound by NIS2, one sysadmin to rebuild everything. Meet the fictional company behind the lab.","title":"The scenario: Norrøn Voyages","type":"heading-north-lab"},{"content":"Project from the OpenClassrooms Web Developer path, 2022.\nAn API where most of the work is invisible: authentication, access control and data protection.\nThe brief # Piquante is an app where users post hot sauces and rate them with likes or dislikes. OpenClassrooms provided the Angular front end. My job: build the API behind it, with a strong focus on security.\nWhat I built # a complete REST API: create, read, update and delete sauces, plus likes and dislikes; user sign-up and login, with a JWT for every authenticated request; ownership checks: only the author of a sauce can edit or delete it, and the user ID is taken from the token, never from the client\u0026rsquo;s request; image uploads with multer. Security # passwords hashed with bcrypt, with an enforced password policy (length, upper case, digits, symbols); email addresses pseudonymised with an HMAC before storage: the database never holds them in clear text; HTTP headers hardened with helmet, input sanitised against XSS, rate limiting per IP address; every secret (database, signing keys) kept in environment variables, never in the code. Tech stack # Node.js · Express · MongoDB · Mongoose · JWT · bcrypt · crypto-js · helmet · express-rate-limit · multer · dotenv\nWhy it matters today # Of all my web developer projects, this is the closest to where I\u0026rsquo;m heading now, DevSecOps: think first about what an attacker could do, then make it hard.\nNo live demo: an API needs a server and a database, which GitHub Pages doesn\u0026rsquo;t provide.\nCode on GitHub ","date":"26 November 2022","externalUrl":null,"permalink":"/projects/piquante/","section":"Projects","summary":"The only back-end project of my web developer training, and the closest to what I do today: a Node.js API where most of the work is about security.","title":"Piquante — a secure API","type":"projects"},{"content":"In the previous article, Norrøn Voyages lost its website to an outdated plugin, on a flat network with shared passwords. Before touching anything, here is where I want to go — and in what order.\nThe target # The target is a segmented network: each zone is a separate VLAN, and every flow between zones goes through the pfSense firewall. Everything is blocked by default; each flow is opened explicitly, for a reason.\nAdministration: the admin interfaces of Proxmox and pfSense are only reachable from here; Servers / DMZ: the WordPress site and its database, the only part exposed to the Internet; Users: the staff\u0026rsquo;s workstations, which reach the website like any visitor; VPN: Bjarni and the sales team connect through the Internet; their encrypted tunnel ends on pfSense, which only lets them reach the services they actually need; Monitoring / SIEM: in its own VLAN. Logs from every zone arrive one way only, so that an attacker who compromises a server can\u0026rsquo;t reach the SIEM to erase their tracks; Offensive lab: an isolated attack machine for the final phase. It may reach the DMZ during the phase 12 tests, never the Administration or Users zones. This is a plan, not something already built. It will change as I build it, and every change will be explained.\nThe 13 phases # # Phase Norrøn Voyages\u0026rsquo; need 0 The plan Know where we\u0026rsquo;re going before touching anything 1 Architecture Audit the existing setup: the flat network 2 Proxmox, VMs, network Rebuild on sound foundations 3 Hardening Never again the spring incident 4 Remote access Bjarni must work safely from Reykjavik 5 WordPress Reinstall the website properly 6 Git / GitHub No more direct changes in production 7 Jenkins Update the site without downtime 8 Docker The same environment from test to production 9 Kubernetes Handle the January booking peak 10 Terraform / Ansible Disaster recovery: rebuild everything fast 11 Monitoring Know about problems before customers do 12 Blue Team Prove to the NIS2 partner that attacks are detected The final phase closes the loop: I\u0026rsquo;ll attack the infrastructure I built and secured myself, and show what my detection catches.\nHow I\u0026rsquo;ll document it # Each phase follows the same structure: the company\u0026rsquo;s need → what I set up → what went wrong or what I learned → the next step. Mistakes included: they are part of learning, and often the most useful part.\nNext step: phase 1, the audit of the flat network.\n","date":"11 October 2026","externalUrl":null,"permalink":"/heading-north-lab/phase-00-plan/","section":"Heading North Lab","summary":"From a flat network to a segmented infrastructure where every flow goes through a firewall: the target architecture and the 13 phases to reach it.","title":"Phase 0 — The plan","type":"heading-north-lab"},{"content":"Project from the OpenClassrooms Web Developer path, 2022.\nA home rental app, broken down into reusable components.\nThe brief # Kasa is a peer-to-peer home rental platform. It was the last project of the training: build the front end in React from a mock-up, with one page per listing generated from the data.\nWhat I built # a home page listing the properties from a JSON data file; a page for each property, built from its ID in the URL, with a redirect to the 404 page if it doesn\u0026rsquo;t exist; reusable components: photo carousel, collapsible sections for the description and amenities, star rating, tags; an \u0026ldquo;About\u0026rdquo; page and a 404 error page; navigation between pages with React Router. Tech stack # React 18 · React Router 6 · JSX · CSS · Create React App\nLive demo Code on GitHub ","date":"26 November 2022","externalUrl":null,"permalink":"/projects/kasa/","section":"Projects","summary":"The last project of my web developer training: a home rental app in React, built from reusable components.","title":"Kasa — a React app","type":"projects"},{"content":"Project from the OpenClassrooms Web Developer path, 2022.\nA sofa shop website, made dynamic in plain JavaScript, no framework.\nThe brief # Kanap sells sofas online. The HTML and CSS pages were provided, along with an Express API. My job: write all the JavaScript connecting the two.\nWhat I built # the catalogue, loaded from the API with fetch and inserted into the page; a product page generated from the ID in the URL, with colour and quantity selection; a cart stored in localStorage: identical items merged, quantities updated, items removed, total calculated; checkout form validation with regular expressions; sending the order to the API, then a confirmation page showing the order number. About the live demo # Originally, the site called the Express API running locally. To publish it on GitHub Pages, which only hosts static files, I adapted a demo version: the catalogue is read from a JSON file and checkout is simulated (the order number is generated in the browser; nothing is sent). The original code, back end included, is unchanged in the repository.\nTech stack # JavaScript · DOM · Fetch API · localStorage · regular expressions · HTML · CSS\nLive demo Code on GitHub ","date":"30 September 2022","externalUrl":null,"permalink":"/projects/kanap/","section":"Projects","summary":"Making an e-commerce site dynamic in plain JavaScript: catalogue loaded from an API, cart, form validation and checkout.","title":"Kanap — an e-commerce site in JavaScript","type":"projects"},{"content":"Project from the OpenClassrooms Web Developer path, 2022.\nNo new site here: take an existing one, find what\u0026rsquo;s wrong, and fix it.\nThe brief # La Panthère is a web design agency in Lyon whose website ranked poorly, loaded slowly and wasn\u0026rsquo;t very accessible. The job: audit the site, then optimise it for SEO, performance and accessibility.\nWhat I fixed # SEO: rewrote the title tag and meta description, put the heading structure back in order, declared the page language, and removed lists of links to web directories, an abusive \u0026ldquo;black hat\u0026rdquo; SEO technique; Performance: lighter, resized images, minified CSS and JavaScript, scripts loaded at the end of the page, more efficient font loading, libraries hosted with the site instead of a CDN; Accessibility: rewrote image alt text, added ARIA labels to social media links, fixed contrast issues (including white text on a white background), used semantic tags; validated the HTML and CSS with the W3C tools. Tech stack # HTML · CSS · Bootstrap · SEO · web performance · accessibility (WCAG)\nLive demo Code on GitHub ","date":"11 August 2022","externalUrl":null,"permalink":"/projects/la-panthere/","section":"Projects","summary":"Taking over a web agency’s website and fixing it: SEO, page weight, accessibility, and removing abusive SEO tricks.","title":"La Panthère — optimising an existing site","type":"projects"},{"content":"Project from the OpenClassrooms Web Developer path, 2022.\nA mock-up built mobile first, with pure CSS animations and no JavaScript.\nThe brief # Ohmyfood lets you book a gourmet restaurant\u0026rsquo;s menu in advance. The job: build the mock-up of the home page and four restaurant pages, mobile first, then for larger screens.\nWhat I built # a mobile-first build, then adapted for tablets and desktops; CSS organised with Sass: colour variables, separate files per component and per page; CSS animations, no JavaScript: loading screen, dishes appearing one by one, hover effects on buttons and cards; code validated with the W3C tools. Tech stack # HTML · CSS · Sass · CSS animations (keyframes) · responsive design\nLive demo Code on GitHub ","date":"28 June 2022","externalUrl":null,"permalink":"/projects/ohmyfood/","section":"Projects","summary":"Building a mock-up mobile first, with Sass and pure CSS animations: loading screen, dishes appearing, hover effects.","title":"Ohmyfood — mobile-first build and CSS animations","type":"projects"},{"content":"Practice exercise, 2022.\nRecreating a home page in HTML and CSS, to practise layout.\nThe exercise # The goal was to recreate the home page of a video game school, to practise layout: navigation bar, header banner, icon sections and content blocks.\nWhat I practised # layout with Flexbox and CSS Grid; adapting to different screen sizes with media queries; CSS hover transitions. Tech stack # HTML · CSS · Flexbox · Grid · responsive design\nLive demo Code on GitHub ","date":"30 November 2022","externalUrl":null,"permalink":"/projects/gaming-campus/","section":"Projects","summary":"A practice exercise: recreating a school’s home page in HTML and CSS, with Flexbox, Grid and a responsive layout.","title":"Gaming Campus — layout exercise","type":"projects"},{"content":"Practice exercise, 2023.\nA tiny game in about thirty lines of JavaScript: pop the bubbles before they disappear.\nThe exercise # Bubbles of random size and direction float up the screen. Each click pops a bubble and adds to the score.\nWhat I practised # creating elements on the fly in the DOM, at regular intervals; events: a click pops the bubble and updates the counter; clean-up: each bubble is removed from the page after a few seconds; a CSS animation whose direction is set from JavaScript through a CSS variable. Tech stack # JavaScript · DOM · events · CSS animations · CSS variables\nLive demo Code on GitHub ","date":"9 January 2023","externalUrl":null,"permalink":"/projects/bubble-game/","section":"Projects","summary":"A short JavaScript exercise: creating elements on the fly, handling clicks and animating bubbles with CSS.","title":"Bubble Game — a small JavaScript game","type":"projects"},{"content":"The attackers didn\u0026rsquo;t steal a single user password. They signed in as a backup app.\nWhat happened # ConnectWise Cloud Backup (formerly SkyKick) backs up its customers\u0026rsquo; Microsoft 365 data: mail, OneDrive, SharePoint, Teams. To do that, each customer has authorised the app to access its tenant.\nOn 15 October 2026, between 06:13 and 08:34 UTC, attackers used one of the app\u0026rsquo;s credentials, stolen from the vendor, to sign in as the application to customer tenants, from a single IP address and in an automated way. As of 16 October, Huntress had confirmed unauthorised sign-ins in 162 tenants. According to a later update, the address attempted sign-ins to nearly 1,000 tenants and succeeded in over 300.\nIn about fifty tenants monitored by Huntress, ConnectWise apps assigned themselves admin roles, mostly Exchange Administrator. In at least one case, one of them gave itself Global Administrator, then added new secrets to two other apps: a way back in for later.\nConnectWise shut down access to the service on 17 October. The vendor says it has no indication so far that backed-up data was compromised.\nWhy it matters # A sign-in \u0026ldquo;as an application\u0026rdquo; involves no user. So there\u0026rsquo;s no password to type and no MFA prompt to approve. Protections designed for accounts simply don\u0026rsquo;t apply.\nAnd a backup app, by design, can reach almost everything. It concentrates read access to the whole organisation. Microsoft describes it as an active supply chain attack.\nWhat to take away # A third-party app is an identity in its own right, often with more rights than any employee. Know which apps can access what, and remove the ones you no longer use. MFA protects accounts, not apps. App sign-ins and role changes deserve the same monitoring as admin accounts. Disable rather than delete. Huntress recommends disabling the affected app without deleting it, to keep the history, then reviewing every secret added to apps since 13 October. A supplier\u0026rsquo;s security is part of yours. That\u0026rsquo;s exactly what regulations like NIS2 ask for. Sources # ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks — Huntress (16/10/2026) Hackers breach Microsoft 365 tenants via ConnectWise supply chain attack — BleepingComputer (17/10/2026) ConnectWise Cloud Backup Compromise in Microsoft 365: What Happened and What to Do Now — Security Boulevard ","date":"20 October 2026","externalUrl":null,"permalink":"/tech-watch/connectwise-cloud-backup/","section":"Tech Watch","summary":"The attackers didn’t hack a single account: they signed in as ConnectWise’s backup app, already trusted by its customers. User MFA never came into play.","title":"A backup app opened up 162 Microsoft 365 tenants","type":"tech-watch"},{"content":"An optional app, described as meant for testing, was all it took to take over Nextcloud servers.\nWhat happened # Nextcloud offers an app called \u0026ldquo;Collabora Online - Built-in CODE Server\u0026rdquo; (richdocumentscode), which downloads and runs an online office suite directly on the Nextcloud server. Its listing describes it as meant for local testing, personal use or small teams.\nUp to version 26.4.302, one of the app\u0026rsquo;s scripts placed part of the requested URL inside a system command. The result: a single request, with no account, could run commands on the server (CVE-2026-110447). The attack only worked at a specific moment: when the built-in document server was down, for example after a restart, an upgrade or a crash.\nThe first attacks show up in logs on 10 September 2026. Attackers planted PHP web shells in the app\u0026rsquo;s folder. The fix, version 26.4.303, was released on 11 September.\nWhy it matters # Two details make this case worth a closer look:\nDisabling the app wasn\u0026rsquo;t enough. Its files stayed on the server and remained reachable. The vendor is clear: update it or remove it. Exploitation started the day before the fix. A server updated afterwards is no longer vulnerable, but a web shell planted earlier is still there. What to take away # Every installed extension is part of the attack surface, even an optional one, even one you rarely use. If you don\u0026rsquo;t need it, remove it. A \u0026ldquo;for testing\u0026rdquo; component has no place in production. Disabled is not removed. As long as the code is on disk, it can be called. Patching doesn\u0026rsquo;t clean up. After an exploited flaw, you also have to look for traces: here, shx*.php files in the app\u0026rsquo;s folder and suspicious requests in the logs since 10 September. Sources # Hackers Backdoor Nextcloud Servers Through Critical Flaw in Collabora\u0026rsquo;s Built-in CODE App — The Hacker News (14/10/2026) Security advisory GHSA-g3vx-3m76-fghh — Collabora Online (GitHub) Vulnerability in Nextcloud app allowed attackers to plant web shells — SC Media ","date":"20 October 2026","externalUrl":null,"permalink":"/tech-watch/nextcloud-built-in-code/","section":"Tech Watch","summary":"A Nextcloud app described as meant for testing let anyone run commands on the server without logging in. Attackers planted web shells, and disabling the app wasn’t enough.","title":"An app \"for testing\" opened up Nextcloud servers","type":"tech-watch"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/cloud/","section":"Tags","summary":"","title":"Cloud","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/devops/","section":"Tags","summary":"","title":"DevOps","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/end-of-life/","section":"Tags","summary":"","title":"End of Life","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/fr/tags/fin-de-support/","section":"Tags","summary":"","title":"Fin De Support","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/fr/tags/fournisseurs/","section":"Tags","summary":"","title":"Fournisseurs","type":"tags"},{"content":"Systems and network technician (TSSR) with a web development background, now completing a Bachelor\u0026rsquo;s in DevOps. I\u0026rsquo;m building Heading North Lab in public: rebuilding, automating and securing a fictional company\u0026rsquo;s infrastructure on my own Proxmox server, one phase at a time.\nExplore Heading North Lab → ","date":"20 October 2026","externalUrl":null,"permalink":"/","section":"Home","summary":"","title":"Home","type":"page"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/fr/tags/journaux/","section":"Tags","summary":"","title":"Journaux","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/logging/","section":"Tags","summary":"","title":"Logging","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/microsoft-365/","section":"Tags","summary":"","title":"Microsoft 365","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/fr/tags/mises-%C3%A0-jour/","section":"Tags","summary":"","title":"Mises À Jour","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/monitoring/","section":"Tags","summary":"","title":"Monitoring","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/networking/","section":"Tags","summary":"","title":"Networking","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/nextcloud/","section":"Tags","summary":"","title":"Nextcloud","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/patching/","section":"Tags","summary":"","title":"Patching","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/fr/tags/r%C3%A9seau/","section":"Tags","summary":"","title":"Réseau","type":"tags"},{"content":"No Wi-Fi password needed. Being within radio range is enough.\nWhat happened # On 16 October 2026, at the Hexacon conference, researcher Quentin Kaiser presented a flaw in WPS Monitor, Broadcom\u0026rsquo;s old component that handles WPS — the button that lets you connect a device to Wi-Fi without typing the password.\nThis component doesn\u0026rsquo;t properly check the size of the WPS messages it receives and reassembles. An attacker within Wi-Fi range, without knowing the password and without going through WPS pairing, can trigger memory corruption. The researcher demonstrated controlled memory disclosure and code execution on the device. The exact consequences depend on the model and its firmware.\nThe list of affected products, which isn\u0026rsquo;t exhaustive, includes devices from many brands: ARRIS, Arcadyan, Askey, Cisco, Comtrend, Huawei, Netgear, Nokia, TP-Link, ZTE, Zyxel… For some models the vulnerability is confirmed; for others, it still needs checking against the firmware.\nWhy it matters # Broadcom did not assign a CVE. The company says it replaced this component in 2018 and considers the affected products obsolete or outside its support window. Turning WPS off isn\u0026rsquo;t always enough. According to the researcher, the settings toggle may leave the vulnerable component running. Some devices will never get a fix. The oldest products, based on the eCos system, sometimes have no update path at all. What to take away # A setting is not a fix. Unticking an option doesn\u0026rsquo;t guarantee the vulnerable code is gone. Network hardware has an expiry date. A device that no longer gets updates stays vulnerable for life: replace it. The ISP box is part of your network. The ISP or manufacturer has to ship the update, but it\u0026rsquo;s up to you to ask for it. Radio range is attack surface. Wi-Fi goes through walls: a flaw that needs no password can be attacked from the pavement. Sources # Broadcom WPS — Quentin Kaiser, Hexacon 2026 talk (16/10/2026) Weekly Security Intelligence Briefing, week of 2026-10-19 — Tech Jacks Solutions ","date":"20 October 2026","externalUrl":null,"permalink":"/tech-watch/broadcom-wps/","section":"Tech Watch","summary":"A flaw in Broadcom’s old WPS module affects routers and ISP boxes from many brands. It can be exploited within radio range, without the Wi-Fi password. No CVE, and no fix for some older models.","title":"Routers and ISP boxes: a Wi-Fi flaw some models will never fix","type":"tech-watch"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/fr/tags/supervision/","section":"Tags","summary":"","title":"Supervision","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/tech-watch/","section":"Tags","summary":"","title":"Tech Watch","type":"tags"},{"content":"Every week, one piece of news in cybersecurity, DevOps or networking, sometimes web development, verified and sourced, with three questions: what happened, why it matters, and what to take away from it in practice.\n","date":"20 October 2026","externalUrl":null,"permalink":"/tech-watch/","section":"Tech Watch","summary":"","title":"Tech Watch","type":"tech-watch"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/third-parties/","section":"Tags","summary":"","title":"Third Parties","type":"tags"},{"content":"Two flaws, two different attackers, one shared habit: wipe the logs on the device they just broke into.\nWhat happened # Ivanti Connect Secure. On 13 October 2026, Volexity disclosed a chain of three unknown flaws in this VPN appliance. The targeted device was fully patched at the time. The attacker gained the highest privileges (root), collected credentials and BitLocker recovery keys, then altered the logs to remove traces of their activity. Ivanti\u0026rsquo;s own integrity checking tool doesn\u0026rsquo;t detect this attack, because the code is only changed in memory.\nBeyondTrust Remote Support. On 15 October 2026, Mandiant described the exploitation of a flaw in this remote support tool since late August. The attacker deployed a web shell, harvested stored credentials, and deleted the appliance\u0026rsquo;s logs throughout the intrusion.\nWhy it matters # These devices face the internet and sit in a privileged position in the network. Once an attacker is inside with the highest privileges, everything stored on the device is within reach, logs included.\nSo Mandiant recommends streaming the appliance\u0026rsquo;s logs to an external collection system (a SIEM), and also keeping logs from the devices around it: firewall, proxy. It also notes that a gap in forwarded logs is in itself a strong sign of tampering.\nWhat to take away # Logs stored only on the compromised device prove nothing. They need to leave it, continuously, before the attacker shows up. Silence is a signal. A source that suddenly stops sending logs deserves an alert, not a shrug. \u0026ldquo;Up to date\u0026rdquo; doesn\u0026rsquo;t mean \u0026ldquo;safe\u0026rdquo;. The Ivanti appliance was patched: only traces kept elsewhere can tell what really happened. Cross-check your sources. Logs from the firewall or proxy in front of the device keep a record the attacker can\u0026rsquo;t change from the device itself. Sources # Ivanti Connect Secure zero-day actively exploited — CyberScoop (13/10/2026) Attackers chained three Ivanti zero-days to gain root on fully patched VPN appliances — Help Net Security (14/10/2026) ARMORY CASTLE exploits BeyondTrust — Mandiant / Google Threat Intelligence (15/10/2026) ","date":"20 October 2026","externalUrl":null,"permalink":"/tech-watch/wiped-appliance-logs/","section":"Tech Watch","summary":"Ivanti Connect Secure and BeyondTrust Remote Support: two flaws, two attackers, and in both cases logs wiped or altered on the compromised device. Logs that stay on the box prove nothing anymore.","title":"Two attacks, one shared habit: wipe the logs","type":"tech-watch"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/vpn/","section":"Tags","summary":"","title":"VPN","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/wi-fi/","section":"Tags","summary":"","title":"Wi-Fi","type":"tags"},{"content":"","date":"16 October 2026","externalUrl":null,"permalink":"/tags/friday-fun-fact/","section":"Tags","summary":"","title":"Friday Fun Fact","type":"tags"},{"content":"Every Friday, a true and sourced story about cybersecurity, DevOps, networking or web development: a famous incident, the origin of a term, a historic mistake. With, when possible, what we can still learn from it today.\n","date":"16 October 2026","externalUrl":null,"permalink":"/fun-facts/","section":"Friday Fun Facts","summary":"","title":"Friday Fun Facts","type":"fun-facts"},{"content":"","date":"16 October 2026","externalUrl":null,"permalink":"/fr/tags/histoire/","section":"Tags","summary":"","title":"Histoire","type":"tags"},{"content":"","date":"16 October 2026","externalUrl":null,"permalink":"/tags/history/","section":"Tags","summary":"","title":"History","type":"tags"},{"content":"","date":"16 October 2026","externalUrl":null,"permalink":"/fr/tags/sans-fil/","section":"Tags","summary":"","title":"Sans Fil","type":"tags"},{"content":"Every time you pair your headphones, you\u0026rsquo;re calling on a Danish king who died over a thousand years ago.\nA king with a blue tooth # Harald Gormsson ruled Denmark in the 10th century. He is remembered for uniting the Danes and, according to tradition, for bringing Norway under his rule too. His nickname, Blåtand in Danish — \u0026ldquo;Bluetooth\u0026rdquo; in English — is often explained by a dead tooth that had turned dark blue or grey.\nA code name over a beer # In the mid-1990s, Intel, Ericsson and Nokia started working together on a short-range radio standard, meant to connect phones and computers without cables. They needed a name for the project.\nLate 1997, after a wireless seminar in Toronto, Jim Kardach, an engineer at Intel, went for a few beers with Sven Mattisson, a Swedish engineer at Ericsson. They talked about Vikings: Mattisson told him about Scandinavian history through The Long Ships, a Viking novel by the Swedish writer Frans G. Bengtsson. Kardach suggested \u0026ldquo;Bluetooth\u0026rdquo; as a code name. As he later put it, Harald was famous for uniting Scandinavia, \u0026ldquo;just as we intended to unite the PC and cellular industries\u0026rdquo;.\nThe placeholder that stayed # The name was only meant to last until marketing found something better. Two candidates were on the table:\nPAN (Personal Area Networking), the favourite — but the term already returned tens of thousands of results online, so it couldn\u0026rsquo;t stand out. RadioWire — but the trademark search couldn\u0026rsquo;t be finished before launch. With no other option ready in time, the temporary name went out. By then, it had already spread through the industry. It was never replaced.\nThe logo is a signature # The Bluetooth logo isn\u0026rsquo;t an abstract shape. It\u0026rsquo;s a bind rune: two runes from the Younger Futhark merged into one symbol, ᚼ (Hagall, H) and ᛒ (Bjarkan, B). Harald Bluetooth\u0026rsquo;s initials.\nWhat any sysadmin will recognise # Nothing is more permanent than a temporary solution. A test server, a quick workaround, a placeholder name \u0026ldquo;until we find better\u0026rdquo;: if it works, it stays. Bluetooth is just the most famous example — and probably the only one with a Viking king attached.\nSources # Origin of the Bluetooth name — Bluetooth SIG Bluetooth — Wikipedia Harald Bluetooth — Wikipedia How a Viking king inspired one of our best-known modern technologies — The Local (2021) Illustration: the two runes are shown separately. The Bluetooth logo itself is a registered trademark of the Bluetooth SIG.\n","date":"16 October 2026","externalUrl":null,"permalink":"/fun-facts/the-viking-behind-bluetooth/","section":"Friday Fun Facts","summary":"Bluetooth was only meant to be a temporary code name, borrowed from a Viking king. It never got replaced.","title":"The Viking behind Bluetooth","type":"fun-facts"},{"content":"","date":"16 October 2026","externalUrl":null,"permalink":"/tags/wireless/","section":"Tags","summary":"","title":"Wireless","type":"tags"},{"content":"Deleting a password from GitHub doesn\u0026rsquo;t switch it off. 543,699 credentials prove it.\nWhat happened # On 29 September 2026, Truffle Security published research based on The Stack v3, a dataset of public GitHub code collected for AI training: 224 million repositories and 58 billion files, crawled until August 2025.\nThe researchers found 1,103,438 exposed credentials. In late July 2026, they tested each one against the service that issued it: 543,699 still worked.\nA few figures stand out:\nthe oldest live credential is an AWS key pushed in 2009, still valid after 16 years; the median credential had been public for 784 days; just under 200,000 live credentials were pushed after GitHub made push protection the default, in February 2024. Why it matters # The most interesting finding isn\u0026rsquo;t the volume, it\u0026rsquo;s the cause. Survival depends on revocation, not detection:\ntokens that their provider revokes automatically (GitHub, npm) are almost all dead — only 260 GitHub tokens and a single npm token were still live; database connection strings (MongoDB, Postgres, MySQL), which nobody revokes automatically, are almost all still live. Push protection roughly halved the rate at which covered secrets reach public code. But, as the researchers put it, it \u0026ldquo;did not change what happens to a credential once it is there\u0026rdquo;. And about half of live credentials are types that push protection does not block by default.\nWhat to take away # A published secret is compromised, even if you delete the commit a minute later. Rotate it first, clean the history second. Blocking future leaks doesn\u0026rsquo;t fix past ones. Scan your repositories\u0026rsquo; full history, especially anything committed before February 2024. Prefer short-lived credentials. Most of the leaked secrets would have expired harmlessly if they had a lifetime. Check your providers. Does the service you use revoke leaked keys automatically? If not, detection alone leaves the key working. For Norrøn Voyages, the fictional company of my lab, this becomes a rule from day one of phase 6: no secret ever goes into Git, and any secret that does is rotated immediately.\nSources # GitHub Repos Exposed 543,699 Credentials. Nobody Revoked Them. — Truffle Security (29/09/2026) 500,000 Active Credentials Left Exposed on GitHub — SecurityWeek (01/10/2026) ","date":"11 October 2026","externalUrl":null,"permalink":"/tech-watch/github-secrets-not-revoked/","section":"Tech Watch","summary":"Out of 1.1 million credentials exposed on public GitHub repositories, 543,699 still worked in July 2026. The problem isn’t the leak, it’s the missing revocation.","title":"543,699 GitHub secrets still work. Nobody revoked them.","type":"tech-watch"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/architecture/","section":"Tags","summary":"","title":"Architecture","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/devsecops/","section":"Tags","summary":"","title":"DevSecOps","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/fr/tags/gestion-des-secrets/","section":"Tags","summary":"","title":"Gestion Des Secrets","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/github/","section":"Tags","summary":"","title":"GitHub","type":"tags"},{"content":"Heading North Lab is the hands-on side of my career change. Instead of collecting isolated exercises, I\u0026rsquo;m building one infrastructure on my own Proxmox server and making it grow as my DevOps training goes on: virtualisation, network segmentation, hardening, CI/CD, containers, infrastructure as code, monitoring, and finally detection.\nWhy one long-running lab rather than separate tutorials?\nEverything connects. Each phase builds on the previous ones, like in a real company: what I set up in phase 2 has to survive phases 3 to 12. Every choice has a reason. The lab follows the needs of a fictional company, so each technical decision answers a concrete problem. Mistakes are part of it. I document what worked, what broke and what I learned. The articles below are in order: start with the first one and follow the project step by step.\n","date":"11 October 2026","externalUrl":null,"permalink":"/heading-north-lab/","section":"Heading North Lab","summary":"","title":"Heading North Lab","type":"heading-north-lab"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/heading-north-lab/","section":"Tags","summary":"","title":"Heading North Lab","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/phase-0/","section":"Tags","summary":"","title":"Phase 0","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/scenario/","section":"Tags","summary":"","title":"Scenario","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/fr/tags/sc%C3%A9nario/","section":"Tags","summary":"","title":"Scénario","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/secrets-management/","section":"Tags","summary":"","title":"Secrets Management","type":"tags"},{"content":"","date":"9 October 2026","externalUrl":null,"permalink":"/fr/tags/cybers%C3%A9curit%C3%A9/","section":"Tags","summary":"","title":"Cybersécurité","type":"tags"},{"content":"","date":"9 October 2026","externalUrl":null,"permalink":"/tags/cybersecurity/","section":"Tags","summary":"","title":"Cybersecurity","type":"tags"},{"content":"","date":"9 October 2026","externalUrl":null,"permalink":"/tags/honeypot/","section":"Tags","summary":"","title":"Honeypot","type":"tags"},{"content":"75 cents. That\u0026rsquo;s all that was missing from a computer bill — and it brought down a spy ring.\nA rounding error that wasn\u0026rsquo;t # In 1986, Cliff Stoll was an astronomer who had become a system administrator at Lawrence Berkeley Laboratory, in California. Scientists paid for the computer time they used, and his supervisor asked him to explain a 75-cent gap in the accounting.\nMost people would have written it off as a rounding error. Stoll dug in. He traced the gap to an unknown user who had used nine seconds of computing time without paying. Worse, the intruder had gained root access to the system.\nTen months on the trail # Instead of simply locking the intruder out, Stoll and his colleagues chose to watch him. For about ten months, Stoll followed his every session, kept detailed notes in a logbook, and discovered that the lab was only a stepping stone: the intruder was using it to reach US military systems.\nThe trap # Stoll noticed that the intruder was interested in the \u0026ldquo;Star Wars\u0026rdquo; missile defense program (SDI). So he created a fake \u0026ldquo;SDInet\u0026rdquo; account full of impressive-sounding but meaningless documents. The bait worked: the intruder stayed connected long enough for the connection to be traced across international networks. It is often described as one of the earliest documented uses of a honeypot.\nThe trail led to West Germany and to Markus Hess, who had been selling the results of his intrusions to the KGB. He was convicted of espionage in 1990.\nThe takeaway # Attacks rarely hide in big, obvious alerts. They hide in small anomalies that nobody takes the time to explain. Stoll\u0026rsquo;s investigation also shows the value of two habits that still matter today:\nKeep and read your logs. Without the accounting records, there would have been no gap to notice. Document everything. Stoll\u0026rsquo;s logbook made it possible to understand the attacker\u0026rsquo;s methods and, later, to prove what happened. Sources # Clifford Stoll, The Cuckoo\u0026rsquo;s Egg (1989) Clifford Stoll, \u0026ldquo;Stalking the Wily Hacker\u0026rdquo;, Communications of the ACM (1988) Markus Hess — Wikipedia The Cuckoo\u0026rsquo;s Egg — Wikipedia How a Berkeley eccentric beat the Russians — California Magazine Illustration: fictional reconstruction of an accounting report, not an original 1986 document.\n","date":"9 October 2026","externalUrl":null,"permalink":"/fun-facts/the-75-cent-hacker/","section":"Friday Fun Facts","summary":"In 1986, a 75-cent gap in a lab’s billing led an astronomer turned sysadmin to a hacker selling secrets to the KGB.","title":"The 75-cent hacker","type":"fun-facts"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/tags/active-directory/","section":"Tags","summary":"","title":"Active Directory","type":"tags"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/tags/cisco/","section":"Tags","summary":"","title":"Cisco","type":"tags"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/tags/glpi/","section":"Tags","summary":"","title":"GLPI","type":"tags"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/tags/gpo/","section":"Tags","summary":"","title":"GPO","type":"tags"},{"content":"My path goes through several fields: web development, then systems and networks, and now DevOps, heading towards DevSecOps. This page brings together the projects from each stage.\nFor each project, you\u0026rsquo;ll find:\nits field, shown as a label; its context: training project, practice exercise or personal project; what I actually built, and the tech stack; a link to the code, and to a live demo when the project allows it. Some projects are a few years old. I\u0026rsquo;m showing them as they are: they show where I come from.\nMy long-running project has its own section: Heading North Lab.\n","date":"14 January 2026","externalUrl":null,"permalink":"/projects/","section":"Projects","summary":"","title":"Projects","type":"projects"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/fr/categories/syst%C3%A8mes-et-r%C3%A9seaux/","section":"Categories","summary":"","title":"Systèmes Et Réseaux","type":"categories"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/categories/systems-and-networks/","section":"Categories","summary":"","title":"Systems and Networks","type":"categories"},{"content":"","date":"14 January 2026","externalUrl":null,"permalink":"/tags/tssr/","section":"Tags","summary":"","title":"TSSR","type":"tags"},{"content":"","date":"9 January 2023","externalUrl":null,"permalink":"/fr/categories/d%C3%A9veloppement-web/","section":"Categories","summary":"","title":"Développement web","type":"categories"},{"content":"","date":"9 January 2023","externalUrl":null,"permalink":"/fr/tags/exercice/","section":"Tags","summary":"","title":"Exercice","type":"tags"},{"content":"","date":"9 January 2023","externalUrl":null,"permalink":"/tags/exercise/","section":"Tags","summary":"","title":"Exercise","type":"tags"},{"content":"","date":"9 January 2023","externalUrl":null,"permalink":"/tags/javascript/","section":"Tags","summary":"","title":"JavaScript","type":"tags"},{"content":"","date":"9 January 2023","externalUrl":null,"permalink":"/categories/web-development/","section":"Categories","summary":"","title":"Web development","type":"categories"},{"content":"","date":"30 November 2022","externalUrl":null,"permalink":"/tags/css/","section":"Tags","summary":"","title":"CSS","type":"tags"},{"content":"","date":"26 November 2022","externalUrl":null,"permalink":"/tags/node.js/","section":"Tags","summary":"","title":"Node.js","type":"tags"},{"content":"","date":"26 November 2022","externalUrl":null,"permalink":"/tags/openclassrooms/","section":"Tags","summary":"","title":"OpenClassrooms","type":"tags"},{"content":"","date":"26 November 2022","externalUrl":null,"permalink":"/tags/react/","section":"Tags","summary":"","title":"React","type":"tags"},{"content":"","date":"26 November 2022","externalUrl":null,"permalink":"/fr/tags/s%C3%A9curit%C3%A9/","section":"Tags","summary":"","title":"Sécurité","type":"tags"},{"content":"","date":"26 November 2022","externalUrl":null,"permalink":"/tags/security/","section":"Tags","summary":"","title":"Security","type":"tags"},{"content":"","date":"11 August 2022","externalUrl":null,"permalink":"/fr/tags/accessibilit%C3%A9/","section":"Tags","summary":"","title":"Accessibilité","type":"tags"},{"content":"","date":"11 August 2022","externalUrl":null,"permalink":"/tags/accessibility/","section":"Tags","summary":"","title":"Accessibility","type":"tags"},{"content":"","date":"11 August 2022","externalUrl":null,"permalink":"/tags/seo/","section":"Tags","summary":"","title":"SEO","type":"tags"},{"content":"","date":"28 June 2022","externalUrl":null,"permalink":"/tags/sass/","section":"Tags","summary":"","title":"Sass","type":"tags"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"The best way to reach me is through LinkedIn. You can also follow the lab\u0026rsquo;s progress on GitHub.\n","externalUrl":null,"permalink":"/contact/","section":"Home","summary":"","title":"Contact","type":"page"},{"content":" Profile # Systems and network technician with a web development background, now training in DevOps with a clear direction: DevSecOps.\nI discovered cybersecurity during my web development training. It has since become both the common thread of my career change and a passion, which I practise regularly on training platforms such as TryHackMe and which led me to the eJPT. The TSSR qualification then gave me solid foundations in systems and networks; my DevOps Bachelor\u0026rsquo;s is teaching me to automate, industrialise, and build security in from the start.\nFrom my professional background, I keep a habit that matters in this field: applying strict procedures, without exception, even when things go wrong. That\u0026rsquo;s exactly what a production release, incident handling or a security policy requires.\nI\u0026rsquo;m now building Heading North Lab, a complete infrastructure on my own Proxmox server, documented in public step by step. Long-term goal: working in the Nordic countries.\nEducation and certifications # Bachelor\u0026rsquo;s in DevOps Systems Administration (French state-recognised qualification, EQF level 6) — Studi — in progress Systems and Network Technician (TSSR) — French state-recognised professional qualification, EQF level 5 (two years of higher education) — Studi — October 2025 to August 2026 Claude Academy: AI Fluency — Framework and Foundations — Anthropic — October 2026 (verify) eJPT v2 — eLearnSecurity Junior Penetration Tester — INE — August 2025, valid until August 2028 (verify) Jr Penetration Tester — TryHackMe — October 2023 Google Cybersecurity Professional Certificate — Google — August 2023, about 170 hours (verify) Web Developer and Integrator — French state-recognised professional qualification, EQF level 5 — OpenClassrooms — February 2023 Cisco Network Technician and Cybersecurity Analyst learning paths — Cisco Networking Academy Technical skills # Systems and virtualisation: Linux (Ubuntu), Windows Server, Active Directory, DNS, DHCP, Proxmox, Hyper-V Networking and security: pfSense, VLAN segmentation, firewall rules, penetration testing fundamentals DevOps: Git, GitHub, GitHub Actions (CI/CD), Hugo — Docker, Kubernetes, Terraform and Ansible currently being learned in my Bachelor\u0026rsquo;s programme Development: HTML, CSS, JavaScript, Python Projects # Heading North Lab — rebuilding, automating and securing a fictional company\u0026rsquo;s infrastructure on a Proxmox server, in 13 documented phases. This website — bilingual static site (Hugo), versioned on GitHub and deployed automatically by a GitHub Actions pipeline. Professional experience # Train conductor (passenger service and on-board safety) — SNCF, French national railways\nTER Hauts-de-France regional trains — since 2022 OUIGO high-speed trains — 2013 to 2022 Paris Austerlitz — 2010 to 2013 Strict application of safety and security procedures, handling of disrupted situations and on-board conflicts, ticket inspections, daily customer relations.\nReal estate agent — various agencies — 1998 to 2010\nFire and rescue team leader — French national service — 1996 to 1998\nEarlier education # French baccalauréat in accounting and business management — 1994 Vocational diploma in accounting (BEP) — 1992 Languages # French: native English: B2 (upper intermediate) Norwegian (bokmål): learning Icelandic: learning ","externalUrl":null,"permalink":"/cv/","section":"Home","summary":"","title":"Resume","type":"page"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]