root権限で好きに弄れる外部サーバー、VPSを利用するまで (DTI ServersMan@VPS契約, CentOSセットアップ)

# はじめに

外部にレンタルサーバーを持ちたかったので覚書程度に。
利用目的が「root権限で好きに弄れる、外部から参照できるサーバーを持ちたい！」だったので、Herokuなんかだと物足りないし
自宅サーバーは怖い。でもレンタルサーバーは邪魔。
なんかあるかなと思って調べてると、安いVPSもあるみたいなのでそのまま契約しました。

参考:[ノートPCをサーバーにして大惨事になった話](http://www.hotel-raj.si/hr)

こういうのは機能面と契約・解約出来るかだけ見てその場の勢いで決めることが多いので、各社の吟味はしてないです。
ただ、契約以外の手番としては大体自分でセットアップするからやることは一緒だと思います。

# 契約

まずは決めたサイトで契約します。今回はこちらからお申込みを選択。
https://dream.jp/vps/

私はお試しなのでEnrtyプラン(467円/月)を選択。
プラン選択時にOSや初期インストールソフトも選べます。特にほしい物が無かったのでシンプルセットを選択しました。
この辺はUIの指示通りに進めればいいので割愛

クレジット決済後、色々調べてるうちに気付いたら開設出来ました！
飛んでくるメールに書いてあるMyDTIってのから見れば、解説状況等が見えます。
稼働中になっていればサーバーに触れる状態になっています。

<img width="342" alt="memo.png" src="https://qiita-image-store.s3.amazonaws.com/0/252277/50c170c2-369d-973e-038c-5ab84bc97e0b.png">

[teraterm](https://forest.watch.impress.co.jp/library/software/utf8teraterm/)等をインストールし、メールで届いたIPアドレス+ポートに対してsshアクセスしてログイン出来れば準備OKです！
以降の作業は基本sshログインした状態で行います。

# 初期セットアップ

最初にやりたいことは以下です。これはどんなLinux OSをインストールしても変わらないと思います。

1. パッケージのアップデート
2. sshアクセスを厳しくする
3. ファイヤーウォール設定によるセキュリティ対策
4. やった手番のスクリプト化、github公開

その後は利用したい機能に合わせてパッケージインストールですかね。

**注意: ネットワーク関連のパッケージを弄るとサーバーとの通信に支障が出るので、触れてはいけない！**

## 0. 忙しい人向け: スクリプト公開

以下に初期セットアップでやることをまとめてあります。

https://github.com/developer-kikikaikai/vps_initial_setup

gitを使う為にはパッケージインストールの外にcurlのアップデートも必要です。

```
yum -y install git
yum -y update  nss curl libcurl
```

参考: [git fatal: unable to access Peer reports incompatible or unsupported protocol version.](https://qiita.com/nakazii-co-jp/items/04602647c42cf8e7fb78)

## 1. パッケージのアップデート

### yum updateには--skip-brokenを付ける

基本は以下コマンドで出来ます。今回はCentOSなのでyumですが、Debian/Ubuntuならapt or apt-getに変えればOK！

```console
$ yum update
```

…と思ったらエラーが発生。

```
--> Finished Dependency Resolution
Error: systemd conflicts with initscripts-9.49.17-1.el7_0.1.x86_64
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
```

initscriptsはアップデートするとインターフェイスが正常に起動できなくなるのでupdate対象外。
その影響でsystemdもupdate出来ないという感じです。
(IFの設定周りも起動時にinitscriptsでやっているので、initscriptsアップデート非サポートもしょうがなさそう)
またsystemdのupdateが他のパッケージにもかなり影響しているので、素直にyumのメッセージに従い`--skip-broken`を付けるのがベターですね。

```console
$ yum --skip-broken update
```

参考:
[yum updateでエラー「Error: systemd conflicts with initscripts」](https://ex1.m-yabe.com/archives/1612)
[CentOS7 yum update 後、VPSサーバーにアクセスができなくなった](https://www-wp.dream.jp/search.php/?p=23141)

### IPアドレスやルーティングに関わる設定は弄っちゃダメ！絶対！

ちなみに先ほどの参考記事で分かりましたが、**NetworkManagerをインストールしてしまうと、初期化以外復旧方法はないそうです！**
…まあIP制御を自前でやっているのは明らかなので、NetworkManagerが動いちゃうと想定したネットワーク構成にならないですよね。
同じ理屈でIPアドレスやルーティングに関わる設定は弄っちゃダメ！絶対！

とはいいつつ失敗したら初期化出来るので、最初のうちは怖がらす色々触って試してみましょう！
[初期化方法](https://dream.jp/vps/support/manual/mnl_basic_02.html)

## 2. sshアクセスを厳しくする

デフォルトだと適当なポートに短いパスワードでアクセスできる状態。ユーザー名rootは固定。
どうぞログインしてください！と言わんばかりなので強固な設定に変えます。

1. ssh公開鍵認証を設定し、ログイン出来ることを確認
2. sshパスワード認証を無効化
3. 一般ユーザーを作成し、sshログインを確認
4. sshアクセスをrootログイン禁止にする

変更の際、**無効化手番を実施する際は、実施前に別の手段が使えることを確認する**ようにしてください。
VPSは実機が手元に無いのでアクセスできなくなります。

### 1. ssh公開鍵認証を設定し、ログイン出来ることを確認

#### ssh鍵を作成する

よくあるssh-keygenを使ってもいいんですが、デフォルトの鍵長が脆弱になってきているのでいいアルゴリズムを選びます。
2019/1/25現在、ssh-keygenで使えるアルゴリズムで一番いいのはed25519ですね。参考で書かれているように意識高くいきましょう。
参考:[2017年版 SSH公開鍵認証で使用する秘密鍵ペアの作り方](https://qiita.com/wnoguchi/items/a72a042bb8159c35d056)
…と思ったのですが、私の契約したサーバーのopensshはed25519非サポートらしい(マジか…)。ecdsaがあるのでECDSA 521bitでいきましょう。

サーバーでも実行出来ますが、秘密鍵をサーバーからダウンロードしないといけないのはあれなので**ローカルPCで作成**したいです。必要なのはssh-keygen。
Linuxなら大抵入っていますし、WindowsでもGitをインストールしてあげれば使えます([WindowsでSSHの鍵を作る
](https://qiita.com/digdagdag/items/9e5c061e7d86e0af9a57))。パスワードはよしなに設定してください。

```console
$ ssh-keygen -t ecdsa -b 521 -f vps_ssh.pem
...略
$  ls vps_ssh.pem*
vps_ssh.pem  vps_ssh.pem.pub
```

#### 作成した鍵の公開鍵をサーバー側に登録する

`vps_ssh.pem.pub`とついている方をサーバーに登録します。
公開鍵を.ssh/authorized_keys(/etc/ssh/sshd_configのAuthorizedKeysFileに記載されているファイルパス)に書き込めばOK

```shell:initialize.sh
mkdir -p .ssh
cat initialize.sh >> .ssh/authorized_keys
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
```

#### sshdの設定を変更し、公開鍵認証を有効化する。

後はsshd_configの設定を変更して再起動すればOKです。

```conf:/etc/ssh/sshd_config
...
HostKey /etc/ssh/ssh_host_ecdsa_key #ここの先頭に記載されている#を削除する。
...
PasswordAuthentication yes #no=>yesへ
```

CentOSならsystemctlで再起動。うまく起動できたかはstatusで確認します。

```console
$ systemctl restart sshd
$ systemctl status sshd
./initialize.sh vps_ssh.pem.pub
=== Update authorized keys in /root/.ssh ===
...
sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
   Active: active (running) since Sat 2019-01-26 02:00:46 JST; 87ms ago
  Process: 1728 ExecStartPre=/usr/sbin/sshd-keygen (code=exited, status=0/SUCCESS)
```

設定をミスっていると泣きを見るので、statusの確認及び接続確認はしましょう。
sshログイン時は、作成した鍵の秘密鍵側を利用すれば公開鍵認証での接続が出来ます。

### 2. sshパスワード認証を無効化

sshdの設定を一行変えるだけです。設定を変えたら忘れずに`systemctl restart sshd`。

```conf:/etc/ssh/sshd_config
PasswordAuthentication no #yes=>noへ
```

### 3. 一般ユーザーを作成し、sshログインを確認

新規ユーザー作成。`passwd root`でrootユーザーパスワードも変えときましょう。

```console:
$ useradd developer
$ passwd developer
Changing password for user developer.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
```

ユーザーが出来たらユーザーを変更して再度公開鍵を登録しましょう。やり方はrootの時と同じ。

後はrootと一般ユーザーの行き来が出来ることを確認しときましょう。

```console:
# su developer #developerユーザーに変更
$ su # rootに変更
```

### 4. sshアクセスをrootログイン禁止にする

```conf:/etc/ssh/sshd_config
PermitRootLogin no # PermitRootLoginを有効化して、noに変える
```

参考:[rootログインを禁止する - さくらのVPSを使ってみた](http://doc.mas3.net/sakuravps/disablerootlogin.html)

## 3. ファイヤーウォール設定によるセキュリティ対策

iptablesやfirewalldの設定により、外部からアクセスできるポート等を制限しましょう。**※sshポートを塞がないよう注意です！**
せっかくなのでfirewalldを！と思ったら入っていなかったのでiptablesの設定をします。

ただ、iptablesのルールを追加しすぎるとメモリ不足になります。国のIPアドレスではじく設定を[こちら](https://qiita.com/developer-kikikaikai/items/655a88009cfa6cc15469)で紹介しましたが、メモリがとてもじゃないけど足りないのでまるっと消しました。
最低限のポートだけ空けてるくらいなら大丈夫でしょ！

また、間違ったルールをとりあえず全リセットしようと`iptables -F`なんてしてしまうと大事なルーティングまで消えることがあるようです(一敗)
その場合は慌てず初期化しましょう。

# 必要アプリのインストール

お好きなアプリをインストールしましょう。mysqlのインストールでちょっとハマったので追記しておきます。

## mysql

CentOSだとMariaDB-serverというのを使うそうです。

[CentOS7にyumでMariaDB最新版インストール](https://qiita.com/ys-0-sy/items/f7e316f8dd84a386e82e)のように、リポジトリを持ってくればいいのね。と思いきや最新versionはDTI ServersManでは動きませんでした。またしてもinitscriptsでエラー。

```console
--> Finished Dependency Resolution
Error: systemd conflicts with initscripts-9.49.17-1.el7_0.1.x86_64
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
```

手段としては余計なリポジトリを無効にします。(最新版のリポジトリをインストールしてはいけなかったのか(-_-;))

```console
$ yum --disablerepo=mariadb-main install mariadb-server
```

参考:[mariadb 5.5 のインストールがしたいが、10.3 になってしまう](https://teratail.com/questions/152768)

後は有効化して好きな設定をしてください。

```console
$ systemctl enable mariadb
$ systemctl start mariadb
$ mysql_secure_installation
#対話式になるので好きに入力。最初のrootパスワード問いかけは何もなしで入力⇒パスワード登録の流れになります。
```

そしたらrootログインしてユーザー作成します。

```
create user your_account@localhost identified by "your_passphrase";
```

# その他やりたいこと

例えば以下とかがすぐわかるように仕込みたい。
外部アクセスの口を空けるなら、状態把握の方法くらいはやれたら楽しいですよね、きっと。

- 通信状況の監視
- SSH等の管理者ログイン監視
- etc

多分参考にします。[10年モノのインフラを3年がかりでカイゼンした](https://qiita.com/sasasin/items/30585a3a117d64973645)