Polecenie Linux uzyskać nieużywany port

20

Szukam polecenia lub skryptu, który zwraca nieużywany port w moim systemie Ubuntu Linux. Zajrzałem do Internetu i jedyne, co znalazłem, to port używany / Listen z poleceniem nestat. Najwyraźniej coś z poleceniem netstat będzie działać, ale nie wiem co dokładnie. Masz pomysł jak?

Dzięki.

użytkownik2429082
źródło
1
Dlaczego musisz to zrobić dokładnie? Jeśli tworzysz serwer, możesz połączyć się z portem 0, a system operacyjny przydzieli ci wolny port, nie musisz nic przeszukiwać. W przeciwnym razie wyszukiwanie, a następnie wiązanie jest podatne na warunki wyścigu. Zobacz na przykład stackoverflow.com/questions/1365265/… lub stackoverflow.com/questions/1075399/…
Patrick Mevzek

Odpowiedzi:

14

netstat -latpodaje pełną listę nasłuchiwanych i ustanowionych portów.

Gdy port nie znajduje się w żadnym z tych stanów, system nie istnieje, więc nie znajdziesz polecenia wyświetlającego listę nieużywanych portów.

Pamiętaj, że istnieje 65535 portów, więc wszystko, co nie netstat -latjest włączone, jest nieużywanym portem.

Poniższy skrypt bash wykona proste skanowanie portów TCP i poinformuje, które są otwarte, a które zamknięte :

#!/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

Jeśli zapiszesz go jako portcan.sh , musisz go uruchomić jako ./portscan.sh IP pierwszy_port ostatni_port , na przykład: ./portscan 127.0.0.1 20 135skanuje sprzęt lokalny z portów 20 do 135

jcbermu
źródło
7

Ruby 2.x (jednowarstwowy):

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

Na mojej maszynie w tej chwili wydrukowano:

42644

Wydrukowano kolejne wezwanie:

36168

Ta technika powoduje, że bieżący użytkownik żąda nieużywanego portu (powiązanie z portem „0”), a następnie drukuje numer portu podany przez system operacyjny. A ponieważ pyta obecny użytkownik, porty poniżej 1024 nie zostaną zwrócone (chyba że bieżący użytkownik = root).

Kredyt, na który przypadają kredyty - rozwiązanie pochodzi z komentarza Franklina Yu na unix.stackexchange.com Jaki jest najłatwiejszy sposób na znalezienie nieużywanego portu lokalnego?

G. Sylvie Davies
źródło
Jak mogę przypisać wynik tego do zmiennej w skrypcie bash?
Neil Stevens,
export PORT = $ (ruby -e 'wymaga "gniazda"; wstawia Addrinfo.tcp ("", 0). powiązać {| s | s.local_address.ip_port}')
G. Sylvie Davies
3

Krótki skrypt bash, który losowo generuje liczbę od 1025 do 60000 i pętle, dopóki ta liczba nie zostanie znaleziona na liście używanych portów. To szybkie i brudne rozwiązanie ma tendencję do większych portów:

CHECK="do while"

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

echo $PORT
Taras
źródło
Sprawdź swoje polecenie grep, zobacz komentarz do odpowiedzi adarshr
Nick
2

Jednowarstwowa

Stworzyłem ładny jednowierszowy, który szybko służy temu celowi, pozwalając złapać dowolną liczbę portów w dowolnym zakresie (tutaj jest podzielony na 4 linie dla czytelności):

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"

Linia po linii

commto narzędzie, które porównuje posortowane linie w dwóch plikach. Wyprowadza trzy kolumny: linie, które pojawiają się tylko w pierwszym pliku, linie, które pojawiają się tylko w drugim, i linie wspólne. Określając -23, pomijamy te ostatnie kolumny i zachowujemy tylko pierwszą. Możemy to wykorzystać, aby uzyskać różnicę dwóch zestawów, wyrażoną jako ciąg wierszy tekstu. Dowiedziałem się comm tutaj .

Pierwszy plik to zakres portów, które możemy wybrać. seqtworzy posortowaną sekwencję liczb od $FROMdo $TO. Wynik jest przesyłany do commpierwszego pliku przy użyciu podstawienia procesu .

Drugi plik to posortowana lista portów, którą uzyskujemy przez wywołanie sspolecenia (w -tznaczeniu portów TCP, -aco oznacza , że wszystkie - ustanowione i nasłuchujące - i -nliczbowe - nie próbuj rozstrzygać, powiedzmy, 22na ssh). Następnie wybieramy tylko czwartą kolumnę awk, która zawiera adres lokalny i port. Używamy cutdo dzielenia adresu i portu za pomocą :separatora i zatrzymywania tylko tego ostatniego ( -f2). sswypisujemy również nagłówek, którego pozbywamy się przez grepping dla niepustych sekwencji liczb, które nie są dłuższe niż 5. Następnie spełniamy commwymaganie, sortwpisując numerycznie ( -n) i usuwając duplikaty uniq.

Teraz mamy posortowaną listę otwartych portów, które możemy shufFLE aby następnie chwycić pierwsze "$HOWMANY"te z head -n.

Przykład

Chwyć trzy losowe otwarte porty z zakresu prywatnego (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

może na przykład wrócić

54930
57937
51399

Uwagi

  • przełączyć -tsię -uw ssdostać darmowe porty UDP zamiast.
  • upuść, shufjeśli nie jesteś zainteresowany złapaniem losowego portu
stefanobaghino
źródło
1
Podoba mi się twój liner, ta wersja poprawnie analizuje IPv6 np. [:: 1]: 52792 i używa opcji --no-header zamiast grep. gist.github.com/fstefanov/ff4dcec7ded59514421bf944d1bb9a6f
Filip Stefanov
1

Musiałem znaleźć tylko jeden losowy nieużywany port i nie wydrukować ich listy. Oto moje rozwiązanie 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

I wykorzystaj go, zdobywając go

$ . ./random_unused_port.sh; echo $RANDOM_PORT
adarshr
źródło
Podoba mi się ten pomysł, jednak twoje polecenie grep nie zwróci tego, co zamierzasz. Dobrą rzeczą jest to, że będzie konserwatywny, ale jeśli następny losowy port to 2000, a port 2000 jest otwarty, ale port 20000 jest w użyciu, będzie szukał dalej, więc wynikiem nie będzie pełny zakres dostępnych portów.
Nick
1

Być może inne rozwiązanie oparte na liście używanych portów:

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)

netstatPolecenie generuje listę wszystkich otwartych portów. sedPolecenie wyodrębnia liczbie portów, które są używane oraz sort/ uniqpowraca skonstruowania lista uniq otwartych portów. Drugim krokiem jest wygenerowanie listy numerów portów rozpoczynającej się od 1 i kończącej się na 1000 (porty zarezerwowane) oraz dodatkowej listy wszystkich numerów portów od 1 do 65535. Ostateczna lista zawiera wszystkie dostępne porty tylko raz i uniq -uje wyodrębni . Na koniec shuf -n 1wybierze jeden losowy port z pełnej listy dostępnych portów. Niemniej jednak będą istnieć warunki wyścigu, zanim będzie można zarezerwować port.

Frank Förster
źródło
1

Musiałem znaleźć następny otwarty port zaczynający się od numeru portu; oto moja próba użycia rozwiązania @Taras.

_check="placeholder"
START_FROM=1900
PORT=$(( ( "$RANDOM" % 1000 ) + $START_FROM ))
while [[ ! -z "${_check}" ]]; do
    ((PORT++))
    _check=$(ss -tulpn | grep ":${PORT}")
done
Alberto Chiusole
źródło
0

Jeśli 54321 jest twoim portem, uruchom:

sudo netstat -ap |grep 54321

Niektóre warianty korzystania z netstat można znaleźć tutaj .

Overmind
źródło
To polecenie pokaże mi tylko, czy port 54321 jest używany, czy nie. Chcę znaleźć nieużywany port.
user2429082,
Niewykorzystane jest niejednoznaczne. Chcesz sprawdzić, który port jest dostępny do słuchania? Lub z jakim portem można się połączyć? Wszystkie nieużywane są dostępne. Jako użytkownik możesz używać tych powyżej 1024, jako root, możesz również używać tych poniżej 1024.
Overmind