LoginSignup
1
0

More than 5 years have passed since last update.

[Python] python-iptablesに入門してみた

Last updated at Posted at 2019-01-06

python-iptablesとはiptablesをPythonで操作するためのモジュールです。

環境

  • Ubuntu 18.04
  • Python 3.6
  • python-iptables 0.13.0

ソースコード

ソースコードはManipulate iptables using python-iptablesにあります。

demo.py
     1  import iptc
     2  import ipaddress
     3  
     4  
     5  def format_address(address):
     6      """
     7      Support IPv4 only yet.
     8      Return IPv4 with prefix length (e.g. 192.168.0.1/32)
     9      """
    10  
    11      if isinstance(address, (str, ipaddress.IPv4Address)):
    12          try:
    13              address = ipaddress.ip_network(address)
    14          except ValueError:
    15              raise
    16      elif isinstance(address, ipaddress.IPv4Network):
    17          pass
    18      else:
    19          raise TypeError
    20  
    21      return address.with_prefixlen
    22  
    23  
    24  def display_matches(matches=[]):
    25      print("Match:", end=' ')
    26      for match in matches:
    27          for key, value in match.get_all_parameters().items():
    28              if isinstance(value, list):
    29                  value = ', '.join(value)
    30  
    31              print("[{}] {}".format(key, value))
    32  
    33  
    34  def display_rule(rule):
    35      print('+'*40)
    36      print("Target:", rule.target.name)
    37      print("Protocol:", rule.protocol)
    38      print("Source address:", format_address(rule.src))
    39      print("Destination address:", format_address(rule.dst))
    40      display_matches(rule.matches)
    41      print('+'*40)
    42  
    43  
    44  def delete_rule(chain, rule):
    45      chain.delete_rule(rule)
    46  
    47  if __name__ == '__main__':
    48      # Create rule
    49      rule1 = iptc.Rule()
    50      rule1.out_interface = 'eth0'
    51      rule1.dst = "192.168.0.1"
    52      rule1.protocol = 'icmp'
    53      match_for_rule1 = rule1.create_match('icmp')
    54      match_for_rule1.icmp_type = 'echo-request'
    55      rule1.create_target('DROP')
    56  
    57      rule2 = iptc.Rule()
    58      rule2.out_interface = 'eth0'
    59      rule2.dst = "192.168.0.2"
    60      rule2.protocol = 'icmp'
    61      match_for_rule2 = rule2.create_match('icmp')
    62      match_for_rule2.icmp_type = 'echo-reply'
    63      rule2.create_target('DROP')
    64  
    65      # Create chain
    66      chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT')
    67      # Apply rule to chain
    68      chain.insert_rule(rule1)
    69      chain.insert_rule(rule2, position=1)
    70  
    71      for rule in chain.rules:
    72          try:
    73              display_rule(rule)
    74          except:
    75              from traceback import print_exc
    76              print_exc()

5~21行目

モジュールから返される送信元/宛先アドレスは192.168.0.0/255.255.255.0のようなフォーマットなので、これを192.168.0.0/24のようにネットマスクをプレフィックス長に変換するための関数

24~31行目

iptablesのmatch extensionsを表示するための関数
match.get_all_parameters()で設定されている全ての値を取得

34~41行目

設定したルールを表示するための関数

44~45行目

特定のchainに設定されているルールを削除するための関数

49~63行目

ルールの作成

66行目

FilterテーブルのOUTPUT Chainの作成

68~69行目

作成したルールをchainに適用
69行目の第2引数のpositionはchainの何番目にルールを挿入するか指定

71行目

chain.rulesによって、chainに設定されている全てのルールを取得
返り値はRuleオブジェクトであり、Ruleオブジェクトには__str____repr__が書かれていないので素のオブジェクト情報が返されます
つまり、詳細なルール情報を表示したい場合は34~41行目にあるように自作する必要があります

検証

$ python3 demo.py
++++++++++++++++++++++++++++++++++++++++
Target: DROP
Protocol: icmp
Source address: 0.0.0.0/0
Destination address: 192.168.0.1/32
Match: [icmp-type] 8
++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++
Target: DROP
Protocol: icmp
Source address: 0.0.0.0/0
Destination address: 192.168.0.2/32
Match: [icmp-type] 0
++++++++++++++++++++++++++++++++++++++++
$ iptables -L OUTPUT
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       icmp --  anywhere             192.168.0.1          icmp echo-request
DROP       icmp --  anywhere             192.168.0.2          icmp echo-reply

ちゃんとiptablesにルールがコミットされました。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0