ipsetを使ってスマートにiptablesを設定する
ギークな知人から「vpsでiptables設定していたらルール設定数の上限に引っかかって思い通りの設定ができない!」との話を聞き、それは一体どんな大きさのiptablesなんだと内心ツッコミを入れつつ、対応方法を調べることにした。知人曰くipsetが使えそうとの事なので、調査した結果をブログにまとめておく。
ipsetとは?
ipsetとはLinuxカーネルバージョン2.4以降で利用できるIP管理用のユーティリティのことだ。 ipsetを利用することで、IPアドレスの集合を簡単に管理することができる。
ipset自体はネットワーク管理機能を持たないが、iptablesと組み合わせることで、
- iptablesのフィルタリングルールを一括で更新できる
- IPを集合として扱う事で、煩雑なiptables管理を単純化できる
といったメリットがある。
ipsetを使ってみよう
それでは、実際にipsetを使ってiptablesを設定してみよう。今回は接続を拒否したいネットワークアドレスの集合をipsetを利用して”BLACKLIST”という名称で管理し、iptablesに追加してみる。ipsetは私の環境(CentOS6.5)では標準で入っていないため、インストールから始める。
1.iptablesのインストール
$ sudo yum install ipset # 一部省略 Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package ipset.x86_64 0:6.11-1.el6 will be installed --> Processing Dependency: libmnl.so.0(LIBMNL_1.0)(64bit) for package: ipset-6.11-1.el6.x86_64 --> Processing Dependency: libmnl.so.0()(64bit) for package: ipset-6.11-1.el6.x86_64 --> Running transaction check ---> Package libmnl.x86_64 0:1.0.2-3.el6 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================== Package Arch Version Repository Size ============================================================================================================================================== Installing: ipset x86_64 6.11-1.el6 base 61 k Installing for dependencies: libmnl x86_64 1.0.2-3.el6 base 21 k Transaction Summary ============================================================================================================================================== Install 2 Package(s) Total download size: 82 k Installed size: 205 k Is this ok [y/N]: y Downloading Packages: (1/2): ipset-6.11-1.el6.x86_64.rpm | 61 kB 00:00 (2/2): libmnl-1.0.2-3.el6.x86_64.rpm | 21 kB 00:00 ---------------------------------------------------------------------------------------------------------------------------------------------- Total 115 kB/s | 82 kB 00:00 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Warning: RPMDB altered outside of yum. Installing : libmnl-1.0.2-3.el6.x86_64 1/2 Installing : ipset-6.11-1.el6.x86_64 2/2 Verifying : libmnl-1.0.2-3.el6.x86_64 1/2 Verifying : ipset-6.11-1.el6.x86_64 2/2 Installed: ipset.x86_64 0:6.11-1.el6 Dependency Installed: libmnl.x86_64 0:1.0.2-3.el6 Complete!
2.セットの作成
ipsetでは、IPアドレスの集合をセットという単位で管理する。先ず、セットを作成し、セットに対してIPアドレス(エントリ)を追加していくイメージだ。
先ずは接続を拒否したいネットワークのアドレスを保持するセット”BLACKLIST”を作成する。
$ #接続拒否IPの集合"BLACKLIST"を作成 $ sudo ipset create BLACKLIST hash:net
コマンドはipset create SET名 TYPENAME [CREATE-OPTIONS]
という書式を持つ。TYPENAMEとCREATE-OPTIONについて解説しておこう。
TYPENAME
作成するセットの種類を指定する。指定可能なTYPENAMEはいくつかパターンがあり、このページに詳しく記載されている。簡単に言えば「アドレスの格納方法:格納できる情報(カンマ区切り)」という形式だ。TYPENAMEの一覧と簡単な説明は以下の通りだ。
TYPE | 格納情報 | 詳細 |
---|---|---|
bitmap:ip | IP | IPアドレスを保持。 CIDR形式でエントリを追加した場合、指定したネットワークに属する全てのIP(NW、ブロードキャストアドレス含)が個々に展開されて格納される。ただし、展開されるだけで、展開後IPはネットマスクを保持していない。 また、後述する「netmask」CREATE-OPTIONを指定するとネットワークアドレスのみ保持するセットとして定義できる。 |
bitmap:ip,mac | IPとMACのペア | IPとMACの組合せを保持。IPはネットマスクを保持できない。 |
bitmap:port | PORT | PORT番号を保持。 1-1023のようにPORTを範囲指定してエントリ追加できるものの、個々のPORT番号に展開されて格納される。 |
hash:ip | IP | hashを利用してIPアドレスを保持。 セットに格納できるIPの範囲を制限(「range」CREATEオプション。詳細は後述)できない点を除きbitmap:ipと同じ。 |
hash:net | IP (NWアドレス) | ネットワークアドレスを保持。 CIDR表記でエントリ追加した場合、指定されたIPのネットワークアドレスがエントリとして登録される。(ホストアドレス部分は無視される。) ⇒ 192.0.2.1/24を追加しても、エントリ追加されるのは192.0.2.0/24(ホストアドレス無視) ※ CIDR形式を利用しなければ、単一IPをエントリ追加可能だが、ネットマスクを持てない |
hash:ip,port | IP、PORT、L4 Protocolの組合せ | IP(ネットマスク保持不可)、PORT、L4プロトコルの組み合わせをハッシュで保持。 エントリ追加時にL4プロトコルは省略可能で、デフォルトはTCP。 また、CIDR表記によるエントリ追加は可能だが、該当ネットワークに属する個々のIPに展開されてエントリ追加される。(展開されるだけでネットマスクの情報はセットに保持されない) |
hash:net,port | IP(NWアドレス)、PORT、L4 Protocolの組合せ | NWアドレスを含むIP、PORT、L4プロトコルの組合せで保持。 IPのエントリ追加に関する挙動は「hash:net」と同じ。 L4プロトコルの考え方は「hash:ip,port」と同じ。 |
hash:ip,port,ip | IP×2、PORT | 1エントリで2つのIPアドレスとPORT番号の組合せを保持。 1対1のIPの紐付け管理ができるからNAT設定向きか? |
hash:ip,port,net | IP、PORT、L4 Protocolの組合せ | IPアドレスとPORTとネットワークアドレスを保持。 L4プロトコルの考え方は「hash:ip,port」と同じ。 エントリの追加は紛らわしい。CIDR表記によってIPを指定できるが、ネットワークアドレスは別途指定する。 CIDR表記が表すNWの全てのIPが展開されてエントリに追加され、その後、個々のIPに対して指定したネットワークアドレスが割り当てられる。(ネットマスクではなく、ネットワークアドレスで管理される) |
hash:net,iface | IP、NWインタフェースのペア | ネットワークアドレスを含むIPとネットワークインタフェースをペアで保持できる。NWインタフェースの指定はインタフェース名(eth1など)を使う。 |
list:set | セット | 上記のセットを複数まとめて保持。 複数のセットをまとめて管理することができる。 |
今回作成する”BLACK LIST”は接続を拒否したいネットワークのアドレスを保持するので、hash:net
を選択する。
CREATE-OPTIONS
セットに対して様々な設定を行う事ができる。セットのTYPENAMEによって利用できるオプションは異なる。主なオプションは以下の通り。
OPTION | 使途 | 対応TYPE |
---|---|---|
range | セットに保持するIPやPORTの範囲指定が可能。 指定した範囲から外れたエントリを追加しようとするとエラー。 bitmap系のTYPEでのみ指定可能であり、かつ指定必須。 | bitmap:ip bitmap:ip,mac bitmap:port |
timeout | セット内のエントリの有効期間を秒指定。 指定した秒数の経過後、エントリはセット内から削除される。 デフォルトは"0"(無期限)。 | 全てのTYPE |
family | セット内で利用するIPのアドレスファミリ。 デフォルトは"inet"(IPv4)。IPv6を扱う場合は"inet6"を指定。 | IPを取り扱える全TYPE |
hashsize | ハッシュのサイズ。 デフォルトは"1024"。 | hash系の全TYPE |
maxelem | ハッシュに登録できるエントリの最大数。 デフォルトは"65536" | hash系の全TYPE |
netmask | エントリに適用するネットマスク。 当オプションを指定したセットはネットワークアドレスしか保持できない。(ホストアドレス部分は常に無視される) 1 - 31で指定する。 | bitmap:ip hash:ip |
3.エントリの追加
作成したセット「BLACKLIST」に対してエントリを追加する。
今回は「192.0.2.128/26」と「192.0.2.192/26」の2つのネットワークを追加してみよう。
$ sudo ipset add BLACKLIST 192.0.2.128/26 $ sudo ipset add BLACKLIST 192.0.2.192/26 $ sudo ipset list BLACKLIST Name: BLACKLIST Type: hash:net Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16816 References: 0 Members: 192.0.2.128/26 192.0.2.192/26
セットに対するエントリの追加はipset add セット名 追加エントリ
コマンドで実行可能だ。また、セットが保持するエントリのリストはipset list セット名
で表示できる。
なお、エントリの削除はipset del セット名 削除エントリ
コマンドで実行できる。
4.作成したセットをiptablesに追加
では、作成したセット”BLACKLIST”をiptablesに混ぜ込んでみる。
$ #BLACKLIST内に保持するNWアドレスを持つパケットは全てアクセスさせない $ sudo iptables -I INPUT -m set --match-set BLACKLIST src -j DROP $ sudo iptables -L # 一部省略 Chain INPUT (policy ACCEPT) target prot opt source destination DROP all -- anywhere anywhere match-set BLACKLIST src
iptablesは-m(または-match)オプションを利用することで拡張モジュールを使うことができる。今回、iptablesコマンドでipsetを使っているのは-mオプションに続く-m set --match-set BLACKLIST src
の部分だ。
ipsetを利用する場合の拡張モジュール名は「set」であるため、今回の-mオプションは-m set
となる。また、拡張モジュール側のコマンドとして--match-set BLACKLIST src
を利用しているが、これは、”BLACKLIST”にマッチするIPアドレスsourceアドレスとして利用するというコマンドだ。 なお、拡張モジュール側で利用できるコマンドと書式はiptables -m set -h
コマンドから確認できる。
$ sudo iptables -m set -h # --match-setと関係する部分のみ抜粋 iptables v1.4.7 set match options: [!] --match-set name flags 'name' is the set name from to match, 'flags' are the comma separated list of 'src' and 'dst' specifications.
今回、iptables -L
コマンドで出力されたルールのsourceはanywareとなっているが、実際はBLACKLISTに指定されたネットーワークからのパケットをDROPすることができる。
これで、iptables上に設定しているルールは1つだが、実際は複数のNWに対してルールを設定することができた。(ルール数を削減できた)
注意点.セットはサーバ再起動時に削除される
ipsetのセットはiptablesのルールと同じでサーバ再起動時に削除される(iptablesの場合はサービス再起動でも削除される)。
再起動後にセットを引き継ぐためにはipset save
コマンドとipset restore
コマンドを利用する。
$ sudo ipset list Name: BLACKLIST Type: hash:net Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16816 References: 0 Members: 192.0.2.192/26 192.0.2.128/26 $ #restore用のコマンドを保存しておく $ sudo ipset save | tee restorecommand create BLACKLIST hash:net family inet hashsize 1024 maxelem 65536 add BLACKLIST 192.0.2.192/26 add BLACKLIST 192.0.2.128/26 $ #ここでサーバが再起動されたと仮定。今回の例ではセットを削除 $ sudo ipset destroy $ #destroyした後だから全てのセットが存在しない $ sudo ipset list $ #リストアする $ sudo ipset restore < restorecommand $ #リストアによってBLACKLISTが復活 $ sudo ipset list Name: BLACKLIST Type: hash:net Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16816 References: 0 Members: 192.0.2.192/26 192.0.2.128/26
基本的な考え方はiptables-save
とiptables-restore
と同じだ。ipset save
コマンドでリストア用のコマンドを出力し、ipset restore
コマンドで取り込めば良い。
後日談
この手順を知人が試した結果、知人のvps環境ではipsetが使えないことが分かった。
どうやら必要なカーネルモジュールが足りていないらしい。vpsがOSレベル仮想化を利用しているため、ホスト側にモジュールが無い⇒どうしようもないという展開に。うーん、なんとかならないものか・・。
関連記事
-
-
sshd再起動時にssh接続が継続する動作について
Linux/Unixサーバにsshしている際、sshdを再起動したとする。 sshdは一度終了する
-
-
Java8のインタフェース実装から多重継承とMixinを考える
2014年3月18日、ついにJava8が正式にリリースを迎えた。 折角なので、今後、Java8の新
-
-
Ctrl+Cとkill -SIGINTの違いからLinuxプロセスグループを理解する
しばらくLinuxネタが続く・・。 近いうちに最近出たJava8ネタを書いてみようと思います。が、
-
-
「Systemd」を理解する ーシステム起動編ー
2014年6月10日、とうとうRHEL7が正式リリースを迎えた。RHEL7での変更点については、この
-
-
Linuxプロセス起動時の環境変数ダンプの取得
UnixやLinux上で不具合の調査等々を行う際、特定のプロセス起動時の環境変数を知りたい場合がある
-
-
Java8のHotSpotVMからPermanent領域が消えた理由とその影響
今回も前回の記事につづき、Java8による変更点で未だあまり紹介されていないポイントを記事にしようと
-
-
例示専用のIPアドレスとドメインを使いこなす
前回の記事ではネットワークに関する記事を投稿させていただいたが、今回も引き続きネットワーク関連のネタ
-
-
文字コードの考え方から理解するUnicodeとUTF-8の違い
UnicodeとUTF-8の違いを理解していない方が結構居るようなので、文字コードの考え方を元に解説
-
-
「Systemd」を理解する ーシステム管理編ー
前回の記事「Systemd」を理解するーシステム起動編ーでは、Systemdの概念とSystemdに
Comment
Really enjoyed reading ur blog. aagfebceddcf
Sexy photo galleries, daily updated collections
http://lesbiantubes.relayblog.com/?kate
cowlist porn powered by phpbb gay porn jesus crucifixion xxx porn action toon porn harry potter porn videos quik time