[{"content":"3 mẫu kiến trúc xác thực kinh điển trong ứng dụng Web Hầu hết các hệ thống xác thực (Authentication) cho ứng dụng Web hiện nay đều xoay quanh 3 mẫu thiết kế nền tảng:\nStateful Session Pattern Đây là mô hình kinh điển nhất, gắn liền với các framework Web truyền thống như ASP.NET MVC hay PHP.\nSau khi đăng nhập, server tạo một phiên làm việc (Session) và lưu vào bộ nhớ (RAM/Redis). Client chỉ nhận về một Session ID vô nghĩa, được lưu trong HttpOnly Cookie.\nƯu điểm: Cực kỳ bảo mật — dữ liệu thực (Claims) không bao giờ rời khỏi server. Muốn thu hồi phiên làm việc? Chỉ cần xóa Session ở server là xong. Nhược điểm: Triển khai Session trong Microservices đòi hỏi Shared Cache hoặc cấu hình Sticky Sessions trên Load Balancer, đồng thời gây rắc rối khi xử lý các chính sách SameSite Cookie trên đa domain. Điều này làm mất đi tính Stateless và sự độc lập của mỗi service. sequenceDiagram participant B as Browser participant S as Server participant C as Cache/Database B-\u0026gt;\u0026gt;S: 1. Gửi credentials (user/pass) S-\u0026gt;\u0026gt;S: 2. Xác thực thông tin S-\u0026gt;\u0026gt;C: 3. Tạo Session, lưu Session ID S--\u0026gt;\u0026gt;B: 4. Trả về HttpOnly Cookie (Session ID) B-\u0026gt;\u0026gt;S: 5. Gửi request + Cookie (Session ID) S-\u0026gt;\u0026gt;C: 6. Kiểm tra Session ID S--\u0026gt;\u0026gt;B: 7. Trả về Resource Token-by-Value Pattern (Stateless JWT) Mô hình này bùng nổ cùng với sự phát triển của Single Page Application và Mobile App.\nToàn bộ thông tin người dùng được đóng gói vào một JWT và ký số. Server không lưu trạng thái (Stateless) — client tự giữ token và gửi kèm trong header Authorization.\nƯu điểm: Scale rất tốt vì server không cần truy vấn DB/cache để xác thực. Phù hợp với kiến trúc Microservices. Nhược điểm: Hacker có thể giải mã Base64 để đọc nội dung bên trong (rò rỉ PII). Một khi JWT đã được phát ra, gần như không có cách nào thu hồi trước khi hết hạn. Việc để lộ cấu trúc Claims hoặc ID người dùng trong JWT (dù đã mã hóa Base64) là một điểm trừ lớn khi Audit. sequenceDiagram participant B as Browser participant S as Server participant R as Resource API B-\u0026gt;\u0026gt;S: 1. Gửi credentials (user/pass) S-\u0026gt;\u0026gt;S: 2. Xác thực thông tin S--\u0026gt;\u0026gt;B: 3. Tạo JWT (chứa Claims, ký số), trả về Client B-\u0026gt;\u0026gt;B: 4. Lưu JWT (LocalStorage/Memory) B-\u0026gt;\u0026gt;R: 5. Gửi request + Authorization: Bearer JWT R-\u0026gt;\u0026gt;R: 6. Giải mã, kiểm tra chữ ký JWT (Stateless) R--\u0026gt;\u0026gt;B: 7. Trả về Resource Token-by-Reference Pattern (Opaque Token) Thường dùng trong các hệ thống yêu cầu bảo mật cao hoặc các Identity Server chuyên dụng.\nServer trả về một chuỗi ngẫu nhiên vô nghĩa (Opaque Token), còn thông tin thực sự được lưu tập trung tại Identity Server.\nƯu điểm: Client không chứa bất kỳ dữ liệu nhạy cảm nào. Nhược điểm: Mỗi lần cần xác thực, Resource API phải gọi ngược về Identity Server (Introspection) để giải mã token — tạo ra \u0026ldquo;điểm nghẽn\u0026rdquo; khi traffic lớn. sequenceDiagram participant B as Browser participant S as Server participant I as Identity Server participant R as Resource API B-\u0026gt;\u0026gt;S: 1. Gửi credentials (user/pass) S-\u0026gt;\u0026gt;I: 2. Xác thực, tạo Opaque Token, lưu vào cache I--\u0026gt;\u0026gt;B: 3. Trả về Opaque Token (chuỗi ngẫu nhiên) B-\u0026gt;\u0026gt;R: 4. Gửi request + Opaque Token R-\u0026gt;\u0026gt;I: 5. Gọi Introspection để giải mã token I--\u0026gt;\u0026gt;R: 6. Trả về Claims thông tin người dùng R--\u0026gt;\u0026gt;B: 7. Trả về Resource Giải pháp tối ưu: Phantom Token Pattern Nhận ra điểm yếu của cả hai hướng trên, Phantom Token Pattern ra đời như một sự kết hợp thông minh: dùng Opaque Token làm lớp bảo mật bên ngoài, và JWT làm động cơ hiệu năng bên trong.\nCơ chế vận hành Mẫu thiết kế này chia hệ thống thành hai vùng rõ rệt: Public Zone (không tin cậy) và Private Zone (tin cậy).\nCấp phát: Khi đăng nhập, Identity Server tạo JWT đầy đủ claims nhưng không gửi đi. Nó lưu JWT vào cache và chỉ trả về cho Client một Opaque Token. Gửi request: Client gửi request kèm Opaque Token đến API Gateway. Hoán đổi token: Tại API Gateway (nằm ở biên mạng), Gateway nhận Opaque Token và gọi sang Identity Server để đổi lấy JWT tương ứng. Xử lý nội bộ: Gateway thay thế Opaque Token bằng JWT trong header rồi forward vào các Microservices bên trong. sequenceDiagram box rgb(255, 245, 230) Public Zone participant B as Browser participant N as Internet end box rgb(230, 245, 255) Private Zone participant G as API Gateway participant I as Identity Server participant M as Microservices end B-\u0026gt;\u0026gt;N: 1. Gửi credentials (user/pass) N-\u0026gt;\u0026gt;G: 2. Chuyển tiếp tới Gateway G-\u0026gt;\u0026gt;I: 3. Điều phối xác thực I-\u0026gt;\u0026gt;I: 4. Xác thực, tạo JWT, lưu vào cache I--\u0026gt;\u0026gt;G: 5. Trả về Opaque Token G--\u0026gt;\u0026gt;B: 6. Trả về Opaque Token cho Client B-\u0026gt;\u0026gt;G: 7. Gửi request + Opaque Token (qua Internet) G-\u0026gt;\u0026gt;I: 8. Exchange: gửi Opaque Token I--\u0026gt;\u0026gt;G: 9. Trả về JWT tương ứng G-\u0026gt;\u0026gt;G: 10. Thay Opaque Token bằng JWT trong header G-\u0026gt;\u0026gt;M: 11. Forward request + JWT M-\u0026gt;\u0026gt;M: 12. Xử lý Stateless (như Token-by-Value) M--\u0026gt;\u0026gt;B: 13. Trả về Resource Tại sao gọi là \u0026ldquo;Phantom\u0026rdquo;? Vì đối với Client, JWT hoàn toàn không tồn tại. Nó như một \u0026ldquo;bóng ma\u0026rdquo; — chỉ xuất hiện và lưu hành bên trong vùng mạng nội bộ của hệ thống.\nƯu điểm vượt trội Bảo mật đa lớp (Defense in Depth \u0026amp; PII Protection): Thông tin nhạy cảm (User ID, Role, Email\u0026hellip;) được đóng gói trong JWT và chỉ lưu hành trong mạng nội bộ. Client chỉ nhận Opaque Token vô nghĩa, triệt tiêu hoàn toàn nguy cơ rò rỉ dữ liệu cá nhân (PII) ra Internet. Thu hồi quyền truy cập tức thì (Immediate Revocation): Khác với JWT truyền thống khó thu hồi trước khi hết hạn, Opaque Token có thể bị vô hiệu hóa ngay lập tức tại API Gateway hoặc Identity Server, giúp kiểm soát phiên làm việc của người dùng chặt chẽ hơn. Tối ưu hiệu năng Microservices: Các service phía sau Gateway nhận được JWT đã được \u0026ldquo;giải mã sẵn\u0026rdquo;, cho phép xử lý Stateless hoàn toàn mà không cần gọi ngược về Identity Server (Introspection). Ngoài ra, request từ Client qua mạng cũng nhẹ hơn nhờ payload của Opaque Token rất gọn. Tách biệt trách nhiệm (Separation of Concerns): Identity Server lo việc phát hành/định danh. API Gateway lo việc chuyển đổi (Introspection). Microservices chỉ quan tâm đến Business Logic với một JWT sạch. Khi nào nên dùng? Phantom Token Pattern đặc biệt phù hợp khi bạn xây dựng hệ thống Microservices hiện đại, có yêu cầu bảo mật cao, và muốn tách biệt rõ ràng trách nhiệm giữa Security và Business Logic.\nLời kết: Phantom Token không chỉ là một kỹ thuật xác thực — nó là tư duy thiết kế bảo mật theo chiều sâu. Vừa đạt được sự an toàn của Opaque Token, vừa giữ được hiệu năng của JWT.\n","date":"2026-05-03T10:00:00+07:00","permalink":"https://vuvtdhh.pages.dev/p/t%E1%BB%AB-monolith-%C4%91%E1%BA%BFn-microservices-t%E1%BA%A1i-sao-phantom-token-l%C3%A0-l%E1%BB%B1a-ch%E1%BB%8Dn-t%E1%BB%91i-%C6%B0u-cho-authentication/","title":"Từ Monolith đến Microservices: Tại sao Phantom Token là lựa chọn tối ưu cho Authentication?"},{"content":"Hầu hết các trang web và ứng dụng hiện đại đều cần hoạt động liên tục.\nTuy nhiên, trên thực tế, để cập nhật phiên bản hoặc sửa lỗi, đội ngũ vận hành cần một khoảng thời gian nhất định để thực hiện một số công việc như ghi đè artifact, database migration, health check,\u0026hellip;\nTrong thời gian này, hệ thống sẽ tạm ngưng hoạt động, dẫn đến việc gián đoạn truy cập của người dùng. Ngoài ra, việc ngắt kết nối có thể gây thất thoát dữ liệu do mất đồng bộ với các hệ thống bên thứ ba hoặc làm đứt gãy quy trình nghiệp vụ trong kiến trúc microservices.\nĐể giải quyết vấn đề này, chúng ta cần một chiến lược triển khai đảm bảo không gián đoạn. Có nhiều chiến lược triển khai không gián đoạn, trong đó blue-green deployment là một trong những chiến lược phổ biến.\nCơ chế hoạt động của Blue-Green Deployment Về cơ bản, chiến lược này duy trì hai môi trường song song:\nBlue (Live): Môi trường hiện tại đang tiếp nhận và xử lý các yêu cầu (traffic/requests) thực tế. Green (Idle): Môi trường dự phòng, nơi phiên bản mới được triển khai và kiểm soát chất lượng (QA/Staging) trước khi chính thức tiếp nhận traffic. Quy trình triển khai tiêu chuẩn: Deploy: Đưa code mới lên môi trường Green. Verify: Thực hiện smoke test, kiểm tra các endpoint để đảm bảo dịch vụ hoạt động ổn định trong môi trường cô lập. Swap: Điều hướng lưu lượng truy cập (traffic) từ Blue sang Green thông qua bộ chuyển mạch (Router/Load Balancer/Gateway). Monitor \u0026amp; Rollback: Theo dõi log và chỉ số hệ thống. Nếu có bất kỳ sự cố nào, chỉ cần chuyển mạch ngược lại về Blue ngay lập tức. Triển khai thực tế trên IIS (Internet Information Services) Dù IIS không có sẵn \u0026ldquo;Blue-Green\u0026rdquo;, chúng ta hoàn toàn có thể thiết lập kiến trúc này bằng cách kết hợp bộ ba công cụ mạnh mẽ: Application Request Routing (ARR), URL Rewrite, và Server Farm.\nVai trò của các thành phần:\nGateway Site (Tầng 1): Đây là site duy nhất công khai ra Internet (cổng 80/443). Site này không chứa code ứng dụng, chỉ chứa file web.config để cấu hình điều hướng. Server Farm (Tầng 2): Đối tượng quản lý danh sách các server hoặc cổng (port) của Blue và Green. Tại đây, chúng ta có thể bật/tắt các node để điều phối traffic. Application Sites (Tầng 3): Các instance thực tế chạy code ứng dụng (ví dụ: Blue chạy port 8081, Green chạy port 8082). Ưu điểm của mô hình này: Zero-Downtime: Đảm bảo không gián đoạn truy cập cho người dùng cuối và các upstream services trong hệ thống. Tính cô lập (Isolation): Việc triển khai và kiểm thử trên môi trường Green hoàn toàn không ảnh hưởng đến tiến trình đang chạy của Blue. An toàn tuyệt đối: Luôn có bản dự phòng sẵn sàng để Rollback tức thì nếu phiên bản mới gặp lỗi logic. Kiểm soát tập trung: Mọi hành động \u0026ldquo;Swap\u0026rdquo; chỉ diễn ra ở tầng Gateway, giúp giảm thiểu rủi ro vận hành. Khả năng mở rộng: Dễ dàng tích hợp thêm các node mới vào Server Farm khi nhu cầu tải tăng cao. Lưu ý quan trọng: Khi triển khai Blue-Green, hãy đảm bảo cơ sở dữ liệu (Shared Database) của bạn có thiết kế tương thích ngược (backward compatibility) để cả hai phiên bản cũ và mới đều có thể hoạt động ổn định trong thời điểm chuyển giao. Nếu cần thiết, phải triển khai thêm chiến lược Expand and Contract (Parallel Change) để đảm bảo tính nhất quán của dữ liệu khi schema có sự thay đổi.\n","date":"2026-04-26T14:45:00+07:00","permalink":"https://vuvtdhh.pages.dev/p/zero-downtime-v%E1%BB%9Bi-chi%E1%BA%BFn-l%C6%B0%E1%BB%A3c-blue-green-deployment/","title":"Zero-downtime với chiến lược Blue-Green Deployment"},{"content":"Gọi là \u0026ldquo;hack\u0026rdquo; nghe cho nguy hiểm, thật ra việc này gần với Reverse Engineering và Protocol Analysis hơn (về sau tôi mới biết các khái niệm này). Đây là một nhiệm vụ được công ty giao, không gây thiệt hại cho bất cứ ai hay tổ chức nào vì\u0026hellip; đọc hồi sau sẽ rõ!\nSau khi tốt nghiệp, tôi gia nhập phòng R\u0026amp;D của công ty cung cấp giải pháp IoT về năng lượng.\nNgày đó, chúng tôi có một hệ thống đang chạy. Do một số vấn đề khách quan trong quá trình chuyển giao và lưu trữ. Không còn đủ thông tin để xác định nó đang chạy trên phiên bản nào (chúng tôi có khá nhiều phiên bản tùy biến). Hơn nữa, cũng chưa có một công cụ nào có thể giao tiếp hiệu quả với các hệ thống dạng này.\nTôi được giao một source code mà không chắc có trùng khớp với hệ thống kia hay không. Nhiệm vụ của tôi là cố gắng hiểu nó đang chạy thế nào và giao tiếp để lấy được thông tin, ít nhất là số hiệu phiên bản.\nTôi nhận source code và bắt đầu nghiên cứu, xem ra cũng khá phức tạp, hệ thống này là một server giao tiếp với các thiết bị IoT thông qua socket.\nGiao thức giữa server và client được định nghĩa trên các mảng byte. Mỗi vị trí byte ẩn chứa một ý nghĩa riêng: một số vị trí là mã lệnh, một số là checksum, một số là payload. Toàn bộ gói tin được mã hóa.\nTôi bắt đầu dựng lab và viết một chương trình giả lập thiết bị IoT để giao tiếp với source code kia.\nTrải qua hơn một tuần thử và sai, tìm và thiết lập hàng trăm hàm mã hóa, đặt hàng nghìn breakpoint. Cuối cùng, tôi đã có thể giao tiếp và lấy được thông tin, bao gồm cả số hiệu phiên bản.\nTôi hớn hở báo lại với sếp, chuyển sang giao tiếp với server thật thay vì lab đã dựng. Và\u0026hellip; không nhận được bất kỳ phản hồi nào.\nCó thể là server kia đang chạy một phiên bản khác chăng? Hoặc\u0026hellip;?! À, tôi nhớ ra là cần NAT port, giao thức này yêu cầu server phải chủ động kết nối ngược lại client, và nếu máy tôi nằm sau Router mà không NAT port thì gói tin phản hồi sẽ \u0026ldquo;mất tích\u0026rdquo; ngoài cửa ngõ.\nNhưng\u0026hellip; thử nhiều cách, tôi vẫn không thể giao tiếp được với server kia như tôi đã làm được với lab.\nTôi chấp nhận rằng mọi chuyện không đơn giản như vậy. Chỉ dựa vào lượng thông tin ít ỏi tôi có để tìm cách giao tiếp với server kia là không thể.\nKhông có gì đảm bảo phiên bản source code tôi có, hàm mã hóa và giao thức tôi reverse thành công là trùng khớp với phiên bản đang chạy.\nDẫu vậy, công cụ tôi phát triển để giao tiếp với server kia vẫn rất hữu ích, nó mở ra nhiều thứ. Nhờ đó, chúng tôi giao tiếp với các server và thiết bị IoT khác một cách linh hoạt hơn.\nSau lần này, tôi học được nhiều kiến thức mà lúc đi học ở trường không dạy, cả về chuyên môn lẫn kỹ năng giải quyết vấn đề.\nTôi bắt đầu có hứng thú với bảo mật, mã hóa và các loại giao thức. Những kiến thức này giúp ích cho tôi nhiều và như một kim chỉ nam của tôi trong quá trình thiết kế các hệ thống phần mềm về sau.\nDù kết quả cuối cùng không như mong đợi ban đầu, nhưng những gì học được đối với tôi là vô giá.\nTôi nhận ra rằng, để thiết kế một hệ thống thực sự an toàn, cần phải thấu hiểu tường tận cơ chế vận hành của nó ở mọi cấp độ và đặc biệt là tại các điểm giao thoa. Đó không chỉ là việc bắt lỗi logic ở tầng Application, mà còn là sự am tường về cách Framework vận hành, cách các giao thức kết nối, cách các Middleware xử lý yêu cầu, cho đến tận lớp Infrastructure bên dưới.\nCách tốt nhất để bảo vệ hệ thống chính là hiểu được cách mà nó có thể bị tấn công. Mà cách nhanh nhất để hiểu, không gì bằng tự mình nghiên cứu và thử nghiệm thực tế vào từng ngóc ngách của hệ thống.\nCũng từ đó mà tôi mắc \u0026ldquo;bệnh nghề nghiệp\u0026rdquo;, mỗi khi được nhờ test một hệ thống nào đó, tôi lại không nhịn được mà \u0026ldquo;chọc ngoáy\u0026rdquo; một chút, để xem có vô tình kích hoạt được \u0026ldquo;tính năng ẩn\u0026rdquo; nào không \u0026#x1f606;.\nĐỉnh điểm là có lần, mải test vui quá, tôi lỡ \u0026ldquo;can thiệp\u0026rdquo; hơi sâu và ẵm luôn giải Nhất game nội bộ công ty. Đúng là ranh giới giữa một người làm kỹ thuật và một \u0026ldquo;hacker\u0026rdquo; đôi khi chỉ cách nhau bởi\u0026hellip; cái mục tiêu ban đầu!\n","date":"2026-04-19T22:40:59+07:00","permalink":"https://vuvtdhh.pages.dev/p/t%C3%B4i-l%C3%A0m-hacker/","title":"Tôi làm \"Hacker\""},{"content":"Mở đầu series Soft-to-System, mình sẽ hướng dẫn các bạn tự dựng một Homelab để giả lập môi trường server thực tế ngay tại nhà.\nĐây là bước đầu tiên để làm quen với quản trị hạ tầng, tạo tiền đề để triển khai các thử nghiệm thực tế (ví dụ: CI/CD, host ứng dụng, dựng database,\u0026hellip;).\nTrong bài viết này, mình sử dụng Hyper-V để cài đặt Windows Server 2025. Nội dung sẽ đi chi tiết từ cấu hình từng bước cho đến khi máy ảo có thể kết nối mạng và hoạt động ổn định.\nBước 1: Kích hoạt Hyper-V Mặc định, Hyper-V sẽ không bật sẵn, bạn cần kích hoạt tính năng này trong Windows Features.\nSau đó, mở Hyper-V Manager. Đây là giao diện quản lý trung tâm của chúng ta.\nBước 2: Khởi tạo máy ảo (New Virtual Machine Wizard) Nhấn New \u0026gt; Virtual Machine và bắt đầu cấu hình thông tin cho server.\nName \u0026amp; Location: Đặt tên gợi nhớ như Windows Server 2025. Generation: Luôn chọn Generation 2 để hỗ trợ UEFI và các tính năng bảo mật mới. Ở đây mình dùng bản Desktop Experience nên sẽ cấp 4096 MB (4GB) cho RAM và bật Dynamic Memory để tối ưu tài nguyên cho máy thật. Networking: Tại bước này, hãy chọn Not Connected. Chúng ta sẽ thiết lập card mạng thủ công ở bước sau. Hard Disk: Thiết lập ổ đĩa ảo VHDX với dung lượng 60 GB. Installation: Trỏ đường dẫn đến file .iso Windows Server 2025. Summary: Kiểm tra lại lần cuối và nhấn Finish. Bước 3: Cài đặt OS Chuột phải vào máy ảo chọn Connect, sau đó nhấn Start.\n⚠️ Lưu ý cực kỳ quan trọng: Nếu bạn thấy màn hình báo Boot loader failed như ảnh dưới. Hãy nhấn Tab để focus vào nút Restart, restart máy ảo và ngay khi thấy dòng chữ \u0026ldquo;Press any key to boot\u0026hellip;\u0026rdquo;, hãy nhấn phím bất kỳ để có thể boot.\nQuá trình cài đặt Windows Server sẽ diễn ra.\nBước 4: Cấu hình và Kiểm tra kết nối Sau khi cài xong, hãy đăng nhập với tài khoản Administrator.\nDo ban đầu khi cấu hình máy ảo phần Networking, chúng ta đã chọn Not Connected nên lúc này máy ảo chưa được cấp IP và chưa có kết nối mạng.\nBước 5: Thiết lập card mạng (External Switch) Để máy ảo ra được internet và \u0026ldquo;nhìn thấy\u0026rdquo; máy thật, chúng ta cần tạo một cầu nối (Bridge).\nVào Virtual Switch Manager, chọn New virtual network switch \u0026gt; External. Đặt tên là vSwitch External và mapping vào đúng card mạng vật lý. Đừng quên tích chọn Allow management operating system to share this network adapter. Bước 6: Kết nối card mạng với máy ảo Vào Settings của máy ảo, mục Network Adapter, gán Switch vừa tạo vào.\nMáy ảo sẽ nhận IP và có thể kết nối Internet.\nBước 7: Kết nối máy thật và máy ảo. Mặc định, Windows Defender Firewall sẽ chặn phần lớn các giao thức và cổng không cần thiết để bảo mật. Tùy vào tính năng hoặc phần mềm muốn sử dụng, chúng ta cần tìm và kích hoạt các Rule tương ứng (hoặc tạo mới nếu cần).\nỞ đây mình sẽ ví dụ với lệnh Ping. Nếu bạn dùng máy thật Ping vào máy ảo mà bị Request timed out, đó là do Firewall của Windows Server đang chặn giao thức ICMP.\n⚠️ Lưu ý nhỏ: Khác với Web hay Database chạy trên các cổng (Port) như 80 hay 1433, lệnh Ping sử dụng giao thức ICMP hoạt động ở tầng thấp hơn nên nó không có khái niệm \u0026ldquo;cổng\u0026rdquo;. Để thông mạng, chúng ta phải cho phép giao thức này đi qua Firewall.\nCách xử lý:\nTrong máy ảo, mở Windows Defender Firewall with Advanced Security. Tìm Rule: File and Printer Sharing (Echo Request - ICMPv4-In). Chuột phải chọn Enable Rule. Kết quả là lệnh Ping từ máy thật đã thông suốt!\nKiểm tra lại Ping từ Windows Server đến máy thật.\n⚠️ Lưu ý: Máy thật cũng cần Enable Rule File and Printer Sharing (Echo Request - ICMPv4-In) thì máy ảo mới Ping đến được nhé.\nKết luận Vậy là chúng ta đã hoàn tất việc dựng máy chủ Windows Server 2025 trên Hyper-V. Với phần Networking đã thông suốt, hệ thống hiện tại đã sẵn sàng để chúng ta bắt đầu triển khai thêm các dịch vụ khác.\nHẹn gặp lại các bạn ở những bài viết sau trong series Soft-to-System!\n","date":"2026-01-27T00:00:00Z","image":"https://vuvtdhh.pages.dev/p/homelab-part-1-d%E1%BB%B1ng-windows-server-%E1%BA%A3o-h%C3%B3a-v%E1%BB%9Bi-hyper-v-t%E1%BB%AB-a-z/homelab-part-1-cover.jpg","permalink":"https://vuvtdhh.pages.dev/p/homelab-part-1-d%E1%BB%B1ng-windows-server-%E1%BA%A3o-h%C3%B3a-v%E1%BB%9Bi-hyper-v-t%E1%BB%AB-a-z/","title":"Homelab Part 1: Dựng Windows Server ảo hóa với Hyper-V từ A-Z"}]