Как узнать, открыт или закрыт определенный порт на linux ubuntu, а не удаленной системе, используя python? Как я могу перечислить эти открытые порты в python?
- Netstat: Есть ли способ интегрировать вывод netstat с помощью python?
Как узнать, открыт или закрыт определенный порт на linux ubuntu, а не удаленной системе, используя python? Как я могу перечислить эти открытые порты в python?
Вы можете использовать модуль сокета, чтобы просто проверить, открыт порт или нет.
Это будет выглядеть примерно так.
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()
Если вы хотите использовать это в более общем контексте, вы должны убедиться, что сокет, который вы открываете, также закрывается. Поэтому проверка должна быть более такой:
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"
Для меня приведенные выше примеры зависают, если порт не был открыт. В строке 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)
Если вы заботитесь только о локальном компьютере, вы можете положиться на пакет psutil. Вы можете либо:
Проверьте все порты, используемые конкретным pid:
proc = psutil.Process(pid)
print proc.connections()
Проверьте все порты, используемые на локальной машине:
print psutil.net_connections()
Работает и на Windows тоже.
Средство Netstat просто анализирует некоторые файлы /proc, такие как /proc/net/tcp, и объединяет их с другими файлами. Да, это очень специфично для платформы, но для Linux-единственного решения вы можете придерживаться этого. Документация ядра Linux подробно описывает эти файлы, чтобы вы могли найти их, как их читать.
Также обратите внимание, что ваш вопрос слишком неоднозначен, потому что "порт" также может означать последовательный порт (/dev/ttyS * и аналоги), параллельный порт и т.д.; Я снова использовал понимание из другого ответа, это сетевой порт, но я бы попросил вас более точно сформулировать ваши вопросы.
В случае, если вы исследуете 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
Просто добавлен к решению 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()
Пожалуйста, проверьте ответ Михаэля и проголосуйте за него. Это правильный способ проверить открытые порты. 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
Вот быстрый многопоточный сканер портов:
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)