お名前.com VPS (KVM) に最新の CentOS をインストールする

## お名前.com VPS (KVM)

### 国内の主な VPS サービス
- [お名前.com VPS(KVM)](https://www.onamae.com/server/vps/)
- [GMOクラウド VPS](https://vps.gmocloud.com/)
- [さくらのVPS](https://vps.sakura.ad.jp/)
- [WebARENA VPSクラウド](https://web.arena.ne.jp/vps-cloud/)
- [ConoHa](https://www.conoha.jp/)
- [KAGOYA CLOUD／2](https://www.kagoya.jp/cloud/vps/)
- [使えるねっと クラウドVPS](https://www.tsukaeru.net/cloud-vps)

なお、DTI の ServersMan@VPS は Web でコンソール接続できない、強制アップデートすると接続できなくなる、などの問題が生じるのでオススメできない。

### プランと月額費用
メモリ 2GB の場合、初期費用0円で年払いだと月あたり1,187円とコスパがよい。
使用経験はないが [KAGOYA CLOUD／2 (KVM)](https://www.kagoya.jp/cloud/vps/price/) も SSD 50GB で月額1,080円と安い。

https://www.onamae.com/server/vps/price/

| プラン | 1GB | 2GB | 4GB | 8GB | 16GB |
|:-:|:-:|:-:|:-:|:-:|:-:|
| 容量 | 100GB | 200GB | 400GB | 800GB | 1TB |
| CPU | 2コア | 3コア | 4コア | 6コア | 10コア |
| 初期費用 | ¥0   | ¥0     | ¥5,843 | ¥9,958 | ¥17,157 |
| 1ヶ月払い | ¥968 | ¥1,420 | ¥3,992 | ¥8,105 | ¥16,334 |
| 6ヶ月払い | ¥911 | ¥1,293 | ¥3,635 | ¥7,381 | ¥14,874 |
| 1年払い  | ¥857 | ¥1,187 | ¥3,336 | ¥6,774 | ¥13,650 |


## 最新の CentOS のインストール
お名前.com VPS (KVM) の標準 OS は CentOS 6.5 となっており、OS 再インストールは必須。
用意されている最新の CentOS は 7.1 (1503) となっており、これをアップデートするか、最新の ISO からインストールすることになる。
ここでは最新の ISO からインストールする手順を紹介する。

### ISO ファイルのダウンロード
CentOS 7.5 の最新の ISO ファイルをダウンロードする。
執筆時点では、[通常のダウンロードページ](https://www.centos.org/download/)からだと 2018-05-04 06:07 更新の [CentOS-7-x86_64-Minimal-1804.iso](http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1804.iso) (906MB) がダウンロードされる。
最近アップデートがおかしくなっている[ローリング版](https://buildlogs.centos.org/rolling/7/isos/x86_64/)では 2018-06-04 14:52 更新の [CentOS-7-x86_64-Minimal-1805-01.iso](https://buildlogs.centos.org/rolling/7/isos/x86_64/CentOS-7-x86_64-Minimal-1805-01.iso) (849MB) がダウンロードできる。なぜか CentOS-7-x86_64-Minimal-1804.iso は配置されていない。

### ISO ファイルのアップロード

#### アップロード先接続情報の確認
コントロールパネル左サイドメニューのサーバーリスト下にある当該VPSを選択しコンソール画面に遷移。画面右下に接続情報が出力されている。

![onamae_console.png](https://qiita-image-store.s3.amazonaws.com/0/15175/5a669f62-ed5f-211a-b5c5-0772a1b6af4c.png)

「接続先」と「ユーザー名」、および「SSH Key」からダウンロードできる「SSH Private Key」を利用する。

#### FileZilla でアップロード
[ISOイメージアップロード方法 (FileZilla) | OS情報 | VPS（KVM） 活用ガイド](http://guide.onamae-server.com/vpskvm/1_12_13_74/)
[ISOイメージアップロード方法 (Cyberduck) | OS情報 | VPS（KVM） 活用ガイド](http://guide.onamae-server.com/vpskvm/1_12_18_94/)

ここでは FileZilla でのアップロードを説明する。
「ホスト (H):」に「接続先」を、「プロトコル(T)」は「SFTP - SSH File Transfer Protocol」を、「ログオンの種類(L):」は「鍵ファイル」を、「ユーザ(U):」は「ユーザー名」を、「鍵ファイル:」は「SSH Private Key」をそれぞれ入力・選択する。

<img width="486" alt="FileZilla" src="https://qiita-image-store.s3.amazonaws.com/0/15175/0afd36bf-d0f3-fba1-5861-437d53c00924.png">

うまく接続できたら `/images` 配下に先ほどダウンロードした `CentOS-7-x86_64-Minimal-XXXX.iso` をアップロードする。

未検証だが SSH 接続により `scp` コマンドでも転送できると思われる。

### OS 再インストール
[OS再インストール（アップロード済みISO） | コントロールパネルログイン | VPS（KVM） 活用ガイド](http://guide.onamae-server.com/vpskvm/2_2_2_55_5/)

![onamae_reinstall.png](https://qiita-image-store.s3.amazonaws.com/0/15175/7dae9a2b-266c-f374-1e08-0c70fba80081.png)
アップロードした ISO は「OS」欄のプルダウンの最下部に追加されている。
「ディスク構成」はここでは「カスタム」ですべて使用する。

完了画面まで遷移したら「起動」をクリックして VPS を起動し、コンソールからインストールを開始する。
![onamae_start.png](https://qiita-image-store.s3.amazonaws.com/0/15175/c39d26a4-fa06-cded-ba02-e582f6751812.png)

### CentOS のインストール
テキストカーソルで「Install CentOS 7」を選択する。

この記事では「日本語」を選択。 English でも特に問題はない。

「ネットワークとホスト名(N)」で「設定(O)」ボタンを押下し、「全般」タブの「この接続が利用可能になったときは自動的に接続する(A)」をチェックする。

「ROOT パスワード(R)」で root アカウントのパスワードをインストール中に設定しておく。

インストール完了後、再起動前に「取り出す」ボタンを押下して ISO イメージをアンマウントする。

## CentOS 7.5 初期設定
「[CentOS 7 の初期設定でやっておくべきこと - Qiita](https://qiita.com/bezeklik/items/0622fbaf7d33dd95d005)」をベースに初期設定を行う。

### 先行設定

#### LC_ALL の指定
```bash
echo 'LC_ALL="ja_JP.utf-8"' >> /etc/environment
```
ssh でログインした際に `-bash: 警告: setlocale: LC_CTYPE: ロケールを変更できません (UTF-8): そのようなファイルやディレクトリはありません` という警告が表示されてマルチバイトが表示できなくなるので `LC_ALL` を指定する。

#### etckeeper による /etc 配下のバージョン管理
```bash
yum --assumeyes install epel-release git && \
yum --assumeyes install etckeeper && \
etckeeper init && \
etckeeper commit ':hatching_chick: Initial commit'
```
必要に応じて、サーバーの設定ファイルの差分を保持するために etckeeper をインストールする。

#### history の設定
```bash
cat << '_EOF_' > /etc/profile.d/history.sh && \
source /etc/profile.d/history.sh
# history initialization
HISTTIMEFORMAT='%F %T '
HISTSIZE=100000
HISTFILESIZE=100000
HISTIGNORE=
HISTCONTROL=ignoreboth
PROMPT_COMMAND='history -a; history -c; history -r'
shopt -u histappend
_EOF_
```
```bash
etckeeper commit ":new: Add a history setting shell script"
```
デフォルトではコマンド履歴に日時が残らないので設定を変更する。

### セキュリティ向上設定

#### 管理ユーザーの追加
```bash
useradd joe && \
passwd $_ && \
usermod -G wheel $_ && \
getent group wheel
```
ここでは `joe` というユーザーを作成し、パスワードを設定した後、管理ユーザーとして `wheel` グループに所属させる。

#### 公開鍵の生成 (ローカル PC)
```bash
SERVER=example.com && USER=joe && \
ssh-keygen -t ed25519 -C "joe@example.net $(date +'%Y-%M-%dT%T%z')" -f ~/.ssh/id_ed25519_${SERVER} && \
ls -t ${HOME}/.ssh/id*.pub && \
ssh-add ~/.ssh/id_ed25519_${SERVER} && \
ssh-add -l && \
ssh-copy-id -o PreferredAuthentications=password -i ~/.ssh/id_ed25519_${SERVER} ${USER}@${SERVER} && \
cat << _EOF_ >> ~/.ssh/config && \
ssh ${SERVER}

Host ${SERVER}
  HostName       ${SERVER}
  User           ${USER}
  IdentitiesOnly yes
  IdentityFile   ~/.ssh/id_ed25519_${SERVER}
_EOF_
```
```bash
su -
```
`Too many authentication failures` のエラーが出る場合は `-o PreferredAuthentications=password` オプションを付ける。

#### ssh のポート番号の変更
`10022` や `22022` などは IANA によって割り当てられている User Ports (Registered Ports) [^user_ports] である 1024〜49151 の範囲内であることと `nmap-services` [^nmap-services] に登録されていることから特に使用は避け、Dynamic Ports (Private or Ephemeral Ports) [^dynamic_ports] である 49152〜65535 の範囲内から指定する。

[^nmap-services]: https://github.com/nmap/nmap/blob/master/nmap-services
[^user_ports]: ["the User Ports, also known as the Registered Ports, from 1024-49151 (assigned by IANA)" - 6.  Port Number Ranges - RFC 6335](https://tools.ietf.org/html/rfc6335#page-11)
[^dynamic_ports]: ["the Dynamic Ports, also known as the Private or Ephemeral Ports, from 49152-65535 (never assigned)" - 6.  Port Number Ranges - RFC 6335](https://tools.ietf.org/html/rfc6335#page-11)

##### ポート番号の追加
```bash
cp -av /{usr/lib,etc}/firewalld/services/ssh.xml && \
sed -i '/22/a \  <port protocol="tcp" port="50022"/>' /etc/firewalld/services/ssh.xml && \
firewall-cmd --reload && \
sed -i -e '/#Port 22/ s/#//' -e '/Port 22/a Port 50022' /etc/ssh/sshd_config && \
systemctl reload sshd
```
`/usr/lib/firewalld/services/` 配下の XML ファイルを直接書き換えると sshd のアップデートなどで上書き更新されて突然接続できなくなるので絶対に避ける。

`/etc/firewalld/services/` 配下に同名のファイルを配置して設定を上書きする。

##### 追加ポートでの接続確認 (ローカル PC)
```bash
ssh -p 50022 example.com
```
ローカル PC から追加したポート番号での接続を確認。

##### ポート番号の削除
```bash
sed -i '/Port 22/d' /etc/ssh/sshd_config && \
systemctl reload sshd && \
sed -i '/"22"/d' /etc/firewalld/services/ssh.xml && \
firewall-cmd --reload
```
```bash
etckeeper commit ':lock: Change the default SSH port'
```

#### アップデート
```bash
yum --assumeyes remove NetworkManager-{team,tui,wifi} {aic94xx,ivtv,iwl*}-firmware alsa-* teamd wpa_supplicant && \
yum --assumeyes update
```
```
reboot
```
優先度の高いセキュリティ向上設定が完了した後に時間のかかるアップデートを行う。

### セキュリティ向上設定 (Lynis)

#### Postfix の情報漏洩対策
```bash
sed -i.org "s/#smtpd_banner = \$myhostname ESMTP \$mail_name$/smtpd_banner = \$myhostname ESMTP/" /etc/postfix/main.cf
```

[MAIL-8818](https://cisofy.com/controls/MAIL-8818/)

#### パスワードの変更不可期間と有効期限
```bash
sed -i 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t1/' /etc/login.defs
sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t7300/' /etc/login.defs
```
[AUTH-9286](https://cisofy.com/controls/AUTH-9286/)

#### デフォルトの umask 値の変更
```bash
sed -i "s/umask 002/umask 027/" /etc/profile
sed -i "s/umask 022/umask 027/" /etc/profile
```
[AUTH-9328](https://cisofy.com/controls/AUTH-9328/)

#### 未使用ドライバーの無効化
```bash
echo "blacklist usb-storage" > /etc/modprobe.d/blacklist-usbstorage.conf
echo "blacklist firewire_core" > /etc/modprobe.d/blacklist-firewire.conf
echo "blacklist firewire_ohci" >> /etc/modprobe.d/blacklist-firewire.conf
```
[STRG-1840](https://cisofy.com/controls/STRG-1840/) [STRG-1846](https://cisofy.com/controls/STRG-1846/)

#### 要求パッケージのインストールとサービス起動
```bash
yum --assumeyes install arpwatch epel-release psacct sysstat yum-utils && \
yum --assumeyes install rkhunter unhide && \
systemctl start arpwatch psacct && \
systemctl enable arpwatch psacct
```
[PKGS-7384](https://cisofy.com/controls/PKGS-7384/) [NETW-3032](https://cisofy.com/controls/NETW-3032/)

#### SSH のセキュリティ強化
```bash
sed -i /etc/ssh/sshd_config \
    -e 's/#AllowTcpForwarding yes/AllowTcpForwarding no/' \
    -e 's/#ClientAliveCountMax 3/ClientAliveCountMax 2/' \
    -e 's/#Compression delayed/Compression no/' \
    -e 's/#LogLevel INFO/LogLevel VERBOSE/' \
    -e 's/#MaxAuthTries 6/MaxAuthTries 2/' \
    -e 's/#MaxSessions 10/MaxSessions 2/' \
    -e 's/#PermitRootLogin yes/PermitRootLogin no/' \
    -e 's/#Port 22/Port 50022/' /etc/ssh/sshd_config \
    -e 's/#TCPKeepAlive yes/TCPKeepAlive no/' /etc/ssh/sshd_config \
    -e 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config \
    -e 's/X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config \
    -e 's/#AllowAgentForwarding yes/AllowAgentForwarding no/' && \
systemctl reload sshd
```

#### 法的メッセージの出力設定
```bash
(echo; echo "Unauthorized access to this machine is prohibited."; echo "Disconnect now if you are not an authorized user."; echo) >> /etc/issue
(echo; echo "Unauthorized access to this machine is prohibited."; echo "Disconnect now if you are not an authorized user."; echo) >> /etc/issue.net
```
[TipsAndTricks/BannerFiles - CentOS Wiki](https://wiki.centos.org/TipsAndTricks/BannerFiles)

#### sysctl の設定値の改善
```bash
cat << "_EOF_" >> /etc/sysctl.conf && \
sysctl -p
kernel.dmesg_restrict=1
kernel.kptr_restrict=2
kernel.sysrq=0
kernel.yama.ptrace_scope=1
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.all.log_martians=1
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.default.log_martians=1
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0
_EOF_
```

#### コンパイラのセキュリティの強化
```bash
chmod 700 /usr/bin/as
```

### セキュリティ向上設定 (OpenSCAP)

#### RPM によるファイルパーミッションの修正
```bash
rpm --setperms binutils
```

#### 空パスワードでのログインの禁止
```bash
sed -i 's/\<nullok\>//g' /etc/pam.d/system-auth && \
systemctl reload sshd
```
```bash
etckeeper commit ':lock: Disable login with null password'
```


### パフォーマンス向上設定

#### i-search（コマンド履歴検索モードの順検索）の有効化
```bash
echo '[ -t 0 ] && stty -ixon' > /etc/profile.d/stty.sh && \
source /etc/profile.d/stty.sh
```
```bash
etckeeper commit ":new: Add a disabling XON/XOFF flow control (enabling i-search) shell script"
```

#### bash 補完の強化
```bash
yum --assumeyes install bash-completion-extras
```

#### Yum プラグインの導入
```bash
yum --assumeyes install yum-{axelget,cron,plugin-{ps,rpm-warm-cache}} && \
echo "exclude=kernel* centos* openssh* httpd* php* mysql*" >> /etc/yum.conf && \
echo "alias yum='yum --disableexcludes=all'" >> /etc/profile.d/yum.sh && \
sed -i /etc/yum/yum-cron.conf \
    -e '/apply_updates / s/no/yes/' \
    -e '/skip_broken/ s/^# //' && \
systemctl start yum-cron && \
systemctl enable yum-cron
```

#### GSS-API 認証の無効化
```bash
sed -i '/GSSAPIAuthentication / s/^#//' /etc/ssh/sshd_config
systemctl reload sshd
```
```bash
etckeeper commit ':new: Disable the GSS-API Authentication'
```

#### パスワードなしでの sudo 実行の有効化
```bash
sed -i '/NOPASSWD/ s/^# //' /etc/sudoers
```
```bash
etckeeper commit ':unlock: Enable sudo execution without password'
```

#### パスワードなしでの su の有効化
```bash
sed -i '/trust use_uid/ s/^#//' /etc/pam.d/su
```

#### require a user to be in the "wheel" group
```bash
sed -i '/pam_wheel.so use_uid/ s/^#//' /etc/pam.d/su
```
```bash
etckeeper commit ':unlock: Enable su without password'
```

#### root および管理ユーザーのメール設定
```bash
sudo -u joe echo 'joe@example.com' > ~/.forward && \
sed -i /etc/aliases -e '/root:/ s/^#//' -e '/root:/ s/marc/joe/' && \
newaliases && \
echo "Test mail" | sendmail root
```
```bash
etckeeper commit ':email: Set a mail alias for root user'
```

#### 古いカーネルのパッケージ保持数の削減
```bash
sed -e '/installonly_limit/ s/5/2/' -i /etc/yum.conf
```

#### ホスト名の変更
```bash
hostname && \
hostnamectl set-hostname example.com && \
hostname
```

#### NTP サーバーの変更
```bash
sed -i 's/centos/jp/' /etc/chrony.conf && \
systemctl restart chronyd
```
```bash
etckeeper commit ':: Change the addresses of NTP servers to better ones'
```