엔지니어링 글

클라우드 Mac CI의 아웃바운드 연결을 감사하는 방법

클라우드 Mac CI의 아웃바운드 연결을 감사하는 방법

원래 안정적으로 작동하던 CI 파이프라인이 갑자기 낯선 주소에 접속하기 시작했다면 즉시 차단부터 해서는 안 됩니다. 빌드 도구, 의존성 해석기, 테스트 프로세스, 백그라운드 업데이트 작업 모두 아웃바운드 연결을 생성할 수 있습니다. 효과적으로 조사하려면 재현 가능한 빌드 하나를 선택하고, 제한된 시간 동안 “어떤 프로세스가 실행되었는지, 어디에 연결했는지, 언제 연결이 발생했는지”를 함께 기록한 뒤 그 결과를 기준선으로 정리해야 합니다.

비교 가능한 샘플링 구간부터 고정하기

의존성이 이미 설치되어 있고 작업 공간이 깨끗하며 다른 팀의 작업이 실행되지 않는 시간을 선택합니다. 커밋 ID, 빌드 명령, macOS 버전, Xcode 버전, 시작 시간을 기록합니다. 첫 번째 샘플링에서는 하나의 작업만 실행하여 두 파이프라인이 프로세스를 공유해 연결의 출처를 구분할 수 없게 되는 상황을 피합니다.

두 종류의 데이터를 준비하는 것이 좋습니다. 하나는 최소 빌드를 실행하고, 다른 하나는 전체 테스트를 실행합니다. 전자는 의존성 해석과 컴파일 과정의 연결을 보여 주며, 후자는 시뮬레이터, 테스트 서비스, 산출물 업로드까지 포함합니다. 각 작업을 두 번씩 반복하면 두 번째 실행에서 최초 다운로드와 안정 상태의 빌드를 구분하기가 대체로 쉬워집니다.

아웃바운드 기준선은 영구적으로 유효한 IP 목록이 아니라, “알려진 작업이 알려진 단계에서 특정 유형의 서비스에 접속한 이유”를 보여 주는 증거입니다.

세 계층의 증거로 연결 관찰하기

프로세스와 현재 연결

lsof는 샘플링 시점에 어떤 프로세스가 연결을 유지하고 있는지 확인하는 데 적합합니다. 숫자 주소를 사용하면 역방향 조회로 인해 추가 DNS 트래픽이 발생하는 것을 방지할 수 있습니다.

sudo lsof -nP -iTCP -sTCP:ESTABLISHED \
  | awk 'NR == 1 || $1 ~ /xcode|swift|git|ruby|node|curl/'

프로세스 이름만 기준으로 필터링한 뒤 원본 결과를 버리지 마십시오. 먼저 전체 스냅샷을 저장하고, 그다음 읽기 쉬운 하위 집합을 생성합니다. 빌드 스크립트가 시스템 도구를 통해 다운로드를 수행할 수 있으므로 프로세스 이름에 프로젝트 관련 키워드가 포함되지 않을 수도 있습니다.

트래픽과 단기 연결

nettop은 프로세스별로 집계된 실시간 보기를 제공하며, tcpdump는 수십 밀리초 안에 종료되는 TCP 핸드셰이크도 기록할 수 있습니다. 원격으로 실행할 때는 페이로드를 수집하지 않고 아웃바운드 SYN만 캡처하면 로그에 포함되는 업무 데이터를 줄일 수 있습니다.

nettop -P -L 1
sudo tcpdump -i any -nn -l \
  'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'

패킷 캡처를 시작하기 전에 현재 SSH 세션의 원격 주소를 확인합니다. 필터 조건을 잘못 작성하면 많은 노이즈가 발생할 수 있지만, 관찰 명령 자체가 방화벽 규칙을 변경하지는 않습니다.

보관 가능한 수집 번들 만들기

아래 스크립트는 시스템 정보, 라우팅 정보, 연결 스냅샷, 60초 동안의 핸드셰이크 기록을 저장합니다. 실행하기 전에 빌드를 바로 시작할 수 있는 상태로 준비하고, 스크립트를 시작한 뒤 다른 세션에서 빌드를 실행합니다.

#!/bin/zsh
set -euo pipefail

OUT="${1:-$HOME/ci-egress-$(date -u +%Y%m%dT%H%M%SZ)}"
mkdir -p "$OUT"

date -u > "$OUT/time.txt"
sw_vers > "$OUT/system.txt"
xcodebuild -version > "$OUT/xcode.txt"
route -n get default > "$OUT/default-route.txt"
scutil --dns > "$OUT/dns.txt"
sudo lsof -nP -i > "$OUT/lsof-before.txt"

sudo tcpdump -i any -nn \
  'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0' \
  -w "$OUT/outbound-syn.pcap" &
CAPTURE_PID=$!

sleep 60
sudo kill -INT "$CAPTURE_PID"
wait "$CAPTURE_PID" || true

sudo lsof -nP -i > "$OUT/lsof-after.txt"
nettop -P -L 1 > "$OUT/nettop.txt"
printf '%s
' "$OUT"

빌드가 60초를 초과한다면 하나의 캡처 시간을 계속 늘리는 대신 “의존성 해석, 컴파일, 테스트, 아카이브” 단계별로 샘플링해야 합니다. 단계별 결과를 사용하면 새 연결이 어느 단계에서 발생했는지 더 쉽게 파악할 수 있습니다.

연결 대상을 통신 기준선으로 분류하기

낯선 IP가 보인다는 이유만으로 비정상이라고 판단해서는 안 됩니다. 먼저 프로세스, 포트, 발생 단계, 프로젝트 구성을 함께 검토해 분류합니다. 동적 배포 네트워크는 주소가 자주 변경될 수 있으므로 기준선은 용도와 검증 가능한 도메인을 중심으로 작성하고, IP는 해당 수집 시점의 증거로만 보관해야 합니다.

| 범주 | 기록해야 할 증거 | 처리 방법 | |---|---|---| | 소스 코드 및 의존성 | 프로세스, 도메인, 빌드 단계 | 잠금 파일 및 저장소 구성과 대조 | | 테스트 서비스 | 테스트 케이스, 포트, 지속 시간 | 예상된 통합 테스트인지 확인 | | 산출물 전송 | 업로드 스크립트, 대상, 파일 유형 | 아카이브 단계에서만 발생하는지 확인 | | 시스템 백그라운드 트래픽 | 시스템 프로세스, 발생 시간 | 빌드 트래픽과 별도로 표시 | | 알 수 없는 연결 | 전체 명령줄, 부모 프로세스, 캡처 시간 | 병합을 중단하고 재현하여 증거 수집 |

알 수 없는 프로세스에는 ps -o pid,ppid,user,start,command -p PID를 추가로 실행한 뒤 부모 프로세스도 확인합니다. 연결이 한 번만 발생했다면 기억에 의존하지 말고 패킷 캡처 시간과 CI 로그 시간을 UTC로 통일한 후 서로 대조합니다.

흔한 오판과 안전 경계

가장 흔한 오판은 동적 IP를 고정된 식별 정보로 간주하는 것입니다. 두 번째 문제는 빌드가 끝난 뒤에만 lsof를 수집하는 것으로, 이 시점에는 단기 연결이 이미 사라졌을 수 있습니다. 세 번째 문제는 원격 노드에서 곧바로 차단 규칙을 활성화하는 것입니다. 로컬 콘솔에서 검증하지 않은 규칙은 SSH, DNS 또는 의존성 다운로드까지 동시에 끊을 수 있습니다.

더 안전한 순서는 관찰, 분류, 재현, 검토를 거친 뒤 마지막에 제한을 적용하는 것입니다. 아웃바운드 연결을 반드시 제한해야 한다면 기존 관리 연결과 DNS 경로를 먼저 유지하고 롤백 명령을 준비한 다음, 중요하지 않은 단일 작업에서 검증합니다. 방화벽 규칙, 프록시 구성, 빌드 스크립트는 버전 관리에 포함해야 하며 노드 로컬에만 남겨 두어서는 안 됩니다.

기준선을 일상적인 점검에 통합하기

도구 체인, 의존성 소스 또는 업로드 절차가 변경될 때마다 동일한 샘플링을 다시 실행합니다. 비교할 때는 IP 행 수가 아니라 새로 추가된 “프로세스—대상—단계” 조합에 주목합니다. 허용 항목에는 담당자, 용도, 재검토 조건을 명확히 기록해야 하며, 설명할 수 없는 연결을 메모만 남긴 채 영구적으로 허용해서는 안 됩니다.

마지막으로 수집 스크립트, 원본 파일, 분류표, 해당 커밋 ID를 보관합니다. 그러면 비정상적인 다운로드, 빌드 지연, 자격 증명의 외부 전송 의심과 같은 문제가 발생했을 때 정상 트래픽의 모습을 처음부터 다시 추측하지 않고 실제 차이에서 조사를 시작할 수 있습니다.

자주 묻는 질문

수집한 대상 IP를 바로 방화벽 허용 목록에 넣어도 되나요?

권장하지 않습니다. 다운로드 서비스는 동적 또는 공유 주소를 사용할 수 있으므로 먼저 용도와 도메인 기준으로 분류해야 합니다.

lsof와 tcpdump의 연결 수가 다른 이유는 무엇인가요?

lsof는 조회 순간에 열려 있는 연결만 보여 주지만 tcpdump는 수집 구간 안에서 이미 종료된 짧은 연결의 시작도 기록합니다.

OrbVPS 클라우드 Mac

전용 Apple Silicon 물리 노드에서 빌드 실행

기종, 지역 및 대여 기간에 따라 노드를 구성할 수 있으며, 실제 사용 가능 여부는 콘솔에서 실시간으로 확인되는 상태를 따릅니다.

클라우드 Mac 지금 대여하기