forループを使って、対象のIPアドレスの到達性とTCPポートの状態を確認する
この記事は、Test-Connectionを使ってTCPポートをスキャンするをPythonで実施したものです。
ユースケース
- with open() でテキストファイルを開く
- forでテキストファイルと変数のリストから対象を取り出す
- forの中でforを回すネスト構造
- subprocessモジュールから、pingとncを呼び出して実行
- ncコマンド (macOSの場合)でポートの状態を確認
- f文字列で出力フォーマットの体裁を整える
以下、環境です。
macOS Montrey(12.4)
Python 3.10.4
ipAddrList.txt
172.22.1.201
172.22.1.170
172.22.1.179
172.22.1.81
172.22.1.26
172.22.1.25
172.22.0.1
172.22.0.2
- IP到達性を確認したいIPアドレスリスト
portCheck.py
import subprocess
file_path = '/Python/ipAddrList.txt'
with open(file_path) as f:
ip_addr_list = f.readlines()
port_list = ['22', '80', '443']
for ip_addr in ip_addr_list:
target_ip = ip_addr.rstrip('\n')
result_ip = subprocess.call(['ping', target_ip, '-c 1', '-t 1'],
stdout = subprocess.DEVNULL,
stderr = subprocess.DEVNULL)
if result_ip == 0:
for target_port in port_list:
result_port = subprocess.call(['nc', target_ip, target_port, '-vzw 1'],
stdout = subprocess.DEVNULL,
stderr = subprocess.DEVNULL)
if result_port == 0:
print(f'Host: {target_ip:15} Port: {target_port:3} is opened')
else:
print(f'Host: {target_ip:15} Port: {target_port:3} is NOT opend')
else:
print(f'Host: {target_ip:15} is NOT reachable')
- 実行結果
$ python ./portCheck.py
Host: 172.22.1.201 is NOT reachable
Host: 172.22.1.179 is NOT reachable
Host: 172.22.1.170 Port: 22 is NOT opend
Host: 172.22.1.170 Port: 80 is NOT opend
Host: 172.22.1.170 Port: 443 is NOT opend
Host: 172.22.1.81 Port: 22 is NOT opend
Host: 172.22.1.81 Port: 80 is NOT opend
Host: 172.22.1.81 Port: 443 is NOT opend
Host: 172.22.1.26 is NOT reachable
Host: 172.22.1.25 Port: 22 is NOT opend
Host: 172.22.1.25 Port: 80 is opened
Host: 172.22.1.25 Port: 443 is NOT opend
Host: 172.22.0.1 Port: 22 is NOT opend
Host: 172.22.0.1 Port: 80 is NOT opend
Host: 172.22.0.1 Port: 443 is NOT opend
Host: 172.22.0.2 is NOT reachable
コード解説
line.py
with open(file_path) as f:
ip_addr_list = f.readlines()
- with open( ) で開いて、勝手にファイルクローズできるようにする
- readlines( ) で1行ずつ読み込んでリスト化する
line.py
for ip_addr in ip_addr_list:
target_ip = ip_addr.rstrip('\n')
- for文でリストからアドレスを取り出す
- 末尾に改行(\n)がついているので、.strip( )メソッドで削除
line.py
result_port = subprocess.call(['nc', target_ip, target_port, '-vzw 1'],
stdout = subprocess.DEVNULL,
stderr = subprocess.DEVNULL)
- subprocess で 別のアプリケーションを起動する
- call( )メソッドで実行すると、戻り値を判断できる。成功は0、その他は1とか2になる。
line.py
if result_port == 0:
print(f'Host: {target_ip:15} Port: {target_port:3} is opened')
else:
print(f'Host: {target_ip:15} Port: {target_port:3} is NOT opend')
- if文で戻り値を確認
- f文字列でフォーマットを整えて出力