サーバー構築で最低限考えるべき仕様

Webサーバー、DBサーバー、Dockerホストなどを構築するときに、用途はともかく最低限考えるべき仕様をまとめてみました。設置場所、用途によって仕様を取捨選択することで、ある程度楽に仕様を定義できると思います。

なお、当記事ではあくまで仕様を定義するだけなので、具体的な実装手順はOSやツールによって変わります。今時、全部手作業で構築するものでもなく、`Chef`、`Ansible`、`Fabric`などを使用すると思いますので、その手の記事を探せば良いです。

# 初期設定仕様
サーバー構築時の設定仕様を定義します。

## OS基本仕様
OSの基本的な仕様を定義します。

### ホスト名
ホスト名を定義します。ネットワーク内で重複しない文字列を定義します。

* 定義項目
    * ホスト名

### ネットワーク設定
ネットワークに接続する場合、IPアドレスの割り当て方式を定義します。

* 定義項目
    * DHCPによる自動割り当て
    * 固定割り当て
        * IPアドレス
        * サブネット
        * デフォルト・ゲートウェイ

### タイムゾーン設定
タイムゾーンを定義します。日本の場合、`Asia/Tokyo`または`UTC+09:00`です。

* 定義項目
    * タイムゾーン

### 時刻同期設定
正しい時刻を保つ方式を定義します。通常、NTPを使用して時刻同期を行うため、NTPを使用すること、NTPサーバーのアドレスを定義します。

業務システムなどオンプレミス運用の場合、LAN内にNTPサーバーが存在する場合があります。

IaaSなどのサービスの場合、NTPサーバーを提供していることがあります。

利用できるNTPサーバーが存在しない場合、[Ring Server Project](http://www.ring.gr.jp/ring/ntp.html.ja)により提供されているNTPサーバー(`ntp.ring.gr.jp`)や、[NICT](http://jjy.nict.go.jp/ntp/)により提供されているNTPサーバー(`ntp.nict.jp`)を利用することができます。

ネットワークに接続していない場合、時刻を手動で設定することになります。

* 定義項目
    * NTPサーバーのアドレス

### 必要なサービス(不要なサービス)
OSは多数のサービスが稼働していますが、パフォーマンス面・セキュリティ面から考えて、不要なサービスは停止すべきです。仕様としては、「必要なサービス」を定義します。

* 定義項目
    * サービス名

sshdやcronのように当然稼働しているサービスが不要である場合は、「不要なサービス」として明示的に定義すべきです。

### 作業ユーザー
使用するOSユーザーを定義します。ユーザーは目的ごと、サービスごとに定義し、ログイン可否、sudo可否、権限も制限します。権限は、最低でもスーパーユーザーか否か、できれば使用可能なコマンドやディレクトリなどを定義すべきです。

* 定義項目
    * ユーザー名
    * 使用目的(または使用サービス)
    * ログイン可否
    * ssh可否
    * sudo可否
    * 権限

> _NOTE:_ ログイン・シェルを`/bin/false`か`/sbin/nologin`に設定すると、ログインができなくなります。

### 導入するパッケージ
OSに標準でインストールされているパッケージ以外にインストールするパッケージを定義します。OSの標準パッケージ管理方式とは別に、手動インストール、Node.jsのnpm、Maven、Ruby gemなど様々な方式が存在するため、それも定義する。

* 定義項目
    * パッケージ名
    * パッケージ管理方式

## sshサービス仕様
リモート・シェルであるsshに関する仕様を定義します。sshを使用しない場合は定義する必要はありませんが、その場合はsshdサービスを無効化することを明示的に定義します。

### ポート番号
sshdは標準で`22`番ポートを使用します。サーバーをインターネットに公開する場合、セキュリティの面からポート番号を変更するべきです。

* 定義項目
    * ポート番号

### rootログインを禁止
リモート接続におけるrootログインはセキュリティの面から望ましくないため、通常は禁止すべきです。

* 定義項目
    * rootログイン可否

### パスワード認証を無効化、公開鍵認証を有効化
パスワード認証はセキュリティの面から望ましくないため、パスワード認証を無効化して公開鍵認証を有効化するべきです。公開鍵認証を有効化する場合、公開鍵の運用方法を定義すべきです。

* 定義項目
    * パスワード認証可否
        * 空パスワード可否
    * 公開鍵認証可否

パスワード認証を有効にする場合、少なくとも空パスワードを無効化するべきです。

### ssh有効ユーザー
「作業ユーザー」の定義項目にありますが、セキュリティの面からsshログインが可能なユーザーを定義するべきです。

### プロトコル・バージョン
sshプロトコルのバージョン1は脆弱性が発見されているため、理由が無ければバージョン2のみを使用するべきです。

* 定義項目
    * sshプロトコル・バージョン (1、または、2)

### 認証猶予時間、試行回数
sshクライアントがコネクションを確立してから認証するまでの猶予時間、認証を試行する回数を定義します。

* 定義項目
    * 認証猶予時間 (秒数)
    * 試行回数

### 接続元IPアドレス
サーバーへの接続元拠点が特定できるのであれば、セキュリティ面から接続元IPアドレスを制限したほうが良いです。

* 定義項目
    * 接続元IPアドレス
    * 拠点名

## ファイアウォール
外部からのネットワーク接続に関する防御を行う仕様を定義します。通常、`iptables`や`ufw`を使用します。

### 使用するポートのみを有効化
使用しないポートはセキュリティの面から閉じるべきです。仕様としては、「開くポート番号」を定義します。

* 定義項目
    * ポート番号
    * 使用目的

よく使うポート番号は[ウェルノウンポート番号](https://ja.wikipedia.org/wiki/TCP%E3%82%84UDP%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%AE%E4%B8%80%E8%A6%A7)として知られています。その中でもよく使うポート番号を引用します。

|サービス|ポート番号|
|---|---|
|SSH|22|
|SMTP|25|
|HTTP|80|
|POP3|110|
|HTTPS|443|

## sudo
sudoは、一般ユーザーがrootにsuすることなく、root権限でプログラムを実行するためのコマンドです。

### rootへのsuを禁止
rootでの作業を制限するため、特に理由が無ければrootへのsuを禁止するべきです。

* 定義項目
    * rootへのsuの可否

### sudo可能ユーザー
「作業ユーザー」の定義項目にありますが、セキュリティの面からsudoが可能なユーザーを定義するべきです。

# 運用仕様
サーバー構築後の運用仕様を定義します。

## ユーザー管理作業
作業者の着任、離任したなどでユーザーを変更することがあります。また、セキュリティ面から発生する定期作業などを定義します。

### ユーザー作成、削除
作業者の着任によりユーザーの作成、離任によりユーザーの削除を行います。作業手順自体は初期構築時に実施した手順と同じですが、その旨を仕様として定義すべきです。

### パスワード定期変更
セキュリティ・ポリシーにより、パスワードの定期変更が義務となっている場合があります。変更期間、変更手順、パスワード・ポリシーなどを定義します。

## ログ監視
OSやソフトウェアが出力する各種ログを監視し、異常の発生を検知します。監視するファイル、監視する文字列、検知時の通知手段、検知時の対応手順を定義します。

## パッケージ管理
OSやソフトウェアは随時バージョンアップされるので、特に理由が無ければソフトウェアを更新した方が良いです。

### 更新ポリシー
ソフトウェアは様々な理由によりバージョンアップされます。例えば、発見された脆弱性を解消するためにバージョンアップされることがあるため、可能な限り素早く更新するべきと言えます。しかし、バージョンアップすることでソフトウェア仕様が変更され、これまで正常に動作していたソフトウェアが動作しなくなることもあります。このため、更新ポリシーを検討するべきです。

* 自動更新、または、手動更新
    * 手動更新の場合、更新手順

### 手動更新手順
ソフトウェアを手動で更新する場合、更新手順を定義します。更新前に特に何もしないのであれば、自動更新でも良いからです。更新前に行うべき作業は、以下のことが考えられます。

* 更新によるOS再起動の要否
* 更新後に新しく依存するソフトウェア
    * 更新により依存ソフトウェアも同時に更新する必要がある場合
* 更新後のサービス動作確認
    * 検証用サーバーで、更新後ソフトウェアを使用してサービスの動作確認を実施
* 更新作業のタイムスケジュール
* 更新作業の周知・連絡手順

## ストレージ監視
OSやソフトウェアが動作することで、ストレージ容量を消費します。ストレージ容量が不足することで、OSやソフトウェアが正常に動作しなくなります。このため、ストレージ残容量を監視して、閾値を下回ったことを検知します。閾値、検知時の通知手順、検知時の対応手順を定義します。

## CPU使用率監視
CPU使用率を監視して、サービスが異常にCPUを占有した場合、それを検知します。閾値、検知時の通知手順、検知時の対応手順を定義します。

## 死活監視
サービスが正常に動作しているかどうかを監視して、異常の発生を検知します。検知方法、検知時の通知手順、検知時の対応手順を定義します。

# 脆弱性検知
脆弱性は日々発見されるため、自分のサーバーがどの脆弱性に対応しているかを調べるべきです。しかし、それには大変な労力が必要になります。このため、脆弱性検知ツールを使用したほうが良いです。

* [あなたのサーバは本当に安全ですか？今もっともイケてる脆弱性検知ツールVulsを使ってみた](http://qiita.com/sadayuki-matsuno/items/0bb8bb1689425bb9a21c)
* [Qualys SSL Report](https://www.ssllabs.com/ssltest/)

# 参考リンク
* [そこそこセキュアなlinuxサーバーを作る](http://qiita.com/cocuh/items/e7c305ccffb6841d109c)
* [su rootできるユーザを制限する。](http://qiita.com/shimohiko/items/f45d02bea949f1f5cc85)
* [サーバ初心者に捧ぐ、サーバを立てたらまずすべきセキュリティの設定](http://qiita.com/saitoxu/items/5ea998164c6225358567)

# リンク
* GitHub
    * https://github.com/u6k/blog/blob/master/page/20160520-server-base-spec.md