某オンライン証券でアクセス権奪取による被害が続いています。
何が原因であるかは現時点で定かではありませんが、不審な国・エリアからのアクセスを制御するのも1つの考え方です。
オンライン上には下記のような特定の国やエリアのIPアドレスを一覧にしているサイトがあります。
今回はそれを利用して、Cisco IOS-XE のACLの形式にダウンロードしつつ、netconfで書き換えるPython3 scriptをChatGPTの協力を得て作成しましたので、備忘録を兼ねて公開します。
今回はkrfilter v1を利用しましたが、これだけでACL行数は6000行近くになります。デバイス側のキャパシティの管理にはご注意ください。
ACL行数があるため、timeout時間を600秒としています。
皆さんの環境に合わせて、そのあたりは書き換えましょう。
from ncclient import manager
import ipaddress
import requests
# ---------- 接続設定 ----------
DEVICE = {
"host": "YOUR ROUTER IP ADDRESS", # ルータのIP
"port": 830,
"username": "YOUR USERNAME",
"password": "YOUR PASSWORD",
"hostkey_verify": False,
"allow_agent": False,
"look_for_keys": False
}
ACL_NAME = "BLOCK_KR"
ACL_URL = "https://ipv4.fetus.jp/krfilter.1.txt"
# ------------------------------
def download_ip_list(url):
response = requests.get(url)
response.raise_for_status()
return response.text.strip().splitlines()
def build_acl_config_xml(ip_list):
seq = 10
acl_entries = ""
for cidr in ip_list:
try:
net = ipaddress.IPv4Network(cidr)
acl_entries += f"""
<access-list-seq-rule>
<sequence>{seq}</sequence>
<deny>
<std-ace>
<ipv4-address-prefix>{net.network_address}</ipv4-address-prefix>
<ipv4-prefix>{net.network_address}</ipv4-prefix>
<mask>{net.hostmask}</mask>
</std-ace>
</deny>
</access-list-seq-rule>"""
seq += 10
except ValueError:
continue
# 最後に permit any を追加
acl_entries += f"""
<access-list-seq-rule>
<sequence>{seq}</sequence>
<permit>
<std-ace>
<any/>
</std-ace>
</permit>
</access-list-seq-rule>"""
# 完全なNetconf構成XMLを返す
return f"""<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<ip>
<access-list>
<standard xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-acl">
<name>{ACL_NAME}</name>
{acl_entries}
</standard>
</access-list>
</ip>
</native>
</config>"""
def push_acl_config():
ip_list = download_ip_list(ACL_URL)
config_xml = build_acl_config_xml(ip_list)
print("🔄 Connecting to device...")
with manager.connect(timeout=600, **DEVICE) as m:
print("🚀 Sending ACL config via Netconf...")
response = m.edit_config(target="running", config=config_xml)
print("✅ ACL successfully updated.")
print("📄 Netconf reply:")
print(response.xml)
if __name__ == "__main__":
push_acl_config()
このACLをWAN interface に適用いただければアクセス制御はできるかと思いますし、cronなどで定期的に適用いただければ、データソースの更新を追いかけることがかのう
よいネットワークライフを!