「CentOS 7」環境の「firewalld」で特定の国からのアクセスを拒否する設定を行ったところ、ルールが4000~5000とかなり多くなってしまいました。
その結果「firewalld」の動作がかなり重くなってしまい、良い方法を色々と調べてみたところ「ipset」と組み合わせて使用することで幸せになれるという情報が見つかりましたので、導入した際の手順についてまとめました。
ipsetとは
IPアドレスやネットワークアドレス、ポート番号、インターフェイス名などを組み合わせて管理することができるユーティリティになります。
「firewalld」で一つ一つルールを追加するよりも、格段にパフォーマンスも向上します。
ipsetインストール
まずは「yum」で「ipset」をインストールします。
# yum install ipset
セットの作成
「ipset」を使用するには、まずセット(ポリシー名みたいなもの)作成してから、そこにネットワークアドレスやIPアドレス等を追加していく必要があります。
セットを作成するためコマンドは下記の通りとなります。
ipseet create セット名 タイプ名 オプション
セット名
セット名はどのようなルールを管理しているのかが分かりやすい名前を設定します。
今回はアクセスを禁止するネットワークアドレスをまとめて管理するため「BLACKLIST」と付けることにします。
タイプ名
作成するセットの種類を指定します。
指定できるタイプは色々とあるのですが、今回使用するタイプはネットワークアドレスを管理するための「hash:net」を指定します。
タイプ一覧
指定できるタイプについて簡単にまとめて見ました。
タイプ | 管理する情報 |
---|---|
hash:ip | hashを使用してIPアドレスを管理 |
hash:net | hashを使用してネットワークアドレスを管理 |
hash:ip,port | hashを使用してIPとポート番号を管理 |
hash:net,port | hashを使用してネットワークアドレスとポート番号を管理 |
hash:ip,port,ip | hashを使用してIPとポート番号の2つを管理 |
hash:ip,port,net | hashを使用してIPとポート番号とネットワークアドレスの3つを管理 |
hash:net,iface | hashを使用して、ネットワークアドレスとNICの2つを管理 |
bitmap:ip | IPアドレスを管理 オプションでrange指定が必要 |
bitmap:ip,mac | IPアドレスとMACアドレスの管理 オプションでrange指定が必要 |
bitmap:port | ポート番号を管理 オプションでrange指定が必要 |
list:set | 複数のセットを管理することができる |
オプション
今回はすべてデフォルト設定でいきますので、特にオプションの指定は行いません。
オプション一覧
「ipset create」でセット作成する際に使用できるオプションの一覧です。
オプション | 説明 | 使用可能タイプ |
---|---|---|
family | inet(IPv4)かinet6(IPv6)を設定 デフォルトはinet |
IPを使用するタイプ全般 |
hashsize | ハッシュのサイズ デフォルトは1024 |
hashを使用するタイプ全般 |
maxelem | 登録できるルールの数 デフォルトは65536 |
hashを使用するタイプ全般 |
netmask | ネットマスクを指定(1-31) | bitmap:ip hash:ip |
range | IPやポート番号の範囲を指定 | bitmap系のタイプで使用(必須) |
timeout | セットの有効期限を設定 デフォルトは無制限(0) |
全てのタイプで使用可能 |
セット作成例
今回作成する「BLACKLIST」という名前のセットには、ネットワークアドレス登録するのでタイプは「hash:net」を指定して作成します。
# ipset create BLACKLIST hash:net
ネットワークアドレス追加
セットの作成が完了しましたら、「ipset add」コマンドでネットワークアドレスを追加していきます。
ipset add セット名 ネットワークアドレス/ネットマスク
追加例
先ほど作成したセットである「BLACKLIST」にネットワークアドレスを追加していきます。
# ipset add BLACKLIST 192.168.0.0/24 # ipset add BLACKLIST 192.168.2.0/24
追加確認
セットに登録された情報は下記のコマンドで確認することが出来ます。
ipset list セット名
先ほど実際に登録した内容を確認してみます。
# ipset list BLACKLIST Name: BLACKLIST Type: hash:net Revision: 3 Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16848 References: 0 Members: 192.168.0.0/24 192.168.2.0/24
登録したネットワークアドレスが確認できました。
firewalldと連携
「ipset」の準備が出来たので、次に「firewalld」との連携設定を行っていきます。
連携には「firewall-cmd」の「--direct」オプションを使用して設定を行っていきます。
書式
firewall-cmd [--permanent] --direct --add-rule [ipv4|ipv6] テーブル名 チェイン 優先順位 -m set --match-set ipsetセット名 src -j DROP
作業時の注意点
「firewalld」の設定を行う場合は十分に注意して行ってください。
設定を失敗すると、対象サーバに接続することが出来なくなってしまう場合もあります。
設定例
今回は外部からの接続対してのルールを設定するので、テーブルは「filter」を、チェインは「INPUT」を指定しています。
# firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -m set --match-set BLACKLIST src -j DROP # firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -m set --match-set BLACKLIST src -j DROP
ここで設定した内容は「INPUT_direct」チェインに登録されます。
設定ファイル
「--direct」オプションで設定した内容は「/etc/firewalld/direct.xml」に保存されます。
direct.xml内容
<?xml version="1.0" encoding="utf-8"?> <direct> <rule priority="0" table="filter" ipv="ipv4" chain="INPUT">-m set --match-set BLACKLIST src -j DROP</rule> </direct>
設定確認
「iptables -L INPUT_direct -v」コマンドで「INPUT_direct」チェインの設定を確認して、「match-set」の部分に「ipset」で作成したセットが設定されていることを確認します。
INPUT_directチェイン確認
# iptables -L INPUT_direct -v Chain INPUT_direct (1 references) pkts bytes target prot opt in out source destination 0 0 DROP all -- any any anywhere anywhere match-set BLACKLIST src
INPUTチェイン確認
次に「INPUT」チェインに「INPUT_direct」チェインが登録されていることを確認してください。
# iptables -L INPUT -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 432 42740 ACCEPT all -- any any anywhere anywhere ctstate RELATED,ESTABLISHED 0 0 ACCEPT all -- lo any anywhere anywhere 491 48989 INPUT_direct all -- any any anywhere anywhere 491 48989 INPUT_ZONES_SOURCE all -- any any anywhere anywhere 491 48989 INPUT_ZONES all -- any any anywhere anywhere 0 0 ACCEPT icmp -- any any anywhere anywhere 491 48989 REJECT all -- any any anywhere anywhere reject-with icmp-host-prohibited
両方とも確認できましたら、「ipset」と「fireawalld」の連携は完了です。
ipset自動作成
「ipset」と「firewalld」の連携が完了しましたら、次に「ipset」に作成したセットを自動作成する設定を行っていきます。
「ipset」はメモリ上にセット内容を格納しているため、サーバを再起動したりすると内容が削除されてしまいます。
そのため「firewalld」の起動前に「ipset」のセットを作成して、セットにルールを追加するという作業が必要になるのですが、サーバの再起動毎に手動で作業を行うのは現実的ではないので、自動的にセットを作成するためのスクリプトを作成していきます。
ipset データセーブ格納ディレクトリ作成
まずは、データ保存用のディレクトリを作成します。
# mkdir /etc/ipset
セット内容保存
現在の「ipset」の情報は下記の方法で保存することが出来ます。
ipset save > ファイル名
情報の保存
「BLACKLIST」というファイルに「ipset」のセット情報を保存していきます。
# ipset save > /etc/ipset/BLACKLIST
リストア方法
保存した情報は「ipset restore」コマンドでリストアすることができます。
ipset restore < ファイル名
ipset作成スクリプト
サーバ起動時や、「firewalld」の再起動時に自動的に「ipset」のセットを作成するために、「ipset_create.sh」というスクリプトを作成します。
※スクリプトの名前はお好きな名前でかまいません。
# vi /etc/ipset/ipset_create.sh
スクリプト内容
「ipset destroy」で既存のセット情報があればそれを削除して、その後「ipset restore」でバックアップした情報からセットを作成するという動作をします。
#!/bin/bash IPSET=/sbin/ipset DIR=/etc/ipset CONF=BLACKLIST cd $DIR $IPSET destroy $IPSET restore < $CONF
パーミッション設定
作成したスクリプトのパーミッションを設定します。
# chmod 744 ipset_create.sh
スクリプト動作確認
スクリプトの作成が終わりましたら、次に動作試験を行っていきます。
firewalldとの連係解除
「firewalld」と連携していると「ipset destroy」や「ipset restore」が行えないため、一度「firewalld」との連携を解除します。
# firewall-cmd --direct --remove-rule ipv4 filter INPUT 0 -m set --match-set BLACKLIST src -j DROP
スクリプト動作試験
「firewalld」との連携が解除されましたら、「ipset destoy」でセットを削除してからスクリプトを実行しセットがリストアされることを確認してください。
既存のセット削除と削除確認
# ipset destroy # ipset list
スクリプト実行
# sh -x /etc/ipset/ipset_create.sh # ipset list
スクリプトの動作に問題が無ければ、「firewalld」が起動する前に「ipset」のセット作成スクリプトを実行して、セットを作成するように設定を行っていきます。
firewalldsystemd管理用スクリプト変更
「firewalld」が起動する前にipsetのセットが作成されている必要があるため、「firewalld」のsystemd管理用スクリプト(/usr/lib/systemd/system/firewalld.service)を編集していきます。
# cp -p /usr/lib/systemd/system/firewalld.service /usr/lib/systemd/system/firewalld.service_yyyymmdd # vi /usr/lib/systemd/system/firewalld.service
変更内容
[Service]セクションに「ExecStartPre」を設定すると、起動前に実行するスクリプトを指定できるので「ipset」作成用のスクリプト(/etc/ipset/ipset_create.sh)を指定します。
[Service] EnvironmentFile=-/etc/sysconfig/firewalld ExecStartPre=/etc/ipset/ipset_create.sh <-----追加 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS ExecReload=/bin/kill -HUP $MAINPID
動作確認
「/usr/lib/systemd/system/firewalld.service」の編集が完了しましたら、「firewalld」と「ipset」の連携試験を行っていきます。
firewalld再起動テスト
「ipset」の中身を空にしてから「firewalld」を再起動して「ipset」と連携できているか確認します。
ipset flush
一旦「ipset」のセット「BLACKLIST」の情報を削除します。
# ipset destroy # ipset list
「firewalld」を再起動して、「ipset」と連携できているか確認します。
# systemctl restart firewalld
ipset確認
「ipset」のセット登録情報を確認します。
# ipset list BLACKLIST
iptable設定状況確認
「INPUT」と「INPUT_direct」チェインの内容を確認し、それぞれ登録されていることを確認してください。
# iptables -L INPUT_direct -v Chain INPUT_direct (1 references) pkts bytes target prot opt in out source destination 14 612 DROP all -- any any anywhere anywhere match-set BLACKLIST src
# iptables -L INPUT -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 171 15112 ACCEPT all -- any any anywhere anywhere ctstate RELATED,ESTABLISHED 0 0 ACCEPT all -- lo any anywhere anywhere 41 2480 INPUT_direct all -- any any anywhere anywhere 8 1032 INPUT_ZONES_SOURCE all -- any any anywhere anywhere 8 1032 INPUT_ZONES all -- any any anywhere anywhere 0 0 ACCEPT icmp -- any any anywhere anywhere 8 1032 REJECT all -- any any anywhere anywhere reject-with icmp-host-prohibited
サーバ再起動試験
「firewalld」の再起動試験で問題がなければ大丈夫だと思いますが、念のためにサーバの再起動試験が行えるのであれば実施したほうが安心です。
もし、今すぐにサーバの再起動が行えない場合は、次回サーバ再起動時に忘れずに確認を行ってください。
以上で作業完了となります。
国別のIPリスト作成方法
特定の国からの通信を遮断したい場合、その国に配布されているIPアドレスの一覧を調べる必要があります。
IPアドレスを管理している各団体のページから情報をダウンロードしてきて、自分で必要な情報を抽出するという方法もありますが、それは面倒なので私はいつも下記のサイトのお世話になっています。
IPアドレスの一覧が欲しい国を選択すると、その国に割り当てられているIPアドレスの一覧を表示してくれます。
また、画面右側の「Download」の「プレインテキスト」からテキストで情報をダウンロードすることができるので、これを元にIPセットを作成すると良いでしょう。
ちなみに、私はセットに登録する際には下記のようなスクリプトを使用して登録しています。
※登録するセットは事前に作成しておいてください。
#!/bin/bash LIST="ファイル名" SET="セット名" COM="/sbin/ipset add" while read line; do $COM $SET $line done < $LIST
コメント
tamohikoさん suhsiです。
バーチャルホストできました\(*T▽T*)/
本当にありがとうございます!!!
めちゃめちゃ感動ですよ!!!
親身になって優しくしていただいて
なんとお礼を言ったらいいかヽ(^◇^*)/
tamohiko さん の ご回答を何度も
読み直して、わたしの間違っているところを
調べなおしたんですね、そしたら
「あれ?バーチャルホストにしたいドメインの」
DNS設定ってしっかりなってるのかな?と思って
メインのドメインの方は、CENTOS7にインストールした
DICEでやっているんですけど、
サブドメインは未設定だったんですね
(。-人-。) オ、オユルシヲ・・・
それで、バーチャルホストにしたい方のアドレスを
MyDNS のオンラインサービスDNSでやることにしたんです。
そして、/etc/hosts で名前解決もして、
そしたら大成功ですよ!
本当にありがとうございました^^
超うれしいです。本日、さらに一段と自宅サーバーが
大好きになりました^^
なぜBINDの設定をしたかですけど、
以前に、ヤフー知恵袋に
この件を相談したときに、BINDを設定しないとダメだよ!
と回答されて、それで設定したんですね。
私の場合、これは関係なかったんですね、それか、
自分で、DNSサーバーを作る人はこれが必要だったのかな?
直接のメールやり取り!喜んで^^
ぜひぜひ、弟子にしてください!
tamohikoさんから、バーチャルホスト、
ウェブアライザー、ファイヤーウォールdの使い方を
教わって、これで超楽しい自宅サーバーライフが
はじまりますね!
本当にありがとうございました。直接のメール
お待ちしてまーすヽ(*^^*)ノ
tamohikoさん
こんばんわ。
tamohikoさんは、すごく優しいですね。
ipsetについて、すごくわかりやすく、
そして丁寧に教えていただいて
うれしいですウゥゥ((´;ω;`)
本当にありがとうございます。
さっそくやってみます!
バーチャルホストについても、ありがとうございます。
私は、CentOS7 の apacheです。
ドメインは3つ持ってます。
けど、問題なく使えているのは、無料で取得した
hogehoge.dip.jp というドメインだけです。
+——————————+
ieServerで取得無料ドメイン1つ目
hogehoge.dip.jp
ieServerで取得無料ドメイン2つ目
hogevirtual.jpn.ph
VALUE DOMAINで買った有料ドメイン
hogehoge.site
+——————————+
の計3つです。
インターネット回線は「ZAQ」という会社で
マンションに備え付けの無料インターネットで、
これが固定IPに非対応のようなんです。
>>
また、この環境であればDDNS環境での運用になるのかなと思うのですが、
こちらの方の設定は完了していますか?
>>
一応、以下のサイト様を参考にさせてもらって、
hogehoge.dip.jp(無料ドメイン1)これ1つだけなら
問題なく表示はできています。
https://centossrv.com/domain-ieserver.shtml
あと、BINDの設定もできました。nslookupとかも動作します。
https://centossrv.com/bind.shtml
ただ、私の2つ目のドメインの設定方法が間違っているようで
hogevirtual.jpn.ph(無料ドメイン2)
が表示されないんです。(T^T)
サーバーの プライベートIPは 192.168.0.12で
固定IPは 118.87.xxx.xxx です。
ネームサーバーだとか、ゲートウェイとか
DNS とか どのファイルに、どの情報を何の数値を入力するか、
それがよく理解できていなくて、1カ月苦しんでます><
上記の私と同じような環境の方で
バーチャルホストの設定されている方がいないか、
ずっとネット上でいろいろ探しているんですけど、
皆さん、有料ドメインだったり、固定IPだったりして、
その場合、どこをどう自分に合わせて変更したら
いいかわからなくて。。。
tamohikoさん
相談に乗っていただいて本当にありがとうございます。
( ノД`)
sushiさん
お返事ありがとうございます。
バーチャルホストの件について、もう少し確認させてください。
(1)問題点の確認
現時点での問題点は下記2点だと認識しているのですがあっていますか?
・バーチャルホストで表示できないドメインがある
・名前解決が出来ないドメインがある
(2)バーチャルホストの動作確認
まずはバーチャルホストの設定をがあっているかを確認したいので、、
hostsにIPとホスト名を設定して3ドメインとも名前解決が出来るように設定してみてください。
192.168.0.12 hogehoge.dip.jp
192.168.0.12 hogevirtual.jpn.ph
192.168.0.12 hogehoge.site
設定するファイルは、クライアントがWindowsならば「C:Windows\System32\drivers\etc\hosts」でCentOSの場合は「/etc/hosts」となります。
これで、名前解決が出来るようになると思いますので、Webブラウザでそれぞれのドメインにアクセスしてみてください。
もし、これでもWebサイトにアクセスできない場合は、その際に出たメッセージを教えてください。
(3)DDNSの登録について
3ドメインはすべてDiCEを使用して「ieServer」と「バリュードメイン」のDDNSにIPの自動更新設定を行ったが、
「hogehoge.dip.jp」だけしか名前解決が出来ないという認識で良いでしょうか?
> あと、BINDの設定もできました。nslookupとかも動作します。
> https://centossrv.com/bind.shtml
> ただ、私の2つ目のドメインの設定方法が間違っているようで
> hogevirtual.jpn.ph(無料ドメイン2)
> が表示されないんです。(T^T)
BINDは何のために使用しているのでしょうか?
サイトの方を見てみたのですが、いまいちよくわかりませんでしたので…
あと、コメント欄でのやり取りだと読みづらくなってしまうので
よろしければ、直接メールでやり取りさせて頂けますか?
もしよろしければ、その旨コメント頂けますでしょうか。
私の方からメールさせていただきますので、よろしくお願いいたします。
tamohikoさん、
sushiです。
ipsetの記事読ませていただきました。さすがですね!
返信が遅くなってすみません。
tamohikoさんのおっしゃるとおり、あの
大量のIPでしたので、
スクリプトを使って所定の書式を作ってやっていたのですが、
そのスクリプトを作るのも、わたくし超初心者でして、
やっとのやっとだったんですね^^;
最近ようやくその準備ができたところだったんです^^;
でも、なるほど、それだとfirewalldの動作に影響がでてくるんですね。
「ipset」というものを使ってですか、とても勉強になりました^^
さらに深く調べていただけるなんて、ミシュラン星 もう一つ追加
すばらしいですよ!!!
あの・・・お言葉に甘えて、2つお願いがあるのですが、
1つめは、
記事の一番最後の”スクリプト”の記述なんですが、
具体的に、こちらのスクリプトは どのフォルダの中に
何というファイル名で保存すればいいのでしょうか?
詳しい方はすぐに分かるんだと思うんですけど。
すみません^^;
https://ipv4.fetus.jp/ から、国別の大量のIPをTXT形式で保存して。
こちらのスクリプトと同じフォルダに置いておくわけですよね?
具体的にフォルダ/ファイルの名など、tamohiko さんの
サーバーを例として書いていただけると大変助かります^^。
2つめは、
最近かなり困っていることがあります。
実は、バーチャルホストをやってみたいのですが、
かなり時間をかけてやっているのに、ぜんぜんうまくいきません><
tamohikoさんは、バーチャルホストはされていますでしょうか?
わたしは、1つの物理サーバーで2つのドメインを使いたいのですが、
私のマンションは、固定IPに対応していないネット環境なんですね、
非固定IPだとか、無料ドメインなのか、有料ドメインなのかで
いろいろ設定が違うようなのですが、
BINDやらDNSやらしているのですが、もうわけがわからないです(笑)
ご存じでしたら教えてください!
今日の記事も最高でした!お疲れさまでした^^
sushiさん
コメントありがとうございます。
お返事遅くなってしまいすいません。
(1)スクリプトの使用方法
> 具体的に、こちらのスクリプトは どのフォルダの中に
> 何というファイル名で保存すればいいのでしょうか?
特に決まりはないので、どこのフォルダでもどんな名前でも大丈夫です。
> 具体的にフォルダ/ファイルの名など、tamohiko さんの
> サーバーを例として書いていただけると大変助かります^^。
私が作業を行った時の手順を簡単にまとめておきます。
作業の流れ的には/rootフォルダにIPアドレスのリストをダウンロードしてきて、そこに「ipset-create.sh」という名前でスクリプトを作成して「ipset」のBLACKLISTセットに登録といった流れになります。
■IPアドレスリストダウンロード
今回は「https://ipv4.fetus.jp/krfilter」のリスト使用しました。
# cd /root
# wget https://ipv4.fetus.jp/krfilter.1.txt
■スクリプト作成
ipsetのセットは事前に作成しておいてください。
また、LIST(IPアドレスリストのファイル名)とSET(ipsetのセット名)の部分は適宜変更お願いします。
# vi ipset-create.sh
●変更が必要になるかもしれない部分
LIST=”krfilter.1.txt”
SET=”BLACKLIST”
■スクリプト実行
# sh -x ./ipset-create.sh
■登録確認
ipsetのセットに情報が登録されているか確認します。
# ipset list BLACKLIST
(2)バーチャルホストについて
質問が何点かありますので教えてください。
・使用しているOSを教えてください
・使用しているWebサーバは何をお使いですか?
apacheですか?それともnginx?
・ドメインについて
非固定IP環境で運用しようとしているとのことですが、
ドメイン自体はすでに取得されているのでしょうか?
また、この環境であればDDNS環境での運用になるのかなと思うのですが、
こちらの方の設定は完了していますか?
このあたりの情報お教えいただければ、お力になれることはあると思いますよ。
以上、よろしくお願いいたします。