iptables로 특정 Linux 사용자에 대한 아웃바운드 트래픽 차단 (리스닝 포트는 유지)

발행: (2026년 1월 19일 오후 07:18 GMT+9)
6 min read
원문: Dev.to

Source: Dev.to

목표

userA에 대해:

  • 새로운 아웃바운드 연결(예: curl, 패키지 다운로드, 외부 API 호출)을 차단합니다.
  • 포트 리스닝인바운드 서비스 응답은 정상적으로 동작하도록 유지합니다(예: 0.0.0.0:8080에 바인딩된 데몬이 원격 클라이언트에 응답).

핵심은 OUTPUT 체인에 사용자를 매칭하고 conntrack 상태가 NEW인 트래픽만 드롭/리젝트하는 규칙을 추가하는 것입니다.

전제 조건

  • 루트 권한(sudo).
  • conntrack 지원(대부분 최신 Linux 시스템에 기본 제공).
  • 사용자의 UID(정확성을 위해 권장).

사용자의 UID 확인

id -u userA

아래 명령어에서 <UID> 부분을 반환된 숫자로 교체합니다.

iptables 규칙 적용 (IPv4)

먼저 기존 연결 허용 (중요)

sudo iptables -I OUTPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

루프백 트래픽 허용 (권장)

sudo iptables -I OUTPUT 2 -o lo -j ACCEPT

사용자의 NEW 아웃바운드 연결 차단 (핵심 규칙)

sudo iptables -I OUTPUT 3 -m owner --uid-owner <UID> -m conntrack --ctstate NEW -j REJECT

주의:

  • REJECT는 빠르게 실패하고 디버깅이 쉽습니다. 조용히 차단하려면 DROP을 사용하세요.
  • owner 매치는 로컬에서 생성된 패킷(OUTPUT)만 대상으로 하므로 여기서 원하는 동작과 정확히 일치합니다.

왜 이 방식이 리스닝 포트를 유지시키는가

사용자 프로세스는 여전히:

  • 포트에 바인드하고 리스닝할 수 있습니다(리스닝 자체는 네트워크 전송이 아님).
  • 원격 클라이언트가 시작한 인바운드 연결을 받아들일 수 있습니다.

원격 호스트가 서비스에 연결하면, 서버가 보내는 응답 패킷은 이미 ESTABLISHED 상태로 분류됩니다. 따라서 첫 번째 규칙에 의해 허용됩니다.

결과

  • 아웃바운드 연결 시작은 차단됩니다.
  • 인바운드 서비스는 정상적으로 동작합니다.

규칙 확인

sudo iptables -S OUTPUT
sudo iptables -L OUTPUT -n -v --line-numbers

테스트 아이디어

userA로 다음을 시도해 보세요:

curl https://example.com   # 실패해야 함

다른 호스트에서 userA가 리스닝 중인 서비스에 연결:

nc 8080        # 연결되고 응답을 받아야 함

IPv6도 잊지 마세요 (우회 방지)

IPv6가 활성화된 경우, 동일한 ip6tables 규칙을 적용합니다:

sudo ip6tables -I OUTPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -I OUTPUT 2 -o lo -j ACCEPT
sudo ip6tables -I OUTPUT 3 -m owner --uid-owner <UID> -m conntrack --ctstate NEW -j REJECT

운영상의 고려사항 및 주의점

  1. -m owner는 OUTPUT에만 적용
    owner 모듈은 로컬 호스트의 프로세스를 매칭하며, 로컬에서 생성된 트래픽에만 의미가 있습니다. FORWARD 체인이나 다른 호스트에 대한 트래픽에는 적용되지 않습니다.

  2. 권한 상승을 통해 우회 가능
    userAsudo 등을 이용해 다른 사용자(예: root)로 명령을 실행할 수 있다면, 트래픽은 다른 UID로 소유되어 이 규칙에 매치되지 않습니다. sudo 정책을 강화하고 시스템을 하드닝하여 완화하세요.

  3. 이미 존재하는 연결은 계속 열려 있을 수 있음
    규칙이 NEW만 차단하기 때문에, 이미 확립된 아웃바운드 연결은 자연스럽게 종료될 때까지 유지됩니다. 즉시 차단하려면 해당 프로세스를 종료하거나 기존 연결을 강제 종료(ss/lsof 등 사용)하세요.

결론

특정 Linux 사용자에 대해 아웃바운드 트래픽을 차단하면서 리스닝 포트를 유지하는 방법은 iptables를 이용하면 간단합니다:

  1. ESTABLISHED,RELATED 트래픽 허용.
  2. 루프백 허용.
  3. OUTPUT 체인에서 사용자 소유의 NEW 아웃바운드 연결을 리젝트(또는 드롭).

이 최소 침해 방식은 서비스 계정이 외부로 나가는 트래픽을 제한하면서 인바운드 서비스 동작을 깨뜨리지 않아야 할 때 적합합니다.

Back to Blog

관련 글

더 보기 »

고통과 고난. PocketBook의 파일명

문제: 저는 PocketBook e‑reader를 가지고 있는데, non‑ASCII 문자가 포함된 파일 이름을 USB를 통해 PC에서 복사하면 깨진 문자로 표시됩니다. 임시 해결 방법으로는…