2 điểm bởi zxsi2003 12 ngày trước | 4 bình luận | Chia sẻ qua WhatsApp

Xin chào. Đây là công cụ tôi tạo ra vì liên tục gặp tình huống chỉ muốn tạm thời
chuyển lưu lượng ở một cổng cụ thể đang hướng ra máy chủ bên ngoài
sang một mock server chạy cục bộ. (có sử dụng Claude Code)

File hosts không hỗ trợ ánh xạ theo từng cổng, còn proxy thì
chỉ hoạt động khi ứng dụng
nhận biết và hỗ trợ proxy. detour chặn gói tin ở tầng thấp hơn (kernel), nên
ứng dụng vẫn nghĩ rằng nó đang dial tới địa chỉ gốc
và tiếp tục hoạt động như bình thường.

Cách hoạt động

  • Dùng driver WinDivert để chặn các gói outbound trong kernel, rồi
    ở userspace
    thực hiện destination NAT → rewrite đích thành TO, tính lại checksum
    rồi đưa gói trở lại
  • Với gói phản hồi, rewrite src lại thành FROM
    rồi trả về, vì vậy
    ứng dụng sẽ nhận biết như thể chính địa chỉ mà nó đã dial đang phản hồi
  • Áp dụng cho toàn hệ thống (không có lọc theo PID)

Thành phần

  • detour.exe (CLI): áp dụng rule chỉ với một dòng --from 1.2.3.4:5000 --to 127.0.0.1:5001,
    nhấn Ctrl+C để gỡ bỏ
  • detour-gui.exe: biểu tượng khay hệ thống + bảng nhiều rule.
    Tự động lưu rule vào %APPDATA%\detour\rules.json và khôi phục ở lần chạy tiếp theo.
    Mỗi rule chạy với một cặp handle WinDivert độc lập nên có thể vận hành nhiều chuyển hướng
    cùng lúc
  • Nhúng UAC manifest — nhấp đúp sẽ tự động hiện hộp thoại nâng quyền
  • WinDivert.dll / WinDivert64.sys cũng được nhúng vào binary —
    không cần cài driver riêng,
    chỉ một file exe là xong

Stack

  • Go 1.23+
  • GUI dùng lxn/walk (gọi trực tiếp Win32, không phụ thuộc cgo nên
    có thể cross-compile từ macOS)
  • Bản phát hành được đóng gói thành một file zip duy nhất bằng GoReleaser (kèm cả CLI + GUI)

Giới hạn (v1)

  • Chỉ hỗ trợ IPv4 (chưa hỗ trợ IPv6)
  • Lưu lượng local ↔ local (127.0.0.1) có thể hoạt động không nhất quán vì Windows networking stack
    xử lý trường hợp này theo cách đặc biệt
  • Chưa triển khai TCP MSS clamping — nếu MTU của đường chuyển hướng nhỏ thì có thể xảy ra
    fragmentation

Giấy phép là GPLv3 (WinDivert phụ thuộc LGPLv3).
Rất hoan nghênh phản hồi / tình huống sử dụng / báo cáo lỗi.

4 bình luận

 

Vậy là proxy đúng không..?

 

Nói chính xác thì có thể xem đây là Destination NAT hơn là proxy. Vì phần mô tả ở trên quá dài nên tôi xin tóm tắt trường hợp sử dụng của mình bên dưới.

  1. Muốn gửi yêu cầu không tới đích của chương trình client đã được build sẵn (1.2.3.4.:5000) mà tới máy chủ trên PC cục bộ của tôi (172.16.100.201:5000).

  2. Đường đi của yêu cầu bị hardcode nên trong nhiều trường hợp, nếu muốn thay đổi thì phải nhờ phía nhà phát triển client build lại.

  3. Tôi muốn giải quyết bằng cách thay đổi header đích và điểm đến của lưu lượng đi tới IP, Port cụ thể (1.2.3.4.:5000) ở tầng kernel của OS, thay vì ở tầng ứng dụng, thành IP, Port mong muốn (172.16.100.201:5000).

  4. Phát triển detour

 

Các yêu cầu được nhập bằng địa chỉ domain cũng có thể được proxy không?

 

Trong trường hợp yêu cầu được nhập bằng địa chỉ domain, chúng tôi đánh giá độ phức tạp khi triển khai sẽ tăng lên nên ngay từ đầu đã không cho phép nhập... Vì được phát triển để thử nghiệm nội bộ nên không hỗ trợ các tính năng mang tính phổ dụng.
Có thể tìm IP cho một domain cụ thể bằng nslookup rồi cấu hình.

Chúng tôi sẽ cố gắng áp dụng vào các bản cập nhật sau.