Chuyển tiếp SSH động làm proxy SOCKS trên VPN của bạn
Một ứng dụng chỉ nói SOCKS không có điểm cuối proxy trên một VPN thông thường. Hai chặng, một trình lắng nghe loopback và một lần tra tên mà máy chủ SSH phải tự làm.
Một ứng dụng chỉ nói SOCKS không có gì để nói chuyện trên một VPN thông thường, vì đường hầm chở gói tin còn ứng dụng muốn một điểm cuối proxy. OpenSSH có thể cung cấp điểm cuối đó khi chủ sở hữu quyền truy cập cho phép, vì chuyển tiếp động biến một phiên SSH thành proxy cục bộ. Sau đó có hai chặng phải giữ riêng: đường hầm tới máy chủ SSH và kết nối mà máy chủ đó mở tiếp. Tách chúng ra giải thích cả vì sao cách bố trí này hoạt động lẫn điều nó sẽ không bao giờ làm.
Trình lắng nghe SSH trở thành gì và không trở thành gì
Chuyển tiếp động buộc máy khách SSH lắng nghe cục bộ và nói SOCKS4 hoặc SOCKS5 với mọi thứ kết nối tới. Mỗi yêu cầu nêu một đích và máy chủ SSH mở kết nối tiếp theo, đó là lý do việc tra đích có thể diễn ra ở phía xa. Đây là chuyển tiếp TCP ở tầng ứng dụng, không phải VPN cho toàn bộ thiết bị. Nó không mang theo liên kết UDP, không ICMP, và không gì cho các ứng dụng bỏ qua hoàn toàn cài đặt proxy. Chặng từ máy chủ SSH tới ứng dụng cũng không nằm trong đường hầm của bạn, điều này quan trọng khi đích chỉ nhận lưu lượng từ những mạng đã biết.
Các điều kiện tiên quyết là thật: một tuyến tới máy chủ SSH, một tài khoản được cấp quyền, một khóa máy chủ đã xác minh và quyền chuyển tiếp. Không điều nào do proxy tạo ra, và điều cuối thường thiếu trước tiên. Xác nhận cả bốn trước khi gỡ lỗi bất cứ điều gì khác, vì từ phía máy khách lỗi trông giống nhau, thiếu điều nào cũng vậy.
Khởi động nó trên loopback với một cổng rõ ràng
Chọn một cổng cục bộ chưa dùng và gắn nó rõ ràng vào loopback thay vì bỏ trống địa chỉ. Ba tùy chọn dưới đây tồn tại mỗi cái vì một lý do.
ssh -D 127.0.0.1:1080 -NT -o ControlPath=none -o ExitOnForwardFailure=yes \
[email protected]
-N bỏ qua lệnh từ xa và -T bỏ qua pseudo-terminal, nên phiên chỉ tồn tại để chuyển tiếp. ExitOnForwardFailure khiến máy khách thoát khi không tạo được trình lắng nghe, thay vì chạy mà không có chuyển tiếp bạn yêu cầu. ControlPath=none giữ phiên ngoài một kết nối ghép kênh sẵn có có thể thêm chuyển tiếp của riêng nó. Loopback giữ trình lắng nghe ngoài LAN, nhưng trên một máy dùng chung đó không phải ranh giới cấp quyền, vì các tiến trình cục bộ khác cũng chạm tới được. Tài liệu tham chiếu máy khách OpenSSH ghi lại tất cả các cờ này, và cảnh báo về loopback xuất phát từ việc socket lắng nghe là gì.
Gửi tên qua proxy, không đi vòng qua nó
Một máy khách SOCKS5 có thể tự phân giải đích hoặc nhờ proxy làm việc đó, và lựa chọn ấy quyết định trình phân giải nào trả lời. Với socks5h, curl gửi tên máy chủ qua proxy, nên việc tra cứu diễn ra trên máy chủ SSH. Với socks5 thường, máy tính xách tay phân giải trước và chỉ kết nối di chuyển, điều này âm thầm vô hiệu mục đích khi tên là nội bộ. Yêu cầu bên dưới cũng xóa danh sách không-proxy, để một giá trị NO_PROXY thừa hưởng không thể dẫn nó vòng qua proxy.
curl -sS --noproxy '' --proxy socks5h://127.0.0.1:1080 https://app.corp.example/health
Việc kiểm tra chứng chỉ và đăng nhập của chính ứng dụng vẫn áp dụng, vì proxy không thay thế cả hai. Còn lại hai lần tra: máy tính xách tay phải tới được máy chủ SSH qua đường VPN và DNS được phép, và máy chủ SSH phải tự phân giải tên ứng dụng. Lần thứ hai có thể thử riêng trước khi bất kỳ lưu lượng nào đi qua proxy.
ssh [email protected] getent hosts app.corp.example
Chứng minh một đích được phép, rồi đóng phiên
Hãy thử một đích mà chính sách cho phép và một đích mà nó phải từ chối, vì chuyển tiếp hoạt động chỉ chứng minh trình lắng nghe hoạt động và không hơn thế. Ứng dụng thấy địa chỉ nguồn mà máy chủ SSH chọn, và đó không phải địa chỉ đường hầm của máy tính xách tay bạn. Ở nơi đầu xa ghi nhật ký kết nối theo nguồn, khác biệt đó là thứ đầu tiên cần xem khi một yêu cầu bị từ chối.
Dừng phiên qua tiến trình sở hữu nó thay vì giết một shell không liên quan. Sau đó xác nhận trình lắng nghe đã biến mất, vì một cổng còn trả lời là một phiên bạn chưa thật sự đóng. Chỉ gỡ cài đặt proxy mà bài tập này đưa vào, và để phần còn lại của cấu hình ứng dụng yên. Một terminal không người trông coi đang giữ quy tắc chuyển tiếp không phải là dịch vụ, và một proxy thường trực cần vòng đời được phê duyệt, không phải một cửa sổ bị lãng quên.
ss -ltn | grep 1080
Những hỏng hóc mà cách bố trí này không sửa được
Một số triệu chứng chỉ thẳng vào các giới hạn ở trên, và nhận ra sớm tiết kiệm một buổi chiều gỡ lỗi proxy. Bảng ánh xạ điều bạn thấy với điều nó thường có nghĩa. Mọi thứ ở cột cuối là câu hỏi thiết kế, không phải lỗi cấu hình.
| What you see | What it usually means | Where to look |
|---|---|---|
| The app connects and nothing follows | It ignores proxy settings entirely | Its own network settings, not the SSH session |
| A name resolution error for the destination | The SSH server cannot resolve it | Server resolver and search domains |
| A UDP-only application fails | Dynamic forwarding carries TCP only | This arrangement cannot serve it |
| curl works, the browser does not | The browser is not using the socks5h endpoint | Browser proxy configuration |
| The listener answers after the session ended | Another process owns port 1080 | The ss output, then the owning process |
Ba hàng đầu là những hàng người ta chẩn đoán sai, vì mỗi hàng tạo ra một nỗ lực kết nối thay vì một lỗi về chính proxy. Một tên phân giải được trên máy tính xách tay không nói gì về trình phân giải của máy chủ, và lỗi được đọc thành vấn đề chứng chỉ hoặc quá thời gian. Các ứng dụng chỉ dùng UDP nằm ngoài thiết kế, không phải hỏng bên trong nó, và không tùy chọn ssh thêm nào thay đổi điều đó. Hàng về trình duyệt là lời nhắc quen thuộc rằng cài đặt proxy là theo từng ứng dụng. Hàng cuối là lý do tồn tại của việc kiểm tra đóng: một cổng vẫn lắng nghe nghĩa là giờ đây thứ khác sở hữu nó.