Как проверить, открыт ли сетевой порт в Linux?

Как узнать, открыт или закрыт определенный порт на linux ubuntu, а не удаленной системе, используя python? Как я могу перечислить эти открытые порты в python?

  • Netstat: Есть ли способ интегрировать вывод netstat с помощью python?

Ответ 1

Вы можете использовать модуль сокета, чтобы просто проверить, открыт порт или нет.

Это будет выглядеть примерно так.

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
   print "Port is open"
else:
   print "Port is not open"
sock.close()

Ответ 2

Если вы хотите использовать это в более общем контексте, вы должны убедиться, что сокет, который вы открываете, также закрывается. Поэтому проверка должна быть более такой:

import socket
from contextlib import closing

def check_socket(host, port):
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        if sock.connect_ex((host, port)) == 0:
            print "Port is open"
        else:
            print "Port is not open"

Ответ 3

Для меня приведенные выше примеры зависают, если порт не был открыт. В строке 4 показано использование привязки, чтобы предотвратить зависание

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)                                      #2 Second Timeout
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
  print 'port OPEN'
else:
  print 'port CLOSED, connect_ex returned: '+str(result)

Ответ 4

Если вы заботитесь только о локальном компьютере, вы можете положиться на пакет psutil. Вы можете либо:

  1. Проверьте все порты, используемые конкретным pid:

    proc = psutil.Process(pid)
    print proc.connections()
    
  2. Проверьте все порты, используемые на локальной машине:

    print psutil.net_connections()
    

Работает и на Windows тоже.

https://github.com/giampaolo/psutil

Ответ 5

Средство Netstat просто анализирует некоторые файлы /proc, такие как /proc/net/tcp, и объединяет их с другими файлами. Да, это очень специфично для платформы, но для Linux-единственного решения вы можете придерживаться этого. Документация ядра Linux подробно описывает эти файлы, чтобы вы могли найти их, как их читать.

Также обратите внимание, что ваш вопрос слишком неоднозначен, потому что "порт" также может означать последовательный порт (/dev/ttyS * и аналоги), параллельный порт и т.д.; Я снова использовал понимание из другого ответа, это сетевой порт, но я бы попросил вас более точно сформулировать ваши вопросы.

Ответ 6

В случае, если вы исследуете TCP-порты с намерением прослушать его, лучше на самом деле вызвать прослушивание. Подход с tring для подключения не видит клиентских портов установленных соединений, потому что никто не слушает его. Но эти порты не могут быть использованы для прослушивания.

import socket


def check_port(port, rais=True):
    """ True -- it possible to listen on this port for TCP/IPv4 or TCP/IPv6
    connections. False -- otherwise.
    """
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('127.0.0.1', port))
        sock.listen(5)
        sock.close()
        sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
        sock.bind(('::1', port))
        sock.listen(5)
        sock.close()
    except socket.error as e:
        return False
        if rais:
            raise RuntimeError(
                "The server is already running on port {0}".format(port))
    return True

Ответ 7

Просто добавлен к решению mrjandro быстрый хак, чтобы избавиться от простых ошибок/тайм-аутов соединения.

Вы можете изменить пороговое значение переменной max_error_count и добавить уведомления любого типа.

import socket

max_error_count = 10

def increase_error_count():
    # Quick hack to handle false Port not open errors 
    with open('ErrorCount.log') as f:
        for line in f:
            error_count = line
    error_count = int(error_count)
    print "Error counter: " + str(error_count)
    file = open('ErrorCount.log', 'w')
    file.write(str(error_count + 1))
    file.close()
    if error_count == max_error_count:
        # Send email, pushover, slack or do any other fancy stuff
        print "Sending out notification"
        # Reset error counter so it won't flood you with notifications
        file = open('ErrorCount.log', 'w')
        file.write('0')
        file.close()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2) 
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
        print "Port is open"
else:
        print "Port is not open"
        increase_error_count()

И здесь вы найдете версию, совместимую с Python 3 (только фиксированный синтаксис печати):

import socket

max_error_count = 10

def increase_error_count():
    # Quick hack to handle false Port not open errors
    with open('ErrorCount.log') as f:
        for line in f:
            error_count = line
    error_count = int(error_count)
    print ("Error counter: " + str(error_count))
    file = open('ErrorCount.log', 'w')
    file.write(str(error_count + 1))
    file.close()
    if error_count == max_error_count:
        # Send email, pushover, slack or do any other fancy stuff
        print ("Sending out notification")
        # Reset error counter so it won't flood you with notifications
        file = open('ErrorCount.log', 'w')
        file.write('0')
        file.close()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2) 
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
        print ("Port is open")
else:
        print ("Port is not open")
        increase_error_count()

Ответ 8

Пожалуйста, проверьте ответ Михаэля и проголосуйте за него. Это правильный способ проверить открытые порты. Netstat и другие инструменты бесполезны, если вы разрабатываете сервисы или демоны. Например, я пишу TCP-сервер Modbus и клиентские сервисы для промышленной сети. Службы могут прослушивать любой порт, но вопрос в том, открыт ли этот порт? Программа будет использоваться в разных местах, и я не могу проверить их все вручную, поэтому я сделал следующее:

from contextlib import closing
import socket
class example:
    def __init__():

       self.machine_ip = socket.gethostbyname(socket.gethostname())
       self.ready:bool = self.check_socket()

    def check_socket(self)->bool:
        result:bool = True
        with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        modbus_tcp_port:int = 502
        if not sock.connect_ex((self.machine_ip, modbus_tcp_port)) == 0:
            result = False
        return result

Ответ 9

Вот быстрый многопоточный сканер портов:

from time import sleep
import socket, ipaddress, threading

max_threads = 50
final = {}
def check_port(ip, port):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
        #sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
        socket.setdefaulttimeout(2.0) # seconds (float)
        result = sock.connect_ex((ip,port))
        if result == 0:
            # print ("Port is open")
            final[ip] = "OPEN"
        else:
            # print ("Port is closed/filtered")
            final[ip] = "CLOSED"
        sock.close()
    except:
        pass
port = 80
for ip in ipaddress.IPv4Network('192.168.1.0/24'): 
    threading.Thread(target=check_port, args=[str(ip), port]).start()
    #sleep(0.1)

# limit the number of threads.
while threading.active_count() > max_threads :
    sleep(1)

print(final)

Live Demo