TCP Wrapper で SSH のアクセス制限 - さくらのクラウド超入門・サーバ編(2)

# 概要

前回は [仮想サーバの作成](https://qiita.com/zembutsu/items/fe4686cde8a0cd50f2b0) まで学びました。次は、インターネット上で公開しているサーバに対し、最低限度必要なアクセス制限を行います。

# 解説

## サーバに対して最低限のアクセス制限（TCP Wrapper）をする

（ご存じの通り）インターネット上に公開しているサーバは、世界中からアクセス可能です。そのため、公開サーバは常に不正利用や攻撃の危険性に晒されています。ですから、何らかの形でサーバに対して SSH 接続の制限を設けるべきです。

さくらのクラウドの CentOS パブリックアーカイブ（仮想マシン・イメージのテンプレート）は、CentOS のファイアウォール機能である firewalld（ファイアウォールディー）が有効です。しかし、 SSH （ポート 22/TCP）に対してはインターネットを通してログインできるようにするため、制限がありません。

（ちなみに、Fail2ban（フェイル・トゥ・バン）が組み込み済みのため、連続してログインに失敗すると、自動的に iptables で接続を一定期間自動切断する機能はあります。）

公開サーバの安全性を高めるため、以下のコマンドをサーバ内で実行することで、その接続元に対して TCP Wrapper（ティーシーピー・ラッパー）の機能を使い、接続元のホスト（または、インターネット側のゲートウェイ・サーバ）に対する接続を許可します。

```
echo -n "sshd: " >> /etc/hosts.allow
who -m  | awk -F'[()]' '{print $2}' >> /etc/hosts.allow
echo "sshd: all" >> /etc/hosts.deny
```

コマンドを実行後、 `cat /etc/hosts.deny` と `cat /etc/hosts.allow` を表示します。

```
$ cat /etc/hosts.deny
（省略）
sshd: all
```

まず、 `/etc/hosts.deny` は接続を「拒否」する設定が入りました。初期状態では、このファイル内に制限の記述がないため、事実上の TCP Wrapper が全く機能していません。つまり、サーバの IP アドレスさえ分ければ、誰でも接続を試せます。

ここでは「sshd」に対する接続を「all」（全て）拒否するという指定をしました。この記述がなければ、次の `/etc/hosts.allow` にどれだけ記述しても制限が行われません。また、 `all: all` と記述し全ての制限を行うこともできます。

それから、 `/etc/hosts.allow` は接続を許可する環境を記述します。

```
$ cat /etc/hosts.allow
（省略）
sshd: foo.example.ne.jp
```

この行は1行だけでなく、許可したいホストやネットワークを複数行記述できます。

ルールの優先度は `/etc/hosts.deny` （こちらで全て拒否）です。接続を許可する環境を `/etc/hosts.allow` に記述します。つまり、 `/etc/hosts.allow` に書かれていないホストからの接続は（許可するルールがありませんので）拒否します。

これで最低限ではありますが、サーバに対する不必要な SSH アクセスを制限できました。

## もしも接続できなくなったら？ コンソール機能で接続

今回追加した接続元ホストは1箇所だけでした。もしも、アクセス元が動的に変更するなどして、リモートから SSH で接続できなくなった場合は、 [コンソール](https://manual.sakura.ad.jp/cloud/server/console.html) 機能を使い、コントロールパネル上から仮想サーバにログインできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/8bd85416-6543-7af1-96c2-594ea880d74e.png)


ログイン後、 `/etc/hosts.allow` を編集して環境を追加します。あるいは、 `/etc/hosts.deny` の `sshd: all` を削除またはコメントアウトすることでリモートからの接続を一時的に許可する方法もあります。 [コンソールの使い方はマニュアルをご覧ください](https://manual.sakura.ad.jp/cloud/server/console.html) 。

ちなみにコンソール機能とは、仮想的な"据え置き型端末の画面" という意味です。さくらのクラウドの仮想サーバは、インターネット側や LAN 内から接続できなくても、コンソール画面を通して直接仮想サーバに対して接続出来ます。

`login: ` ではログイン可能なユーザを入力します。デフォルトでは `root` です。他にもユーザを作っている場合は、そちらでもログインできます。それから `Password: ` では、対象ユーザのパスワードを入力します。ログイン後は SSH 接続と全く同じような感覚でシェルを操作でき、 `exit` などでシェルを終了すると、ログアウトします。

## さらに細かな制御をするには？　パケットフィルタの活用

このほか、サーバのセキュリティを高めるためには、以下の方法があります。

- CentOS 7 であれば iptables で更に細かな設定する
- さくらのクラウドの「 [パケットフィルタ](https://manual.sakura.ad.jp/cloud/network/packet-filter.html) 」機能を使い、サーバ到達前の段階でアクセス制限する

今回の TCP Wrapper や iptables の設定は、サーバ1台1台に対して設定を行う必要があります。そのため、仮に10台のサーバのアクセス制限を変更するとなると、10台のサーバに都度ログインおよび作業が必要なため、手間と時間がかります。「 [パケットフィルタ](https://manual.sakura.ad.jp/cloud/network/packet-filter.html) 」機能を使えば、コントロールパネル上でアクセス制限が可能で、かつ複数台に対する設定適用も簡単に行えます。 [パケットフィルタの詳細はドキュメントをご覧ください](https://manual.sakura.ad.jp/cloud/network/packet-filter.html) 。

## TCP Wrapper 適用範囲に対する捕捉（より詳しい理解をされたい方へ）

TCP Wrapper で制限できるのは、サーバ上のサービス（一般的には、SSHや、FTPのほか、POP3、IMAPのメールサーバなどのプログラム）に対してのみです。各プログラムは、SSH のようにプログラム作成（make）の段階でライブラリを組みこんでいるか、あるいはxinetd（ザイネットディー、または、エックスアイネットディー）のようなホスト内外の通信を仲介するプログラムを通している場合のみ有効です。

そのため、Apache や Nginx のようなウェブサーバや、BIND などの DNS サーバに対しては TCP Wrapper による制限は行えません。このような TCP Wrapper を使わないプログラムに対しては、 iptables （CentOS 8 以降は Netfilter）で制限する必要があります。

# 振り返り

インターネット上の公開サーバに対してセキュリティを高めるため、TCP Wrapper を使った SSH のアクセス制限を行いました。接続ルールは `/etc/hosts.deny` が「拒否」、 `/etc/hosts.allow` が「許可」です。また、制限のルールで優先度が高いのが `/etc/hosts.deny` でした。

## 次回は

次回は、Dockerを使って、WordPress アプリケーションをセットアップします。

- [さくらのクラウド　チュートリアル目次](https://qiita.com/zembutsu/items/538aa0a0211f9200b6c5)