2020年1月30日 星期四

產生台灣IP清單給iptables防火牆


這個Python程式可以線上將TWNIC的台灣IP清單,轉成iptables的指令,貼到/etc/iptables.rules上,就可以限制只能台灣的IP能存取。

限制port時,用如下寫法,port 80使用"TaiwanIP"規則(平常我們是寫ACCEPT):

-A INPUT -p tcp -m tcp --dport 80 -j TaiwanIP

所以你的iptables.rules裡會先有這些描述:

:INPUT DROP [27:1852]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [164:21816]
:TaiwanIP - [0:0]

如果是更改作用中的防火牆,用以下指令加入:

iptables -N TaiwanIP

設定好iptables.rules後,用如下指令讓新規則產生做用:

sudo iptables-restore < /etc/iptables.rules
P.S. 有些單位的IP範圍不在清單上,好像是比較敏感的單位。


程式碼

# -*- coding: utf-8 -*-
'''
產生台灣IP清單及iptables指令
'''
import urllib.request
import pandas as pd
import ipaddress
from bs4 import BeautifulSoup

response = urllib.request.urlopen('https://rms.twnic.net.tw/twnic/User/Member/Search/main7.jsp?Order=ORG.ID')
html = response.read().decode(response.headers.get_content_charset())
soup = BeautifulSoup(html, 'html.parser')
listTagTable = soup.find_all('table')
df = pd.read_html( str(listTagTable[5]),header=0 )[0]

def getIP(x):
ipStart, ipEnd = x.split(' - ')
ipStartInt = int(ipaddress.IPv4Address(ipStart))
ipEndInt = int(ipaddress.IPv4Address(ipEnd))
return pd.Series([ipStart, ipEnd, ipStartInt, ipEndInt], index=['ipStart', 'ipEnd', 'ipStartInt', 'ipEndInt'])
df2 = df.iloc[:,3].apply( getIP ) #只一行Series,可以不指定axis

df['ipStart'] = 0
df['ipEnd'] = 0
df['ipStartInt'] = 0
df['ipEndInt'] = 0
df[ ['ipStart', 'ipEnd', 'ipStartInt', 'ipEndInt'] ] = df2
df = df.sort_values(by=['ipStartInt'])
dicMerge = {'name':[df.iloc[0, 0]]
, 'ID':[df.iloc[0, 1]]
, 'ipStart':[df.iloc[0, 5]]
, 'ipEnd':[df.iloc[0, 6]]
, 'ipStartInt':[df.iloc[0, 7]]
, 'ipEndInt':[df.iloc[0, 8]] }
rowN, colN = df.shape
dicMergeIndex = 0
#下列For是將IP範圍相鄰的合併,如此只需一組
for i in range(1,rowN):
if (df.iloc[i, 7] - dicMerge['ipEndInt'][dicMergeIndex]) == 1:
dicMerge['ipEndInt'][dicMergeIndex] = df.iloc[i, :]['ipEndInt']
dicMerge['ipEnd'][dicMergeIndex] = df.iloc[i, :]['ipEnd']
else:
dicMerge['name'].append(df.iloc[i, 0])
dicMerge['ID'].append(df.iloc[i, 1])
dicMerge['ipStart'].append(df.iloc[i, 5])
dicMerge['ipEnd'].append(df.iloc[i, 6])
dicMerge['ipStartInt'].append(df.iloc[i, 7])
dicMerge['ipEndInt'].append(df.iloc[i, 8])
dicMergeIndex += 1
dfTaiwanIP = pd.DataFrame(dicMerge)

rowN2, colN2 = dfTaiwanIP.shape
with open('TaiwanIP.txt', 'w', encoding='utf8') as f:
for i in range(0, rowN2):
f.write("-A TaiwanIP -m iprange --src-range %s-%s -j ACCEPT\n" % (dfTaiwanIP.iloc[i]["ipStart"], dfTaiwanIP.iloc[i]["ipEnd"]) )
#上述會產生一連串的iptables指令到TaiwanIP.txt這個檔案,直接貼到/etc/iptables.rules。但我是寫給"TaiwanIP" chain,故前面要有":TaiwanIP - [0:0]"





沒有留言:

張貼留言

IKEA吊櫃廚櫃

 好不容易裝好IKEA買來的吊櫃,花了三天。 從組裝,鑽牆,上牆調水平,累死我了。