Bash /dev/TCP로 curl 없이 HTTP 요청하기
원제: TIL: You can make HTTP requests without curl using Bash /dev/TCP
왜 중요한가
최소화된 컨테이너 환경에서 외부 패키지 설치 없이 네트워크 디버깅과 헬스 체크를 수행할 수 있는 실용적인 기법으로, DevOps와 컨테이너 운영 효율성을 높인다.
개발자 Marek Šuppa가 curl이나 wget이 없는 최소화된 컨테이너 환경에서 Bash의 /dev/TCP 리다이렉션을 이용해 HTTP 요청을 수행하는 방법을 소개했다. Docker 네트워크 상의 내부 서비스 헬스 체크 등에 활용 가능하다.
Šuppa는 Docker 네트워크 상의 컨테이너 간 통신 확인이 필요했으나, 애플리케이션 이미지가 극도로 축소되어 curl이나 wget이 없는 상황에 직면했다. 이 문제를 해결하기 위해 Bash 자체가 HTTP 통신을 수행할 수 있음을 발견했다.
방법은 다음과 같다. 'exec 3<>/dev/tcp/service/8642'로 TCP 소켓을 열고, 'printf' 명령으로 HTTP 요청을 작성한 후 'cat'으로 응답을 읽는다. Authorization 헤더 같은 추가 헤더는 요청 본문 이전의 '\r\n'으로 구분된 줄에 추가하면 된다.
주의할 점은 /dev/tcp가 실제 장치 파일이 아니라 Bash의 내부 리다이렉션이라는 것이다. DNS 조회와 연결을 Bash가 자동으로 처리한다. 또한 'Connection: close' 헤더가 중요한데, 없으면 서버가 연결을 유지해 cat이 무한 대기한다.
이 방식의 한계는 HTTP 리다이렉트, 청크 응답, 압축, TLS 등을 처리하지 못한다는 것이다. 또한 HTTPS는 지원하지 않으며(openssl s_client 필요), POSIX 표준이 아니어서 dash나 zsh에서는 작동하지 않는다. Bash 컴파일 시 --enable-net-redirections 옵션이 필요하며, 구형 또는 매우 최소화된 시스템에서는 비활성화될 수 있다.