web-dev-qa-db-ja.com

Linuxでネットワークポートが開いているかどうかを確認する方法

Pythonを使用して、リモートシステムではなくlinux ubuntuで特定のポートが開いている/閉じているかどうかを知るにはどうすればよいですか?これらの開いているポートをPythonでどのようにリストできますか?

  • Netstat:netstat出力をPythonに統合する方法はありますか?
59
Fatima

socket module を使用して、ポートが開いているかどうかを簡単に確認できます。

これは次のようになります。

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()
109
mrjandro

これをより一般的なコンテキストで使用する場合は、開いているソケットも閉じられることを確認する必要があります。そのため、チェックは次のようになります。

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"
68
Michael

私にとっては、ポートが開いていないと上記の例はハングします。行4は、ハングを防ぐためのsettimeoutの使用を示しています

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)
31
Brent Kinser

ローカルマシンのみを気にする場合は、psutilパッケージを使用できます。次のいずれかが可能です。

  1. 特定のpidで使用されるすべてのポートを確認します。

    proc = psutil.Process(pid)
    print proc.connections()
    
  2. ローカルマシンで使用されているすべてのポートを確認します。

    print psutil.net_connections()
    

Windowsでも動作します。

http://pythonhosted.org/psutil/

18
Joe

TCPポートをリッスンするつもりでプローブする場合は、実際にリッスンを呼び出した方が良いでしょう。接続するためのtringを使用したアプローチでは、確立された接続のクライアントポートを「見る」ことはできません。ただし、これらのポートを使用してリッスンすることはできません。

import socket


def check_port(port, rais=True):
    """ True -- it's 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
2

Netstatツールは、/ proc/net/tcpなどのいくつかの/ procファイルを単純に解析し、他のファイルの内容と結合します。はい、それは非常にプラットフォーム固有ですが、Linuxのみのソリューションの場合は、それに固執することができます。これらのファイルについては、Linuxカーネルのドキュメントで詳細に説明されているため、読み方がわかります。

また、「ポート」はシリアルポート(/ dev/ttyS *およびアナログ)、パラレルポートなども意味するため、質問が曖昧すぎることに注意してください。これはネットワークポートであるという別の回答からの理解を再利用しましたが、質問をより正確に定式化するようお願いします。

2
Netch

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()
1
Pitto

マイケルの回答を確認して投票してください。開いているポートを確認する正しい方法です。サービスまたはデーモンを開発している場合、Netstatおよびその他のツールは使用できません。たとえば、産業用ネットワークのmodbus TCPサーバーおよびクライアントサービスを作成しています。サービスは任意のポートをリッスンできますが、問題はそのポートが開いているかどうかです。プログラムはさまざまな場所で使用される予定であり、それらをすべて手動で確認することはできないため、これは私がやったことです:

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
1
Hadi

これが高速マルチスレッドポートスキャナーです。

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)

ライブデモ

0
Pedro Lobito