はじめに
ルータやファイアウォールの設定の際に複数のサブネットを集約して、最小限のネットワークアドレスで表現したいことがあります。そんな時に必要となるスーパーネット化とかCIDR結合などと呼ばれる操作をPythonで簡単に行う方法があるので紹介します。
手っ取り早くサブネットを集約したい方はこちらをご利用ください。
スーパーネット化
ネットワークスペシャリスト試験に出題された以下の問を題材にPythonを使ってスーパーネット化してみる。
問14 サブネットマスクが 255.255.255.0 である四つのネットワーク 192.168.32.0,192.168.33.0,192.168.34.0,192.168.35.0を,CIDRを使ってスーパーネット化したとき,ネットワーク番号とサブネットマスクの適切な組合せはどれか。
ネットワーク番号 サブネットマスク ア 192.168.32.0 255.255.248.0 イ 192.168.32.0 255.255.252.0 ウ 192.168.35.0 255.255.248.0 エ 192.168.35.0 255.255.252.0
出典:平成27年度 ネットワークスペシャリスト試験 午前Ⅱ 問14
・準備
必要なライブラリのインストール。
pip install netaddr
・スーパネット化
#便利なライブラリのnetaddrを読み込む
from netaddr import IPNetwork, cidr_merge
'''
問に記載されているネットワークアドレスをIPnetworkクラスに渡してsubnetsリストに格納。
(サブネット255.255.255.0はCIDR表記では/24。オクテット形式でも渡せる)
'''
subnets = [IPNetwork('192.168.32.0/24'),
IPNetwork('192.168.33.0/24'),
IPNetwork('192.168.34.0/24'),
IPNetwork('192.168.35.0/24')]
#たったこの1行だけでスーパーネット化できる!
merged_subnets = netaddr.cidr_merge(subnets)
print(merged_subnets)
・結果
この様にサブネットが192.168.32.0/22
に集約されてうまくスーパーネット化ができたことがわかる。
[IPNetwork('192.168.32.0/22')]
なお問14の解答群のサブネットマスクはオクテット表記となっているので、以下の様にCIDR表記のサブネットを求めると、
print(merged_subnets[0].netmask)
255.255.252.0
となるため、答えはイ(192.168.32.0/255.255.252.0
)であることがわかる。
2022/10/21追記:
@shiracamusさんのコメントにある通り、ipaddressライブラリでも同じことが出来ました。このライブラリは標準ライブラリに含まれていて、インストール不要なのでこちら方が使いやすいですね。
#@shiracamusさんのコメントから引用
from ipaddress import IPv4Network, collapse_addresses
subnets = [IPv4Network('192.168.32.0/24'),
IPv4Network('192.168.33.0/24'),
IPv4Network('192.168.34.0/24'),
IPv4Network('192.168.35.0/24')]
merged_subnets = [*collapse_addresses(subnets)]
print(merged_subnets)
[IPv4Network('192.168.32.0/22')]
さいごに
このnetaddrというライブラリはIPアドレスやネットワークアドレスに対する操作をするのにすごく便利なライブラリで、スーパーネット化だけでなく、さまざまな操作ができます。これまでにいくつか記事を書きましたので、そちらもご参照ください。
また、そのような操作をWeb上でできるサイトを提供しているので是非ご利用ください。
IP Addr Tools: IPアドレスやサブネットを操作するいくつかのツールを提供しています。
以上
参考サイト: