コマンドオプション対応のsshdでDocker環境にsshで直接接続

# はじめに
みなさん。Linuxにログインする際に使用するShellは何を使っていますか？

ログイン時の Shell は "/etc/passwd" で設定しますが、"man 5 passwd" には「shell」や「コマンドインタプリタ」と説明されてます。ここの設定は実行可能なコマンドを書くことができるのですが、コマンドオプションを設定することができません。

例えば以下のような事がしたいのですが、実際に設定するとログインに失敗します。

```
cat /etc/passwd
user02:x:1001:1001:user02,,,:/home/user02:/usr/bin/docker run --rm -it ubuntu bash
```

最近は Deep Learning 環境での Docker の利用も増えていますが、セキュアでユーザ管理しやすい構成でDockerを使ったコンテナ環境を構築したかったので、"/etc/passwd" の Shell に複数のコマンドオプション設定が可能な OpenSSH を作ってみました。（OpenSSHのフォークになります）

https://github.com/KentaroAOKI/openssh-portable

![sshd.PNG](https://qiita-image-store.s3.amazonaws.com/0/32580/ea989824-488c-ec4a-5582-f3eae362993e.png)


# コマンドオプション対応のsshdのインストール
Ubuntu にインストールしてみます。ビルドやインストール方法は OpenSSH と全く変わりません。

## 準備
一般的な機能でのOpenSSHビルドには、libz、libsslのライブラリが必要になりますので、ビルドのためのツールと合わせて以下のようなパッケージをインストールします。

```
sudo apt-get install gcc autoconf automake libz-dev libssl-dev
```

### ビルドとインストール
昔はmakeと言っていましたが、今はビルドという機会が多くなりましたね。インストール環境を変えたい場合は、configure --helpしてください。

```
git clone https://github.com/KentaroAOKI/openssh-portable.git
cd ./openssh-portable
autoconf
autoheader
./configure
make
sudo make install
```

# 設定
まずは、sshd_configの設定です。上のインストール方法だと、sshd の設定ファイルは /usr/local/etc にあります。ssh接続するPort番号などを設定してください。

## sshdのコンフィグ
今回は既にインストールされているsshdを残したいので、Port番号は標準の22ではなく8022に設定します。

```
cat /usr/local/etc/sshd_config

#       $OpenBSD: sshd_config,v 1.102 2018/02/16 02:32:40 djm Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

Port 8022
```

## /etc/passwdの設定
そして、ログイン時に使用するShellの設定です。今回は、Docker上のUbuntuのBashを使ってみます。user01 は dockerホストにログイン（通常のログインと同じ）。user02はログイン時にdockerのUbuntuコンテナが作成されて接続します。また、user03は既に動いているmyubuntuコンテナ名にbashで接続します。

なお、dockerは、ターミナル(-it)とコマンド実行(-i)でコマンドオプションを変えないといけないため、runやexecの後にコマンドオプションを変えるための"{docker_tty}"を入れてください。

```
cat /etc/passwd

user01:x:1000:1000:user01,,,:/home/user01:/bin/bash
user02:x:1001:1001:user02,,,:/home/user02:/usr/bin/docker run --rm {docker_tty} ubuntu bash
user03:x:1002:1001:user03,,,:/home/user03:/usr/bin/docker exec {docker_tty} myubuntu bash
```

## /etc/groupの設定
ログイン時にDockerコマンドを実行するので、user02とuser03がdockerを使えるようにdockerのグループに設定しておきます。

```
cat /etc/group

docker:x:999:user02,user03
```

# 試してみる
sshdを起動した後、設定したPort 8022にsshしてみます。

## sshdを起動する
今回は簡単に起動してみますが、ちゃんとしたい場合は起動スクリプトを作ったほうがいいと思います。/etc/init.d/sshを参考に。

```
sudo /usr/local/sbin/sshd
```

## 別のPCからDockerコンテナに接続する
別のPCからsshで接続する例です。接続できない場合は、TCP Port 8022 の Linux のfirewall設定や、Azure とか AWS を使っていたらセキュリティグループの設定を確認しておいてください。

```
ssh -p 8022 user02@<docker host>
ssh -p 8022 user02@<docker host> hostname
```

## 別のPCからDockerコンテナにscpする
scpを使って、直接コンテナにファイルやディレクトリの送受信を行いたい場合は、scpを使うことができます。

```
scp -P 8022 testfile user02@<docker host>:./
```

scpは送信先にもscpが必要になりますので、コンテナ側にもscpのインストールが必要になります。dockerfileやssh接続してscpをインストールしておいてください。

```
apt-get install ssh-client
```


# さいごに
今回紹介したコマンドオプション対応のsshdはDocker以外にも使えます。

ただ、Dockerのように、標準入力やターミナルのコマンドオプションを持つ場合は、sshの接続方法によって動きを変えないといけないため、"{docker_tty}"のようなコマンドオプションを変更するプログラムの追加が必要になってきます。

もし、一般的で多くの利用者がいそうなコマンドであれば追加したいと思いますので、ご要望があればご連絡ください。