Commande Linux obtenir un port inutilisé

19

Je recherche une commande ou un script qui renvoie un port inutilisé sur mon système Linux Ubuntu. J'ai regardé sur Internet et la seule chose que je trouve concerne le port utilisé / Listen avec la commande nestat. Apparemment, quelque chose avec la commande netstat fonctionnera mais je ne sais pas quoi au juste. Une idée comment?

Merci.

utilisateur2429082
la source
Pourquoi avez-vous besoin de faire cela exactement? Si vous développez un serveur, vous pouvez vous connecter au port 0 et le système d'exploitation allouera un port disponible pour vous. Vous n'avez rien à chercher. Sinon, la recherche et la liaison sont sujettes aux conditions de concurrence. Voir par exemple stackoverflow.com/questions/1365265/… ou stackoverflow.com/questions/1075399/…
Patrick Mevzek le

Réponses:

14

netstat -latdonne la liste complète des ports d' écoute et établis .

Lorsqu'un port n'est pas sur l'un de ces états, il n'existe pas pour le système, vous ne trouverez donc pas de commande qui affiche la liste des ports inutilisés.

N'oubliez pas qu'il existe 65535 ports. Par conséquent, tout ce qui ne fonctionne pas netstat -latest un port inutilisé.

Le script bash suivant effectuera une analyse simple des ports TCP et vous indiquera ceux qui sont ouverts et ceux qui sont fermés :

#!/bin/bash
IP=$1
first_port=$2
last_port=$3
function scanner

{
for ((port=$first_port; port<=$last_port; port++))
        do
                (echo >/dev/tcp/$IP/$port)> /dev/null 2>&1 && echo $port open || echo "$port closed"
        done
}

scanner

Si vous l'enregistrez en tant que portscan.sh, vous devez l'exécuter en tant que ./portscan.sh IP first_port last_port , par exemple: ./portscan 127.0.0.1 20 135analysera l'équipement local des ports 20 à 135

jcbermu
la source
7

Ruby 2.x (une doublure):

ruby -e 'require "socket"; puts Addrinfo.tcp("", 0).bind {|s| s.local_address.ip_port }'

Sur ma machine en ce moment qui a imprimé:

42644

Une invocation ultérieure imprimée:

36168

Cette technique oblige l'utilisateur actuel à demander un port inutilisé (liaison au port "0"), puis à imprimer le numéro de port fourni par le système d'exploitation. Et puisque l'utilisateur actuel est celui qui le demande, les ports inférieurs à 1024 ne seront pas retournés (sauf si l'utilisateur actuel = root).

Crédit pour lequel le crédit est dû - cette solution provient d'un commentaire de Franklin Yu sur unix.stackexchange.com's Quel est le moyen le plus simple de trouver un port local inutilisé?

G. Sylvie Davies
la source
Comment est-ce que je pourrais assigner le résultat de ceci à une variable dans un script bash?
Neil Stevens
export PORT = $ (ruby -e 'require "socket"; ajoute Addrinfo.tcp ("", 0) .bind {| s | s.l.local_address.ip_port}')
G. Sylvie Davies
2

Bon mot

J'ai mis en place une belle ligne qui répond rapidement au but recherché, permettant de saisir un nombre arbitraire de ports dans une plage quelconque (ici, il est divisé en 4 lignes pour la lisibilité):

comm -23 \
<(seq "$FROM" "$TO") \
<(ss -tan | awk '{print $4}' | cut -d':' -f2 | grep '[0-9]\{1,5\}' | sort -n | uniq) \
| shuf | head -n "$HOWMANY"

Ligne par ligne

commest un utilitaire qui compare les lignes triées dans deux fichiers. Il génère trois colonnes: les lignes qui apparaissent uniquement dans le premier fichier, les lignes qui apparaissent uniquement dans le second et les lignes communes. En spécifiant, -23nous supprimons ces dernières colonnes et ne conservons que la première. Nous pouvons utiliser ceci pour obtenir la différence de deux ensembles, exprimés sous forme d'une séquence de lignes de texte. J'ai appris à propos de comm ici .

Le premier fichier est la gamme de ports que nous pouvons sélectionner. seqproduit une séquence triée de nombres allant de $FROMà $TO. Le résultat est dirigé vers commle premier fichier utilisant la substitution de processus .

Le deuxième fichier est la liste triée des ports, obtenue en appelant la sscommande (ce qui -tsignifie ports TCP, -asignifiant tout établi et à l'écoute - et -nnumérique - n'essayez pas de résoudre, par exemple, 22en ssh). Nous sélectionnons ensuite uniquement la quatrième colonne awkcontenant l’adresse locale et le port. Nous avons l'habitude cutde scinder l'adresse et le port avec le :délimiteur et de ne garder que celui-ci ( -f2). ssaffiche également un en-tête, que nous éliminons par grepping pour les séquences non vides de nombres ne dépassant pas 5. Nous nous conformons ensuite à comml'exigence de en sortinsérant numériquement ( -n) et en supprimant les doublons uniq.

Maintenant , nous avons une liste triée des ports ouverts, que nous pouvons shufFLE pour saisir ensuite les premiers "$HOWMANY"ceux avec head -n.

Exemple

Saisissez les trois ports ouverts aléatoires dans la plage privée (49152-65535)

comm -23 <(seq 49152 65535) <(ss -tan | awk '{print $4}' | cut -d':' -f2 | grep "[0-9]\{1,5\}" | sort | uniq) | shuf | head -n 3

pourrait revenir par exemple

54930
57937
51399

Remarques

  • passer -tavec -udans sspour obtenir les ports UDP libres à la place.
  • déposer shufsi vous n'êtes pas intéressé par un portage aléatoire
Stefanobaghino
la source
1
J'aime votre one-liner, cette version analyse correctement IPv6, par exemple [:: 1]: 52792, et utilise l'option --no-header au lieu de grep. gist.github.com/fstefanov/ff4dcec7ded59514421bf944d1bb9a6f
Filip Stefanov
1

Short bash script qui génère de manière aléatoire un nombre compris entre 1025 et 60000 et boucle jusqu'à ce que ce nombre ne soit plus dans la liste des ports utilisés. Il s’agit d’une solution rapide et malpropre qui privilégie les grands ports:

CHECK="do while"

while [[ ! -z $CHECK ]]; do
    PORT=$(( ( RANDOM % 60000 )  + 1025 ))
    CHECK=$(sudo netstat -ap | grep $PORT)
done

echo $PORT
Taras
la source
Vérifiez votre commande grep, voir le commentaire sur la réponse de adarshr
Nick
1

Je devais trouver juste un seul port inutilisé au hasard et ne pas en imprimer une liste. Voici ma solution bash.

#/bin/bash

function random_unused_port {
    local port=$(shuf -i 2000-65000 -n 1)
    netstat -lat | grep $port > /dev/null
    if [[ $? == 1 ]] ; then
        export RANDOM_PORT=$port
    else
        random_unused_port
    fi
}

random_unused_port

Et utilisez-le en le recherchant

$ . ./random_unused_port.sh; echo $RANDOM_PORT
Adarshr
la source
J'aime l'idée ici, mais votre commande grep ne vous retournera pas ce que vous voulez. La bonne chose est que ce sera prudent, mais si le prochain port aléatoire est 2000, et que le port 2000 est ouvert, mais que le port 20000 est utilisé, il continuera à chercher, le résultat ne sera donc pas la gamme complète des ports disponibles.
Nick
1

Peut-être une autre solution basée sur la liste des ports utilisés:

function random_unused_port {
   (netstat --listening --all --tcp --numeric | 
    sed '1,2d; s/[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*:\([0-9]*\)[[:space:]]*.*/\1/g' |
    sort -n | uniq; seq 1 1000; seq 1 65535
    ) | sort -n | uniq -u | shuf -n 1
}

RANDOM_PORT=$(random_unused_port)

La netstatcommande génère une liste de tous les ports ouverts. La sedcommande extrait les numéros de port en cours d'utilisation et la construction sort/ uniqrenvoie une liste uniq de ports ouverts. La deuxième étape consiste à générer une liste de numéros de ports commençant par 1 et se terminant par 1000 (ports réservés) et une liste supplémentaire de tous les numéros de ports commençant par 1 à 65535. La liste finale contient tous les ports disponibles une seule fois et uniq -usera extraite par ceux-ci. . Enfin, le shuf -n 1chercheur choisira un port aléatoire dans la liste complète des ports disponibles. Néanmoins, il y aura une condition de concurrence, avant de pouvoir réserver le port.

Frank Förster
la source
0

Si 54321 est votre port, exécutez:

sudo netstat -ap |grep 54321

Certaines variantes d'utilisation de netstat peuvent être trouvées ici .

Surmente
la source
Cette commande ne m'indique que si le port 54321 est utilisé ou non. Ce que je veux, c'est trouver un port inutilisé.
user2429082
Inutilisé est ambigu. Vous voulez vérifier quel port sont disponibles pour écouter? Ou à quels ports sont disponibles pour vous connecter? Tous ceux qui ne sont pas utilisés sont disponibles. En tant qu'utilisateur, vous pouvez utiliser ceux supérieurs à 1024, en tant que root, vous pouvez également utiliser ceux de moins de 1024.
Overmind