<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Salah Eddine Medkour</title>
    <description>The latest articles on DEV Community by Salah Eddine Medkour (@salah_eddine_medkour).</description>
    <link>https://dev.to/salah_eddine_medkour</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3527234%2F229e9471-720d-4276-939c-1c55bb145968.png</url>
      <title>DEV Community: Salah Eddine Medkour</title>
      <link>https://dev.to/salah_eddine_medkour</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/salah_eddine_medkour"/>
    <language>en</language>
    <item>
      <title>How my brain forced me to create "Nadeef". A non-profit civic cleaning PWA</title>
      <dc:creator>Salah Eddine Medkour</dc:creator>
      <pubDate>Wed, 29 Apr 2026 21:54:57 +0000</pubDate>
      <link>https://dev.to/salah_eddine_medkour/how-my-brain-forced-me-to-create-nadeef-a-non-profit-civic-cleaning-pwa-57m9</link>
      <guid>https://dev.to/salah_eddine_medkour/how-my-brain-forced-me-to-create-nadeef-a-non-profit-civic-cleaning-pwa-57m9</guid>
      <description>&lt;p&gt;I'm Salah Eddine Medkour. I teach Python and ICT at Badji Mokhtar University in Annaba, Algeria, and I build things on the web when my brain won't let me sleep. Before Nadeef, I made AirQuiz, an offline quiz platform that saved me 95% of my grading time when the university's internet couldn't handle 289 students taking exams simultaneously. I graduated with a master's in Network Engineering, but most of what I actually build comes from being annoyed at problems that shouldn't exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trash pile that started everything
&lt;/h2&gt;

&lt;p&gt;There's a spot near my apartment. Trash bags piled against a crumbling concrete pillar under a highway overpass. It's been there for three weeks. Every morning I walk past it. Every morning I think someone should clean it. Every morning I realize I'm "someone" and I keep walking.&lt;/p&gt;

&lt;p&gt;This is the problem with civic responsibility. Everyone sees it. Nobody owns it. The municipality won't come unless you call, and calling means navigating a phone tree that goes nowhere. Posting in a Facebook group gets 30 "inshallah someone fixes this" comments and zero action.&lt;/p&gt;

&lt;p&gt;I wasn't planning to build an app about this. I was scrolling through my Notes app looking for a grocery list when I found an entry from 2 AM three months ago. Just a title: "Trash reporting app but make it not annoying." Below it, a messy diagram of pins on a map, some arrows, the word "gamification" circled twice.&lt;/p&gt;

&lt;p&gt;I don't remember writing this. But drunk-brain or sleep-deprived-brain or whatever version of me wrote it was right. The idea wouldn't leave.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Nadeef actually is
&lt;/h2&gt;

&lt;p&gt;Nadeef means "clean" in Arabic. It's a PWA, a progressive web app, which means it works on your phone without downloading anything from an app store. No 50MB install. No permissions popups. Just a link.&lt;/p&gt;

&lt;p&gt;The concept is stupid simple. You see trash. You open Nadeef. You take a photo with your live camera (no uploading old photos from your gallery because people will absolutely try to cheat). GPS tags your exact location. You pick a severity level: minor litter, accumulated waste, or environmental hazard. You add a title. Done. A red pin drops on the map.&lt;/p&gt;

&lt;p&gt;Someone else nearby sees the pin. They tap it. They see your photo, the location, how much XP they'll earn for cleaning it. They accept the mission. They clean it. They take an after photo. You get a notification asking you to confirm the cleanup is real. You swipe through a before/after slider. If it looks good, you approve. They get XP. The pin turns green. Everyone moves on.&lt;/p&gt;

&lt;p&gt;That's the whole loop. Report, clean, verify, reward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it in 24 hours
&lt;/h2&gt;

&lt;p&gt;I gave myself one day. Not because I'm fast but because if I spend more than a weekend on something, I'll overthink it into complexity and never ship.&lt;/p&gt;

&lt;p&gt;I used what I knew would work: React for the UI, Supabase for the database and auth, Leaflet for maps, Netlify to host it. All free tiers. Zero dollars spent. I'm not trying to raise money or pitch investors. This is a tool, not a startup.&lt;/p&gt;

&lt;p&gt;The tech stack matters less than the decisions I made while building:&lt;/p&gt;

&lt;p&gt;Camera-only uploads. No gallery access. This prevents someone from uploading a photo they took six months ago and claiming they just cleaned a spot. The camera forces fresh photos with GPS metadata I can validate.&lt;/p&gt;

&lt;p&gt;Before/after slider. This is the part I'm most proud of. It's just two images with a draggable divider, but the emotional impact of sliding from dirty to clean is absurd. People spend 20 seconds just dragging the slider back and forth. It makes the transformation undeniable.&lt;/p&gt;

&lt;p&gt;Gamification without manipulation. You earn XP for reporting and cleaning. You rank up from Scout to Pioneer to Guardian. You unlock badges for cleaning at dawn, cleaning in teams, being the first to clean in a new neighborhood. But there are no daily login streaks that punish you for missing a day. No dark patterns. No engineered addiction. Just visible progress for actual work.&lt;/p&gt;

&lt;p&gt;Bilingual by default. The app is Arabic and English, toggled with one tap. Most civic tech ignores Arabic or treats it as an afterthought. I built the UI in both languages from day one, with proper right-to-left layout for Arabic, because half of Algeria prefers Arabic interfaces and they shouldn't have to settle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The philosophy underneath
&lt;/h2&gt;

&lt;p&gt;Nadeef is not about altruism. It's about ownership.&lt;/p&gt;

&lt;p&gt;When trash sits on your street for weeks, you feel powerless. The system failed. The municipality didn't come. Nobody cares. So you stop caring too. Learned helplessness.&lt;/p&gt;

&lt;p&gt;Nadeef flips that. You see trash. You report it. Someone cleans it. You verify it. Suddenly you're not powerless. You identified a problem. Someone else solved it. The system worked because you both made it work.&lt;/p&gt;

&lt;p&gt;This is civic infrastructure built by civilians. No budget. No bureaucracy. Just people who live somewhere deciding that somewhere should be cleaner.&lt;/p&gt;

&lt;p&gt;The gamification exists because humans are competitive and we respond to visible progress. The leaderboard shows you the top cleaners this week. The badges show you milestones. The XP number goes up. These are extrinsic motivators, sure, but they get people through the door. Once you've cleaned three spots and seen the before/after photos, you don't need the XP anymore. You're hooked on the transformation itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What people actually do with it
&lt;/h2&gt;

&lt;p&gt;I didn't have a marketing budget or a grand launch plan. I just took some screenshots, wrote a brutally honest post about why I built it, and dropped it into a few Algerian Facebook groups and Reddit.&lt;/p&gt;

&lt;p&gt;I fully expected it to get ignored or buried. Instead, the community loved it.&lt;/p&gt;

&lt;p&gt;Because it’s strictly non-profit—no ads, no subscription fees, no data selling—people immediately dropped their defenses. They realized they weren't being sold a product; they were being handed a tool.&lt;/p&gt;

&lt;p&gt;Within hours, real users were logging in. They were dropping pins on the map over Annaba, testing the mechanics, engaging with the RTL Arabic layout, and validating the core loop. People in the comments started suggesting features like a "Wall of Shame" to hold local municipalities accountable based on the map data.&lt;/p&gt;

&lt;p&gt;Seeing strangers across the internet instantly grasp the value of the platform—and actually care enough to test the mechanics—gave me a feeling I wasn't expecting. Validation. I just built the engine, but the community proved they were ready to drive it.&lt;/p&gt;

&lt;p&gt;That's when I knew this might actually work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problems I didn't anticipate
&lt;/h2&gt;

&lt;p&gt;Spam. Within 48 hours someone uploaded a photo of a cat and marked it as a level 3 environmental hazard. I added a flagging system.&lt;/p&gt;

&lt;p&gt;Fake cleanups. Someone uploaded an after photo that was clearly just a different angle of the same trash pile. I tightened the EXIF validation and added community voting for suspicious submissions.&lt;/p&gt;

&lt;p&gt;Territorial behavior. Two users started competing for the same spots. They'd both rush to claim a pin the second it appeared. I added a claim-locking system. Once someone hits "start cleaning," they get a 30-minute exclusive window.&lt;/p&gt;

&lt;p&gt;These are good problems. They mean people care enough to try to break the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's missing and what's next
&lt;/h2&gt;

&lt;p&gt;Nadeef has no business model. I'm not monetizing this. I'm not putting ads in it. I'm not selling data to waste management companies.&lt;/p&gt;

&lt;p&gt;I do want partnerships, but only under specific terms. If a company wants to sponsor a cleanup campaign or fund supplies, fine. Any profit from those collaborations goes to registered charities or gets reinvested into cleanup campaigns. No one gets rich off people picking up trash.&lt;/p&gt;

&lt;p&gt;I'm also terrible at promotion. The app exists. It works. I posted it on social media once. That's the extent of my marketing. I'm open to volunteers who want to help spread it, moderate content, translate it to other languages, or build on top of it.&lt;/p&gt;

&lt;p&gt;If an NGO in Tunisia or Morocco wants to adapt it for their city, the code will eventually be open source. Take it. Fork it. Make it better.&lt;/p&gt;

&lt;p&gt;Right now I'm focused on making it work well in Annaba. Ten users cleaning three spots each per week is more valuable than 1,000 users who sign up, look around, and leave.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm writing this
&lt;/h2&gt;

&lt;p&gt;I'm writing this because I want the app to show up when someone Googles "civic engagement Algeria" or "community cleanup tool" or "how to report trash in my city."&lt;/p&gt;

&lt;p&gt;I'm also writing this because building in public is uncomfortable and I need to get better at it. I don't naturally share half-finished work. I don't naturally ask for help. But Nadeef won't scale if I'm the only one who knows it exists.&lt;/p&gt;

&lt;p&gt;If you're in Annaba and you've walked past the same trash pile for three weeks, try Nadeef. If you're in another city and you want to adapt the idea, contact me. If you're a graphic designer or developer or community organizer and you want to help, I'll figure out how to coordinate volunteers.&lt;/p&gt;

&lt;p&gt;The app is at nadeef.netlify.app. It's a website. Open it on your phone. No download. No signup required to browse the map. You only need an account if you want to report or clean.&lt;/p&gt;

&lt;p&gt;The source code isn't public yet but it will be. React, Supabase, Leaflet, Tailwind. Standard modern web stack. Nothing fancy. It works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing I keep thinking about
&lt;/h2&gt;

&lt;p&gt;There's a concept in Islam called sadaqah jariyah. Continuous charity. The idea is that some good deeds keep generating reward even after you die. Planting a tree. Digging a well. Teaching someone to read.&lt;/p&gt;

&lt;p&gt;I'm not religious, but the concept resonates. If Nadeef helps someone clean one spot, and that inspires someone else to clean another, and that creates a norm where neighborhoods take care of themselves, then the initial effort compounds.&lt;/p&gt;

&lt;p&gt;I didn't set out to build something altruistic. I set out to scratch an itch. I was annoyed that trash sat in public spaces for weeks because the coordination problem was unsolved. So I solved the coordination problem.&lt;/p&gt;

&lt;p&gt;If that happens to make the world slightly cleaner, I'll take it. But mostly I just wanted to stop walking past that trash pile every morning and feeling helpless.&lt;/p&gt;

&lt;p&gt;Now I don't.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Salah Eddine Medkour&lt;/strong&gt; is a web developer, network engineering graduate, and university instructor from Annaba, Algeria. He builds tools that solve problems he's personally annoyed by. You can find him on &lt;a href="https://www.linkedin.com/in/salah-eddine-medkour/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or contact him at &lt;a href="mailto:medkoursalaheddine@gmail.com"&gt;medkoursalaheddine@gmail.com&lt;/a&gt;. &lt;br&gt;
My Website : salaheddinemedkour.me&lt;br&gt;
Nadeef is live at &lt;a href="nadeef.netlify.app&amp;lt;br&amp;gt;%0A![%20](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8gzp29yxy9kl5rl83zcs.png)"&gt;NADEEF APP&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>civictech</category>
      <category>developer</category>
    </item>
    <item>
      <title>CORP.DZ: Enterprise Infrastructure Home Lab - Salah Eddine Medkour</title>
      <dc:creator>Salah Eddine Medkour</dc:creator>
      <pubDate>Wed, 18 Feb 2026 20:09:01 +0000</pubDate>
      <link>https://dev.to/salah_eddine_medkour/corpdz-enterprise-infrastructure-home-lab-salah-eddine-medkour-2jig</link>
      <guid>https://dev.to/salah_eddine_medkour/corpdz-enterprise-infrastructure-home-lab-salah-eddine-medkour-2jig</guid>
      <description>&lt;p&gt;A hybrid enterprise network simulation replicating Small-to-Medium Business (SMB) infrastructure. This project demonstrates the on-premise integration of Windows Active Directory with Linux services, identity management automation, defensive auditing, and network segmentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Project Overview&lt;/li&gt;
&lt;li&gt;Author &amp;amp; Links&lt;/li&gt;
&lt;li&gt;Laboratory Environment&lt;/li&gt;
&lt;li&gt;Network Topology&lt;/li&gt;
&lt;li&gt;Implementation Walkthrough

&lt;ul&gt;
&lt;li&gt;Phase 1: The Foundation (Identity &amp;amp; DNS)&lt;/li&gt;
&lt;li&gt;Phase 2: Hybrid Services (Linux Integration)&lt;/li&gt;
&lt;li&gt;Phase 3: Operations &amp;amp; Security (GPO &amp;amp; Audit)&lt;/li&gt;
&lt;li&gt;Phase 4: Network Engineering (Routing &amp;amp; Hardening)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Tools &amp;amp; Utilities&lt;/li&gt;

&lt;li&gt;Key Configurations&lt;/li&gt;

&lt;li&gt;Disclaimer&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Corp.DZ&lt;/strong&gt; is a hands-on home lab built to simulate a secure corporate LAN. Unlike cloud-based labs, this environment focuses on on-premise logic, requiring manual configuration of TCP/IP stacks, internal DNS zones, routing tables, and Active Directory forests.&lt;/p&gt;

&lt;p&gt;Key Competencies Demonstrated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Air-Gapped Architecture: Designed an isolated internal subnet structure (192.168.10.x / 172.16.20.x) ensuring zero leakage to the host network.&lt;/li&gt;
&lt;li&gt;Hybrid Integration: Successfully bridged Windows Server 2022 and Ubuntu Linux 24.04 using split-brain DNS.&lt;/li&gt;
&lt;li&gt;Identity Management: Deployed AD DS, RBAC (Role-Based Access Control), and automated user provisioning via PowerShell.&lt;/li&gt;
&lt;li&gt;Security Ops: Implemented Least Privilege delegation, SSH hardening (Key-based auth), and conducted internal penetration tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Author &amp;amp; Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Salah Eddine Medkour&lt;/strong&gt; Junior Network Engineer | Technical Lab Instructor @ Badji Mokhtar University | Master’s in Networks &amp;amp; Telecommunications&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Portfolio: &lt;a href="https://salahmed-ctrlz.github.io/salaheddine-medkour-portfolio/" rel="noopener noreferrer"&gt;salahmed-ctrlz.github.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: &lt;a href="https://www.linkedin.com/in/salah-eddine-medkour/" rel="noopener noreferrer"&gt;Salah Eddine Medkour&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 GitHub: &lt;a href="https://github.com/salahmed-ctrlz/" rel="noopener noreferrer"&gt;salahmed-ctrlz&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Laboratory Environment
&lt;/h2&gt;

&lt;p&gt;The infrastructure operates on a local workstation using Oracle VirtualBox. VMs are bridged via dedicated "Internal Network" adapters to simulate physical LAN cabling.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Host Hardware Configuration&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU: AMD Ryzen 5 5600 (6 Cores / 12 Threads)&lt;/li&gt;
&lt;li&gt;GPU: NVIDIA GTX 1650 (Dual Monitor Setup for Admin Center simulation)&lt;/li&gt;
&lt;li&gt;RAM: 16 GB DDR4 (Dynamically allocated to VMs)&lt;/li&gt;
&lt;li&gt;Storage: NVMe SSD (Critical for concurrent VM I/O)&lt;/li&gt;
&lt;li&gt;Network: 1.5 Gbps FTTH (Host-side only for ISO retrieval)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Virtual Machine Inventory (BOM)&lt;/strong&gt;&lt;br&gt;
CorpDZ-DC&lt;/p&gt;

&lt;p&gt;Role: Domain Controller &amp;amp; Router&lt;/p&gt;

&lt;p&gt;OS: SERVER_EVAL_x64FRE_en-us.iso (Server 2022)&lt;/p&gt;

&lt;p&gt;Network: Static IP (.2) / Dual NIC&lt;/p&gt;

&lt;p&gt;1.CorpDZ-Client&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Role: Employee Workstation&lt;/li&gt;
&lt;li&gt;    OS: en-us_windows_10_enterprise_ltsc_2021...iso&lt;/li&gt;
&lt;li&gt;    Network: DHCP (Relay)&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;CorpDZ-Web&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;    Role: Intranet Server&lt;/li&gt;
&lt;li&gt;    OS: ubuntu-24.04.3-live-server-amd64.iso&lt;/li&gt;
&lt;li&gt;    Network: Static IP (.5)&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Kali-Audit&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;    Role: Red Team / Audit&lt;/li&gt;
&lt;li&gt;    OS: Kali Linux Rolling 2024&lt;/li&gt;
&lt;li&gt;    Network: DHCP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvo87wbsphvjc0jyi0up.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvo87wbsphvjc0jyi0up.png" alt=" " width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Network Topology
&lt;/h2&gt;

&lt;p&gt;The lab evolved from a flat network to a segmented architecture to simulate enterprise security zones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwte96i3vx7nuav6c88fh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwte96i3vx7nuav6c88fh.png" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation Walkthrough
&lt;/h2&gt;

&lt;p&gt;*&lt;em&gt;Phase 1: The Foundation (Identity &amp;amp; DNS)&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Establishing the Data Center core.&lt;/li&gt;
&lt;li&gt;Server Provisioning: Installed Windows Server 2022 and promoted to Domain Controller (corp.dz).&lt;/li&gt;
&lt;li&gt;IP Management: Configured Static IPs and authorized DHCP Scope OfficeLAN (.100-.200).&lt;/li&gt;
&lt;li&gt;Client Onboarding: Joined Windows 10 LTSC Client to the domain; verified internal DNS resolution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;Phase 2: Hybrid Services (Linux Integration)&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bridging OS environments.&lt;/li&gt;
&lt;li&gt;Linux Deployment: Deployed Ubuntu Server; configured Netplan (YAML) for static networking pointing to the Windows DC for DNS.&lt;/li&gt;
&lt;li&gt;Intranet Services: Installed Nginx and deployed a custom "Authorized Personnel Only" dashboard.&lt;/li&gt;
&lt;li&gt;Resolution: Created a Windows DNS A-Record mapping &lt;a href="http://www.corp.dz" rel="noopener noreferrer"&gt;www.corp.dz&lt;/a&gt; to the Linux server IP. Validated access from client browsers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;Phase 3: Advanced Administration (GPO &amp;amp; Security)&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simulating real-world SysAdmin tasks.&lt;/li&gt;
&lt;li&gt;Automation: Scripted bulk user onboarding via PowerShell (CSV import).&lt;/li&gt;
&lt;li&gt;Least Privilege: Created a "Junior Admin" account (Adam.Helpdesk) and Delegated Control for specific OUs only.&lt;/li&gt;
&lt;li&gt;Disaster Recovery: Implemented Folder Redirection GPO. User Desktop data automatically syncs to a central server share (\CorpDZ-DC\UserFiles).&lt;/li&gt;
&lt;li&gt;Policy Management: Managed GPO Precedence (LSDOU), utilizing "Enforced" policies to resolve conflicting wallpaper settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;Phase 4: Network Engineering (Routing &amp;amp; Hardening)&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breaking the network to rebuild it stronger.&lt;/li&gt;
&lt;li&gt;Segmentation: Split the network into two subnets (Server vs. Staff) to isolate critical assets.&lt;/li&gt;
&lt;li&gt;Software Routing: Configured RRAS on Windows Server to route traffic between virtual interfaces.&lt;/li&gt;
&lt;li&gt;DHCP Relay: Configured a Relay Agent to forward IP requests from the isolated Staff LAN to the central DHCP server.&lt;/li&gt;
&lt;li&gt;SSH Hardening: Generated 4096-bit RSA keys, installed them on Linux, and disabled password authentication (PasswordAuthentication no).&lt;/li&gt;
&lt;li&gt;Penetration Test: Deployed Kali Linux internally and attempted a brute-force attack (Hydra) against the hardened server. Result: Attack Failed (Access Denied).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcthx389v8rhdbbnummb7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcthx389v8rhdbbnummb7.png" alt=" " width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools &amp;amp; Utilities
&lt;/h2&gt;

&lt;p&gt;Key tools leveraged for management, automation, and troubleshooting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/salahmed-ctrlz/99SAK-PowershellSwissArmyKnife" rel="noopener noreferrer"&gt;99SAK - Powershell Swiss Army Knife&lt;/a&gt; : A custom single-file, portable admin toolkit I developed. It features 99 menu-driven operations for Windows, including network triage, system maintenance, and log analysis. Used extensively during this lab for rapid diagnostics.&lt;/li&gt;
&lt;li&gt;RSAT: Remote Server Administration Tools for AD management from the client.&lt;/li&gt;
&lt;li&gt;PuTTY: SSH client for remote Linux management.&lt;/li&gt;
&lt;li&gt;Nmap &amp;amp; Hydra: Offensive security tools used for auditing network visibility and defense validation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgbjpvnaiaadw90evz63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgbjpvnaiaadw90evz63.png" alt=" " width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Configurations
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Ubuntu Netplan Config (/etc/netplan/50-cloud-init.yaml)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Critical configuration for pointing Linux DNS to the Windows Controller.&lt;br&gt;
&lt;code&gt;network:&lt;br&gt;
  ethernets:&lt;br&gt;
    enp0s3:&lt;br&gt;
      addresses: [192.168.10.5/24]&lt;br&gt;
      routes:&lt;br&gt;
        - to: default&lt;br&gt;
          via: 192.168.10.2  # Gateway is the Windows Server&lt;br&gt;
      nameservers:&lt;br&gt;
        addresses: [192.168.10.2] # DNS is the Windows Server&lt;br&gt;
  version: 2&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PowerShell Bulk User Import (Snippet)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Automation logic used for HR onboarding.&lt;br&gt;
&lt;code&gt;Import-Csv "C:\HR_Data.csv" | ForEach-Object {&lt;br&gt;
    New-ADUser -Name $_.Name -Path "OU=Sales,DC=corp,DC=dz" -Enabled $true&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Folder Redirection Strategy&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;GPO Setting: User Configuration &amp;gt; Policies &amp;gt; Windows Settings &amp;gt; Folder Redirection&lt;/li&gt;
&lt;li&gt;Target Path: \192.168.10.2\UserFiles\%USERNAME%\Desktop&lt;/li&gt;
&lt;li&gt;Rationale: Using the IP address in the UNC path ensures the policy applies even if DNS services are slow to start during the boot sequence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4klk2nkh6pen2av1gwp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4klk2nkh6pen2av1gwp.png" alt=" " width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation Checklist
&lt;/h2&gt;

&lt;p&gt;The following tests were performed to verify infrastructure integrity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; DNS Resolution: ping &lt;a href="http://www.corp.dz" rel="noopener noreferrer"&gt;www.corp.dz&lt;/a&gt; resolves to 192.168.10.5 from client workstations.&lt;/li&gt;
&lt;li&gt; RBAC Enforcement: Adam.Helpdesk receives "Access Denied" when attempting to reset IT Admin passwords.&lt;/li&gt;
&lt;li&gt; Routing: ICMP traffic flows successfully between Zone A (Server) and Zone B (Staff).&lt;/li&gt;
&lt;li&gt; Defense Hardening: Hydra brute-force attack against the Linux server fails due to public-key enforcement.&lt;/li&gt;
&lt;li&gt; Data Persistence: User files persist on the server even after client VM deletion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;This project is a Home Lab simulation intended for educational purposes and professional skill development. While it utilizes enterprise-grade software and configurations (AD, GPO, Linux Servers), it represents a controlled testing environment.&lt;/p&gt;

&lt;p&gt;© 2026 Salah Eddine Medkour. Documented as part of personal "Zero-to-Hero" Infrastructure Sprint.&lt;/p&gt;

&lt;p&gt;Repo : &lt;a href="https://github.com/salahmed-ctrlz/CorpDZ" rel="noopener noreferrer"&gt;For More Info&lt;/a&gt;&lt;/p&gt;

</description>
      <category>virtualmachine</category>
      <category>linux</category>
      <category>ubuntu</category>
      <category>windows</category>
    </item>
    <item>
      <title>How I Built AirQuiz an Offline-First Exam Server (Python/React) to Beat Bad Wi-Fi</title>
      <dc:creator>Salah Eddine Medkour</dc:creator>
      <pubDate>Thu, 01 Jan 2026 19:14:08 +0000</pubDate>
      <link>https://dev.to/salah_eddine_medkour/how-i-built-airquiz-an-offline-first-exam-server-pythonreact-to-beat-bad-wi-fi-5d67</link>
      <guid>https://dev.to/salah_eddine_medkour/how-i-built-airquiz-an-offline-first-exam-server-pythonreact-to-beat-bad-wi-fi-5d67</guid>
      <description>&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Salah Eddine Medkour&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/salah-eddine-medkour/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;My name is &lt;strong&gt;Salah Eddine Medkour&lt;/strong&gt;. I am a Technical Lab Instructor and Network Engineer in Annaba, Algeria. When the internet infrastructure failed in the labs I manage during my final university exams, I engineered &lt;strong&gt;AirQuiz&lt;/strong&gt;, a local-area network (LAN) assessment platform that operates with zero external connectivity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94zhymxyovwn35s3yemt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94zhymxyovwn35s3yemt.png" alt="AirQuiz Logo" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I teach a Master’s level Python course. The internet stability here is unpredictable. During a final exam setup for 45 students, the campus ISP dropped completely. I realized that a standard "cloud-first" deployment to Vercel or AWS was a single point of failure. I needed a system that ran entirely on local hardware.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Hardware Setup&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I had zero budget for enterprise servers. I repurposed my personal equipment to build a dedicated local node.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Server:&lt;/strong&gt; I used my &lt;strong&gt;ThinkPad&lt;/strong&gt;. The NVMe storage was the most critical component here (Not a necessity). SQLite writes are file-based, so fast disk I/O was necessary to prevent database locking during simultaneous submissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Network:&lt;/strong&gt; I utilized a &lt;strong&gt;spare router&lt;/strong&gt; isolated from the campus network. I configured a static IP for the ThinkPad and enabled a strict DHCP pool for the student devices. I physically disconnected the WAN cable to ensure the network was air-gapped and free from external interference.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Stack: Python (FastAPI) and React&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I prioritized low overhead and high concurrency over ease of development.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; I chose &lt;strong&gt;FastAPI&lt;/strong&gt; over Django. The primary reason was asynchronous request handling. When 45 clients send a POST request at the exact same second, a synchronous server often blocks threads. FastAPI uses an ASGI server (Uvicorn) to handle these concurrent connections without latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; I used &lt;strong&gt;React&lt;/strong&gt;. The application loads once on the client device. After the initial load, the network traffic consists only of tiny JSON payloads. This reduces the load on the router significantly compared to server-side rendering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Logic&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The biggest technical risk was data integrity during the "submit" event. Here is how the backend handles potential race conditions or duplicate submissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/submit-exam/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;submit_exam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExamSubmission&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Check for existing submission to prevent duplicates
&lt;/span&gt;    &lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Submission&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Submission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;already_received&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Calculate score in-memory
&lt;/span&gt;    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculate_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Commit to SQLite with low I/O overhead
&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Submission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;The Results&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We successfully deployed AirQuiz for +180 students across four separate exam sessions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Uptime:&lt;/strong&gt; 100%. The system remained stable even when the building's internet cut out twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency:&lt;/strong&gt; Consistently under 10ms due to the local loopback architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; The auto-grading feature reduced administrative work from days to seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppmpxvdsly72ppe68nir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppmpxvdsly72ppe68nir.png" alt="Students List Live" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This project reinforced that understanding network fundamentals is just as important as knowing modern cloud frameworks. By respecting the constraints of the environment and utilizing local LAN architecture, I ensured a fair and stable exam environment for my students.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/salahmed-ctrlz/AirQuiz" rel="noopener noreferrer"&gt;AirQuiz on Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>teaching</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
