Triển khai Cloudflare Tunnel (cloudflared) trên VM Proxy
Cài đặt binary cloudflared và cấu hình Service Systemd
Ta cần cài đặt client tunnel của Cloudflare lên máy chủ Proxy đã chuẩn bị ở các phần trước. Việc này tạo ra một kết nối TCP an toàn, outbound từ hạ tầng nội bộ ra mạng Cloudflare, loại bỏ nhu cầu mở port firewall hay cấu hình NAT public.
Trước hết, tải binary cloudflared phiên bản mới nhất tương thích với kiến trúc CPU của Proxmox VM (thường là amd64) và đặt vào thư mục system binary.
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && sudo dpkg -i cloudflared.deb
Kết quả mong đợi: Package được cài đặt thành công, không có lỗi dependency. Command cloudflared version trả về phiên bản hiện tại.
Tiếp theo, tạo một user hệ thống riêng biệt để chạy service tunnel, đảm bảo nguyên tắc Least Privilege. Không chạy service này bằng root trực tiếp.
sudo useradd -r -s /bin/false cloudflared
Kết quả mong đợi: User 'cloudflared' được tạo, có home directory và shell bị khóa (/bin/false).
Tạo file cấu hình systemd để khởi động cloudflared tự động khi boot. File này sẽ trỏ đến config file YAML cụ thể mà chúng ta sẽ tạo ở bước sau.
sudo tee /etc/systemd/system/cloudflared.service > /dev/null
Kết quả mong đợi: File service được tạo tại /etc/systemd/system/cloudflared.service.
Reload systemd manager configuration và enable service để chạy ngay lập tức. Lưu ý chưa chạy vì config file chưa tồn tại.
sudo systemctl daemon-reload
Kết quả mong đợi: Không có lỗi, systemd nhận diện được service mới.
Đăng ký Tunnel và tạo file cấu hình YAML
Để tạo tunnel, bạn cần đăng nhập vào tài khoản Cloudflare qua CLI. Command này sẽ mở trình duyệt để bạn xác thực qua IdP hoặc email, sau đó lưu token vào hệ thống.
sudo cloudflared login
Kết quả mong đợi: Trình duyệt mở ra, sau khi xác thực thành công, CLI in ra thông tin tài khoản Cloudflare và token được lưu.
Tạo tunnel mới với tên gọi có ý nghĩa, ví dụ 'prod-internal-proxy'. Command này tạo resource tunnel trên dashboard Cloudflare và trả về Tunnel ID.
sudo cloudflared tunnel create prod-internal-proxy
Kết quả mong đợi: In ra dòng "Created tunnel prod-internal-proxy with ID [UUID-TUNNEL-ID]". Hãy sao chép UUID này.
Tạo thư mục cấu hình và file YAML chứa thông tin Tunnel ID và định tuyến. Thay thế [TUNNEL-ID] bằng UUID vừa tạo ở bước trước.
sudo mkdir -p /etc/cloudflared
sudo tee /etc/cloudflared/config.yml > /dev/null
Kết quả mong đợi: File config.yml được tạo với nội dung định tuyến hostname 'app.example.com' về IP nội bộ của máy chủ ứng dụng (ví dụ 192.168.1.100). Dòng 'https://404' là catch-all để từ chối mọi traffic không khớp.
Khởi động lại service cloudflared để áp dụng cấu hình.
sudo systemctl enable --now cloudflared
Kết quả mong đợi: Service chạy trạng thái 'active (running)'. Log không có lỗi khởi tạo.
Cấu hình Domain và Route cho ứng dụng nội bộ
Thiết lập DNS và Route trên Dashboard Cloudflare
Truy cập vào Dashboard Cloudflare, chọn Zone (Domain) của bạn (ví dụ: example.com). Mục tiêu là trỏ tên miền nội bộ qua Cloudflare Access thay vì DNS trực tiếp.
Vào mục 'Tunnel' trên sidebar, chọn tunnel 'prod-internal-proxy' vừa tạo. Nhấn 'Add public hostnames' để khai báo tên miền nào sẽ đi qua tunnel này.
Nhập hostname là app.example.com. Trong phần 'Origin Host', nhập lại app.example.com (hoặc IP nội bộ nếu cần, nhưng tốt nhất là dùng hostname để tránh loop). Đảm bảo 'Enable Access' được bật (checkbox).
Kết quả mong đợi: Dashboard hiển thị trạng thái 'Connected' cho tunnel và route đã được thêm vào danh sách Public Hostnames.
Chuyển sang tab 'DNS' của Domain, tạo hoặc chỉnh sửa record A/CNAME cho app.example.com. Quan trọng: Record này phải trỏ về Cloudflare (Cloudflare Proxy bật, icon mây màu cam). Không cần trỏ về IP public của server, vì traffic đã đi qua Tunnel.
# Ví dụ về cấu hình DNS trong Zone Editor
# Type: CNAME | Name: app | Content: app.example.com | Proxy: Proxied
Kết quả mong đợi: DNS record được tạo, icon mây màu cam. Khi ping từ internet, bạn sẽ thấy IP của Cloudflare Edge, không phải IP nội bộ.
Thiết lập chính sách truy cập (Access Policy)
Tạo Application và liên kết với Tunnel
Vào mục 'Zero Trust' > 'Access' > 'Applications' trên Dashboard Cloudflare. Nhấn 'Add application'.
Chọn loại 'Self-hosted'. Nhập tên ứng dụng (ví dụ: 'Internal Dashboard'). Trong phần 'Domain', chọn dropdown và tìm app.example.com (nó sẽ hiện ra vì đã cấu hình tunnel ở phần trước).
Trong phần 'Gateway', chọn 'Cloudflare Gateway' nếu cần lọc traffic, hoặc bỏ qua nếu chỉ cần xác thực người dùng. Chọn 'Custom domain' nếu cần SSL riêng, nhưng ở đây dùng 'Cloudflare issued certificate' cho đơn giản.
Kết quả mong đợi: Application được tạo, trạng thái 'Configured'. Cloudflare đã biết route traffic đến tunnel này.
Định nghĩa Policy dựa trên Identity Provider (IdP)
Vào tab 'Configuration' của Application vừa tạo. Nhấn 'Add policy' để tạo quy tắc cho phép hoặc từ chối.
Tên policy: Allow Employees. Action chọn Allow. Trong phần điều kiện (Include), chọn 'Email' hoặc 'Group' tùy thuộc vào IdP bạn đã cấu hình ở Phần 2.
Ví dụ, nếu dùng Google Workspace hoặc Azure AD, chọn điều kiện email ends with @example.com hoặc group equals Engineering.
Kết quả mong đợi: Policy được lưu. Người dùng không thuộc điều kiện này sẽ tự động bị từ chối (do chính sách mặc định là Deny).
Bật tính năng MFA và Time-based Access
Cấu hình Multi-Factor Authentication (MFA)
Vẫn trong tab 'Configuration' của Application, tìm mục 'Authentication' hoặc 'MFA'. Bật tính năng 'Require MFA'.
Chọn loại MFA: 'Cloudflare WARP' (nếu dùng client), 'TOTP', hoặc 'WebAuthn'. Để bảo mật cao nhất cho doanh nghiệp, chọn 'TOTP' (Google Authenticator/Microsoft Authenticator) hoặc 'Duo Security' nếu đã tích hợp.
Kết quả mong đợi: Người dùng khi đăng nhập lần đầu sẽ được yêu cầu nhập mã OTP hoặc xác thực sinh trắc học trước khi truy cập ứng dụng.
Cấu hình Time-based Access (Giờ truy cập)
Quay lại phần 'Add policy' hoặc chỉnh sửa policy 'Allow Employees' đã tạo. Tìm mục 'Conditions' > 'Time'.
Chọn 'Weekday' (Thứ 2 - Thứ 6) và 'Time of day' (ví dụ 08:00 - 18:00). Điều này đảm bảo nhân viên chỉ truy cập được trong giờ hành chính.
Kết quả mong đợi: Policy có thêm ràng buộc thời gian. Nếu người dùng truy cập ngoài khung giờ này, Cloudflare Access sẽ trả về lỗi 403 Forbidden ngay lập tức.
Kiểm tra khả năng truy cập từ bên ngoài
Verify kết nối và luồng truy cập
Mở một trình duyệt ẩn danh (Incognito) từ một máy tính nằm ngoài mạng nội bộ (ví dụ dùng 4G điện thoại).
Truy cập URL: https://app.example.com.
Kết quả mong đợi 1: Trình duyệt chuyển hướng đến trang đăng nhập Cloudflare Access (login.cloudflareaccess.com). Không thấy trang web nội bộ ngay lập tức.
Kết quả mong đợi 2: Sau khi nhập email, hệ thống yêu cầu xác thực IdP (Google/Azure) và sau đó yêu cầu MFA (OTP).
Kết quả mong đợi 3: Sau khi xác thực thành công và nằm trong khung giờ cho phép, người dùng được chuyển vào ứng dụng nội bộ (ví dụ trang dashboard).
Để kiểm tra log, mở terminal trên VM Proxy và xem log của cloudflared.
sudo journalctl -u cloudflared -f | grep "ingress"
Kết quả mong đợi: Thấy log ghi nhận request HTTP từ Cloudflare Edge đi vào tunnel và forward về service nội bộ (192.168.1.100:8080).
Thử truy cập vào một hostname không được định nghĩa trong tunnel (ví dụ: random.example.com) đã trỏ về Cloudflare.
Kết quả mong đợi: Nhận được trang 404 hoặc lỗi 502 Bad Gateway tùy cấu hình, chứng tỏ traffic đã đi qua Cloudflare nhưng không có route khớp, xác nhận cơ chế bảo vệ điểm cuối đang hoạt động đúng.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng Zero-Trust Network cho doanh nghiệp với OpenZiti, Cloudflare Access và Identity-aware Proxy trên hạ tầng Proxmox
« Phần 3: Xây dựng hạ tầng OpenZiti: Controller và Edge Router
Phần 5: Triển khai Identity-aware Proxy (Oauth2-Proxy) và tích hợp OpenZiti »