Curl 없이 Bash /dev/tcp 로 HTTP 요청 만들기
Bash /dev/tcp 로 네트워크 연결 사용하기
Bash는 TCP 소켓을 직접 열 수 있어 curl이나 wget 같은 외부 유틸리티에 의존하지 않고도 네트워크를 통해 데이터를 주고받을 수 있습니다. 이는 새 패키지를 설치할 수 없는 제한된 Docker 컨테이너나 최소 환경에서 연결 상태를 디버깅할 때 특히 유용합니다.
기본적인 HTTP GET 요청을 수행하려면 다음 명령 순서를 사용합니다:
exec 3<>/dev/tcp/service/8642
printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3
cat <&3
이 예시에서 service는 호스트명이고 8642는 포트 번호입니다. exec 3<> 명령은 지정된 호스트와 포트에 소켓을 열어 파일 디스크립터 3에 할당합니다. printf 명령은 원시 HTTP 요청을 전송하고, cat <&3 은 연결이 닫힐 때까지 소켓으로부터 응답을 읽어옵니다.
헤더와 인증 처리하기
Authorization 토큰과 같은 추가 헤더를 포함하려면 HTTP 요청을 종료하는 빈 줄 앞에 헤더 라인을 삽입합니다:
exec 3<>/dev/tcp/service/8642
printf 'GET /v1/models HTTP/1.1\r\nHost: service\r\nAuthorization: Bearer %s\r\nConnection: close\r\n\r\n' "$API_KEY" >&3
cat <&3
기술 구현 및 제한 사항
/dev/tcp 의 본질
표면과 달리 /dev/tcp는 디스크에 실제 존재하는 장치 파일이 아닙니다. Bash 내부에서 처리되는 리다이렉션입니다. Bash가 /dev/tcp/host/port 형태의 경로를 만나면 connect(2) 시스템 콜을 사용해 해당 TCP 소켓을 열려고 시도합니다. 이 설계는 표준 Unix 시스템에 /dev/tcp 혹은 /dev/udp 계층이 없기 때문에 실제 파일과 충돌을 방지하기 위해 선택되었습니다.
주요 제약 사항
디버깅에 강력하지만, 전체 HTTP 클라이언트에 비해 다음과 같은 중요한 제한이 있습니다:
- TLS/SSL 지원 없음:
/dev/tcp는 원시 소켓을 엽니다. HTTPS를 처리할 수 없습니다. 암호화된 트래픽에는openssl s_client같은 도구가 필요합니다. - HTTP 파싱 없음: Bash는 HTTP 프로토콜을 파싱하지 않습니다. 리다이렉션, 청크 전송 인코딩, 압축, 재시도 등을 처리하지 않으며 단순히 원시 바이트를 전송·수신합니다.
- 연결 관리:
Connection: close헤더는 필수입니다. 이 헤더가 없으면 서버가 연결을 유지할 수 있어(HTTP/1.1기본값)cat이 더 이상 데이터가 없을 때까지 무한히 대기하게 됩니다. - 쉘 호환성: Bash 전용 기능이며 POSIX 표준을 따르지 않습니다. Debian의 기본
/bin/sh인dash나zsh에서는 동작하지 않으며, 이 기능을 사용하는 스크립트는 반드시bash로 명시적으로 실행해야 합니다. - 컴파일 시 옵션 필요: 이 기능은 Bash를 컴파일할 때
--enable-net-redirections플래그를 사용해 활성화해야 합니다. 대부분의 메인스트림 배포판에서는 기본으로 포함되지만, 일부 최소 또는 오래된 빌드(예: 특정 오래된 Debian 버전)에서는 비활성화되어 있을 수 있습니다.
실용적인 사용 사례와 대안
디버깅 및 보안
이 기법은 환경이 매우 제한된 상황에서 자주 사용됩니다:
- 최소 컨테이너: 모든 비필수 바이너리가 제거된 이미지에서 헬스 엔드포인트를 확인합니다.
- 침투 테스트:
curl과nc가 없는 CTF나 보안 감사 중에 초기 쉘을 만들거나 로컬 웹 서버와 상호 작용합니다. - 제한 우회: 보안 정책으로 네트워크 도구 설치가 금지된 경우 서비스와 상호 작용합니다.
대체 방법
사용 가능한 도구에 따라 다음과 같은 대안이 더 신뢰성 있을 수 있습니다:
- Netcat (nc): 원시 소켓 상호 작용을 위한 보다 견고한 도구.
- Perl/Python: Perl의
IO::Socket이나 Python의socket모듈을 사용해 프로그래밍 방식으로 네트워크 요청을 처리합니다. - nsenter: 호스트 머신에
curl이 설치되어 있다면nsenter를 이용해 컨테이너의 네트워크 네임스페이스에 들어가 호스트 컨텍스트에서curl을 실행할 수 있습니다.
"이것이 우리가 2026년에 마땅히 받아야 할 콘텐츠이며, 그래서 인터뷰에서 쿠키가 HTTP 프로토콜에서 어떻게 표현되는지 설명하도록 요구하는 이유다." — @dennis16384
요약: Bash는 /dev/tcp 를 통해 TCP 소켓을 여는 내장 메커니즘을 제공하므로, curl이나 wget 같은 도구가 없는 최소 환경에서도 기본적인 HTTP 요청을 수행할 수 있습니다.
제목: Curl 없이 Bash /dev/tcp 로 HTTP 요청 만들기