
Explique pourquoi un port TCP Linux peut être ou ne pas être joignable
PortClue explique pourquoi un port TCP sur une machine Linux peut ou non être joignable.
Il transforme l'état des sockets, des processus, du pare-feu et de Docker en une courte chaîne de preuves
au lieu de vous obliger à corréler manuellement ss, /proc, nftables, iptables et docker inspect.

Exécutez-le sans port pour découvrir quels points de terminaison TCP locaux méritent votre attention :
$ 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 et LOOPBACK_ONLY décrivent où un
socket accepte le trafic. Ils ne prétendent délibérément pas qu'un pare-feu l'autorise.
Inspectez un port pour l'analyse complète du pare-feu local :
$ 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 est un prototype Linux précoce et conservateur.
POTENTIALsignifie que le chemin local observé autorise le trafic ; il ne prétend pas qu'un port est joignable depuis l'internet public. Les expressions de pare-feu non prises en charge produisentUNKNOWN.
NETLINK_INET_DIAG, et non en analysant la sortie de ss/procsystemctl shownft --json list rulesetiptables-save lorsque nftables n'est pas disponiblePortClue identifie à quoi appartient un port avant d'expliquer l'exposition. Les preuves sont classées dans cet ordre :
/etc/services.Un propriétaire réel prime toujours sur un nom de port conventionnel. Si seule la convention de port
est connue, l'identité est explicitement marquée avec une confiance LOW. Le catalogue embarqué est
stocké dans internal/identify/catalog.json et est livré
à l'intérieur du binaire unique ; PortClue ne télécharge pas de données d'identité à l'exécution.
PortClue est en lecture seule. Il ne se connecte pas au port interrogé, ne scanne pas un autre hôte, ne modifie pas les règles de pare-feu, n'arrête pas de processus ou de conteneurs, ne téléverse pas de données et n'exécute pas de démon.
Fonctionne sous Linux (amd64 et arm64). Le script télécharge l'archive GitHub
Release correspondante, vérifie SHA256SUMS et installe un binaire unique. Il ne
modifie pas la configuration du shell.
Installation utilisateur (par défaut, sans root). Installe dans ~/.local/bin, vous en êtes propriétaire :
curl -fsSL https://raw.githubusercontent.com/pbxqdown/portclue/v0.1.2/scripts/install.sh | sh
portclue
Une installation utilisateur s'exécute sans root et rapporte les preuves disponibles pour votre
compte, en signalant ce qui manque. Cela suffit pour explorer les écouteurs et les
mappages Docker. Comme sudo ne recherche pas ~/.local/bin et que ce binaire est
modifiable par votre utilisateur, n'exécutez pas cette copie avec sudo.
Installation système (appartenant à root, pour sudo portclue). PortClue lit les preuves les plus
complètes (restreintes /proc, état complet du pare-feu) en tant que root. Pour cela,
installez un binaire appartenant à root dans /usr/local/bin (le script utilise sudo uniquement
pour l'étape d'installation finale, pas pour le téléchargement ou l'extraction) :
curl -fsSL https://raw.githubusercontent.com/pbxqdown/portclue/v0.1.2/scripts/install.sh | sh -s -- --system
sudo portclue
Substitutions facultatives : PORTCLUE_VERSION=0.1.2 (sans v initial) et
PORTCLUE_INSTALL_DIR pour l'un ou l'autre mode.
Désinstallation :
# 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
Téléchargez le fichier correspondant portclue-VERSION-linux-ARCH.tar.gz et SHA256SUMS depuis
GitHub Releases, vérifiez la
somme de contrôle, puis installez :
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
Correspondance des architectures :
uname -m | Archive |
|---|---|
x86_64 | linux-amd64 |
aarch64, arm64 | linux-arm64 |
Chaque archive inclut le binaire, le README, la licence Apache-2.0 et les mentions tierces.
Nécessite Linux et Go 1.25+ :
go install github.com/pbxqdown/portclue/cmd/[email protected]
Cela place le binaire dans $(go env GOPATH)/bin. Préférez l'archive de release
vérifiée par somme de contrôle ou le script d'installation lorsque vous voulez des artefacts d'installation reproductibles.
Prérequis : Linux et Go 1.25 ou plus récent.
go build -o portclue ./cmd/portclue
./portclue
./portclue --json
./portclue 8080
./portclue --json 8080
Le mode aperçu accepte des filtres facultatifs (les champs ignorés restent non contraints) :
./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 accepte une liste séparée par des virgules de ALL_INTERFACES,
SPECIFIC_INTERFACE et LOOPBACK_ONLY. --source accepte host et/ou
docker. --min-confidence conserve les entrées égales ou supérieures à HIGH, MEDIUM, LOW,
ou UNKNOWN. Ces options ne s'appliquent que lorsque PORT est omis.
L'exécution sans root fournit tout de même des preuves utiles sur les écouteurs, les mappages Docker et les adresses de bind.
L'identité des processus et les preuves de pare-feu peuvent être incomplètes lorsque /proc ou
l'état du pare-feu est restreint ; PortClue le signale sous Incomplete evidence.
Utilisez sudo pour le résultat le plus complet :
sudo ./portclue
sudo ./portclue --bind-scope ALL_INTERFACES,SPECIFIC_INTERFACE
sudo ./portclue 8080
Les formes JSON sont destinées aux scripts et aux agents. Le JSON d'aperçu utilise
schema_version: 2, mode: "overview" et entries avec
service_identity et bind_scope. Un rapport détaillé utilise
schema_version: 1, query, verdict, paths avec
service_identity, unknowns et warnings.
Au sein d'une version de schéma, les noms et significations des champs existants sont traités comme stables.
De nouveaux champs facultatifs peuvent être ajoutés. Une suppression, un renommage ou un changement de signification incompatible
nécessite un nouveau schema_version. Les deux contrats disposent de tests de régression.
| Verdict | Signification |
|---|---|
POTENTIAL | Un chemin local non-loopback est observé et les preuves de pare-feu prises en charge l'autorisent. Le routage externe est inconnu. |
NOT_EXPOSED_LOCALLY | Aucun écouteur/mappage n'existe, le bind est limité au loopback, ou les preuves de pare-feu local prises en charge bloquent le chemin. |
UNKNOWN | Un fait requis est indisponible ou une expression de pare-feu potentiellement pertinente n'est pas prise en charge. |
CONFIRMED | Réservé à une future sonde externe explicite. Le CLI actuel, purement local, ne l'émet jamais. |
--bind-scope, --source, --min-confidenceNon inclus : UDP, Podman, Kubernetes, groupes de sécurité cloud, découverte de routeur, scan à distance, eBPF, surveillance continue ou remédiation.
PortClue n'essaie intentionnellement pas d'implémenter l'intégralité de la machine virtuelle Netfilter.
La première version comprend un petit ensemble de règles directes. Plusieurs chaînes de base,
sauts, ensembles, maps, fib, expressions dynamiques ou toute autre logique non reconnue
provoquent UNKNOWN lorsqu'ils peuvent affecter la requête. C'est plus sûr que de traiter silencieusement
une règle non analysée comme accept ou drop.
Voir CONTRIBUTING.md pour le périmètre, les tests et la manière de signaler
les résultats de pare-feu UNKNOWN.
make check
make release VERSION=0.1.2
make release nécessite un arbre de travail Git propre et crée des archives versionnées amd64/arm64
ainsi que dist/SHA256SUMS. Pousser un tag v* vers le dépôt distant GitHub
configuré exécute les mêmes vérifications et crée une release GitHub. Aucun tag n'est créé
par le Makefile.
La conception à long terme maintient l'analyseur, le modèle causal et les moteurs de rendu indépendants de la plateforme. Linux est le premier backend de preuves ; Windows est probablement le second backend si le prototype Linux gagne une réelle utilisation.
PortClue est sous licence Apache License 2.0. Voir LICENSE. Les archives binaires incluent également THIRD_PARTY_NOTICES.
Voir CHANGELOG.md pour l'historique des versions et les notes de compatibilité JSON, SECURITY.md pour les versions prises en charge et le signalement privé de vulnérabilités, et CONTRIBUTING.md pour contribuer.