Gửi yêu cầu HTTP mà không cần curl: Giải thích về Bash /dev/tcp

Bạn đang ở trong một Docker container được lược bỏ tối giản. Bạn cần kiểm tra một API endpoint. Bạn gõ curl và nhận được thông báo "command not found." Bạn thử wget và cũng nhận được lỗi tương tự.

Bạn không cần phải hoảng loạn. Bash có một tính năng ẩn được tích hợp sẵn trong nhân của nó. Nó được gọi là /dev/tcp.

Tính năng này cho phép bạn mở các kết nối TCP thô mà không cần cài đặt bất kỳ công cụ nào. Nó hoạt động trên hầu hết mọi hệ thống Linux.

Cách thức hoạt động: Khi bạn tham chiếu đến /dev/tcp/hostname/port, Bash sẽ mở một kết nối socket. Đây là một tính năng đặc thù của Bash. Nó sẽ không hoạt động trong sh hoặc zsh.

Câu lệnh "ma thuật": exec 3<>/dev/tcp/hostname/port

Dòng này mở một file descriptor hai chiều. Bạn có thể ghi dữ liệu vào đó và đọc phản hồi trả về.

Ví dụ về yêu cầu GET:

#!/bin/bash
exec 3<>/dev/tcp/example.com/80
printf "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n" >&3
cat <&3
exec 3>&-

Tại sao điều này lại hữu ích: • Gỡ lỗi (debugging) trong các môi trường tối giản nơi bạn không thể cài đặt các gói phần mềm. • Chạy các bước kiểm tra sức khỏe (health checks) trong các pipeline CI/CD mà không cần bất kỳ phụ thuộc nào. • Kiểm tra kết nối trên các hệ thống nhúng. • Tìm hiểu chính xác cách thức hoạt động của các HTTP header.

Các giới hạn quan trọng cần lưu ý: • Không có HTTPS: Bash không thể xử lý mã hóa TLS/SSL. Hãy sử dụng openssl s_client cho các lưu lượng truy cập được mã hóa. • Không có Redirects: Bạn phải tự xử lý chúng một cách thủ công. • Không dành cho các tác vụ phức tạp: Đừng sử dụng cách này để làm HTTP client cho môi trường production. Hãy sử dụng curl cho mục đích đó.

Luôn bao gồm header Connection: close. Nếu bạn quên nó, script của bạn có thể bị treo trong khi chờ đợi máy chủ.

Lần tới khi bạn bị kẹt trong một máy chủ bị hạn chế quyền truy cập, hãy sử dụng mẹo này. Nó biến một ngõ cụt thành một công cụ hữu dụng.

Source: https://dev.to/onsen/http-requests-without-curl-bash-devtcp-explained-5852

Optional learning community: https://t.me/GyaanSetuAi