Máy Windows ở văn phòng truy cập từ xa qua Cloudflare Tunnel
Tóm tắt
Ghi chú thao tác trực tiếp (2026-08-22): dựng đường truy cập từ xa vào một máy Windows đặt tại văn phòng công ty, từ MacBook ở nhà, qua Cloudflare Tunnel + Access — cả SSH lẫn RDP trên cùng một tunnel. Không mở cổng nào trên firewall công ty, không dùng VPN. Đây là bản mở rộng của mô hình đã dùng cho ssh-vao-pi-qua-cloudflare-tunnel-va-access, khác ở ba điểm: origin là Windows chứ không phải Linux, tunnel được quản lý từ dashboard (remotely-managed) thay vì file config cục bộ, và có thêm ingress RDP bên cạnh SSH.
Điểm khác biệt về mặt vận hành so với homelab: máy này không có đường cứu hộ vật lý — chủ hệ thống không ở văn phòng, mọi thao tác tại chỗ đều phải nhờ người khác. Điều đó chi phối gần như mọi lựa chọn kỹ thuật bên dưới.
Thông số máy
| Mục | Giá trị |
|---|---|
| Hostname | DESKTOP-NTJREDH |
| Hệ điều hành | Windows 10 Pro (đã hết hỗ trợ bảo mật từ 10/2025) |
| Loại máy | Desktop |
| IP LAN văn phòng | 10.1.22.50 (mạng riêng, không cùng subnet với vtech:tam hay vtech:mik5009) |
| Tài khoản dùng | admin (local account, thuộc nhóm Administrators) |
| BitLocker | Không bật — reboot vào thẳng Windows, không có màn hình chờ chặn mạng |
| Tunnel | tantan-office-desktop (remotely-managed) |
| cloudflared | 2026.8.2, cài bằng MSI, chạy dưới dạng Windows service |
Hai hostname công khai, cùng trỏ về tunnel trên:
chiissh.nguyenbinhson.com→ssh://localhost:22chiirdp.nguyenbinhson.com→rdp://localhost:3389
Cả hai đều có Cloudflare Access application dạng self-hosted, policy Allow theo email cá nhân (email OTP).
Điểm chính
Thứ tự thiết lập quan trọng hơn nội dung từng bước
Trình tự đã dùng: chuẩn bị máy Windows → tạo tunnel + published application route → tạo Access application → mới cài connector. Lý do: từ giây phút connector chạy, hostname đã sống trên Internet; nếu Access chưa có policy thì cổng RDP hở ra cho bất kỳ ai biết tên miền, chỉ còn mật khẩu Windows chắn lại. Đây đúng là loại cửa sổ hở đã gặp một lần trong topology-mang-homelab (WAN mới lên trước, interface list WAN thêm sau, SSH router hở mấy phút).
Phía Windows
- RDP bật qua registry:
fDenyTSConnections=0tạiHKLM:\System\CurrentControlSet\Control\Terminal Server, và bật NLA bằngUserAuthentication=1tại...\WinStations\RDP-Tcp. - OpenSSH Server là optional feature, không có sẵn:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0, rồi đặt servicesshdsangAutomatic. Đổi shell mặc định từcmdsang PowerShell bằng khoáDefaultShelltrongHKLM:\SOFTWARE\OpenSSH. - Public key cho tài khoản Administrator nằm ở chỗ khác thường:
sshdkhông đọcC:\Users\<user>\.ssh\authorized_keysnếu user thuộc nhóm Administrators — nó đọc file chungC:\ProgramData\ssh\administrators_authorized_keys, và file đó phải có ACL chỉ gồmAdministrators:F+SYSTEM:F(icacls ... /inheritance:r). Sai ACL thìsshdtừ chối im lặng và rơi về hỏi mật khẩu, không báo lỗi gì rõ ràng. - Tài khoản phải thật sự có mật khẩu. Account
adminban đầu ở trạng tháiPassword required: No; Windows có policy mặc định chặn account mật khẩu rỗng đăng nhập qua mạng, nên cả RDP lẫn SSH đều sẽ từ chối với thông báo mơ hồ. Sửa bằngnet user admin *vànet user admin /passwordreq:yes. - Điện năng là phần quyết định máy có còn dùng được hay không:
powercfg /change standby-timeout-ac 0,hibernate-timeout-ac 0, vàpowercfg /hibernate off(lệnh cuối tắt luôn Fast Startup). Máy desktop nên không phải xử lý hành vi gập nắp. wingetkhông có trên bản Windows 10 này (build cũ, thiếu App Installer) — cài cloudflared bằng MSI tải trực tiếp từ GitHub release, rồimsiexec /i ... /quiet. Cần đặt[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12trước khiInvoke-WebRequest.- MSI cài vào
C:\Program Files (x86)\cloudflared\và thêm vàoPATH, nhưng cửa sổ PowerShell đang mở không thấyPATHmới — gọi bằng đường dẫn đầy đủ hoặc mở cửa sổ mới. - Đăng ký service bằng
cloudflared.exe service install <TOKEN>. Token lấy từ dashboard, không cần đăng nhập tài khoản Cloudflare trên máy Windows — khác hẳn cáchcloudflared tunnel loginđã dùng trên Pi, và là lý do chọn kiểu remotely-managed: người thao tác hộ tại văn phòng chỉ cần chạy đúng một lệnh.
Phía Cloudflare
- UI Zero Trust đã đổi tên: chỗ thêm public hostname giờ nằm ở tab Published application routes trong trang tunnel. Tab
Hostname routesvàCIDR routeslà cho private network qua WARP, không dùng ở đây. - Trường Type phải chọn đúng
SSH/RDPtừ dropdown; trường URL chỉ ghilocalhost:22/localhost:3389, không thêm tiền tố giao thức. - Cloudflare tự tạo CNAME proxied trỏ về
<tunnel-id>.cfargotunnel.com. - Kiểm chứng Access thật sự chắn:
curlvàohttps://<hostname>/từ ngoài phải trả 302 về<team>.cloudflareaccess.com/cdn-cgi/access/login/...vớiauth_status: NONE.
Phía MacBook (opera)
- SSH: alias
cf:tantan:wintrong~/.ssh/config, dùngProxyCommand /opt/homebrew/bin/cloudflared access ssh --hostname %h— cùng mẫu vớicf:home:pivàcf:vtech:tam. - RDP cần hai phần rời nhau:
- Mở đường hầm và giữ tiến trình chạy:
cloudflared access rdp --hostname chiirdp.nguyenbinhson.com --url rdp://localhost:13389 - Dùng Windows App của Microsoft (cask Homebrew
windows-app) trỏ tớilocalhost:13389.
- Mở đường hầm và giữ tiến trình chạy:
- Dùng port local
13389chứ không phải3389vì cổng mặc định hay bị chiếm trên máy client. - Cảnh báo certificate không tin cậy khi kết nối là bình thường (Windows dùng self-signed cert cho RDP, lại đang nối qua
localhost). - Tắt cửa sổ chạy
cloudflared access rdplà mất kết nối ngay — đây là điểm gây bối rối nhất trong vận hành hàng ngày.
Đánh đổi giữa SSH và RDP
Cả hai được dựng song song trên cùng một tunnel vì chúng bù cho nhau, không thay thế nhau:
- RDP cho toàn bộ desktop, cần cho phần mềm GUI. Nhưng nhạy với độ trễ, tốn băng thông, chỉ một session tương tác (RDP vào là khoá màn hình người đang ngồi trước máy, và ngược lại), và yêu cầu Windows Pro trở lên — Windows Home không làm RDP host được.
- SSH nhẹ, chịu độ trễ tốt, hợp cho script và truyền file, và quan trọng nhất: là đường cứu hộ. RDP hỏng thì SSH vào chạy
Restart-Service TermServicecứu được; chiều ngược lại thì không.
Chi phí thêm ingress thứ hai gần như bằng 0 khi tunnel, DNS và Access policy đã dựng sẵn — nên không có lý do gì phải chọn một.
Ràng buộc vận hành
- Không có đường cứu hộ ngoài người ở văn phòng. Mọi thay đổi có khả năng làm máy mất mạng hoặc không boot (BIOS, driver mạng, firewall, Windows Update lớn) chỉ nên làm khi có người ở đó. Vì lý do này, việc bật “Restore on AC Power Loss” trong BIOS đã được hoãn có chủ ý — nó đòi reboot vào BIOS, mà lúc dựng thì chưa có đường remote nào để cứu nếu hỏng.
- Windows 10 đã hết hỗ trợ bảo mật. Máy không nhận bản vá nữa. Lớp Access đứng trước là thứ bù lại: kẻ tấn công không chạm được tới RDP nếu chưa qua xác thực email OTP.
- Đây là máy đặt tại công ty. Dựng tunnel ra ngoài về bản chất là mở một đường bypass firewall của họ; kỹ thuật thì trong suốt với IT (chỉ thấy outbound 443 tới Cloudflare) nhưng nên xin phép.
- Nếu firewall công ty chặn UDP outbound, QUIC (UDP 7844) không lên được — ép
protocol: http2để chạy trên TCP 443. - Sau khi tunnel chạy ổn, nên
Disable-NetFirewallRule -DisplayGroup "Remote Desktop"để đóng RDP với LAN công ty. Không ảnh hưởng kết nối qua tunnel vì cloudflared nối tớilocalhost, mà traffic loopback thì Windows Firewall không lọc. Kết quả: đường vào duy nhất là qua Cloudflare Access.
Khái niệm
Nguồn liên quan
- ssh-vao-pi-qua-cloudflare-tunnel-va-access — mô hình gốc mà ghi chú này mở rộng; so sánh Linux/systemd + local config với Windows service + remotely-managed tunnel.
- topology-mang-homelab — bối cảnh homelab và bài học về cửa sổ hở khi dựng đường vào trước khi dựng lớp chặn.
Người liên quan
Câu hỏi mở
- Tiến trình
cloudflared access rdphiện phải chạy tay trong Terminal mỗi phiên. Có nên gói thành LaunchAgent chạy nền trênopera— như đã làm cho tunnel Companion — hay việc chạy tay lại là một lớp an toàn có ích (không có đường hầm mở thường trực)? - Có nên nhờ bật “Restore on AC Power Loss” trong BIOS ở lần có người tại văn phòng tiếp theo không? Đổi lại là một lần reboot có rủi ro.
- Máy chạy Windows 10 hết hỗ trợ — nâng lên Windows 11, hay chấp nhận và dựa hoàn toàn vào lớp Access?