socat qua HTTP CONNECT: mở luồng TCP qua proxy và kiểm thử
socat qua HTTP CONNECT là cách dùng địa chỉ PROXY của socat để mở một luồng TCP bất kỳ qua proxy HTTP, ví dụ SSH hay TLS. ProxyVN đọc mã nguồn socat 1.8.1.3 và dựng lab echo TCP. Lab chỉ ra socat gửi gì tới proxy và vì sao tệp mật khẩu thừa dấu xuống dòng làm hỏng xác thực.
socat qua HTTP CONNECT: tác vụ cụ thể và ranh giới với bài đã có
Việc bài này giải quyết
Tình huống hay gặp là máy chỉ ra Internet được qua một proxy HTTP, nhưng anh em cần nối tới một dịch vụ không phải web. Ví dụ SSH tới máy chủ ở cổng 22, gọi một broker ở cổng riêng, hoặc chuyển tiếp một cổng cục bộ tới API bên ngoài. Trình duyệt và curl tự biết dùng proxy, còn ssh hay một chương trình cũ thì không.
socat lấp khoảng trống đó. Nó nhận dữ liệu từ một đầu, ví dụ bàn phím hay một cổng đang nghe, rồi đẩy sang đầu kia là địa chỉ PROXY. Ở đầu PROXY, socat gửi yêu cầu CONNECT tới proxy, chờ trả lời 200, sau đó chỉ chuyển byte qua lại.
Đầu ra cần có sau bài: một lệnh socat có timeout, một echo server để kiểm, và bảng đọc lỗi theo mã trả lời của proxy.
Ranh giới với các bài khác
Bài proxy tunnel là gì giải thích khái niệm tunnel và cách curl, Python đi qua proxy. Bài Wireshark proxy chỉ cách đọc gói CONNECT trên giao diện đồ họa. Bài này không nhắc lại phần khái niệm, chỉ đi vào cú pháp PROXY của socat, các tùy chọn của nó, cách socat phản ứng với từng kiểu trả lời và cách đóng gói lệnh để dùng lâu dài.
Ncat cũng mở được kết nối qua proxy, nhưng đó là công cụ chẩn đoán khác. Bài này không so hai công cụ dòng lệnh với nhau, chỉ nói về socat.
Phạm vi kiểm thử
Máy lab chạy Windows 10, không có bản socat dựng sẵn. Bài đọc trang man socat trên Debian và tệp xio-proxy.c trong gói mã nguồn socat 1.8.1.3 tải từ trang chủ socat của tác giả ngày 29/10/2026. Lab viết bằng Python 3.12: một echo server, một proxy HTTP có kiểm tài khoản và danh sách cổng cho phép, và một client gửi đúng từng byte mà hàm _xioopen_proxy_connect của socat gửi. Lab không chạy binary socat, nên kết quả mô tả giao thức chứ không đo hiệu năng của socat.
Địa chỉ PROXY mở luồng TCP socat qua HTTP CONNECT
Phần này đi từ cú pháp tới từng byte trên dây. Hiểu đúng bước bắt tay thì đọc lỗi nhanh hơn nhiều.
Cú pháp địa chỉ PROXY
Trang man ghi cú pháp là PROXY:<proxy>:<hostname>:<port>. Phần đầu là máy proxy, hai phần sau là đích mà proxy sẽ nối tới. Cổng của proxy không nằm trong ba phần này mà đặt bằng tùy chọn proxyport, mặc định là 8080 theo hằng số PROXYPORT trong mã nguồn.
Đây là chỗ nhiều người gõ nhầm. Viết PROXY:proxy.example.com:3128:đích:cổng sẽ không chạy, vì socat hiểu 3128 là tên máy đích. Cổng proxy luôn đi qua proxyport=3128.
socat - PROXY:proxy.example.com:echo.example.net:7,proxyport=3128
Lệnh trên nối bàn phím tới cổng 7 của echo.example.net qua proxy ở cổng 3128. Dấu gạch ngang đơn là STDIO, tức đầu vào và đầu ra của terminal.
Socat gửi gì tới proxy
Hàm _xioopen_proxy_connect trong xio-proxy.c dựng dòng yêu cầu bằng định dạng "CONNECT %s:%u HTTP/%s\r\n". Phiên bản mặc định là 1.0. Nếu có tài khoản, socat gửi thêm một dòng tiêu đề viết là "Proxy-authorization: Basic" kèm chuỗi base64, rồi một dòng trống để kết thúc.
Socat không gửi tiêu đề Host. Trang man nói rõ tùy chọn http-version chỉ đổi con số sau chữ HTTP và không có cách nào gửi Host. Theo RFC 9110 mục CONNECT, proxy có quyền giới hạn cổng và từ chối yêu cầu không hợp lệ. Proxy nào bắt buộc Host với CONNECT HTTP/1.1 sẽ từ chối, khi đó giữ mặc định 1.0.
Trong lab, proxy ghi lại dòng yêu cầu và danh sách tiêu đề nhận được. Với tài khoản user1, dòng yêu cầu là CONNECT echo.test:9471 HTTP/1.0, chỉ có một tiêu đề proxy-authorization, cả yêu cầu dài 84 byte.
Socat đọc trả lời ra sao

Bảng mã trả lời của proxy
Mã nguồn đọc trả lời từng ký tự theo một máy trạng thái. Dòng trạng thái phải bắt đầu bằng "HTTP/1.0 " hoặc "HTTP/1.1 ", sau đó bỏ qua khoảng trắng và so ba ký tự với "200". Khác 200 thì socat in ra dòng CONNECT kèm phần lý do của proxy rồi trả về trạng thái thử lại sau.
Socat chỉ nhận mã 200, kể cả các mã 2xx khác cũng bị coi là lỗi. Phần tiêu đề phía sau được đọc và in ở mức info, không ảnh hưởng kết quả. Toàn bộ phần trả lời không được vượt 2048 byte, đó là giá trị BUFLEN trong xio-proxy.c. Vượt mức này, socat báo lỗi và không thử lại.
Sau khi có 200
Khi proxy trả 200, socat không gửi thêm gì của HTTP nữa. Từ đây mọi byte từ đầu bên kia đi thẳng tới đích qua proxy. Vì vậy giao thức bên trong có thể là SSH, TLS hay văn bản thường, proxy không đọc được nội dung nếu giao thức đó có mã hóa.
Chuẩn bị phiên bản, tài khoản và lab cho socat qua HTTP CONNECT
Chuẩn bị kỹ ở bước này giúp lần chạy đầu cho kết quả đọc được, thay vì một lỗi chung chung.
Ghi phiên bản
Chạy socat -V để in phiên bản và các tính năng đã biên dịch. Dòng có chữ WITH_PROXY cho biết bản đó có hỗ trợ địa chỉ PROXY. Bản trong kho Debian, Ubuntu hay Homebrew thường bật sẵn.
Ghi phiên bản vào ghi chú vận hành. Trang man nhắc từ bản 1.8.0.1, tùy chọn -T0 nghĩa là hết giờ ngay chứ không còn là vô hạn như trước. Một lệnh cũ dùng -T0 có thể đổi hành vi khi nâng cấp.
Tài khoản proxy
Proxy HTTP thường cấp tài khoản dạng host, cổng, user và mật khẩu. Bài định dạng proxy chỉ cách tách chuỗi ip:port:user:pass thành từng phần. Với socat, host đi vào phần đầu của địa chỉ PROXY, cổng đi vào proxyport, còn user và mật khẩu đi vào proxyauth hoặc một tệp riêng.
Kiểm trước rằng proxy cho phép CONNECT tới cổng đích. Nhiều proxy chỉ mở CONNECT tới cổng 443. Muốn SSH cổng 22 thì phải hỏi nhà cung cấp hoặc đổi máy đích sang nghe ở cổng được phép.
Echo server để kiểm
Đích kiểm tốt nhất là một echo server do chính anh em dựng, vì nó trả lại đúng chuỗi đã gửi. Có dòng trả về là biết đường đi thông hai chiều. Trên một máy chủ Linux có quyền, có thể dùng chính socat làm echo server.
# Tren may dich, nghe cong 9471 va tra lai moi dong nhan duoc
socat -v TCP-LISTEN:9471,reuseaddr,fork EXEC:cat
Tùy chọn fork cho phép nhiều kết nối, reuseaddr cho phép khởi động lại ngay mà không chờ cổng giải phóng. Lab của bài dùng một echo server Python tương đương, trả về chuỗi có tiền tố "echo:".
Sơ đồ client, proxy và đích

Ba bên client, proxy, đích
Có ba bên. Client chạy socat, proxy nhận CONNECT, đích là echo server. Client chỉ cần ra được cổng của proxy. Proxy cần ra được cổng của đích. Tên máy đích được proxy phân giải, trừ khi bật tùy chọn resolve.
Khi đọc log, luôn ghi bên nào thấy gì. Client thấy mã trả lời của proxy. Proxy thấy dòng CONNECT và kết quả nối tới đích. Đích thấy địa chỉ IP của proxy, không thấy IP của client.
Cấu hình tối thiểu socat qua HTTP CONNECT và phạm vi từng tùy chọn
Mỗi tùy chọn dưới đây chỉ tác động tới một chặng. Đặt sai chặng là nguyên nhân của phần lớn lỗi.
Lệnh tối thiểu có timeout
socat -d -d -T 30 - PROXY:proxy.example.com:echo.example.net:9471,proxyport=3128,proxyauthfile=/home/u/.socat-proxy,connect-timeout=10
Hai cờ -d -d in thông báo mức notice, đủ để thấy dòng "opening connection" và "successfully connected". Muốn xem từng dòng gửi và nhận với proxy thì dùng -d -d -d để lên mức info.
-T 30 là thời gian không hoạt động tối đa sau khi đã vào vòng chuyển dữ liệu. connect-timeout=10 chỉ áp dụng cho bước nối TCP tới proxy. Hai giới hạn này khác nhau, nên đặt cả hai cho lệnh chạy tự động.
proxyauth và proxyauthfile
proxyauth=user:mật khẩu đưa tài khoản thẳng vào dòng lệnh. Trang man cảnh báo hai điều. Mật khẩu hiện trong danh sách tiến trình, ai chạy ps trên máy cũng thấy. Proxy nhận mật khẩu dưới dạng base64, không mã hóa.
proxyauthfile=đường dẫn đọc tài khoản từ tệp để khỏi lộ trong ps. Mã nguồn chỉ cho dùng một trong hai, có cả hai thì socat báo lỗi và dừng. Tệp nên có quyền 600 và chỉ người chạy socat đọc được.
Bẫy dấu xuống dòng trong tệp tài khoản

Tệp mật khẩu thừa dấu xuống dòng
Đọc hàm _xioopen_proxy_init sẽ thấy socat đọc toàn bộ tệp theo độ dài tệp, không cắt khoảng trắng hay dấu xuống dòng ở cuối. Toàn bộ nội dung đó được mã hóa base64 rồi gửi đi.
Lệnh echo trong shell luôn thêm dấu xuống dòng. Tệp tạo bằng echo 'user1:p@ss#2026' > tệp sẽ chứa thêm một ký tự \n. Trong lab, proxy giải mã được chuỗi 'user1:p@ss#2026\n' và trả 407.
# Sai: echo them \n vao cuoi tep
echo 'user1:p@ss#2026' > ~/.socat-proxy
# Dung: printf khong them \n
printf '%s' 'user1:p@ss#2026' > ~/.socat-proxy
chmod 600 ~/.socat-proxy
Gặp 407 dù mật khẩu đúng, việc đầu tiên là kiểm byte cuối của tệp bằng lệnh xxd hoặc od -c. Trình soạn thảo như vim cũng tự thêm dòng mới khi lưu, nên tạo tệp bằng printf an toàn hơn.
Mật khẩu có ký tự đặc biệt
Với proxyauth trên dòng lệnh, dấu phẩy và dấu hai chấm có nghĩa riêng trong cú pháp địa chỉ của socat. Mật khẩu chứa dấu phẩy sẽ bị cắt, phần sau bị hiểu là tùy chọn khác. Dùng proxyauthfile tránh được chuyện này vì nội dung tệp không qua bộ phân tích cú pháp.
Ký tự @ và # trong mật khẩu không gây vấn đề với socat, vì socat không ghép tài khoản vào URL. Lab dùng mật khẩu p@ss#2026 và xác thực thành công ở cả hai cách truyền.
resolve và tên máy đích
Mặc định socat gửi tên máy đích nguyên văn trong dòng CONNECT, proxy phân giải tên. Bật tùy chọn resolve thì socat tự phân giải trên máy client, chỉ lấy địa chỉ IPv4, rồi gửi IP. Lab xác nhận dòng yêu cầu đổi thành CONNECT 127.0.0.1:9471.
Giữ mặc định khi máy client không có DNS ra ngoài, hoặc khi muốn tên được phân giải ở phía proxy. Chỉ bật resolve khi proxy không phân giải được tên trong mạng nội bộ mà client biết.
ignorecr với proxy trả lời sai chuẩn
HTTP yêu cầu mỗi dòng kết thúc bằng CR và LF. Một số proxy tự viết chỉ trả LF. Không có ignorecr, socat tiếp tục chờ CR và treo tới khi hết giờ. Lab mô phỏng proxy trả LF và thấy client dừng ở trạng thái chờ, bật ignorecr thì đọc được 200 và chuyển dữ liệu bình thường.
Proxy thương mại thường trả đúng chuẩn. ignorecr chỉ dùng khi log -d -d -d cho thấy dòng trạng thái đã tới mà socat vẫn không đi tiếp.
Chạy đối chứng socat qua HTTP CONNECT và đọc log
Phần này ghi lại các ca đã chạy trong lab và cách đọc từng ca. Mỗi ca chỉ đổi một yếu tố so với ca chuẩn.
Mã lab
Proxy lab trả 407 khi thiếu hoặc sai tài khoản, 403 khi cổng đích không nằm trong danh sách cho phép gồm 9471 và 443, 502 khi không nối được tới đích. Client gửi đúng thứ tự byte như socat, rồi xét trả lời theo luật trong xio-proxy.c.
def socat_like(target, port, auth=None, version="1.0"):
s = socket.create_connection(("127.0.0.1", 9472), timeout=3)
s.sendall(f"CONNECT {target}:{port} HTTP/{version}\r\n".encode())
if auth is not None:
s.sendall(b"Proxy-authorization: Basic " + base64.b64encode(auth) + b"\r\n")
s.sendall(b"\r\n")
# doc den dong trong, chi nhan "HTTP/1.x 200"
Đoạn trên là phần lõi của tệp t256.py. Mã đầy đủ có thêm echo server, proxy và vòng lặp chạy các ca.
Bảng kết quả
Bảng dưới là kết quả thật của lab ngày 29/10/2026. Cột cuối là thông báo mà socat sẽ in theo mã nguồn, ở dạng dòng CONNECT kèm lý do.
Ca |
Thay đổi |
Proxy trả |
Kết quả |
|---|---|---|---|
1 |
proxyauth đúng, cổng 9471 |
200 |
echo: hello qua tunnel |
2 |
Không có tài khoản |
407 |
CONNECT echo.test:9471: Proxy Authentication Required |
3 |
Tệp tài khoản tạo bằng echo |
407 |
Proxy giải mã được user1:p@ss#2026\n |
4 |
Tệp tạo bằng printf '%s' |
200 |
echo trả về đúng |
5 |
Cổng đích 22 |
403 |
CONNECT echo.test:22: Forbidden |
6 |
Bật resolve |
200 |
Dòng CONNECT dùng 127.0.0.1 |
7 |
http-version=1.1 |
200 |
Proxy lab không đòi Host |
8 |
Cổng 443 không có dịch vụ |
502 |
CONNECT echo.test:443: Bad Gateway |
9 |
Proxy trả chỉ LF |
200 |
Treo nếu thiếu ignorecr |
Ca 7 chỉ đúng với proxy lab. Proxy thật có thể đòi Host với HTTP/1.1, nên chưa có cơ sở để khuyên đổi phiên bản.
Đọc log của socat
Với -d -d, một lần chạy thành công có hai dòng notice chính: opening connection to đích via proxy, rồi successfully connected to đích via proxy. Có dòng thứ nhất mà không có dòng thứ hai nghĩa là lỗi nằm ở bước bắt tay với proxy.
Lên -d -d -d sẽ thấy dòng sending "CONNECT ..." và proxy_connect: received answer kèm dòng trạng thái. Mật khẩu ở dạng base64 cũng được in ra ở mức info. Không dán log mức info lên chỗ công khai khi có dùng tài khoản.
Phân biệt lỗi ở ba chặng
Không nối được tới proxy thì socat báo lỗi connect ngay từ đầu, kèm tên proxy và proxyport. Proxy trả mã khác 200 thì thông báo có dạng CONNECT đích:cổng kèm lý do. Đã qua 200 mà vẫn không có dữ liệu thì vấn đề nằm ở đích hoặc giao thức bên trong.
Thông báo có chữ CONNECT ở đầu là của proxy. Thông báo không có chữ CONNECT là của mạng hoặc của đích.
Cách tách này giúp gửi đúng câu hỏi tới đúng người. Lỗi 407 hay 403 là chuyện với nhà cung cấp proxy, lỗi sau 200 là chuyện với chủ máy đích.
Xem dữ liệu đi qua tunnel
Khi đã qua 200 mà giao thức bên trong vẫn lỗi, cờ -v của socat in mọi byte đi qua ra stderr ở dạng văn bản, có tiền tố > cho chiều đi và < cho chiều về. Cờ -x in cùng dữ liệu đó ở dạng hex. Hai cờ này hữu ích với giao thức văn bản như SMTP hay Redis.
Với SSH hay TLS, dữ liệu đã mã hóa nên -v chỉ cho thấy độ dài và thời điểm. Vậy cũng đủ để biết đích có trả lời hay không. Nếu chiều về không có byte nào sau vài giây, vấn đề nằm ở đích hoặc ở luật tường lửa phía đích.
Các mẫu dùng socat qua HTTP CONNECT hay gặp
Ba mẫu dưới đây bao phủ phần lớn nhu cầu. Mỗi mẫu có giới hạn riêng cần biết trước khi đưa vào chạy thật.
SSH qua proxy bằng ProxyCommand
SSH cho phép thay kết nối TCP bằng đầu vào và đầu ra của một lệnh, theo mục ProxyCommand trong trang man ssh_config. Đặt socat vào ProxyCommand là cách gọn nhất.
# ~/.ssh/config
Host may-chu-xa
HostName may-chu-xa.example.net
Port 443
User deploy
ProxyCommand socat - PROXY:proxy.example.com:%h:%p,proxyport=3128,proxyauthfile=/home/u/.socat-proxy
%h và %p là biến của ssh, thay bằng HostName và Port. Cổng đích ở đây là 443 vì proxy thường chỉ cho phép CONNECT tới 443, nên máy chủ SSH phải nghe thêm ở cổng đó. ssh tự lo phần mã hóa, proxy chỉ thấy tên máy và cổng.
Chuyển tiếp một cổng cục bộ
Chương trình không hỗ trợ proxy có thể trỏ tới một cổng trên máy mình, socat nhận rồi chuyển qua proxy.
socat -d -d TCP-LISTEN:15432,bind=127.0.0.1,reuseaddr,fork,max-children=20 PROXY:proxy.example.com:db.example.net:5432,proxyport=3128,proxyauthfile=/home/u/.socat-proxy,connect-timeout=10
bind=127.0.0.1 giữ cổng chỉ nghe trên máy cục bộ. Thiếu bind, socat nghe trên mọi địa chỉ, người khác trong mạng có thể dùng tunnel bằng tài khoản proxy của anh em. max-children giới hạn số kết nối cùng lúc. Proxy phải cho phép cổng 5432 thì mẫu này mới chạy.
TLS tới API qua cổng chuyển tiếp
Với HTTPS, chuyển tiếp như trên vẫn chạy, nhưng client phải gửi đúng tên máy trong TLS để chứng chỉ khớp. Với curl, tùy chọn --connect-to giữ tên máy trong URL mà vẫn nối tới cổng cục bộ.
socat TCP-LISTEN:18443,bind=127.0.0.1,reuseaddr,fork PROXY:proxy.example.com:api.example.com:443,proxyport=3128,proxyauthfile=/home/u/.socat-proxy
curl --connect-to api.example.com:443:127.0.0.1:18443 https://api.example.com/health
Nếu chương trình hỗ trợ proxy HTTP thì cấu hình proxy trực tiếp sẽ đơn giản hơn. Mẫu này chỉ dành cho công cụ không có tùy chọn proxy.
Chạy lại tự động khi lỗi
Địa chỉ PROXY thuộc nhóm tùy chọn RETRY. retry=5,interval=2 thử lại năm lần, mỗi lần cách hai giây. forever thử mãi. Mã nguồn trả trạng thái thử lại sau cho các mã khác 200, nên 407 cũng bị thử lại.
Thử lại khi sai mật khẩu chỉ làm proxy ghi thêm lần đăng nhập lỗi, có nơi còn khóa tài khoản. Nên dùng retry có giới hạn, và dừng hẳn khi log báo 407.
Lỗi hay gặp khi chạy socat qua HTTP CONNECT
Bảng dưới gom các lỗi theo thông báo, nguyên nhân hay gặp và việc cần làm đầu tiên. Các dòng về mã trả lời lấy từ lab và mã nguồn, các dòng về mạng lấy từ trang man.
Thông báo |
Nguyên nhân hay gặp |
Việc cần làm |
|---|---|---|
Connection refused tới proxy |
Sai proxyport, dùng mặc định 8080 |
Thêm proxyport đúng |
CONNECT ...: Proxy Authentication Required |
Thiếu tài khoản hoặc tệp thừa \n |
Tạo lại tệp bằng printf |
CONNECT ...: Forbidden |
Proxy không cho cổng đích |
Đổi đích sang 443 hoặc hỏi nhà cung cấp |
CONNECT ...: Bad Gateway |
Proxy không nối được đích |
Kiểm đích có nghe cổng đó không |
proxy: invalid answer |
Dòng trạng thái không phải HTTP/1.0 hay HTTP/1.1 |
Kiểm có đúng cổng HTTP của proxy |
proxy answer exceeds 2048 bytes |
Proxy trả trang lỗi dài |
Xem log -d -d -d để đọc mã |
Treo không báo gì |
Proxy trả LF hoặc đích không gửi dữ liệu |
Thêm -T và thử ignorecr |
Nhầm cổng SOCKS với cổng HTTP
Nhà cung cấp thường cấp cả cổng HTTP và cổng SOCKS5. Trỏ địa chỉ PROXY vào cổng SOCKS5 sẽ nhận về chuỗi byte nhị phân, socat báo invalid answer. Địa chỉ PROXY chỉ nói được giao thức HTTP CONNECT.
socat có địa chỉ SOCKS5-CONNECT riêng, nhưng trang man ghi rõ hiện chưa có cơ chế xác thực. Proxy SOCKS5 cấp user và mật khẩu sẽ không dùng được với địa chỉ đó, nên dùng cổng HTTP và địa chỉ PROXY.
Lỗi 407 với proxy dùng NTLM hoặc Digest
Mã nguồn chỉ gửi Basic. Proxy công ty dùng NTLM, Kerberos hay Digest sẽ luôn trả 407 dù tài khoản đúng. Cách xử lý là xin một cổng Basic, xin xác thực theo IP, hoặc dùng một proxy trung gian nói được kiểu xác thực đó.
Đích chặn IP của proxy
Đi qua proxy, đích thấy IP của proxy. Máy chủ SSH có danh sách IP cho phép sẽ ngắt kết nối ngay sau 200. Log của socat lúc đó chỉ cho thấy kết nối đóng, phải xem log phía đích mới biết lý do.
Giới hạn của socat qua HTTP CONNECT và cách chọn proxy
Socat làm tốt một việc hẹp. Biết giới hạn của nó giúp chọn đúng công cụ ngay từ đầu.
Những gì socat không làm
Socat không biết danh sách bỏ qua proxy, không đọc biến HTTP_PROXY và không tự chọn proxy theo đích. Mỗi địa chỉ PROXY trỏ cố định tới một proxy. Muốn đi thẳng với mạng nội bộ thì không dùng socat cho các đích đó, cách đặt danh sách bỏ qua cho công cụ khác có trong bài no_proxy là gì.
Socat cũng không gói UDP vào CONNECT. Truy vấn DNS hay giao thức chạy UDP không đi qua địa chỉ PROXY được.
Số kết nối và tài nguyên
Với tùy chọn fork, mỗi kết nối tới cổng nghe sinh ra một tiến trình con. Một chương trình mở hàng trăm kết nối song song sẽ tạo hàng trăm tiến trình socat, mỗi tiến trình giữ một kết nối tới proxy. max-children chặn số này lại, kết nối vượt mức phải chờ.
Proxy cũng có giới hạn số kết nối đồng thời theo tài khoản. Đặt max-children thấp hơn giới hạn đó để lỗi xảy ra ở phía socat, nơi anh em đọc được log, thay vì nhận lỗi khó hiểu từ proxy.
Proxy không mở rộng quyền
Proxy chỉ đổi đường đi của TCP. Nó không cấp quyền đăng nhập máy chủ, không thay khóa SSH hay token API. Tunnel tới hệ thống mà anh em không có quyền dùng là vi phạm chính sách của chủ hệ thống đó, dù về kỹ thuật lệnh vẫn chạy.
Chọn loại proxy cho tunnel
Tunnel dài như SSH cần một IP ổn định trong suốt phiên. Proxy xoay đổi IP theo thời gian có thể làm đứt phiên hoặc làm máy chủ nghi ngờ vì IP nhảy liên tục. Proxy dân cư tĩnh hoặc datacenter dùng riêng hợp hơn cho việc này.
ProxyVN có proxy dân cư tĩnh, datacenter Việt Nam và Mỹ, proxy 4G và proxy xoay, hỗ trợ HTTP và SOCKS5, cấp tài khoản user và mật khẩu. Cần một cổng HTTP có IP cố định để đặt sau địa chỉ PROXY, anh em có thể mua proxy tại trang chủ ProxyVN rồi chạy lại ca 1 trong lab với echo server của mình.
Trước khi đưa vào chạy thật, hỏi nhà cung cấp danh sách cổng CONNECT được phép. Ca 5 trong lab cho thấy proxy từ chối cổng ngoài danh sách bằng 403, đó là hành vi thường gặp ở proxy HTTP.
Gỡ cấu hình, quản lý bí mật và checklist socat qua HTTP CONNECT
Một tunnel quên tắt là một cửa mở. Phần cuối này giúp dọn dẹp sau khi thử và giữ bí mật khi chạy lâu dài.
Gỡ cấu hình thử
Dừng mọi tiến trình socat đã mở bằng PID cụ thể, không dừng theo tên vì có thể đụng tiến trình khác. Xóa dòng ProxyCommand thử nghiệm trong ~/.ssh/config. Xóa tệp tài khoản thử, rồi kiểm lại bằng ss -ltnp rằng không còn cổng nào nghe ngoài ý muốn.
Với echo server tự dựng trên máy đích, tắt luôn sau khi thử. Một echo server mở ra Internet có thể bị dùng để dò mạng.
Quản lý bí mật khi chạy lâu dài
Chạy socat bằng systemd thì để tài khoản trong tệp riêng có quyền 600, chủ sở hữu là tài khoản dịch vụ. Không đặt proxyauth trong tệp unit, vì tệp unit thường đọc được bởi mọi người dùng và lệnh systemctl status in nguyên dòng lệnh.
[Unit]
Description=socat tunnel toi db qua proxy HTTP
After=network-online.target
[Service]
User=tunnel
ExecStart=/usr/bin/socat -d -d TCP-LISTEN:15432,bind=127.0.0.1,reuseaddr,fork,max-children=20 PROXY:proxy.example.com:db.example.net:5432,proxyport=3128,proxyauthfile=/etc/socat/proxy-auth,connect-timeout=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Restart=on-failure với RestartSec=5 thay cho forever của socat, vì systemd ghi lại mỗi lần khởi động lại vào journal. Đổi mật khẩu proxy thì chỉ cần sửa tệp và khởi động lại dịch vụ.
Checklist dùng thật

Checklist socat tunnel
- Ghi phiên bản socat -V và kiểm có WITH_PROXY.
- Cổng proxy đặt bằng proxyport, không đặt trong phần địa chỉ.
- Tài khoản nằm trong tệp tạo bằng printf, quyền 600, đã kiểm byte cuối.
- Đã hỏi nhà cung cấp danh sách cổng CONNECT được phép.
- Cổng nghe cục bộ có bind=127.0.0.1 và max-children.
- Có connect-timeout cho bước nối và -T cho lúc chuyển dữ liệu.
- Đã thử với echo server riêng trước khi trỏ tới dịch vụ thật.
- Log mức info không bị đẩy lên kênh công khai.
- retry có giới hạn, không thử mãi khi gặp 407.
Kiểm sau khi gỡ
Chạy lại lệnh ss -ltnp và ps để chắc không còn socat. Kiểm log proxy hoặc trang quản lý của nhà cung cấp để thấy không còn kết nối CONNECT từ máy đó. Đổi mật khẩu proxy nếu đã dùng proxyauth trên dòng lệnh ở máy dùng chung.
Câu hỏi thường gặp về socat qua HTTP CONNECT
Socat có đọc biến HTTP_PROXY không?
Không. Trang man và mã nguồn xio-proxy.c không đọc biến môi trường nào cho proxy. Mọi thông tin phải nằm trong địa chỉ PROXY và các tùy chọn của nó.
Có dùng được proxy HTTPS, tức proxy nói TLS ở cổng proxy không?
Địa chỉ PROXY nói HTTP thường với proxy. Proxy chỉ nhận TLS ở cổng của nó thì cần thêm một lớp TLS trước, ví dụ một tiến trình socat thứ hai dùng địa chỉ OPENSSL. Bài chưa thử cách ghép này.
Socat chạy trên Windows được không?
Có các bản biên dịch cho Cygwin và MSYS2, nhưng lab không chạy các bản đó. Trên Windows, WSL với gói socat của Linux là cách dễ kiểm nhất.
Vì sao proxy log ghi IP của đích thay vì tên?
Vì lệnh có tùy chọn resolve. Bỏ tùy chọn đó, socat gửi tên máy nguyên văn, proxy tự phân giải.
Giới hạn của bài
Bài không chạy binary socat. Hành vi gửi và đọc trả lời lấy từ mã nguồn socat 1.8.1.3 và được mô phỏng bằng Python. Chưa thử proxy thương mại, Squid, proxy công ty dùng NTLM, SSH thật qua ProxyCommand và bản Windows của socat.
socat qua HTTP CONNECT và những điều cần nhớ
socat qua HTTP CONNECT cần ba thứ đúng: cổng proxy trong proxyport, tài khoản trong tệp không thừa dấu xuống dòng, và cổng đích nằm trong danh sách proxy cho phép. Thử với echo server riêng trước, đặt timeout rõ ràng, rồi mới trỏ tới dịch vụ thật. Cần cổng HTTP ổn định cho socat qua HTTP CONNECT, liên hệ Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam.