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.



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


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?


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

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

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

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.


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

0

Jeśli 54321 jest twoim portem, uruchom:

sudo netstat -ap |grep 54321

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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.