Port

A port is a logical entity that acts as an endpoint of communication associated with an application or process in an operating system.

— IANA 및 RFC 통신 기술 표준 지침서 상의 포트 개념 정의 구문

내 컴퓨터가 아파트 단지(IP 주소)라면, 포트는 각 세대 문앞에 적혀 있는 동호수(호실 번호)다. 번호를 모르면 아파트 정문 앞에서 문전박대당하는 것과 같다. 왜 내가 로컬에서 띄운 리액트 서버와 익스프레스 서버는 꼭 매번 3000번 포트에서 영혼의 다툼을 벌여 에러를 뿜어내는가.(...)

1. 개요

포트(Port)는 컴퓨터 네트워크 및 운영체제 환경에서 외부의 데이터 패킷이 특정 네트워크 서비스나 응용 프로그램(Process)을 찾아 들어갈 수 있도록 정해둔 가상의 식별 번호(Endpoint)다. 하나의 컴퓨터(단일 IP 주소)에는 웹 서버, DB 서버, 채팅 서버 등 수많은 통신 프로그램이 동시에 가동될 수 있는데, 네트워크를 타고 들어온 데이터가 정확한 대상 프로세스에 전달될 수 있도록 마법 같은 종착지 라벨 역할을 해준다. 0부터 65535까지의 정수 범위 안에서 움직이며, TCP와 UDP라는 양대 전송 프로토콜 계층 위에서 각각 독립적으로 작동한다.

2. 포트의 세 가지 영역과 잘 알려진 도둑놈들

포트 번호의 전체 6만여 개의 세계는 엄격한 규칙 아래 세 가지 분류 영역으로 나뉘어 할당된다. 첫째, 0번부터 1023번까지의 잘 알려진 포트(Well-Known Ports) 영역이다. 여기에는 웹 표준 통신용 HTTP(80), HTTPS(443), 원격 접속 ssh(22), 파일 전송 FTP(20, 21) 등 전 지구적인 약속이 미리 박혀 있다. 둘째, 1024번부터 49151번까지의 등록된 포트(Registered Ports) 영역이다. MySQL(3306), Redis(6379), Tomcat(8080) 같은 굵직한 상용/오픈소스 소프트웨어들이 자신들의 깃발을 꽂아 둔 전유 영역이다. 마지막 셋째는 49152번부터 65535번까지로, 운영체제가 임시 통신을 위해 자유롭게 동적으로 뜯어 쓰는 동적 포트(Dynamic Ports) 영역이다. 이 영역을 함부로 건드렸다가 엉뚱한 임시 시스템 소켓과 충돌하면 컴퓨터 네트워크가 기절해 버린다.1

3. 개발자들의 일상: 포트 충돌과 소켓 킬러

웹 개발자들이 로컬 환경(로컬호스트)에서 다수의 서비스를 띄우다 보면, 높은 확률로 EADDRINUSE (Address already in use) 라는 치명적이고 뻘건 에러 메시지를 마주한다. 하나의 포트 번호에는 동시에 단 하나의 프로세스 소켓(Socket)만 바인딩될 수 있는 운영체제의 대원칙을 어겼기 때문이다. 흔히 React 서버가 3000번 포트를 먹고 있는데, Node.js 서버도 눈치 없이 3000번 포트로 띄우려 할 때 발생한다. 이때 초보 개발자들은 컴퓨터를 재부팅하는 미개한(...) 의식을 거행하지만, 조금 굵어진 고인물 개발자들은 터미널을 열고 lsof -i :3000 혹은 netstat 명령어로 도둑놈 프로세스를 귀신같이 색출해 낸 뒤 kill -9로 영혼까지 무자비하게 날려버리는 카타르시스를 즐기곤 한다.(...)

4. 관련 밈 및 드립

4.1. 3000번과 8080번의 영혼의 맞다이

리액트, 뷰 등 현대 프론트엔드 빌드 툴들이 약속이나 한 듯 기본 포트로 3000번을 사용하고, 스프링 부트나 톰캣 등 자바 진영의 백엔드 프레임워크들은 유구한 역사에 따라 8080번을 기본값으로 사용한다. 로컬에서 풀스택 개발을 하다가 무심코 서버를 두 번 켜는 순간, 포트가 이미 점유되어 있다며 실행이 거부되는 유서 깊은 충돌 밈이다. '서버를 두 번 켰을 뿐인데, 내 리액트 서버가 스프링 서버의 뺨을 갈겼다'며 자조 섞인 개발 짤방이 주기적으로 소셜 미디어에 공유된다.(...)

4.2. 포트 포워딩이라는 방화벽 만리장성

내가 집에서 열심히 띄운 로컬호스트 웹사이트를 친구에게 자랑하기 위해 공유기 외부 IP 주소를 알려줬으나 친구는 절대 들어오지 못한다. 공유기가 외부 패킷을 어떤 컴퓨터의 어떤 포트로 넘겨줄지 정해두지 않는 포트 포워딩(Port Forwarding) 설정을 빠뜨렸기 때문이다. 주니어 개발자가 공유기 설정 페이지에 들어가 DMZ와 포트 포워딩의 알 수 없는 한문 용어들을 정복하다가, 결국 비밀번호를 잊어먹고 공유기 초기화 버튼을 이쑤시개로 누르며 멘탈이 함께 초기화되는 밈이 유명하다.

5. 여담

  • 포트의 개수가 하필 65535개인 이유: 컴퓨터 통신 프로토콜인 TCP와 UDP 헤더에서 소스 포트와 목적지 포트를 지정하는 필드의 크기가 각각 정확히 16비트(16-bit)로 설계되었기 때문이다. 2의 16승인 65536개의 가짓수 중 0번 포트는 특수 예약 용도로 빠지므로, 사용 가능한 최대 번호는 65535번으로 영원히 고정되었다.
  • 0번 포트의 신비: 포트 번호 0은 사용할 수 없는 것처럼 보이지만, 사실 네트워크 소켓 바인딩 시 프로그램이 '포트 번호 0으로 바인딩해줘'라고 운영체제에 요청하면, OS 커널이 현재 비어 있는 임의의 포트 번호 중 아무거나 하나를 알아서 즉석에서 골라 할당해 주는 '와일드카드 포트'로 매우 유용하게 쓰인다.
  • 존 포스텔이라는 전설의 수문장: 초기 아르파넷(ARPANET) 시절부터 전 세계 모든 포트 번호와 프로토콜 번호를 수작업으로 장부에 기록하고 관리했던 인물은 전설적인 전산학자 존 포스텔(Jon Postel)이다. 그의 꼼꼼한 관리 철학이 오늘날 글로벌 포트 할당 관리 기관인 IANA의 기틀이 되었다.

6. 관련 문서

각주

  1. 실제로 macOS 12 Monterey 업데이트 당시, 애플이 무심코 내장 에어플레이(AirPlay) 수신용 데몬 서버의 기본 포트를 5000번과 7000번으로 몰래 점유하는 바람에, 기존에 플라스크(Flask) 등 웹 개발을 하던 전 세계 개발자들의 로컬 서버가 일제히 터지며 애플 본사를 향해 전 세계적인 욕설이 쏟아진 적이 있다.