
Linux TCP 포트가 도달 가능한지 여부를 설명합니다
PortClue는 Linux 머신의 TCP 포트가 왜 도달 가능하거나 도달 불가능한지를 설명합니다.
ss, /proc, nftables, iptables, docker inspect를 직접 대조하지 않아도 되도록,
소켓, 프로세스, 방화벽, Docker 상태를 짧은 증거 체인으로 바꿔 줍니다.

포트 없이 실행하면 주목할 만한 로컬 TCP 엔드포인트를 찾아냅니다:
$ sudo portclue
LOCAL TCP LISTENERS
PORT SERVICE CONFIDENCE BIND OWNER SOURCE BIND SCOPE
22 OpenSSH server HIGH 0.0.0.0,:: ssh.service host ALL_INTERFACES
8080 NGINX web server HIGH 0.0.0.0,:: nginx host ALL_INTERFACES
8443 api service MEDIUM 192.0.2.10 demo-api docker SPECIFIC_INTERFACE
9000 Python HTTP server MEDIUM 127.0.0.1 python3 host LOOPBACK_ONLY
BIND SCOPE describes socket binding, not firewall reachability.
Run `portclue PORT` for the complete evidence chain and local exposure verdict.
ALL_INTERFACES, SPECIFIC_INTERFACE, LOOPBACK_ONLY는 소켓이 어디에서 트래픽을
받아들이는지를 나타냅니다. 방화벽이 이를 허용한다고 주장하지는 않습니다.
전체 로컬 방화벽 분석을 보려면 포트를 검사하세요:
$ sudo portclue 8080
POTENTIAL EXTERNAL EXPOSURE
TCP port 8080
0.0.0.0:8080/tcp [POTENTIAL]
Service NGINX web server
Category web
Confidence HIGH
Identity evidence executable basename matched "nginx"
-> LISTEN NETLINK_INET_DIAG reports socket inode 123456 bound to 0.0.0.0:8080/tcp
-> OWNED PID 4242 (nginx), systemd unit nginx.service
-> ALL_INTERFACES 0.0.0.0 accepts traffic addressed to any local interface
-> ACCEPT nftables: a direct rule matches TCP destination port 8080 and returns accept
Unknown outside this machine:
- router port forwarding
- cloud firewall or security group
- upstream NAT, including carrier-grade NAT
[!IMPORTANT] PortClue v0.1은 초기 단계의 보수적인 Linux 프로토타입입니다.
POTENTIAL은 관측된 로컬 경로가 트래픽을 허용한다는 뜻이며, 해당 포트가 공용 인터넷에서 도달 가능하다고 주장하지는 않습니다. 지원되지 않는 방화벽 표현식은UNKNOWN을 생성합니다.
ss 출력을 긁어모으는 대신 NETLINK_INET_DIAG를 통한 TCP 리스너/proc를 통한 프로세스 소유권, 실행 파일, 명령줄, cgroup, 네트워크 네임스페이스systemctl show를 통한 활성 소켓 트리거nft --json list ruleset을 통한 nftablesiptables-save를 통한 iptablesPortClue는 노출을 설명하기 전에 포트가 무엇에 속하는지 식별합니다. 증거는 다음 순서로 순위가 매겨집니다:
/etc/services 포트 관례.실제 소유자는 항상 관례적인 포트 이름을 덮어씁니다. 포트 관례만 알려진 경우,
식별은 명시적으로 LOW 신뢰도로 표시됩니다. 내장 카탈로그는
internal/identify/catalog.json에 저장되어
단일 바이너리 안에 포함됩니다; PortClue는 런타임에 식별 데이터를 다운로드하지 않습니다.
PortClue는 읽기 전용입니다. 조회한 포트에 연결하거나, 다른 호스트를 스캔하거나, 방화벽 규칙을 변경하거나, 프로세스나 컨테이너를 중지하거나, 데이터를 업로드하거나, 데몬을 실행하지 않습니다.
Linux (amd64 및 arm64)에서 실행됩니다. 스크립트는 일치하는 GitHub
Release 아카이브를 다운로드하고, SHA256SUMS를 검증한 뒤, 단일 바이너리를 설치합니다.
셸 설정은 수정하지 않습니다.
사용자 설치 (기본, root 불필요). ~/.local/bin에 설치되며, 소유자는 본인입니다:
curl -fsSL https://raw.githubusercontent.com/pbxqdown/portclue/v0.1.2/scripts/install.sh | sh
portclue
사용자 설치는 root 없이 실행되며, 계정에서 사용할 수 있는 증거를 보고하고
무엇이 누락되었는지 알려줍니다. 리스너와 Docker 매핑을 살펴보기에는 충분합니다.
sudo는 ~/.local/bin을 검색하지 않고 이 바이너리는 사용자가 쓸 수 있으므로,
이 복사본을 sudo로 실행하지 마세요.
시스템 설치 (root 소유, sudo portclue용). PortClue는 root로 실행할 때
가장 완전한 증거(제한된 /proc, 전체 방화벽 상태)를 읽습니다. 이를 위해
root 소유 바이너리를 /usr/local/bin에 설치합니다 (스크립트는 다운로드나
압축 해제가 아닌 마지막 설치 단계에서만 sudo를 사용합니다):
curl -fsSL https://raw.githubusercontent.com/pbxqdown/portclue/v0.1.2/scripts/install.sh | sh -s -- --system
sudo portclue
선택적 재정의: PORTCLUE_VERSION=0.1.2 (앞의 v 없음) 및
두 모드 모두에 대한 PORTCLUE_INSTALL_DIR.
제거:
# user install
rm ~/.local/bin/portclue
# system install
sudo rm /usr/local/bin/portclue
# or, matching how you installed:
curl -fsSL https://raw.githubusercontent.com/pbxqdown/portclue/v0.1.2/scripts/install.sh | sh -s -- --uninstall
curl -fsSL https://raw.githubusercontent.com/pbxqdown/portclue/v0.1.2/scripts/install.sh | sh -s -- --system --uninstall
GitHub Releases에서 일치하는
portclue-VERSION-linux-ARCH.tar.gz와 SHA256SUMS를 다운로드하고, 체크섬을
검증한 뒤 설치하세요:
sha256sum -c SHA256SUMS --ignore-missing
tar -xzf portclue-0.1.2-linux-amd64.tar.gz # or linux-arm64
sudo install -m 0755 portclue-0.1.2-linux-amd64/portclue /usr/local/bin/portclue
portclue --version
아키텍처 매핑:
uname -m | Archive |
|---|---|
x86_64 | linux-amd64 |
aarch64, arm64 | linux-arm64 |
각 아카이브에는 바이너리, README, Apache-2.0 라이선스, 서드파티 고지가 포함됩니다.
Linux와 Go 1.25+가 필요합니다:
go install github.com/pbxqdown/portclue/cmd/[email protected]
이 명령은 바이너리를 $(go env GOPATH)/bin에 넣습니다. 재현 가능한 설치
아티팩트를 원한다면 체크섬으로 검증된 릴리스 아카이브나 설치 스크립트를
선호하세요.
요구 사항: Linux 및 Go 1.25 이상.
go build -o portclue ./cmd/portclue
./portclue
./portclue --json
./portclue 8080
./portclue --json 8080
개요 모드는 선택적 필터를 받습니다 (무시된 필드는 제약 없이 유지됩니다):
./portclue --bind-scope ALL_INTERFACES,SPECIFIC_INTERFACE
./portclue --source docker
./portclue --min-confidence MEDIUM
./portclue --json --bind-scope ALL_INTERFACES --min-confidence HIGH
--bind-scope는 ALL_INTERFACES, SPECIFIC_INTERFACE, LOOPBACK_ONLY의
쉼표로 구분된 목록을 받습니다. --source는 host 및/또는 docker를 받습니다.
--min-confidence는 HIGH, MEDIUM, LOW, UNKNOWN 이상의 항목을 유지합니다.
이 플래그들은 PORT가 생략된 경우에만 적용됩니다.
root 없이 실행해도 유용한 리스너, Docker 매핑, 바인드 주소 증거를 얻을 수 있습니다.
/proc이나 방화벽 상태가 제한된 경우 프로세스 식별과 방화벽 증거가 불완전할 수
있으며, PortClue는 이를 Incomplete evidence 아래에 보고합니다. 가장 완전한
결과를 얻으려면 sudo를 사용하세요:
sudo ./portclue
sudo ./portclue --bind-scope ALL_INTERFACES,SPECIFIC_INTERFACE
sudo ./portclue 8080
JSON 형식은 스크립트와 에이전트를 위한 것입니다. 개요 JSON은
schema_version: 2, mode: "overview", 그리고 service_identity와
bind_scope를 가진 entries를 사용합니다. 상세 보고서는
schema_version: 1, query, verdict, service_identity, unknowns,
warnings를 가진 paths를 사용합니다.
스키마 버전 내에서 기존 필드 이름과 의미는 안정적인 것으로 취급됩니다.
새로운 선택적 필드가 추가될 수 있습니다. 제거, 이름 변경, 또는 호환되지 않는
의미 변경은 새로운 schema_version을 필요로 합니다. 두 계약 모두 회귀 테스트를
가집니다.
| Verdict | Meaning |
|---|---|
POTENTIAL | 루프백이 아닌 로컬 경로가 관측되었고 지원되는 방화벽 증거가 이를 허용합니다. 외부 라우팅은 알 수 없습니다. |
--bind-scope, --source, --min-confidence포함되지 않음: UDP, Podman, Kubernetes, 클라우드 보안 그룹, 라우터 검색, 원격 스캔, eBPF, 지속적 모니터링, 또는 교정.
PortClue는 의도적으로 전체 Netfilter 가상 머신을 구현하려고 시도하지 않습니다.
첫 버전은 작은 규칙 집합을 이해합니다. 여러 기본 체인, 점프, 집합, 맵, fib,
동적 표현식, 또는 기타 인식되지 않는 로직이 쿼리에 영향을 줄 수 있는 경우
UNKNOWN을 생성합니다. 이는 파싱되지 않은 규칙을 조용히 허용 또는 차단으로
취급하는 것보다 안전합니다.
범위, 테스트, 방화벽 UNKNOWN 결과를 보고하는 방법은
CONTRIBUTING.md를 참조하세요.
make check
make release VERSION=0.1.2
make release는 깨끗한 Git 작업 트리를 요구하며 버전이 지정된 amd64/arm64
아카이브와 dist/SHA256SUMS를 생성합니다. 구성된 GitHub 원격에 v* 태그를
푸시하면 동일한 검사가 실행되고 GitHub 릴리스가 생성됩니다. Makefile은 태그를
생성하지 않습니다.
장기적인 설계는 분석기, 인과 모델, 렌더러를 플랫폼 중립적으로 유지합니다. Linux가 첫 번째 증거 백엔드이며, Linux 프로토타입이 실제 사용을 얻는다면 Windows가 두 번째 백엔드가 될 가능성이 높습니다.
PortClue는 Apache License 2.0에 따라 라이선스가 부여됩니다. LICENSE를 참조하세요. 바이너리 아카이브에는 THIRD_PARTY_NOTICES도 포함됩니다.
릴리스 이력과 JSON 호환성 노트는 CHANGELOG.md, 지원 버전과 비공개 취약점 보고는 SECURITY.md, 기여 방법은 CONTRIBUTING.md를 참조하세요.
NOT_EXPOSED_LOCALLY | 리스너/매핑이 없거나, 바인드가 루프백 전용이거나, 지원되는 로컬 방화벽 증거가 경로를 차단합니다. |
UNKNOWN | 필요한 사실을 사용할 수 없거나 잠재적으로 관련된 방화벽 표현식이 지원되지 않습니다. |
CONFIRMED | 향후 명시적 외부 프로브를 위해 예약되어 있습니다. 현재의 로컬 전용 CLI는 이를 결코 출력하지 않습니다. |