サーバ初回起動時のsshとかポートの設定

VPS(KVM)などを借りた時、毎回ssh認証の設定を調べ直しているので備忘録です。
サーバ環境はCentOSではなくUbuntu 16.04.1 LTSです。


## 新規ユーザ作成

### サーバ側

sshで認証する時、rootでのログインをやめてユーザでログインできるようにします。
なのでまずはサーバに新規ユーザを作成します。

ubuntuの場合、`useradd`だとホームディレクトリが作成されないので`adduser`で作成します。

```
$ adduser myuser
```

パスワードを設定してください。
Full Name以下は全部空白でいいです（Enter連打）。

```
新しい UNIX パスワードを入力してください: 
新しい UNIX パスワードを再入力してください: 
passwd: password updated successfully
Changing the user information for myuser
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] y
```

sudoが使えるようにします。

```
$ gpasswd -a myuser sudo
Adding user myuser to group sudo
```


## 鍵の作成と認証

sshはパスワード認証じゃなくて秘密鍵認証にしたほうがセキュリティが向上するので準備します。

### クライアント側
まずクライアント側で鍵のペアを作成をします。
方式はいろいろあると思いますが、2018年現在`Ed25519`が推されていたのでこれで作ります。

```
$ ssh-keygen -t ed25519
Enter file in which to save the key (/home/user/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase): 
```

場所はデフォルトでよければそのままで。
パスフレーズは入れておきましょう。

以下のようなファイルが作成されます。

```
$ cd ~/.ssh
$ ls
id_ed25519  id_ed25519.pub  known_hosts
```

`scp`等の方法で公開鍵をサーバに転送します。
とりあえず場所はどこでもいいです。
公開鍵なのでgithubとかで共有してもいいかと思います。

```
$ scp ./id_ed25519.pub user@host:~/
```

### サーバ側

先程作ったユーザに切り替えてから作業します。
これから作るファイル等は所有者がユーザ（rootではだめ）になっていないとだめみたいです。
※ssh認証の時、エラーが出る。


```
$ su - myuser
```

ユーザのホーム以下に`.ssh`ディレクトリを作成します。
また先程転送した公開鍵も移動させます。

```
$ mkdir /home/[myuser]/.ssh
$ mv ~/id_ed25519.pub /home/[myuser]/.ssh/
```

`authorized_keys`を作成して情報を追記します。

```
$ cd .ssh
$ cat id_ed25519.pub >> authorized_keys
$ rm id_ed25519.pub 
```

パーミッションを設定します。
権限の範囲が広すぎるとエラーが出るので以下に制限します。

```
$ chmod 700 .ssh
$ chmod 600 authorized_keys
```

`sshd_config`を確認して以下の設定になっていることを確認します。

```
$ vim /etc/ssh/sshd_config
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      %h/.ssh/authorized_keys
```

変更した場合、サービスを再起動します。
※ubuntuは`sshd`じゃなくて`ssh`というサービス名なので注意。

```
sudo service ssh restart
```

クライアントからsshと鍵認証でアクセスできることを確認します。

```
ssh myuser@host -i id_ed25519
```

## rootでのログインを禁止

### サーバ側

このままだとrootでsshログインできてしまうので無効にします。
また鍵認証を使うのでパスワード認証も無効にしておきます。

```
$ sudo vim /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
```

再起動します。

```
sudo service ssh restart
```

### クライアント側

rootでssh認証ができないことを確認します。

```
ssh root@host
root@host: Permission denied (publickey).
```

## SSHのポートの設定

あんまりいらないかもしれませんが、念のため、sshのポートを22から変更します。
UFWで設定するのが楽とのことですが、大した量じゃないので`iptables`を直接操作します。

### サーバ側

以下root権限で作業します。

iptablesで任意のポートを開放します。
なお自由に使えるポート番号はVPSによって決まっている場合があります。
(例：http://blog.on-chan.jp/pg/kagoya-ssh/)

```
$ iptables -A INPUT -p tcp --dport 65535 -j ACCEPT
※--dportは送り先、--sportが送信元
```
ちゃんと設定されていることを確認します。

```
$ iptables -nvL --line-numbers
Chain INPUT (policy ACCEPT 6 packets, 364 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:65535
```

もし間違えた場合は`-D`オプションで削除できます。
上記のステータスの`Chain`部分と`num`を指定します。

```
iptables -D INPUT 1
```

問題なければ設定を反映します。
CentOSの場合、`iptables.rules`の場所が違うので注意してください。

```
$ iptables-save > /etc/iptables.rules
```

`sshd_config`のポートも書き換えます。
再起動も忘れないで行います。

```
$ vim /etc/ssh/sshd_config
#Port 22
Port 65535
$ service ssh restart
```

### クライアント側

sshで接続してみて`port 22`で繋がらないことを確認します。

```
$ ssh  myuser@xxx.xx.xx.xxx
ssh: connect to host xxx.xx.xx.xxx port 22: Connection refused
```

逆に設定したポート番号で接続できることを確認します。
なおちゃんと接続が確認出来るまで今繋いでいる接続はログアウトしないようにしましょう。
最悪ログインできなくなる可能性があります。

```
$ ssh  myuser@xxx.xx.xx.xxx -p 65535
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-34-generic x86_64)
```

## エイリアスの設定

必須ではないですが、`.ssh`以下に`config`ファイルを作っておくとssh認証での入力を省略できます。

```
$ vim ~/.ssh/config
Host servername
     HostName host
     Port port
     User hoge
     IdentityFile ~/.ssh/秘密鍵
```

パーミッションを設定して接続できることを確認します。

```
$ chmod 600 ~/.ssh/config
$ ssh servername
```

## 接続する端末を追加する時

基本的に同じ要領ですが、`sshd_config`とかは設定済みなので、

1. クライアント側でキーペアを作成
2. publicキーを何らかの方法でサーバ側に転送
3. `authorized_keys`に転記

をしてやればsshで接続できます。