20
26
Building · The · Future
● Infrastructure · Networks · Security

Emil Emilov

Infrastructure specialist · Network & Security Engineer
Open to remote & EU relocation
25+
Years experience
14
LXC containers
32
APs deployed
3
Languages
Skills
Stack $ cat /etc/skills.conf
01
Networking
TCP/IP · VLANs · MikroTik · OpenWRT · Dual-ISP · DNS/DHCP · Hotspot
Infrastructure +

Runs network operations for a full hotel property day to day, then mirrors the same patterns at home to keep the muscle memory sharp.

32 access points across a live hotel site, MikroTik RB5009 as core router
Triple-ISP failover with automatic MikroTik-side switchover and per-subnet load distribution
5 VLANs — staff/management, guest, and expandable systems/IoT segments, DHCP scaling to roughly 500 IPs
DNS/DHCP via PiHole, home lab as a testbed before touching production
RouterOS RAW-table DDoS/ICMP rate-limiting hardening across edge routers
02
Security
Firewall · Tailscale VPN · Cloudflare Tunnel · SSL/TLS · pf · Zero-trust
Infrastructure +

Inbound-closed by default — every remote path goes through an explicit tunnel or mesh, never an open port.

Tailscale mesh for all admin access, zero exposed management ports
Cloudflare Tunnel fronts every public-facing service instead of port-forwarding
RouterOS RAW-table DDoS/perimeter hardening on every edge router — closed gaps like unrestricted WAN ICMP and unscoped management-service ACLs
Diagnosed and fixed a live Tailscale routing misconfiguration causing source-IP masking that had locked out legitimate SSH access
Self-hosted Vaultwarden for credential management, 2FA everywhere it is supported
Working a structured cert path: Security+ → CySA+ → GCFE/GCFA
03
Virtualisation
Proxmox VE · LXC · KVM · Docker · Compose · Portainer · PBS
Infrastructure +

Runs a real multi-tenant Proxmox host at home the same way you would run one in a datacenter — isolated per service, backed up, monitored.

15+ LXC containers on Proxmox VE, one service per container
Migrated three live production sites off a shared web+DB pair onto dedicated per-domain containers with zero downtime
Docker/Compose layered on top where it fits better than native LXC
Automated daily/weekly backups (PBS) across tiered ZFS storage
04
Storage
ZFS · Btrfs · NFS · Samba/CIFS · Snapshots · Tiered pools
Infrastructure +

ZFS end to end — tiered pools, scrubbed and verified, sized for headroom rather than filled to the edge.

Four ZFS pools spanning ~18TB (HDD bulk + NVMe fast tier), all scrubbed clean
Samba/CIFS shares for the whole household plus dedicated dev mounts
Snapshot-based backup strategy, daily and weekly rotation
NVMe reserved for live app/container disks, HDD for media and cold backups
05
Operating Systems
Arch/CachyOS · Debian · RHEL/Rocky · Ubuntu Server · Windows Server & AD · FreeBSD · Novell legacy systems
Infrastructure +

Genuinely does not have a favorite distro — picks whichever one fits the job and stays current on the rest by actually running them.

Arch/CachyOS as daily driver, Debian underneath Proxmox and most production containers
RHEL/Rocky and Ubuntu Server for anything expecting an enterprise-standard base
Windows Server & Active Directory from hands-on hotel IT administration
FreeBSD and legacy Novell/eDirectory exposure — comfortable outside the Linux-only comfort zone
06
Development
PHP 8.4 · Python · Bash · PostgreSQL · MariaDB · REST APIs · HTML/CSS
Development +

Ships and maintains real production PHP/Python apps end to end — schema, backend, deploy, and the bug report that comes after.

Built the ARK hotel platform (events, staff, reception, kitchen — one codebase, several subdomains)
Rewrote a live Node.js/Express app to PHP 8.4 with zero data loss
PostgreSQL and MariaDB schema design, REST APIs, admin tooling
Comfortable across the full path from a bare VM to a deployed, monitored app
07
AI Engineering
LLM app design · RAG pipelines · Prompt & context engineering · Agentic tool-use (MCP) · Claude API integration · Multi-model orchestration
Development +

Treats LLMs as another service to architect around, not a black box to prompt and hope.

Designs RAG pipelines end to end — embedding model choice, indexing, retrieval, generation
Wires agentic tool-use via MCP so models can call real infrastructure, not just chat
Works daily with the Claude API and multi-agent workflows on production codebases
Thinks in context windows, tool schemas, and failure modes — not just prompts
08
MLOps / LLMOps
Self-hosted inference (Ollama) · Model selection & quantization · Embeddings & vector search · Local + hosted model routing · Eval-driven iteration · Latency/cost tradeoffs
Development +

Runs models the same way infra gets run — self-hosted where it makes sense, evaluated, and monitored.

Self-hosted inference via Ollama, running quantized models locally for cost and privacy
Deliberate routing between local and hosted models based on task sensitivity and latency
Embedding pipelines and vector search for local knowledge retrieval
Evaluates models on real tasks before trusting them in a workflow, not just benchmarks
09
Offensive Security
Authorized Web App Pentesting · XSS · IDOR · Auth/Session Testing · CVE Research · Price/Parameter Tampering
Infrastructure +

Authorized web app pentesting across checkout/payment, XSS, IDOR, account security and the full infrastructure lifecycle, tested against each platform's own known CVE history, not generic scanning.

Full authorized engagements end to end: scope and rules of engagement agreed in writing, systematic coverage of the attack surface, written report delivered and reviewed line by line with the owner
Identifies the underlying platform from its own telemetry and tests directly against its known CVE history rather than generic fuzzing
XSS tested across multiple separate rendering surfaces, IDOR across every resource type, account security and session management, file-upload handling
Root-cause investigation under live engagement conditions — traces a symptom back through logs and system state to the real mechanism, not just the first plausible explanation
Working a structured certification path: Security+ → CySA+ → GCFE/GCFA
Projects
01
Hotel Terra Europe Brontes
A full-stack hotel website rebuild — multi-language, role-based admin panel, real booking pipeline.
Ongoing +

Complete rebuild of a 4-star hotel's marketing and booking site from a static template into a real product: custom navy/gold design system, full BG/EN/TR translation layer, an interactive date-range picker, and a database-driven booking pipeline with email-verified guest submissions. Built a full internal admin panel from scratch — role-based access (Superadmin/Admin/Reception) with a content-approval workflow so front-desk staff can add photos and news posts without publishing unsupervised. Includes real SMTP email notifications, Cloudflare Turnstile bot protection, and per-IP/per-email rate limiting.

Restaurant section — table reservations, plus Lunch, Dinner and Drinks menus read live from the hotel's POS system, so the head waiter updates the website from the till.
Full i18n system — BG/EN/TR, DB-persisted for logged-in users, cookie-persisted for guests
Role-based admin panel — Dashboard, Customers, Inquiries, Rooms & Spaces, Gallery, News & Events, Admin management
Content-approval workflow — Reception-submitted photos/posts held for admin review before going live
Per-room photo galleries synced from real server folders, with a lightbox viewer
Email verification (double opt-in) for both loyalty accounts and guest bookings
Cloudflare Turnstile + custom rate-limiting against spam/abuse
Real-time SMTP notifications via PHPMailer
STACK · PHP 8 · MySQL/MariaDB · Vanilla JS · PHPMailer · Cloudflare Turnstile
PHP MySQL i18n Admin Panel

Built with CODE-OSS + Claude

02
Hotel Network Infrastructure
9-floor hotel network — 32 APs, dual ISP, 3 VLANs, captive portal with QR hotspot.
Production +

Full enterprise network design and deployment for a 9-floor hotel. Built from scratch — planning, hardware selection, installation, and ongoing management.

3 ISPs → MikroTik core router (failover + per-subnet load distribution)
32 Access Points across 9 floors (seamless roaming)
Unmanaged Gigabit TP-Link switch distributing most floors off the RB5009 core — floor 4 and the office connect directly to the router instead
5 VLANs — Staff, Guest, and three expandable Systems/IoT segments
Guest and Systems VLANs expandable per floor/zone, DHCP pools scaling to roughly 500 IPs
Captive portal with QR code scanning → instant internet access
Bandwidth management per user/device
RouterOS RAW-table DDoS/ICMP rate-limiting on the edge router, evaluated ahead of connection tracking for minimal overhead
ISP 1 PRIMARY ISP 2 FAILOVER MIKROTIK CORE ROUTER VLAN 1 STAFF / MGMT VLAN 2 SYSTEMS / IOT VLAN 3 GUEST EXPANDABLE HOTSPOT CAPTIVE PORTAL QR SCAN → ACCESS 9-FLOOR COVERAGE F0 F1 F2 F3 F4 F5 F6 F7 F8 32 ACCESS POINTS seamless roaming · band steering · VLAN tagged
STACK · MikroTik RouterOS · TP-Link switch · OpenWRT · VLANs · Hotspot
MikroTik VLANs OpenWRT Hotspot Captive Portal
03
ARK Platform — ks.vg
Multi-tenant hospitality SaaS built with Claude. Running live at Hotel Terra Europe.
Live +

A complete hospitality management platform. Multiple hotels, one login. Each property gets its own modules — Events, Counter POS, Workers, Reception. The interface is available in Bulgarian, English and Turkish. Each business sees only its own data and roles, and staff who work in more than one place switch between them. Each property can connect its own website through revocable API keys. Each module can be sold on its own, with a free trial, usage limits and a paused mode, all enforced on the server, so a client cannot unlock a module from their own side. For support, an administrator can view a business exactly as one of its staff, a role or a customer sees it; the view is look-only, enforced twice on the server (every change is refused and the database connection is read-only), and every view is logged. Client websites run live on their own ks.vg address or on the client's own domain. Orders portal customers can have agreed terms: a discount or fixed prices per product. A client's own web designer can embed the live menu or shop catalogue with two pasted lines; the key works only on the domains the client lists, with daily quotas and rate limits. The platform's move to a rented server is scripted and was rehearsed in three full dry runs, with a cutover and rollback checklist. Staff can sign in on a client's own website through a hidden key press or triple tap, see only the modules their role allows in a white-label left bar, and install the site as a phone app from the client's address, with no app store. An OAuth-style client login (authorization code with PKCE) and a small kit let a client's own site show platform data after sign-in. A rank model lets a person manage only people strictly below their rank. A security pass added login throttling, constant-time password checks, stronger password hashes upgraded at next login, origin checks, secure __Host- cookies and revoke-everyone switches, plus a cookie audit across all sites. Ten website layouts are available, and the application was renamed from ARK to ks.vg with a light default theme. From 31 October to 3 November every client got one predictable address of the form business-name.ks.vg, with a staff-only mode that closes the public site. A tenant-isolation pass closed twelve cross-business reads, and the whole platform moved without a wipe from a home server to a hardened VPS beside the mail server, with a scripted data restore checked by row counts, a tested rollback and 30-minute off-site database pulls. A public brand guide went live in English and Bulgarian. Next, the platform's real screens were ported module by module onto a client's own address through one generic mount, so onboarding a client is configuration rather than code, and a security audit closed cross-business reads in the staff, supply, POS, reception and ticket screens, backed by a two-business end-to-end test of 136 assertions. Five landing-page designs became reusable website templates.

Events — Full event lifecycle, menu planning, kitchen/waiter/client print sheets, allergen tracking, deposit management.
Counter — POS system for hotel bar, coffee shop, restaurant. Tables, orders, fiscal printer integration, end-of-shift reports. Guests can browse the menu and order from a QR code at the table. The head waiter keeps daily Lunch, Dinner and Drinks lists that feed the POS, the table QR, printable menus and the hotel website.
Workers — QR check-in/out, schedule builder, overtime calculation, payroll export.
Menus — One builder for restaurant menus, event packages and client proposals, with variants, per-person pricing and print templates. A menu is applied to an event in one step. Menus print in Bulgarian or English, with optional portion sizes and allergens. Print templates keep a long menu on one page.
Catalogue — Dishes, drinks and ingredients on one screen, with recipes, pack sizes, cost per portion and automatic shopping lists for events. Buy prices per case and per bottle, temporary supplier offers with an end date, price history and stock counts live on one Prices page, so event costing always uses the price actually paid. A dish can appear in several categories, and categories can share one heading on guest-facing menus. English dish descriptions are written from the recipes and appear in print, on the guest QR page and in the website feed.
Orders portal — A B2B ordering portal for any supplier. Customer companies register and are approved by the supplier, see prices and promotions, order for a delivery date, and can change or cancel until a cutoff time. Each customer has an account (prepaid balance, credit with a limit, or cash) with a full statement. The supplier checks every order, removes, replaces or adds items, and the customer sees exactly what changed. Notification emails go through an outbox with retry. Tested end to end; in trial on a pilot business.
Websites — Complete websites for client businesses, built from ready-made designs. Each site runs on the client's own domain with their logo and colours, while menus and the product catalogue come live from the platform, so nothing is entered twice. A new site is set up from one console in three choices. In preview; client domains come next.
Reception — Room bookings, guest check-in, Booking.com API integration. (Planned)
Housekeeping — Room status board, task assignments, consumables tracking. (Planned)
STACK · PHP 8.4 · PostgreSQL 17 · nginx · Cloudflare Tunnel · SSO tokens · Vanilla JS
PHP PostgreSQL Multi-tenant SSO Claude

Built with Claude (Anthropic)

04
Proxmox Homelab
Self-hosted Proxmox node — 14 LXC containers, 20TB ZFS storage, zero cloud dependency.
Ongoing +

Full self-hosted infrastructure running on a single Proxmox VE node. AMD Ryzen 5 5500GT, 16GB RAM, ~20TB across 4 ZFS pools. Also the proving ground for self-hosted AI infrastructure: a personal AI agent (OpenClaw), local LLM inference via Ollama on a dedicated GPU workstation with a RAG pipeline over a personal knowledge base, and an agentic dispatcher routing bash/coding tasks to local models. Recently audited the full local-model roster with real tool-calling tests (not just load-success checks) across three independent integration paths, pruned it down to a single verified-reliable model, and live-confirmed the entire chain end-to-end after reconfiguring every dependent tool. Patch levels are checked across the whole fleet: for the PHP 8.4.26 security release, every host running PHP (Nextcloud, the application containers and the standby site) was verified, and the one host still behind (the mail VPS) was upgraded to PHP 8.5.12 and re-verified. An unattended AI job runner lives in its own unprivileged container: it sees only one folder of my notes vault through a dedicated Nextcloud user, runs Claude Code jobs from queued job notes with a tool allow-list and time and turn limits, writes its results back and reports every run by Telegram. Its first job produced the school reference cards for pi.gd (13 subjects, about 770 topics, 28 runs); when its sync stalled I traced it to stale Redis file locks (423 Locked) and cleared them.

Nextcloud — Family file sync, calendar, contacts
Immich — Photo library with ML face recognition
Jellyfin — Media server (1.4TB TV, 217GB movies, 406GB music)
Vaultwarden — Bitwarden-compatible password manager
Gitea — Self-hosted Git
Pi-hole — Network-wide DNS ad blocker
Tailscale — Mesh VPN secure remote access
NPM — nginx reverse proxy manager
cloudflared — Cloudflare tunnel (zero open ports)
PostgreSQL 17 — Main DB server
MariaDB — Secondary DB
STACK · Proxmox VE 9.1 · Debian 13 · ZFS · PBS · LXC · Docker · Ollama
Proxmox ZFS LXC Self-hosted Docker Ollama LLM
05
Cloudflare Zero-Trust Stack
Zero open ports. All public traffic via Cloudflare Tunnel. Complete zero-trust ingress.
Live +

Every public-facing service runs through Cloudflare Tunnel — no ports open on the firewall. DNS managed via Cloudflare, wildcard certificates, DDoS protection built in. Administrative/management access on the router side gets the same zero-trust treatment: no exposed management ports, and every edge router is actively hardened and audited, not just configured once.

cloudflared daemon in LXC → outbound tunnel to Cloudflare edge
NPM (nginx Proxy Manager) → routes by hostname
Zero inbound firewall rules needed
Wildcard SSL — *.ks.vg, *.edemilov.com, *.pi.gd, *.mr.photos
Cloudflare WAF + DDoS mitigation
Multiple domains: ks.vg · edemilov.com · pi.gd · mr.photos
MikroTik RAW-table DDoS/ICMP rate-limiting on the home and hotel edge routers, evaluated before connection tracking for minimal overhead
Router management services (API/reverse-proxy) locked to LAN-only, default admin accounts disabled
Diagnosed and fixed a live Tailscale accept-routes misconfiguration that was silently tunneling local LAN traffic through a subnet-router container, masking source IPs and tripping SSH brute-force protection — root-caused via systematic elimination (firewall rules, intrusion-prevention state, and router ACLs all ruled out using live packet capture) down to routing-table priority, then confirmed as a genuine fleet-wide issue by finding and fixing the identical bug a second time, on a different machine
Onboarded a new domain through the full stack end-to-end (Cloudflare zone → Tunnel ingress → reverse-proxy vhost → Let's Encrypt certificate) and found two platform-level bugs doing it: a Tunnel wildcard ingress rule silently doesn't match the bare apex domain (present on the other live domains too, just masked by an unrelated redirect), and forcing TLS at the reverse-proxy layer behind a tunnel that always speaks plaintext to origin causes an infinite redirect loop — both root-caused and fixed same-day
Root-caused a router listing itself as one of its own two upstream DNS forwarders, producing intermittent resolution failures that looked like propagation lag but weren't — fixed via the router's REST API
STACK · Cloudflare · cloudflared · nginx · NPM · Let's Encrypt · MikroTik RouterOS
Cloudflare Zero-trust nginx SSL Tunnel
06
WalletPi — Personal Finance Tracker
Wallet — focused micro-walle
Live +

A full-featured multi-user personal finance tracker — accounts, categorized transactions, recurring bills, and a dashboard that actually separates real cash from available credit. Manual entry by design, so it needs no bank API connections or PCI-level security surface.

Multi-account tracking — bank, cash, savings, credit card, and crypto accounts side by side
Credit card intelligence — limit, due date, minimum payment, and a live utilization bar, not just a balance
Recurring bills — subscriptions, leases, salary, on any schedule from daily to yearly, auto-generating transactions
Dashboard that separates "my money" from available credit, plus a 30-day upcoming view and card-payments-due panel
Multi-user with an admin-approval flow — first account becomes admin, everyone after needs sign-off before they can log in
Full EN/BG/TR interface
Manual entry only, by design — no bank/card API connections, so the security surface stays simple
STACK · PHP - PostgreSQL - Nginx
07
Personal Notes
A private space for markdown notes, code snippets, and technical references.
Live +

A private, invite-only space for markdown notes, code snippets, and technical references — rewritten from a live Node.js/Express app to PHP 8.4 with zero data loss. Each note is public or private, taggable, and searchable, with an admin panel for issuing invite codes instead of open registration.

Rewrote a live Node.js/Express app to PHP 8.4 in place, migrating the PostgreSQL schema (users, notes, tags, attachments, invites) with zero data loss
Per-note public/private visibility, so individual references can be shared without opening the whole notebook
Full tag system with filtering — 40+ tags across a real, actively-used note collection
Invite-only registration — admin generates and revokes invite codes instead of open sign-up
Markdown rendering with code-block support, built for technical reference notes and snippets
php - sql
08
pi.gd — Personal web platform with one login
A bilingual site built from scratch in plain PHP and PostgreSQL: Tech, Tools, a family blog and school reference pages, with one account and tool-access system shared by all its small apps.
Live +

Designed and built, from a written spec and a 14-task plan, the site behind pi.gd: a bilingual (Bulgarian and English) platform with a Tech section, a Tools section, a blog run by a family member as editor, and school reference pages for my children. Plain PHP 8.4 and PostgreSQL with no framework and no CDN, live since 14 October 2026.

Tech: Linux distro picks with a nightly DistroWatch top 10
Tools: the CV Builder, a finance tracker (by invitation) and a calculator, all on one login
Ay's Corner: a blog with hashtags and full-text search that also works in Cyrillic
School: maths and physics cards for grades 6 to 9 with step-by-step worked examples
Accounts with verified email and five levels (user, superuser, moderator, editor, admin) enforced on the server; staff log in with two-factor codes, encrypted secrets, recovery codes and replay protection
One login for every tool: each tool is a module that is either open or restricted. For a restricted tool a user asks for access and a moderator approves it, or the user enters a one-time invite code that is stored hashed, valid for 14 days and works once
A rich-text editor with hardened image uploads (re-encoded, EXIF applied and then stripped) and moderated comments with a first-comment trust rule
Staging and live are two checkouts of the same repositories with separate databases and session stores; publishing is a fast-forward merge plus database migrations, backed by nightly database dumps with a restore test
Built task by task with a fresh AI agent per task and an independent security review after each, backed by 262 unit tests and a 328-check end-to-end test. The reviews caught real problems before any user could: login timing that revealed which emails have accounts, an account hijack through re-registration, a test runner that could empty a live database, and a sanitiser that corrupted pasted text
The database uses a locale that cannot lower-case Cyrillic, so search keeps its own lower-cased copy of every post
Ay's Corner also has a natal chart calculator (Swiss Ephemeris astronomy, AGPL source linked per its licence) and a tarot reading tool with three spreads, saved readings for signed-in users, and an original hand-drawn card back used across the spread picker and a face-down-to-face-up reveal animation. Every night it also publishes a daily zodiac post: one card for each of the twelve signs.
Redesigned the whole site in place on 31 October and 1 November 2026, with every old design kept under /old/: a start page of four strips that take on the look of their section on hover, a floating top dock instead of a side menu, a corkboard School, a drifting starfield behind most pages, and a Tech section in the style of the btop and htop terminal monitors. Also built ip.pi.gd, a "what is my IP" tool with a DNS resolver test backed by a small authoritative DNS server I wrote.
On 2026-11-04 the start page went live in a new form: a plain list of the four sections on the left and, on the right, the real page of whatever you point at, shown live and scaled to fit; a click grows it into the full window while the list stays in place (keyboard, Back and Esc all work, and phones get a tap-to-open flow). Framing is limited to the site's own hosts by a content-security policy, and the previous start page stays browsable under /old/. The same day School grew from five subjects for grades 5 to 9 to thirteen subjects for grades 5 to 10: about 770 expandable topic cards in Bulgarian with English explanations, drafted from the Ministry of Education programmes by an unattended AI agent (see Proxmox Homelab) and published with a note to check them against the textbook.
STACK · Nginx · PHP 8.4 · PostgreSQL · TOTP · Cloudflare
PHP 8.4 PostgreSQL Security Two-factor login Cloudflare

Built with Claude (Anthropic)

09
hyprevo — Hyprland+DMS Installer
Public one-command installer for a full Hyprland + Quickshell/DMS Linux desktop, with an interactive app picker instead of a fixed bundle.
Live +

A public, Arch-only (pacman, no AUR) one-command installer that sets up a full Hyprland + Quickshell/DMS desktop environment from scratch. Modeled on Proxmox's community helper-scripts: an interactive whiptail picker (terminal, file manager, mail client, cloud sync as single-choice radiolists, plus an independent checklist for extras) instead of a fixed opinionated bundle, with picks wired into a separate extras.conf so the base hyprland.conf stays clean. Built test-first with bats unit tests and shellcheck before any live run, then hardened through a second person live-installing it in a fresh VM, which surfaced real bugs invisible from local testing alone.

Terminal — Konsole / Terminator / Kitty / Alacritty
File manager
Mail client
Cloud sync
Extras — Telegram, screen capture, Bitwarden (independent toggles)
STACK · Bash · whiptail · bats · shellcheck · Gitea
Bash Hyprland Wayland Quickshell/DMS bats shellcheck

Built with Claude (Anthropic)

10
Self-Hosted Mail Server — pi.gd / ks.vg / edemilov.com
Self-hosted mail platform for 3 domains — Exim/Dovecot, DKIM/SPF/DMARC, verified real send/receive both directions.
Live +

Built and hardened a full self-hosted mail platform (HestiaCP: Exim, Dovecot, ClamAV, SpamAssassin, DKIM/SPF/DMARC, Roundcube webmail) on a dedicated VPS, replacing a forward-only Cloudflare Email Routing setup with real send and receive for all 3 domains and 9 live mailboxes.

Correctly wired the full deliverability chain — PTR/HELO/hostname identity, DKIM, SPF, DMARC — matched across mail server and DNS
Verified end-to-end with real Gmail round-trip tests in both directions across all 3 domains, confirmed landing in the inbox (not spam) on a zero-reputation fresh IP
Ran a full security pass: own audit plus an independent DeepSeek second opinion fed the real config
Found and closed a live SSH password-auth bypass around existing passwordless-sudo hardening
Found and closed FTP cleartext logins for a sudo-capable system account, and unnecessary BIND public exposure
Rotated every panel/mailbox/system credential
Gated the admin panel behind Tailscale while keeping public-facing services — webmail, SMTP, IMAP — open by design
STACK · HestiaCP · Exim · Dovecot · ClamAV · SpamAssassin · DKIM/SPF/DMARC · Roundcube · Tailscale
HestiaCP Exim Dovecot DKIM/SPF/DMARC Roundcube Tailscale
11
Media Automation Pipeline — Sonarr/Radarr/qBittorrent
Root-caused a silent two-day access-control misconfiguration that had disabled all automated downloads across three services, fixed cleanly, replaced with safer automation.
Live +

Diagnosed a subtle, silent access-control misconfiguration that had disabled every automated download across three services (Sonarr, Radarr, Lidarr) for two full days with no visible error — a well-intentioned but mistaken tag-based routing scheme had tagged both the indexers and the download clients, which independently gate on the content's own tags rather than on each other, so nothing was ever tagged and every indexer/client silently went unusable.

Traced from a vague symptom (playback issues on some downloaded files) through a quality-profile misconfiguration — most of the library was on an unrestricted profile instead of the intended capped one, letting oversized/incompatible releases through
Found the real root cause via direct application log inspection ("0 active indexers" on every search), not guesswork — confirmed empirically before touching any config
Fixed the tag-based routing mistake across all three apps (Sonarr, Radarr, Lidarr), restoring normal automated search and download immediately
Replaced the original broken automation idea with a safer systemd-timer-based cleanup job that only ever acts on state the download client has already independently confirmed is safe to reclaim, rather than guessing at source-based rules
Verified the fix end-to-end with real grabs completing successfully, not just config validation
STACK · Sonarr · Radarr · Lidarr · qBittorrent · systemd timers · Python
Sonarr Radarr Lidarr qBittorrent systemd Debugging
12
mr.photos — Kids' Art Gallery
Public museum-style gallery for children's artwork with verified sign-up, moderated uploads and comments, and a trust system — built spec-first with independent per-task reviews and a whole-codebase security review before launch.
Live +

Designed, built and deployed a public online museum for children's drawings and paintings: anyone can browse, registered users upload, and every picture is approved by a moderator before it is shown. Plain PHP 8.4 and PostgreSQL with no framework, a Bulgarian/English interface, and a landing page where gold-framed pictures orbit an empty, lit centre like Saturn's rings.

Went from idea to written spec to a 14-task implementation plan, then built it task by task with a fresh AI agent per task and an independent code review after every task — 180 automated tests
Accounts with mandatory email verification, password reset and three roles (user, moderator, admin); one moderation queue for pictures and comments, a trust rule that lets proven commenters skip the queue, an email digest for moderators, and nothing ever hard-deleted
Child safety and privacy first: uploads are re-encoded to strip EXIF/GPS location data, unapproved pictures return 404 to everyone except their owner and moderators, public placards show only a first name and age, and parents can withdraw their child's picture at any time
A final whole-codebase security review found real problems before launch — out-of-memory risk from parallel large uploads (image decoding serialised with a lock), an open redirect through tab characters, sessions surviving a password reset, and a missing mail timeout — all fixed and re-reviewed
Deployed to its own Proxmox container behind Cloudflare Tunnel, with outgoing mail DKIM/SPF/DMARC-aligned through the self-hosted mail server, and verified with a 34-step live acceptance run using real email
STACK · PHP 8.4 · PostgreSQL 17 · nginx · GD · PHPMailer · PHPUnit · Proxmox LXC · Cloudflare Tunnel
PHP 8.4 PostgreSQL Security i18n Proxmox Cloudflare Tunnel

Built with Claude (Anthropic)

13
CV Builder — pi.gd/cv
Public CV-builder tool with a multi-step wizard and five print-ready A4 designs, built spec-first with independent reviews. Since October 2026 CVs belong to a pi.gd account.
Live +

Designed and built a public CV-builder feature from scratch on the site's own plain PHP 8/PostgreSQL stack, with no framework: a card-gallery landing page, a multi-step wizard (about, experience, education, skills, languages, summary), a clean print-ready view, and, since October 2026, ownership through the shared pi.gd account (at first account-free, with a cookie and an email magic link for recovery).

Built spec-first: design spec, then an implementation plan, then subagent-driven development with an independent code review and fix loop after each task
Share links and edit rights are separate secrets, so a shared view link can never grant edit access; the recovery flow answers identically whether or not an email matches, so it cannot be used to find out who has a CV
The final whole-branch review caught five real defects before users did — a broken photo upload, a dead Save button, a wrong claim-email link, a silently dropped email field and a swallowed mail error
The fix for those then broke the wizard itself (a checkValidity() call on a plain div) — caught only because the re-review clicked through the page in a real browser instead of relying on curl checks
Added five selectable print-ready A4 designs with a thumbnail picker and a live design switcher, fixed stale CSS caused by Cloudflare edge caching with mtime-based cache-busting, and re-themed the admin panel from dark to a light pastel palette
Moved onto the shared pi.gd login: CVs now belong to the user's account, a CV made earlier with the cookie or email link moves into the account the first time its holder signs in, and guests only see three example CVs of invented people, never a real person's CV
STACK · PHP 8 · PostgreSQL · HTML/CSS print layouts · Cloudflare
PHP 8 PostgreSQL Print CSS Security Cloudflare

Built with Claude (Anthropic)

14
Legacy System Virtualisation (P2V)
Moving a hotel's core PMS and POS systems off ageing physical hardware onto Proxmox, with zero-interruption backups and host problems found and fixed before any restore.
In progress +

Migrating the hotel's core operational software — a property-management system and two point-of-sale/restaurant systems — off ageing physical hardware onto Proxmox virtual machines, without interrupting the live systems the hotel runs on every day.

Standard vssadmin shadow copies turned out to be unsupported on the source machine's Windows edition; engineered an alternative through the WMI Win32_ShadowCopy.Create API under a SYSTEM scheduled task — the same mechanism commercial backup tools use — for a clean copy of in-use databases with zero service interruption
Completed the full source backup, including a 91.8 GB VHDX image of the C: drive pulled over the hotel LAN, and identified three USB licence dongles that will need passthrough in the target VM
Before any restore, found the test VM's 931 GB thin disk sitting on a 348 GB thin pool — 2.7× over-committed, enough to freeze every guest on the host — and recovered headroom with a second LVM-thin pool, byte-verified data moves and fstrim (66% → 34% used)
Found the host's uplink capped at 100 Mbit with 30–40% packet loss by an in-line extender; replaced it with a repurposed MikroTik router set up as a pure Layer-2 switch, giving 1 Gbit with 0% loss
The faster link exposed a known Intel e1000e "Hardware Unit Hang"; recovered the host remotely by bouncing its switch port, then fixed it permanently by disabling TSO/GSO/GRO offloads in the host's network config
STACK · Proxmox VE · LVM-thin · Windows VSS/WMI · VHDX · MikroTik · Linux networking
Proxmox LVM-thin Windows VSS/WMI MikroTik Networking
15
Security Monitoring & Honeypot
Central logging, Telegram alerts, automatic blocking of attackers, an SSH honeypot and internal decoy servers across a homelab, a hotel network and a public mail server.
Live +

Central security visibility for a homelab, a hotel network and a public mail server. Every server and router sends its logs to one place, alerts arrive on Telegram, known attackers are blocked automatically, and a honeypot records what attackers do once they think they are in.

Logs from two Proxmox hosts, 18 containers, a mail server and two MikroTik routers are collected in Loki and kept for 30 days. RouterOS syslog over TCP lacks the trailing newline that Promtail needs, so the routers send UDP through rsyslog relays
Fourteen Grafana alert rules report to Telegram: bursts of failed logins, router login failures and configuration changes, logins from unknown devices, log sources that go silent, touches on the decoy servers and automatic login bans. The rules were tuned after the first day so that only actionable alerts fire
CrowdSec on the reverse proxy: the websites sit behind a Cloudflare Tunnel, so the proxy was configured to trust the real client IP address, and bans are synced into an nginx deny list. Tested end to end with a simulated scanner
CrowdSec on the mail server with an nftables bouncer in its own tables, leaving the control panel's own firewall untouched, plus a custom parser for its Dovecot log format
A Cowrie SSH honeypot answers on port 22 of the mail server, while real SSH runs on another port and outbound traffic is blocked for the honeypot user. It logged more than 500 attacker IP addresses and about 34,000 sessions in the first three days
Internal decoys: on the hotel and the home network an OpenCanary container poses as a NAS with SSH, FTP, telnet and a web login. Nobody has a reason to touch it, so any touch raises an alert naming the device. Each MikroTik router passes attempts on its own FTP and telnet ports to the decoy and logs the device's IP and MAC address. Built the same afternoon an unknown laptop tried anonymous FTP on the hotel router
Automatic login bans: fail2ban on both Proxmox hosts for SSH and the web panel, and on both routers a RouterOS script that reads the router's own log and bans a source for one hour after three failed logins, with an explicit never-ban list for the administrator's own machines
STACK · Loki · Promtail · Grafana · rsyslog · CrowdSec · nftables · Cowrie · OpenCanary · fail2ban · MikroTik RouterOS · Telegram
Loki Grafana CrowdSec Cowrie OpenCanary fail2ban MikroTik
16
Automatic Site Failover: Home to Off-Site Standby
When the home server goes dark, a standby at a second site takes over the public websites and the password manager within three minutes, and hands the data back when home returns.
Live +

A power cut at home took every public website and the password manager offline, and no copy of the data existed anywhere else. Now a standby container at a second site keeps a copy that is at most two minutes old, takes over by itself when the home server disappears, and returns everything, including what was written in the meantime, when the home server is back.

The home Proxmox host sends database dumps (PostgreSQL and MariaDB), site files, uploads, nginx and PHP settings and the password manager's database to the standby every two minutes, using a key that can only write into one folder. The standby restores only what changed and keeps the last good copy if a restore fails
No DNS change during a takeover: the standby runs a second connector for the same Cloudflare Tunnel, normally stopped. A watchdog starts it only when Cloudflare itself reports for three minutes that the tunnel has no connector, which also proves that the standby's own internet connection works
Protection against both sites serving at the same time: the home connector no longer starts by itself. A gate service opens it only when the standby is idle, and stops it after two minutes without a connection to Cloudflare, before the standby would take over
Automatic return: when the home server is back, it asks the standby to stop, restores only the databases that differ, fetches only the files written during the outage, and saves every replaced copy first
Proven with real outage tests on the live websites: the standby took over 2 minutes 39 seconds after the home connector stopped, the return took about 40 seconds, and test records written on the standby arrived at home. The first test exposed a mistake: the watchdog was watching an address that Cloudflare redirects by itself, so it never saw the outage. It was fixed and tested again within the hour
Telegram messages on takeover, on return and on errors are sent from the second site, because the monitoring system itself runs on the home server
STACK · Proxmox · LXC · Cloudflare Tunnel · nginx · PHP-FPM · PostgreSQL · MariaDB · Vaultwarden · rsync · systemd · Bash · Tailscale · Telegram
Proxmox Cloudflare Tunnel PostgreSQL High availability Bash systemd
17
External Security Assessment — VPS/VDS Hosting Platform
Two rounds of an authorized security test on a friend's live VPS hosting platform — real findings, real fixes, each round reviewed and acted on the same day.
Completed +

Two rounds of an authorized security assessment of a friend's live VPS/VDS reseller platform (a Paymenter-based client panel plus a provisioned test VPS), end to end, each delivered as a full written report.

Round 1: systematic coverage of the checkout/payment flow, XSS across three separate rendering surfaces, IDOR checks across servers/tickets/invoices, account security, file-upload handling and the full VPS lifecycle, each verified against real system state rather than trusted from the admin panel
Identified the platform from its own telemetry and tested directly against its known CVE history: a checkout-parameter price/plan injection and a critical ticket-attachment arbitrary-file-upload RCE class, both confirmed already patched
Found and root-caused one real bug: a VPS restart action was silently regenerating SSH host keys and discarding a customer's hostname customization, traced from host-key timestamps and cloud-init logs to the platform pushing hostname changes through to the hypervisor's VM name; fixed by the owner the same day
Round 2: subdomain enumeration, exposed source-control/environment files, CORS policy, SPF/DKIM/DMARC email authentication, Laravel debug-route exposure, a specific CVE check against a payment-webhook SSRF class, and login rate-limiting
Login rate-limiting tested live against the real login form in a browser rather than by replaying raw requests, since it runs through a JavaScript framework rather than a plain form target; confirmed an invisible bot check and the framework's own throttling both active together
One further low-severity finding (a publicly readable but harmless configuration file) and a recommendation to tighten the domain's email-authentication posture, relevant to a hosting brand's own phishing exposure
Both rounds reviewed line by line by the platform owner, with findings acted on the same day each time
STACK · Paymenter · Laravel · Livewire · Proxmox · KVM · nginx · Cloudflare
Security Pentest Web App Testing
Experience
Oct 2021 — Present
Terra Europa Hotel — BRONTES BC
Targovishte, Bulgaria
Assistant Manager & IT Infrastructure Lead
Full hotel network design & deployment. Proxmox virtualisation. Full-stack hospitality platform (ARK/ks.vg). Mixed OS environment. Level 1–3 support across all departments.
2007 — 2021
Self-employed
United Kingdom
Freelance IT Support & Various Roles
Freelance PC repair and computer troubleshooting for private clients, alongside non-IT work (driving, delivery, taxi) in the UK.
2006 — 2007
Synovate Global Market Research
Istanbul, Turkey
Expert IT Services — ARGE / IT Specialist
Large-scale server infrastructure for global market research. Server hardware, OS administration, data integrity, internal network support.
2005 — 2006
TEN Underwear
Istanbul, Turkey
Expert IT Services Specialist
Expert-level IT support across Windows and Linux in manufacturing & retail environments.
2002 — 2004
Locomotif IT Services
Istanbul, Turkey
IT Services & Web Design Specialist
IT services, web design, and project delivery. Dreamweaver, Fireworks, Flash, Photoshop.
1997 — 2001
Kale / DMS / Anet Communication
Istanbul, Turkey
Technical Specialist & IT Support
Hardware diagnosis, repair, assembly. ISP first-line support during the formative period of consumer internet in Turkey.
Get in
Touch

Open to full-time roles in Network Engineering, Security, or DevOps/Infrastructure.
Available for remote work and EU relocation.