Hien Portfolio
Luong Minh Hien · Software & systems engineer

Software & Systems Engineer. Network / Linux. Indie Game Developer.

I build systems end to end: C++ firewall software for Linux network appliances that protect critical-infrastructure and OT networks, from the packet path to HA and the Web UI. On the side I ship web products for brands and games on Steam.

Game
Network securityDPI · IDS/IPS · VPN · NAT
Systems engineeringLinux appliances · HA · performance
WebReact · Next.js · Django · Payload
GamesC# · 3 titles on Steam

About Hien.

I'm Hien, a software and systems engineer at OPSWAT. I write C++ and Python for Linux firewall appliances that protect industrial networks, and on the side I build web products and games.

Based in
Ho Chi Minh City, Vietnam
Now
Software Engineer I · OPSWAT
Education
B.Sc. Information Technology, High-Quality Program · VNUHCM University of Science, 2026
Languages
Vietnamese · English (TOEIC 905)
Evidence board hover · click
Luong Minh Hien receiving the OPSWAT Employee of the Year 2025 award
Employee of the Year 2025
Salad First kiosk game at the NLU event
Salad First · on site, 2025
BrightStudio winning at Vietnam GameVerse 2024
GameVerse '24 champion
Luong Minh Hien during university
HCMUS · B.Sc. IT, 2026
BrightStudio team at Vietnam GameVerse 2024
BrightStdio · GameVerse team
Stack
Languages
C++TypeScriptJavaScriptPythonC#Rustlimited
Systems & network
LinuxNFQUEUEiptables / nftablesTCP/IPDPI · IDS/IPSVPN · NATFRR · OSPF · RIPVRRPVLAN / STPtc · QoSgRPCtshark
Web
ReactNext.jsDjangoTornadoREST APIsPayload CMSGatsbyWordPress
Data
PostgreSQLRedisMongoDBNeo4jSupabase
Ops & tools
DockerGitVPSCloudflare CDNClaude CodeOpenAI Codex
Games
UnityGame AIGame design
Recognition & certificates8
Recognition
2025Employee of the YearOPSWAT
×3Employee of the QuarterOPSWAT
2024ChampionTopebox Accelerator · GameVerse
2024Top 3HackHCMC · Social Responsibility
Certificates
905TOEICout of 990
PACEGrowth MindsetPACE Institute of Management
PACECritical ThinkingPACE Institute of Management
PACEPresentation & CommunicationPACE Institute of Management
01 / Experience

OPSWAT

Intern → Associate → Software Engineer IMay 2024 – Present

Firewall software for OT networks, from Web UI to data plane.

C++ and Python on Linux appliances (4P, 8P, 1U) that sit between a plant's OT network and the IT side. Click a stage or scroll to see each feature.

  1. 01Web UI & migrationintern →
  2. 02DPI for OT protocolsassociate
  3. 03IDS / IPSassociate
  4. 04VPNSE I
  5. 05NATSE I
  6. 06Routing & ARP detectionSE I
  7. 07High availabilitySE I
  8. 08QoS shapingSE I
  9. 09Monitoring & captureSE I
OT NETWORK IT NETWORK PLCModbus RTUDNP3 Field IOProfinet SCADA Eng. WS Internet Web UIReact + Django REST · monitoring · capture HA · VRRP · gRPC sync over WireGuard Node A · master Node B · backup
allowed trafficattack, dropped at IPSclick a stage to open its feature
1–9 Gbpsthroughput validated
52,000+IDS/IPS rules
300+merged PRs
EoY 2025+ 3× Employee of the Quarter
Scroll for each feature
01 / 09 · Intern → now

Owned the Web UI and moved it to React.

Became primary owner of the appliance's Web UI and led the migration off Tornado, then wired every network feature into the new stack.

Before
Tornado templates
After
React + Django REST
Covers
Firewall, DPI, VPN, routing, monitoring
https://appliance.local/dpi
DPI · OT protocolsApply
Modbus TCPread ✓ · write ✗
DNP3allow
MQTT-SNallow
Profinet IOinspect
LLC / 802.3off
Tornado→React + Django REST· UI → config → data-plane reload
02 / 09 · Associate

Deep packet inspection for OT protocols.

End-to-end DPI from the UI down to the data-plane reload, plus C++ parsers in the packet-processing engine that read industrial protocols field by field.

Protocols
Modbus, DNP3, MQTT-SN
Parsers
Profinet IO, LLC / IEEE 802.3 (C++)
Decides
Allow or block per function code
10.0.2.15:49152 → PLC 10.0.1.10:50212 bytes
MBAP headerPDU
03 / 09 · Associate

Signature IDS/IPS with 52,000 rules.

Packets come off NFQUEUE, go to the engine through a request ring, and come back with a verdict through a second ring. If the engine is down, traffic keeps flowing: the plant matters more than the alert.

Catalog
ET Open, 52K rules
IDS
Out-of-band, alerts only
IPS
Inline via NFQUEUE, fail-open
Hand-off
Two rings: REQ (packets) and VER (verdicts)
Tested
On lab appliances
Hand-off: two rings, one per direction10 of 1,024 slots shown
REQ
VER
Why two rings

Each ring has exactly one writer and one reader. The worker owns req_head and ver_tail, the engine owns req_tail and ver_head. No index is written by both sides, so no lock is needed.

Why a ring

1,024 slots allocated once, one L3 packet (≤ 2048 B) per slot, so no allocation per packet. Each verdict carries the packet's seq, so the worker applies PASS or DROP to the right packet.

head == tail · head + 1 == tail

Equal means empty: the reader has nothing and waits. Full is head + 1 == tail: one slot is left unused so full and empty never look the same.

04 / 09 · Software Engineer I

Route-based IPsec and OpenVPN.

Sites connect through an IPsec tunnel that behaves like a normal interface, so the routing table decides what goes into it. The appliance can also dial out as an OpenVPN client.

IPsec
Route-based, xfrm interface
Selects by
Route, not per-policy selectors
OpenVPN
Client mode
Plant A10.0.0.0/24 HQ172.16.0.0/16 xfrm0 · IPsec tunnel route 172.16.0.0/16 dev xfrm0
inside the plant
IP 10.0.0.25 → 172.16.4.9TCP 502Modbus
on the internet
IP 203.0.113.10 → 198.51.100.20ESPencrypted · IP · TCP · ModbusICV
05 / 09 · Software Engineer I

NAT: DNAT, SNAT and 1:1.

Publish an internal service, hide a subnet behind one address, or pin a device to its own public address. Replies are translated back from connection tracking.

DNAT
Inbound · rewrite destination
SNAT
Outbound · rewrite source
1:1
Fixed pair, both directions
DNATpublish a server
src 198.51.100.7dst 203.0.113.10:443
→
src 198.51.100.7dst 10.0.1.20:443
SNAThide a subnet
src 10.0.0.25dst 198.51.100.20
→
src 203.0.113.10dst 198.51.100.20
1:1one device, one IP
src 198.51.100.7dst 198.51.100.5
⇄
src 198.51.100.7dst 10.0.2.5

Highlighted field = what the firewall rewrites. The reply takes the reverse mapping automatically.

06 / 09 · Software Engineer I

Dynamic routing and ARP spoofing detection.

FRR runs OSPF and RIP so the firewall learns routes from its neighbours, alongside static routes. On the same segments it watches ARP and flags an IP that suddenly answers from a different MAC.

Dynamic
OSPF, RIP via FRR
Static
Default and fixed routes
ARP
Detect an IP claimed by a new MAC
R1 FW R2 R3 FULLFULL RIP OSPF area 0
PrefixVia
O172.16.0.0/1610.0.0.2 [110/20]
R192.168.5.0/2410.0.0.3 [120/2]
S0.0.0.0/0203.0.113.1
C10.0.0.0/24eth1
ARP watch · eth1IP → MAC
10.0.0.100:1b:21:3a:4f:01gateway · known
10.0.0.200:1b:21:3a:4f:02R1 · known
10.0.0.1de:ad:be:ef:00:66new MAC for a known IP
ARP spoofing suspected · 10.0.0.1 claimed by 2 MACs
07 / 09 · Software Engineer I

Failover that keeps the plant connected.

When the master fails, the virtual IP moves to the backup and its config is already in sync. I hardened the sync path and removed a job backlog.

Failover
VRRP, virtual IP
Sync
gRPC over a WireGuard tunnel
Fixed
Hardened apply path · coalesced queued jobs
UI
Cluster page
Node A ● MASTER ✕ DOWN Node B ○ BACKUP ● MASTER VIP 10.0.0.1 VRRP heartbeat gRPC config sync · WireGuard master fails → VIP moves → traffic continues
queued config jobs→ coalesced →1 apply
08 / 09 · Software Engineer I

Per-rule traffic shaping down to 5 Kbps.

Each firewall rule can carry a bandwidth policy. Its packets get a mark in iptables mangle, tc sends that mark to the rule's own HTB class, and the class's token bucket holds it to the rate.

Classify
iptables mangle · MARK per rule
Queue
tc HTB class per rule · rate + ceil
Floor
5 Kbps
Also
Packet-rate limits in the C++ engine
  1. firewallrule #12 match
  2. mangleMARK 0x12
  3. tc filterfw → 1:12
  4. HTB class1:12 · 5kbit
  5. egresseth1
root 1: htb · eth1 1:1 · uplink 100mbit 1:10 · SCADArate 2mbit ceil 10mbit 1:11 · camerasrate 20mbit ceil 50mbit 1:12 · guestrate 5kbit ceil 5kbit
09 / 09 · Software Engineer I

Live traffic monitoring and packet capture.

The packet engine hands packets to one reader over a Unix socket file. The reader writes them into a capped Redis Stream, and every viewer reads the stream from its own position, so a slow browser falls behind instead of blocking the others.

Connect
Unix domain socket file from the engine
Fan-out
Redis Streams · 1 reader → up to 5 viewers
Safety
Capped stream (MAXLEN), per-viewer read position
Capture
Background, file rotation, disk-limit guard
Packet engineC++ · data plane Reader1 shared unix socket /run/monitor.sock Redis Stream · XADD MAXLEN ~ N -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 old entries trimmed ← · → newest viewer 1last id -42 viewer 2last id -40 viewer 3last id -43 viewer 4last id -34 viewer 5last id -41 XREAD BLOCK from each viewer's last ID · slow viewer lags, nobody waits reader also writes capture/ in the background cap-0001.pcap cap-0002.pcap cap-0003 ● rec disk limit → rotate
02 / Experience

BrightStdio

Freelance Web & Game DeveloperNov 2021 – Present YouTube

From a client's brief to a product that's live.

A small studio working with brands, media and partners like PhuotLuon.vn, Không Che and Algorithmics. I take the input, write the proposal, get sign-off, build, and keep it running.

  1. 01Briefinput
  2. 02Proposalscope · plan
  3. 03Web productsNext.js · Payload
  4. 04Real-time displaysSupabase
  5. 05GamesC# · Steam
  6. 06Ship & supportlive
Clients & productssince 2021
Kewpie Vietnamweb · brand
VTV / HTVweb · media
IIDPayload CMS · performance
iSEEweb
Biscoo · Bida.vnreal-time displays
PhuotLuon.vnpartner
Không Chepartner
Algorithmicspartner
3 indie gamesSteam · C#
9clients & partners
3games on Steam
ChampionGameVerse 2024
Top 3HackHCMC 2024
Scroll through a project
01 / 06 · Input

Listen to the brief.

Goals, audience, budget and references. The questions asked here decide what the proposal can promise.

Collect
Goals, users, budget, deadline
Output
Requirements the client agrees with
Messages · new clientMon 09:12
We need screens in our venues that show ads in real time.
How many venues, and who updates the content?
Around 40. Our marketing team should change ads from a dashboard.
Got it. Proposal by Thursday.
Requirements40 venuesChange ads liveNon-technical adminsKeep playing if offline
02 / 06 · Proposal

Turn it into a proposal.

Scope, stack, milestones and price, written so the client can say yes or point at exactly what to change.

Includes
Scope, stack, milestones, estimate
Format
Versioned PDF
proposal-v1.pdfpage 1 / 4
Real-time ad display system
ScopeAdmin dashboard, display client, schedulingStackNext.js · Supabase realtime · Docker on VPSEstimateFixed price per milestone
MilestonesW1W2W3W4W5W6
M1 · Dashboard
M2 · Display client
M3 · Rollout
03 / 06 · Build · Web

Web products for brands and media.

Editors manage content in a CMS, the site is built with Next.js or Gatsby, and everything runs in Docker on a VPS. For IID I reworked the production site on Payload CMS to make it faster.

Clients
Kewpie Vietnam, VTV/HTV, IID, iSEE, PhuotLuon.vn, Không Che, Algorithmics
Stack
Next.js, Gatsby, WordPress, Payload CMS
Hosting
VPS · Docker
editorsPayload CMS
buildNext.js
VPSDocker · Nginx
visitorsBrand site
brand-site.vn
New flavour, same kitchen.Campaign landing · CMS-managedFind a store
IID production pages
before
after Payload rework
load time · illustrative
04 / 06 · Build · Real-time

Ad screens that update the moment you hit save.

Centralized Advertisement Management System for Biscoo and Bida.vn (2026): marketing changes an ad in a dashboard, Supabase pushes the change, and every screen in every venue swaps it live.

Clients
Biscoo, Bida.vn
Data
Supabase (Postgres + realtime)
Screens
Subscribe and swap content live
Admin dashboard ad: Summer promo Save Supabasepostgres + realtimechannel: ads venue 01 venue 02 venue 40
Ad screen running at a Bida.vn venue
On site

A venue screen running the system. Saved once in the dashboard, every subscribed screen swaps to the new ad.

05 / 06 · Build · Games

Games: indie titles and campaign games.

Three games released independently on Steam in C#, plus interactive campaign games for brands like Kewpie × HTV and iSEE. Gameplay AI, algorithms and game architecture.

Released
3 games on Steam
Focus
Gameplay AI, algorithms, architecture
Awards
Champion · Topebox Accelerator, GameVerse 2024
Indie game production loop
01Prototypecore loop · Godot / C#
02Playtestfeel · pacing · balance
03Polishart · audio · UX
04ShipSteam · campaign launch
Shape: Mind of Thinker title screen
Shape: Mind of Thinker
Salad First start screen
Salad First · Kewpie × HTV
Thiếu một tờ giấy poster
Thiếu một tờ giấy · iSEE
Watch gameplay on BrightStdio's YouTube @brightstdio1610
06 / 06 · Ship

Live, then looked after.

Production deploys for brands, releases on Steam, and maintenance after launch.

Deploy
Docker on VPS
After launch
Fixes, content updates, performance
Statusall systems
Kewpie Vietnam● live
VTV / HTV● live
IID · faster after Payload rework● live
Biscoo · Bida.vn displays● realtime
3 games● on Steam
01 / 04 · Architecture

Pick the right tool for each job.

Course data lives in MongoDB, learning paths are a graph in Neo4j, public pages come from Payload CMS for SEO, and Cloudflare's CDN carries video and pages so the platform holds up under load.

Own
Solution architecture, technology selection
Data
MongoDB · Neo4j
SEO
Payload CMS, server-rendered pages
Load
Cloudflare CDN for video and pages
Learnersweb · mobile Cloudflare CDNedge cache · video · pages Video storageorigin · lesson filesPayload CMSSEO pages · SSR App APIcourses · progress · paths MongoDBdocuments Neo4jgraph · learning paths miss HIT
Right tool per jobdecided
MongoDBUsers, courses, lessons, progress: flexible documents read by idNeo4jPrerequisites and "what next?": one path query instead of many joinsPayload CMSPublic course pages rendered on the server, so search engines index them (SEO)Cloudflare CDNVideo and pages served from the edge, so traffic spikes hit the cache, not the origin
02 / 04 · Review

Review decisions and code before they ship.

Ask the question early, while it's still cheap to change: in the design doc or in the pull request.

Review
Technical decisions and code
Aim
Catch problems while they're cheap
Add next-lesson recommendation endpointchanges requested → approved
12 for (const id of learnerIds) {
13- await session.run(nextLessonQuery, { id })
13+ await session.run(nextLessonBatch, { ids: learnerIds })
HienThis runs one query per learner. Can we send them in one batch with UNWIND?
AuthorDone, one round trip now.
✓ Approved2 comments · 1 resolved
03 / 04 · Unblock

Get engineers moving again.

When a deploy fails or a bug won't reproduce, sit with the engineer, read the logs together, and fix the cause rather than the symptom.

Help with
Troubleshooting and deployment
Leave behind
A fix and a note so it doesn't recur
  1. build
  2. test
  3. deploy staging
  4. fix
  5. staging
  6. production
14:02ERROR app: connect ECONNREFUSED graph-db:7687
14:05note app starts before the database is ready
14:11fix healthcheck on db · app waits for healthy
14:18OK deploy staging · all checks green
04 / 04 · People

Interview candidates, grow the team.

Run interviews for new engineers and keep regular 1:1s with the people already on the team.

Hiring
Interview candidates
Mentoring
Team members and new joiners
Interview loop
  1. Screen
  2. Coding
  3. System design
  4. Team fit
  5. Offer
1:1 notes · example
GoalOwn the deploy pipeline end to end
This monthPair on the healthcheck fix · write the runbook
NextLead a design review
01 / 03 · Teach

Make the invisible part visible.

The hard part of C is what happens in memory. I draw it: where a variable lives, what a pointer holds, and what changes when you write through it.

Tracks
C/C++, Python, React
Style
Draw the model, then write the code
int  x = 42;
int *p = &x;
*p = 7;   // x is now 7
addressvaluename 0x1010427x 0x1014… 0x10180x1010p *p
02 / 03 · Mentor

Mentor students on real projects.

Teams run their project like a small product team: a board, pull requests, and review from me before anything is merged.

Format
Team projects with a board and PRs
My part
Reviews, 1:1s, unblock
To doLogin pageSeed data
DoingCart APIProduct list
ReviewCheckout flowMentor: handle the empty cart case
DoneRepo + CIWireframes
03 / 03 · Ship

Every course ends on demo day.

Students leave with a project that's deployed and that they can explain, not just a set of exercises.

Outcome
A deployed project per team
Courses
10+ courses and workshops
week 1Hello, worldweek 4Pointers & dataweek 8Team projectfinalDemo day
Study plannerReact · Firebase● deployed
Inventory CLIC++ · file storage● shipped
Price trackerPython · scraper + bot● deployed

Example student projects

Selected projects.

More on LinkedIn
Ad screen at a Bida.vn venue showing a product ad
Real-time · Supabase · VPS

Centralized Advertisement Management System

Biscoo & Bida.vn · Mar – May 2026

A server–client system: marketing schedules ads centrally and screens in each venue update live.

Students playing the Salad First kiosk game at an outdoor event
Game · Godot · Lead

Salad First · NLU

Kewpie × HTV · TMS · Apr – May 2025

The on-site edition of the “Start your meal with vegetables” campaign game, played on touch kiosks.

Salad First start screen and the game played on a table display
Game · C# · Unity

Salad First

Kewpie × HTV · Sep – Oct 2024

Interactive campaign game for Kewpie: “Hãy bắt đầu bữa ăn bằng rau”.

Thiếu một tờ giấy key art and launch poster
Game · Unity · Web

Thiếu một tờ giấy (Need One Paper)

iSEE × EP4 · Jun – Oct 2025

A game developed with the EP4 team, with its own launch site.

Shape: Mind of Thinker title screen
Game · Unity · C#

Shape: Mind of Thinker

Jun 2022 – Jun 2023

A game that tells the story of a negative thinker.

Game · Unity · C#

Paper War

Indie · Steam

A 2D strategy defense game.

Build notes.

All posts

Notes from the systems I build

Deep dives, diagrams, and lessons from Linux networking, product engineering, games, and teaching.

Notion-ready · mock content

Topics I keep exploring

Network securityLinux systemsProduct engineeringGame developmentTeaching & mentoringAI-assisted engineering
Contact

Let's build something together.

Open to new opportunities, collaborations, or just a tech chat.