Sổ tay kỹ thuật

Cloudflare Tunnel – publish dịch vụ nội bộ không mở port

how-to#cloudflare-tunnel#linux#tls· cập nhật 2026-11-06

Dùng khi cần đưa web/SSH nội bộ ra internet qua Cloudflare mà không mở port inbound, không cần IP public.

Sửa trang này
Mục lục

Tóm tắt: cloudflared chạy trên máy nội bộ, mở kết nối outbound tới Cloudflare edge. Tạo tunnel bằng cloudflared tunnel create, gắn hostname bằng cloudflared tunnel route dns, khai báo ingress trong config.yml, cài thành service systemd, rồi bảo vệ bằng Cloudflare Access. Domain phải đang dùng DNS của Cloudflare.

Luồng hoạt động

flowchart LR U[Người dùng] -->|HTTPS| E["Cloudflare edge + Access"] E <-->|"tunnel outbound (QUIC/HTTP2)"| C[cloudflared] C -->|HTTP| A["app 127.0.0.1:8000"] C -->|SSH| S["sshd 127.0.0.1:22"]

TLS từ người dùng terminate ở Cloudflare edge. cloudflared nói chuyện với origin theo service: khai báo (thường là HTTP nội bộ).

Lệnh

Tạo tunnel (locally-managed)

# Cài trên Debian/Ubuntu: theo hướng dẫn repo pkg.cloudflare.com, rồi
cloudflared --version
 
cloudflared tunnel login                      # mở trình duyệt, chọn zone; tạo ~/.cloudflared/cert.pem
cloudflared tunnel create netlab              # in ra Tunnel ID, tạo ~/.cloudflared/<UUID>.json
cloudflared tunnel list
cloudflared tunnel route dns netlab grafana.example.com   # tạo CNAME -> <UUID>.cfargotunnel.com
cloudflared tunnel route dns netlab ssh.example.com

config.yml

/etc/cloudflared/config.yml
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /etc/cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
 
ingress:
  - hostname: grafana.example.com
    service: http://127.0.0.1:3000
  - hostname: ssh.example.com
    service: ssh://127.0.0.1:22
  - hostname: nms.example.com
    service: https://127.0.0.1:8443
    originRequest:
      noTLSVerify: true          # origin dùng cert self-signed
  - service: http_status:404     # rule cuối bắt buộc, bắt mọi request còn lại

Rule được so từ trên xuống, khớp rule nào dùng rule đó. hostname hỗ trợ wildcard *.example.com, có thể thêm path: (regex).

sudo mkdir -p /etc/cloudflared
sudo cp ~/.cloudflared/<UUID>.json /etc/cloudflared/
cloudflared tunnel --config /etc/cloudflared/config.yml ingress validate
cloudflared tunnel --config /etc/cloudflared/config.yml ingress rule https://grafana.example.com
cloudflared tunnel --config /etc/cloudflared/config.yml run netlab   # chạy thử foreground

Chạy như service systemd

sudo cloudflared service install          # đọc /etc/cloudflared/config.yml, tạo unit cloudflared.service
sudo systemctl enable --now cloudflared
journalctl -u cloudflared -f

Cách khác (tunnel quản lý trên dashboard Zero Trust, không cần config.yml): tạo tunnel trên dashboard, copy token rồi chạy sudo cloudflared service install <TOKEN>. Ingress lúc này cấu hình trên dashboard, file local bị bỏ qua.

Chi tiết unit file, restart policy: systemd service.

Bảo vệ bằng Cloudflare Access

Trên dashboard Zero Trust → Access → Applications → Add an application → Self-hosted: nhập hostname (grafana.example.com), tạo policy Allow với rule Emails ending in @example.com hoặc nhóm IdP. Người dùng phải đăng nhập trước khi request tới được tunnel.

SSH qua Access từ máy client:

~/.ssh/config
Host ssh.example.com
  ProxyCommand cloudflared access ssh --hostname %h

Origin có thể xác thực JWT trong header Cf-Access-Jwt-Assertion để chắc chắn request đã qua Access.

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Truy cập hostname báo lỗi 1033 Tunnel không có connector nào đang chạy cloudflared tunnel info netlab, systemctl status cloudflared
HTTP 502 Bad Gateway service: sai port/giao thức, origin chưa chạy curl -v http://127.0.0.1:3000 trên máy chạy cloudflared
Mọi hostname đều 404 Rơi vào rule cuối http_status:404, hostname không khớp cloudflared tunnel ingress rule https://<host>
x509: certificate signed by unknown authority tới origin Origin HTTPS dùng cert tự ký originRequest.noTLSVerify: true hoặc caPool
Service không đọc config, chạy sai tunnel Config ở ~/.cloudflared nhưng service chạy root đọc /etc/cloudflared Chuyển config + credentials sang /etc/cloudflared/
route dns báo record đã tồn tại Đã có A/CNAME cùng tên Xoá record cũ trên dashboard hoặc dùng --overwrite-dns
Kết nối chập chờn, log báo lỗi QUIC Firewall chặn UDP 7844 ra ngoài Mở UDP/TCP 7844 outbound hoặc --protocol http2
App sinh link http://, redirect loop App không biết TLS đã terminate ở edge Đọc X-Forwarded-Proto, xem Vite app sau Nginx

Tham khảo