Ubuntu16.04.3でiptablesを利用し特定IPアドレスからの80ポートのアクセスを拒否する方法

## はじめに

VPSを契約している会社からブログを運用しているサーバーが高負荷によりシャットダウンしたと連絡が来た。前日に引っ越したばかりで自宅のインターネット回線も準備中ですぐに確認ができなかった。ダンボールを開封している間もすごい気になってしまい集中できなかったので、合間を縫ってコワーキングスペースに来て対応することにした。

```text
いつもご利用いただき、まことにありがとうございます。
HOGEHOGE お客様センター です。

ご利用いただいておりますVPSのご運用につきまして
ご連絡申しあげます。

IPv4アドレス：
xxx.xxx.xxx.xxx

上記IPアドレスにてご利用のVPSにつきまして、CPUの使用率が
高い状況が継続しております。

一時的なものであれば問題ございませんが、継続する場合、
収容ホストへの負荷影響や、他のお客様への影響が懸念されます。

そのため、大変恐縮ではございますが、該当VPSのシャットダウンを
実施させていただきました。
```

## WordPressのXML-RPCが狙われていた

Nginxのアクセスログを見ての通りである。WordPressには[XML-RPC WordPress API](https://wpdocs.osdn.jp/XML-RPC_WordPress_API)というものがあり、それが狙われたようです。

```sh
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:14:07 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:06 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:07 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:07 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:08 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:08 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:09 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:12 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
xxx.xxx.xxx.xxx - - [17/Dec/2017:20:28:12 +0900] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
```

## iptables でアクセス拒否

* iptables-persistentのインストール
* 特定IPアドレスからの80ポートへのアクセスを拒否

の２つを実施します。

### iptables-persistentのインストール

知らなかったのですがUbuntuのiptablesは再起動をすると設定が消えてしまうとのことで、それを防止するために `iptables-persistent`が必要とのことでした。 [こちら](https://qiita.com/yas-nyan/items/e5500cf67236d11cce72)を参考に `apt install iptables-persistent` でインストールしました。

### 特定IPアドレスからの80ポートへのアクセスを拒否

以下を実行することで設定できます。

```sh
$ iptables -A INPUT -p tcp -s 拒否したいIPアドレス --dport 80 -j DROP
```

オプション|意味
---|---
-A|指定チェインに1つ以上の新しいルールを追加
-p|チェックされるパケットのプロトコル
-s|送信元の指定。特定のIPアドレスや範囲を指定する
-j|ターゲット(ACCEPT, DROP or RETURN)を指定して。条件にマッチしたときに何をするか。
--dport|パケットの受信側ポートを指定

実行後、`-L` オプションで設定状況を確認できます。

```sh
root@150-95-176-243:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  --  xxx.xxx.xxx.xxx        anywhere             tcp dpt:http

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
```

上記設定後、特定IPアドレスからのアクセスはピタッと止まりました。

## xmlrpc.phpのアクセスは完全に拒否
本記事はiptablesを利用して特定IPアドレスからのアクセスを拒否する内容につき、それでゴールは達していますが、WordPressのセキュリティの観点では未解決です。Nginxの`/etc/nginx/sites-available/default`ファイルのserverディレクティブ内に以下を加えることで、xmlrpcへのアクセスを完全拒否しました。

```nginx:/etc/nginx/sites-available/default
location = /xmlrpc.php {
    deny all;
    access_log off;
    error_log off;
}
```

## おわりに

WordPress運用の勉強不足から発生した問題ではありましたが、こういった課題があることやiptablesによるIPアドレスの拒否方法が知れて勉強になりました。共用レンタルサーバーやGitHub Pagesを利用してブログ運用をしていると、こういった問題を自分で解決する機会には出会すことがなかなかないので、インフラ運用に興味のある人は是非VPSやクラウドサーバーで個人ブログを運用してみてください。

## 参考
* [iptables まとめ \- Qiita](https://qiita.com/Tocyuki/items/6d90a1ec4dd8e991a1ce)