ポートの状態を確認する 【Python】

Python

Web サーバーなど、ネットワーク機器のポートの状態を確認する Python のスクリプトについてまとめておきます。
よく使われるポート番号についてもまとめておきます。

以下の環境で動作確認をしています。
環境
・ LAN ネットワーク
・ Windows パソコン(ネットワークに接続済み)
・ Raspberry Pi (Linux、ネットワークに接続済み、サーバーとして起動可能)
・ レンタルサーバー

背景 ~ ポートに関する不安を解消する!

個人でレンタルサーバーの申し込みをして Web サイトの設定を行う際、多くの場合、オープンソースのソフトウェアをインストールすると思います。
これらのプログラムの中には、ポートをオープンにして外部からのアクセスが可能になるものがあります。こうしたプログラムの設定ののち、しばらく経つと、どのような設定をしたのか忘れてしまうことがあります。
過去の設定で、閉じ忘れたポートがないか確認をしたくなることがあります。

また、スマートフォンや Raspberry Pi などを自宅の Wi-Fi などのネットワークに接続して使っている人も多いと思います。
こうした機器を使っていると、ルーターや各デバイスのポートの状態や動きはどうなっているのか、どのアプリがどのポートを使っているのかダウンロードしたアプリが勝手にポートをオープンにしていないかなどを確認したくなることがあります。
最近は、サーバーが攻撃されるなどのニュースも増えています。ニュースなどを見ていてセキュリティ上の不安が生じたとき、関連するポート番号を追加して、自分が管理している機器を確認できると、安心にもつながります。

また、情報関連の教科書を読んでいて IPアドレスやポートが出てきたとき、実際にプログラムを動かして、日頃使っているデバイスで確認してみるとよく理解できるといった側面もあります。Web アプリなどのプログラミングをする際も、ポートの状態が確認できると Webアプリの動きをよく把握・理解でき、デバッグにも役立ちます。

ということで、ネットワーク機器のポートの状態を調べる Python のスクリプトをまとめ、公開しておくことにします。ポートのチェックをしたことのない方は、動かしてみてください。

なお、このスクリプトは実質的にポートスキャンを行うことになります。他人のサーバー等に対してポートスキャンを行うと不正なアクセスなどとして問題となることがありますので、ローカルネットワーク内のご自分の機器やご自分で契約しているサーバーに対して本スクリプトを使用するなど、配慮をいただきますようお願いいたします。

設定方法

① 以下を参考にポートをチェックをするためのフォルダを作成します。
例: c:\user\port_checker1
② ①のフォルダ内に port_checker1.py という名前でテキストファイルを作り、下記のサンプルスクリプトを貼りつけて保存してください。
例: c:\user\port_checker1\port_checker1.py

使用方法

③ Windows パソコンなどでコマンドプロンプトを起動して、”arp -a” + [enter] と入力し、ローカルネットワーク内の各機器の IPアドレスを確認してください。
例:
192.168.1.1  (ルーター)
192.168.1.3   (Windows パソコン)
192.168.1.32 (Raspberry Pi)

④ ②のスクリプトで target1 = “…” としている部分が、確認対象となる機器の IPアドレスです。
最初は初期状態のまま実行してみてください。うまく動いたら、③の IPアドレスなどに変更します。

⑤ 以下を例に、コンソールでからスクリプトを実行してください。
例 python c:\user\port_checker1\port_checker1.py

→ 各ポートの状態(開閉)が表示されたら、設定から動作確認まで完了です。

うまく動いたら

・ うまく動いたら、IPアドレスの部分を変更して、日頃使っている機器のポートの状態を調べてみてください。
・ たとえば、③の各機器の IPアドレス(192.168.x.x となっているもの)を順次設定して、ルーターやパソコンなどのポートがどのように設定されているのか確認してみてください。
たとえば、ルーターなどで80番や443番のポートがオープンになっていれば、ブラウザからアクセスすることで設定画面などのウェブページが表示されるように作られていることがわかります。
・ また、スマートフォンや Raspberry Pi など、日頃使っている機器をネットワークに接続し、同様にポートの状態を表示させてみてください。
日頃使っている機器はどういったポートの設定になっているのか、インストールしたプログラムがどのポートをオープンにしているのか、などを調べることが可能です。
・ Raspberry Pi (Linux)で、IPアドレスを固定にしている場合は、設定したIPアドレスで調べることになります。リモートデスクトップの設定をしている場合は、対応するポートがオープンになっていることが確認できると思います。
・ Python の HTTPサーバーやFlask のサーバーを起動/停止すると、ポートが開閉する様子を確認できます。なお、自作したプログラムやアプリで、独自のポート番号を設定しているものがあれば、Python のスクリプトにポート番号を追加してください。
・ サーバーをレンタルして個人サイトを運用している方は、ご自分が管理しているサーバーのIPアドレスについても確認をしてみてください。
・ スクリプトには、一般によく使われるポート番号を記載してあります。初期設定時の抜けがないかチェックできると思います。閉じ忘れたポートがないことを確認できるだけでも安心できると思います。

よく使われるポート番号など

よく使われるポートについてまとめておきます。Python のスクリプト、外部リンクも参照してください。

ポート番号 TCP/UDP 説明
20 TCP FTP ファイル転送 データ
21 TCP FTP ファイル転送 制御
22 TCP SSH 接続 The Secure Shell Protocol
53 UDP DNS Domain Name Server
80 TCP HTTP World Wide Web
443 TCP HTTPS (HTTP protocol over TLS/SSL)
3306 TCP MySQL/MariaDB
3389 TCP RDP リモートデスクトップ
8000など TCP HTTPサーバー、Flask のサーバーなどをポート番号 8000 などとして起動したとき

※ TCP (Transmission Control Protocol) は、ハンドシェイクの通信であり、データが失われたときに再送信が行われるプロトコルです。ウェブサイトの表示などで使われます。
※ UDP (User Datagram Program) は、一方的にデータを送信するプロトコルです。ライブストリーミングやオンラインゲームなどで使われます。
※ ローカルネットワーク内で Raspberry Pi のリモートデスクトップの設定をすると、3389番のポートがオープンになると思います。SSH 接続の設定をすると 22番のポートがオープンになると思います。ローカルネットワーク内での使用であればデフォルトの設定でも問題は比較的少ないですが、一般に、外部のインターネットに公開する場合は、設定を変えるなどの対応が必要です。
※ ローカルネットワーク内で Python の HTTPサーバー、Flask のサーバーなどを起動すると、起動時に指定したポート番号(8000など)がオープンになります。
サーバー(常駐プログラム)やブラウザなどを起動するとき、ポート番号を省略すると、上記のポート番号がデフォルトで設定されるものも多いです。
※ レンタルサーバーで WordPress などのサイトを立ち上げると、デフォルトで HTTP の 80 番等がオープンになります。セキュリティの管理上、HTTPS 443 に変更するなど、初期設定から変更するよう推奨されていると思います。

スクリプトの説明

・ ネットワーク上のポートにのアクセスするため、冒頭で socket をインポートしています。
・ get_list1() は、アクセスするポート番号とその概要を定義しています。
ポート番号を追加する場合は、記載にならって list1 としているところで追加をしてください。
・ list2 = … としているところで、n1 = 1 から n2 = 8 までのすべてのポート番号を追加するようにしています。数値を増やす等により、チェックする範囲を増やすことができます。(他人のサーバーにはアクセスしないようにしてください。)
・ def port_scan1() は、ポートの開閉をチェックする関数です。ターゲットとなるホストと、ポート番号のリストを渡すと、ポートをスキャンします。オープンになっているものがあれば、ポート番号等を返します。
・ Python のスクリプトを実行すると、target1 = “192.168.x.x” 等とした行以降を実行します。
target1 は、IPアドレスですので、使用しているネットワーク内の機器のプライベートIPアドレス等を設定すると、ポートの開閉をチェックするようになっています。
以降、list1 = “…” としたところで、ポート番号のリストを取得し、open1 = “…” としたところで、ポートのチェックをします。
・ if 文の部分で、オープンになっているポートを表示します。

まとめ

ネットワーク上の各機器のポートの状態を調べる Python のスクリプトについてまとめました。

サーバーを運用している方は、意図せず開放したままのポートがないか確認することができ、安心できると思います。
また、Raspberry Pi を使ってローカルネットワーク内で HTTPサーバーや Flask を動かしている方は、サーバーがどのように動いているのか確認できると思います。
ポートのチェックをしたことのない方は、確認をしてみてください。

他にも、Web 関連の Python のツールやスクリプトのポイントなどをまとめています。
関心のある方は、関連リンクなども参照してみてください。

関連リンク
・ Raspberry Pi で Flask を動かしてみる 【Python】
・ Raspberry Pi でローカルWebサーバー 【Python 活用】
・ Raspberry Pi でファイルアップローダ 【Flask】
・ バーコード作成 Web アプリ 【Raspberry Pi & Flask】

外部リンク
・ IANA の公式サイト Service Name and Transport Protocol Port Number Registry

サンプルスクリプト port_checker1.py


import socket as so1 

def get_list1(): 
    list1 = [
    [20, "FTP - Data Transfer"],
    [21, "FTP - Control"],
    [22, "SSH - Secure Shell"],
    [23, "Telnet - Non-secure Login"],
    [25, "SMTP - Simple Mail Transfer Protocol"],
    [53, "DNS - Domain Name System"],
    [67, "DHCP server"], 
    [68, "DHCP client"], 
    [80, "HTTP - Hyper Text Transfer Protocol"], 
    [88, "Kerberos"], 
    [110, "POP3 - Post Office Protocol version3, Email Receiving"],
    [123, "NTP - Network Time Protocol" ], 
    [135, "RPC - Remote Procedure Call, Windows" ], 
    [137, "NetBIOS Name Service, Windows" ], 
    [138, "NetBIOS Datagram Service, Windows" ], 
    [139, "NetBIOS Session Service, Windows" ], 
    [143, "IMAP - Internet Message Access Protocol, Email Receiving"],
    [161, "SNMP"], 
    [389, "LDAP"], 
    [443, "HTTPS - HTTP over SSD/TLS, Secure Web Communication"],
    [445, "SMB - Microsoft-DS, Windows" ], 
    [1433, "MSSQL1"], 
    [1434, "MSSQL2"], 
    [1521, "Oracle Database"],
    [2049, "NFS"], 
    [3306, "MySQL/MariaDB - Database Access"],
    [3389, "RDP - Remote Desktop Protocol"],
    [5000, "UPnP - Universal Plug and Play"], 
    [5060, "SIP"], 
    [5432, "PostgreSQL - Database Access"],
    [5900, "VNC - Virtual Network Computing"],
    [6379, "Redis - In-memory Database"],
    [8000, "HTTP test1 "],
    [8080, "HTTP - Alternative to port 80 for proxy servers"],
    [9042, "Cassandra"], 
    [9200, "Elasticsearch1"], 
    [9300, "Elasticsearch2"], 
    [25565, "Minecraft Server"], 
    [27017, "MongoDB"] 
    ] 
    n1 = 1                                         # start 
    n2 = 8                                         # end 
    list2 = [ [i1, ""] for i1 in range(n1, n2 + 1 )] 
    list3 = list1 + list2 
    return list3 

def port_scan1(host1, list1):
    open_ports1 = []
    for port0 in list1:
        port1 = port0[0]                           # port number 
        str1  = port0[1]                           # description 
        with so1.socket(so1.AF_INET, so1.SOCK_STREAM) as s1:
            s1.settimeout(1)
            if s1.connect_ex((host1, port1)) == 0:
                print( str(port1) + ": open : " + str1  ) 
                open_ports1.append( port0 )
            else: 
                print( port1 ) 
    return open_ports1


target1 = "192.168.1.1"                          # ip address or host name 
# target1 = "192.168.1.2"
# target1 = "192.168.1.3"
# target1 = "192.168.1.32" 


print(f"Scanning {target1} for open ports ")

list1 = get_list1()
open1 = port_scan1(target1, list1)    

if open1:
    print("Open ports:")
    for port1 in open1: 
        str1 = " ".join(map(str, port1))
        print(str1)
else:
    print("No open ports found.")


タイトルとURLをコピーしました