Home > ブログ > Amazon EC2でiptables,ipsetを使いホワイトリスト/ブラックリストを設定する

ブログ

Amazon EC2でiptables,ipsetを使いホワイトリスト/ブラックリストを設定する

Linuxカーネルにはnetfilter(iptables,firewalld)というファイアウォール機能がありますが、Amazon EC2ではセキュリティグループを使って簡単にファイアウォールの設定を行うことができるので、iptablesやfirewalldを使うことはあまりありません。Amazon Linuxでもデフォルトではiptables,firewalldサービスはインストールされておらず、netfilterの設定は空になっています。

ただ、ファイアウォールを設定する上で、特定のサービス(ssh,ftp,etc.)に対して特定IPからのみ接続を許可(ホワイトリスト)したり、拒否(ブラックリスト)したいことがあります。

これにはセキュリティグループにルールを登録していけばいいのですが、登録できるルールには上限があるのでそれにひっかかる可能性があります(*1)。

そこで、基本的な設定はセキュリティグループを使いつつ、接続元IPでのホワイトリスト、ブラックリスト設定はLinuxカーネルのnetfilterを使って行う方法を説明したいと思います。アクセス制限を行うサービスはFTPとします。

Linuxのファイアウォール設定にはiptables、firewalld-cmd(firewalld)がありますが、今回のケースではiptablesを使用します(*2)。

セキュリティグループは以下のように設定されているものとします。ソースは0.0.0.0/0とか::/0で接続元制限はしていません。

前提とするセキュリティグループの設定

Port Source 備考
TCP: 80 0.0.0.0/0 http(IPv4)
TCP: 80 ::/0 http(IPv6)
TCP: 443 0.0.0.0/0 https(IPv4)
TCP: 443 ::/0 https(IPv6)
TCP: 22 0.0.0.0/0 ssh
TCP: 21 0.0.0.0/0 FTP(IPv4)
TCP: 60001-60010 0.0.0.0/0 FTP Passive Port

設定をしていく

設定を間違えてsshで接続できなくなるリスクもあるので、作業前にはスナップショットをとっておきましょう。

それでは設定作業です。まずはiptablesとipsetをインストールします。

yum install iptables-services ipset-service

そしてホワイトリストとなるipsetを作成していきます(ipset名はWhiteListFtp)。

ipset create WhiteListFtp hash:net      ← ipset作成
ipset add WhiteListFtp xx.xx.xx.xx/32   ← 許可対象のIPを登録していく
ipset add WhiteListFtp xx.xx.xx.xx/32
:

作成したipsetの内容を/etc/sysconfig/ipsetに保存しておきます。これで、再起動した時などに設定が自動で読み込まれるようになります。

ipset save > /etc/sysconfig/ipset

自動保存したいような場合は/etc/sysconfig/ipset-configのIPSET_SAVE_ON_STOP="no"を変更しておきましょう。

次にiptablesの設定です。iptablesの設定ファイルは/etc/sysconfig/iptablesになります。このファイルを直接修正していきます。

デフォルトでは以下のようになっていますが、

デフォルトの/etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

この設定を全部消して以下のように書き換えます。

修正後の/etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state NEW -m set --match-set WhiteListFtp src -m tcp -p tcp --dport 21 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j REJECT
COMMIT

設定の要点としては、WhiteListFtpにマッチする接続元からのFTP(port 21)に対する新規接続はACCEPTし、ホワイトリスト外からのFTP接続はREJECTしています。それ以外の通信はINPUTチェーンのデフォルトアクション(つまりACCEPT)に飛ばしています。

デフォルトの設定にあった'-A INPUT -j REJECT --reject-with icmp-host-prohibited'がないので、セキュリティグループを通過したPort21宛以外の通信はすべて通すことになります。

なお、今回はIPv6についてはFTPを提供していない前提なので、アクセス元制限の設定は行わないものとします。アクセス制限を行わない場合は/etc/sysconfig/ip6tablesは空にしておきます。

/etc/sysconfig/ip6tables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

これで、IPv6については、セキュリティグループを通過してきた通信は全て通すことになります。

設定ファイルができたので、ipsetとiptablesサービスを開始しておきます。

systemctl enable ipset.service
systemctl start ipset.service
systemctl enable iptables.service
systemctl start iptables.service
systemctl enable ip6tables.service
systemctl start ip6tables.service

これで、設定したIP制限が有効になります。

上記はホワイトリストの例ですが、httpで特定のネットワークからのアクセスを拒否したいような場合(ブラックリスト)には、/etc/sysconfig/iptablesに以下のエントリを追加します(httpsの方は省略)。

ブラックリスト設定の例

-A INPUT -m state --state NEW -m set --match-set BlackListHttp src -m tcp -p tcp --dport 80 -j REJECT

BlackListHttpにマッチする接続元からのhttp接続を拒否します(BlackListHttpセットは別途作成しておく必要があります)。

ただし、http/httpsについてはWebサーバーがApplication Load Balancer配下で動作している場合はこの方法は使えないので、Webサーバー(apache,nginx)でdeny設定をするかWAFを別途導入する必要がありますが。

まとめ

以上のようにして、セキュリティグループのルール数を抑えながら、細かいアクセス制限を行うことができます。

sshについては設定を間違えて接続できなくならないよう、セキュリティグループのみでの設定にしておいた方がよいと思います。繰り返しになりますが、作業前には念の為スナップショットをとっておきましょう。

(*1) 2019.8.6時点では、VPC セキュリティグループ当たりのルールの数は60。制限緩和申請もできますが、VPC セキュリティグループ当たりのルールの数 × Elastic Network Interface 当たりの VPC セキュリティグループの数 の値が1000までとなります。
参考: https://aws.amazon.com/jp/premiumsupport/knowledge-center/increase-security-group-rule-limit/

(*2)今回のケースではfirewalldだとゾーン設定が邪魔になります。Linuxカーネル側に設定するのは接続元IPに関する最低限の設定しか行わないので、必要最低限のルールだけ設定できるiptablesを使います。

投稿日:2019/08/07 12:50

タグ: Linux Server AWS

Top

アーカイブ

タグ

Server (18) プログラミング (15) 作業実績 (15) PHP (11) ネットワーク (9) C (7) C++ (7) Webアプリ (6) EC-CUBE (6) Nginx (5) OpenSSL (5) laravel (4) Linux (4) 書籍 (4) JavaScript (3) AWS (3) Rust (3) Vue.js (3) Golang (2) Symfony (2) Apache (1) デモ (1) お知らせ (1) MySQL (1) CreateJS (1) OSS (1)