5 LOG

「さくらのVPS」CentOS の初期設定の作業のまとめ&解説(iptablesによるファイアウォール編)

image

今回はさくらのVPS の初期設定のファイアウォール編です。
iptablesの設定は検索するといろいろと出てきて、どれが信頼できるのかわからない状態です。。。
結構、良くわからないから他のサイトをコピペしました的な記事も多く見られます。おそらくコピペで設定している人も多いと思いますので、もう一度確認してみてください。

作業目次

  1. 初期設定 ssh編
    1. サーバー起動、rootパスワード変更
    2. 作業用ユーザーの追加・パスワード設定・管理者グループに追加・sudo・suの設定
    3. 公開鍵認証、パスワードログインの禁止、rootログインの禁止、sshポート番号の変更
  2. ファイアウォール編
    1. iptablesによるファイアウォールの設定(←今回はここ)

iptablesを使用したパケットフィルタリング設定

パケットフィルタリング設定は、簡単に言うとサーバーの通信(データやパケット)の送受信に対して、許可したり、拒否したりする設定です。
例えば、サーバーへのssh接続は特定のIPアドレスのみ許可する
といった設定をしていきます。

今回のパケットフィルタリングを行う上でのポリシーは
すべての通信を遮断して、必要な通信の通過のみを許可していく
方法を取ります。パケットフィルタリングでは、
すべての通信を透過させ、特定の通信だけを遮断する 方法もありますが、セキュリティ面を考えると、あまりお勧めできませんね。例えば自宅サーバーなど、外部からのアクセスのファイアウォールはルータでしっかり行い、内部からは自由なポートにアクセスできる状態にしたい場合などではアリとは思いますが。

今回のiptablesの設定内容は、「Wordpressをインストールしてサイトを公開する想定」での基本的な設定です。
設定の概要は、

  • すべての通信を遮断して、必要な通信の通過のみを許可していく。
  • httpsは使用しない。
  • FTPは使用せずに、SFTPを使用する。
  • メールは送信のみにし、受信はしない。

といった内容です。

iptablesの設定は、/etc/sysconfig/iptables ファイルを編集します。

[admin@ ~]$ sudo vi /etc/sysconfig/iptables

今回設定した内容は下記です。

#------------------------------------------------------
#ポリシー:全ての送受信パケットを破棄。必要な用途に応じて開けていく。
#------------------------------------------------------
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]

#------------------------------------------------------
#ループバックアドレス(自分自身のIP)からの送受信を許可
#------------------------------------------------------
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

#------------------------------------------------------
#メンテナンスホスト(xxx.xxx.xxx.xxx)からサーバへのping送受信を許可
#サーバーからメンテナンスホストへのPing送受信を許可
#Pingリクエスト(Echo Request(8))およびそのPing応答(Echo Reply(0))を許可
#------------------------------------------------------
-A INPUT -s xxx.xxx.xxx.xxx -p icmp --icmp-type 0 -j ACCEPT
-A OUTPUT -d xxx.xxx.xxx.xxx -p icmp --icmp-type 8 -j ACCEPT
-A INPUT -s xxx.xxx.xxx.xxx -p icmp --icmp-type 8 -j ACCEPT
-A OUTPUT -d xxx.xxx.xxx.xxx -p icmp --icmp-type 0 -j ACCEPT

#------------------------------------------------------
# 公開サービスの接続設定
#------------------------------------------------------

# SSH(ポートは仮に20022に設定)
# メンテナンスホスト(xxx.xxx.xxx.xxx)のみ接続を許可
# 発信元IPアドレスごとに1分間に2回のアクセス制限
-A INPUT -s xxx.xxx.xxx.xxx -p tcp --dport 20022 -j ACCEPT
-A OUTPUT -d xxx.xxx.xxx.xxx -p tcp --sport 20022 -j ACCEPT
-A INPUT -p tcp --dport 20022 -m hashlimit --hashlimit-name ssh --hashlimit 2/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 60000 -j ACCEPT

#HTTP
-A INPUT -p tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp --sport 80 -j ACCEPT
#サーバーから外部へのHTTP接続を許可
-A INPUT -p tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp --dport 80 -j ACCEPT

#SMTP
-A INPUT -p tcp --dport 25 -j ACCEPT
-A INPUT -p tcp --sport 25 -j ACCEPT
-A OUTPUT -p tcp --sport 25 -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT

#外部DNSサーバーへの問い合わせを許可
-A INPUT -p udp --sport 53 -j ACCEPT
-A OUTPUT -p udp --dport 53 -j ACCEPT

#------------------------------------------------------
#NTPの問い合わせを許可
#------------------------------------------------------
-A INPUT -p udp --dport 123 -j ACCEPT
-A OUTPUT -p udp --sport 123 -j ACCEPT

#------------------------------------------------------
# 接続済みパケットの送受信を許可
#------------------------------------------------------
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


#------------------------------------------------------
#ブロードキャスト宛パケットはログを記録せずに破棄
#------------------------------------------------------
-A INPUT -d 255.255.255.255 -j DROP
-A INPUT -d 224.0.0.1 -j DROP

#------------------------------------------------------
#NETBIOS関連のアクセスはログを記録せずに破棄
#------------------------------------------------------
-A INPUT -p udp -m multiport --dport 137,138,139,445 -j DROP

#------------------------------------------------------
#DropboxのUPDパケット(port 17500)はログを記録せずに破棄
#------------------------------------------------------
-A INPUT -p udp --dport 17500 -j DROP


#------------------------------------------------------
#ログ
#新規にLOGGINGチェインを作成
#DROPしたパケットをログに記録(1時間に最大3回)
#ログ出力後に破棄
#パケットの送受信時にLOGGINGを実行
#------------------------------------------------------
-N LOGGING
-A LOGGING -j LOG --log-prefix "DROP:" -m limit --limit 3/hour
-A LOGGING -j DROP
-A INPUT -j LOGGING
-A OUTPUT -j LOGGING

COMMIT

編集が終わったら、iptablesを再起動させます。

[admin@ ~]$ sudo /etc/rc.d/init.d/iptables restart

上記の設定内容を詳しく説明していきます。

1〜7行目
まず、全ての通信をDROP(拒否)します。

:INPUT DROP [0:0] 全ての受信パケットを拒否
:FORWARD DROP [0:0] 全ての経由パケットを拒否
:OUTPUT DROP [0:0] 全ての送信パケットを拒否

ちなみに、特定の通信だけを遮断するポリシーの場合はこの部分が DROP ではなく、ACCEPT(許可) となります。

これで、すべての通信が遮断されました。
ここから必要な通信の通過を許可していきます。

9〜13行目
自分自身のコンピュータ上で動作しているサービスへ接続させるため、ループバックアドレスからの送受信をすべて許可します。

-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

15〜23行目
pingの応答はメンテナンスホストからのみにする。

-A INPUT -s xxx.xxx.xxx.xxx -p icmp --icmp-type 0 -j ACCEPT
-A OUTPUT -d xxx.xxx.xxx.xxx -p icmp --icmp-type 8 -j ACCEPT
-A INPUT -s xxx.xxx.xxx.xxx -p icmp --icmp-type 8 -j ACCEPT
-A OUTPUT -d xxx.xxx.xxx.xxx -p icmp --icmp-type 0 -j ACCEPT

「ping」コマンドはネットワークの疎通確認やトラブルシューティングに使用でき、とても便利ですが、悪意のあるユーザーにサーバの存在を知らせることになるので、必要なpingにだけ応答させるようにした方が良いです。

29〜34行目
SSHの接続は絶対に守りたいところです。前回のssh編で、sshのポートを変更したので、(Port 20022 に設定)そのポートを対象にします。
まずは、特定のIPからしか接続できないようにしておきます。

-A INPUT -s xxx.xxx.xxx.xxx -p tcp --dport 20022 -j ACCEPT
-A OUTPUT -d xxx.xxx.xxx.xxx -p tcp --sport 20022 -j ACCEPT

さらに、総当たり攻撃対策として、接続回数制限をしておきます。

-A INPUT -p tcp --dport 20022 -m hashlimit --hashlimit-name ssh --hashlimit 2/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 60000 -j ACCEPT

接続回数制限は hashlimit を使用します。

  • –hashlimit-name ssh : 任意に名前を設定(今回は ssh)
  • –hashlimit 2/m : 1分間に2パケット(30秒間に1パケット)を許可
  • –hashlimit-burst 10 : 最初に10パケットを許可
  • –hashlimit-mode srcip : 発信元IPアドレスごとに管理
  • –hashlimit-htable-expire 60000 : 最後のパケットから60000ミリ秒(60秒=1分)でリセット
これにより、発信元IPアドレスごとに最初の10パケットを許可した後、30秒に1パケットのみ許可します。最後のパケットから1分経つとリセットされ、また10パケットを許可します。
ちなみに、接続回数の制限をした場合、接続済のパケット通信を許可(59〜63行目)しておかないとDROPされてしまいます。
参考:hashlimit で ssh へのブルートフォースアタックを減らす

36〜41行目
HTTP接続用に80番ポートの接続を許可します。

-A INPUT -p tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp --sport 80 -j ACCEPT

また、サーバー自身から外部へのHTTP接続を許可させます。(40〜41行目)

-A INPUT -p tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp --dport 80 -j ACCEPT

43〜47行目
メール送信用に25番ポートの双方向の接続を許可します。

-A INPUT -p tcp --dport 25 -j ACCEPT
-A INPUT -p tcp --sport 25 -j ACCEPT
-A OUTPUT -p tcp --sport 25 -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT

49〜51行目
外部DNSサーバーへの問い合わせ用に53番ポートを許可します。

-A INPUT -p udp --sport 53 -j ACCEPT
-A OUTPUT -p udp --dport 53 -j ACCEPT

ちなみに、DNSサーバーとして公開する場合は、双方向の接続を許可しますが、今回はDNSへの問い合わせのみなので、外部への接続許可のみです。

53〜57行目
サーバの時計を定期的に調整するために、NTPサーバの問い合わせを許可

-A INPUT -p udp --dport 123 -j ACCEPT
-A OUTPUT -p udp --sport 123 -j ACCEPT

59〜63行目
接続済みの通信は許可します。

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

今回は、最小限のサービス用のポートのみ許可しています。他にも、例えば https を使用したり、FTP を使用したりする場合は適宜必要なポートを許可してください。

65〜79行目はあとで説明します。先に

81〜92行目
DROPした通信をログに記録します。
ログを見ることによって、どんな通信がDROPされたのかを確認することができるので設定しておきましょう。

-N LOGGING
-A LOGGING -j LOG --log-prefix "DROP:" -m limit --limit 3/hour
-A LOGGING -j DROP
-A INPUT -j LOGGING
-A OUTPUT -j LOGGING

DROPされた通信をすべてログに記録すると、ログファイルが大きくなってしまうので、制限をつける。

  • –log-prefix “DROP:” :記録するログの先頭に DROP: を追加
  • -m limit –limit 3/hour :ログの肥大化を防ぐために1時間に3回の制限設定

これで、DROPされた通信がログに記録されていきます。
ログを見ると、記録する必要のないものも出てきますので、そういった通信はログに記録する前に先にDROPしておきます。
65〜79行目

#------------------------------------------------------
#ブロードキャスト宛パケットはログを記録せずに破棄
#------------------------------------------------------
-A INPUT -d 255.255.255.255 -j DROP
-A INPUT -d 224.0.0.1 -j DROP

#------------------------------------------------------
#NETBIOS関連のアクセスはログを記録せずに破棄
#------------------------------------------------------
-A INPUT -p udp -m multiport --dport 137,138,139,445 -j DROP

#------------------------------------------------------
#DropboxのUPDパケット(port 17500)はログを記録せずに破棄
#------------------------------------------------------
-A INPUT -p udp --dport 17500 -j DROP

ちなみに、76〜79行目のDropboxのUPDパケットについては、Dropboxが同一LAN内にいるDorpboxとのsyncをするために、ブロードキャストに向けてUDPパケットを送信しているようで、大量に飛んできます。下記で詳しく書かれています。
Dropboxを使うな、とまでは言いませんが
VPSでDropboxを使うなら、LAN Syncを止めよう!

他にも、ログに記録したくないものがあれば付け足してください。

今回のiptablesによるパケットフィルタリング設定については、こんなところです。