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/shdashzsh에서는 동작하지 않으며, 이 기능을 사용하는 스크립트는 반드시 bash로 명시적으로 실행해야 합니다.
  • 컴파일 시 옵션 필요: 이 기능은 Bash를 컴파일할 때 --enable-net-redirections 플래그를 사용해 활성화해야 합니다. 대부분의 메인스트림 배포판에서는 기본으로 포함되지만, 일부 최소 또는 오래된 빌드(예: 특정 오래된 Debian 버전)에서는 비활성화되어 있을 수 있습니다.

실용적인 사용 사례와 대안

디버깅 및 보안

이 기법은 환경이 매우 제한된 상황에서 자주 사용됩니다:

  • 최소 컨테이너: 모든 비필수 바이너리가 제거된 이미지에서 헬스 엔드포인트를 확인합니다.
  • 침투 테스트: curlnc가 없는 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 요청 만들기

Sources