SSH接続について調べたのでメモ


## SSHとは
[SSHとは？仕組みとSSHサーバーの設定をわかりやすく解説します！ | カゴヤのサーバー研究室](https://www.kagoya.jp/howto/rentalserver/ssh/)
[初心者がSSHについて学ぶ(´･ω･`) - Qiita](https://qiita.com/Shobon/items/70cc74cd20c8b5b4fe15)
[SSHとは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11722.html)
https://e-words.jp/w/ssh.html
[TCP/IP - Telnetとは、SSHとは](https://www.infraexpert.com/study/tcpip19.html)

- 「Secure Shell（セキュア・シェル）」の略
- telnet の通信が暗号化できるようになったもの
- telnet
	- 他のコンピュータを遠隔操作するための仕組み
	- こちらは通信が暗号化されていない。非推奨。
- SSHには、SSH1 と SSH2 の2種類の通信手段（プロトコル）がある
	- SSH1は非推奨
		- [0035:ssh1とssh2の使い分け](http://mkserver.dip.jp/vinelinux/perform/ssh/0035.html)
	- 使われているのはほとんどSSH2
- サーバー側で「SSHデーモン」、クライアント側で「SSHクライアント」が起動されている必要がある。
	- sshd (ssh daemon)
		- UNIXのOSで外部からのssh接続を受け付ける常駐プログラム
		- 通信経路の暗号化や利用者の認証、操作コマンドの受信と実行などを行なう
		
	- sshクライアント
		- [PuTTY - Wikipedia](https://ja.wikipedia.org/wiki/PuTTY)
		- [Tera Term - Wikipedia](https://ja.wikipedia.org/wiki/Tera_Term)
		- https://ja.wikipedia.org/wiki/OpenSSH
		- windows
			- Windows 10 からは標準で利用できるらしい
		- Mac
			- 標準のターミナルで接続できる
- 「パスワード認証方式」と「公開鍵認証方式」の2通りがある
	- パスワード認証方式
		- 接続先のサーバーで作成した、ユーザー名とパスワードを利用する
		- パスワードが流出したら誰でも接続できてしまう
	- 公開鍵認証方式
		- ローカルで作成した、公開鍵と秘密鍵を利用する
		- 公開鍵を接続先のサーバーに登録する
		- 対応する秘密鍵を持っているクライアントだけが接続できる


## ssh/.config とは
[~/.ssh/configについて - Qiita](https://qiita.com/passol78/items/2ad123e39efeb1a5286b)
[.ssh/configファイルでSSH接続を管理する - Qiita](https://qiita.com/0084ken/items/2e4e9ae44ec5e01328f1)
- sshの設定ファイル
- ssh/.configに設定を記載しておくと長いコマンドをいちいち打たなくてもいい

## gitHubにアクセスするときにも使ったりする
[Mac GitHub SSH接続設定 - Qiita](https://qiita.com/ucan-lab/items/e02f2d3a35f266631f24#_reference-7cbea668d512073f0df4)


## DokcerでたてたサーバーにSSHで接続してみる
[Docker | 公開鍵でコンテナにssh接続する出来るようにするDockerfileの例 - Qiita](https://qiita.com/YumaInaura/items/7509061e4b27e03ea538)
この記事を参考にさせてもらってローカルでsshを試してみた
とりあえずコピペで接続できたので、内容を詳しく見てみる

### Dockerfileを読んでみる

```
FROM ubuntu:16.04

# 1
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd

# 2
# ssh設定ファイルの書換え
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# 3
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

# 4
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

# 5
# 手元の公開鍵をコピー
COPY id_rsa.pub /root/authorized_keys

# 6
# ssh用の port を晒す
EXPOSE 22

# 7
# 公開鍵を使えるようにする (パーミッション変更など)
CMD mkdir ~/.ssh && \
    mv ~/authorized_keys ~/.ssh/authorized_keys && \
    chmod 0600 ~/.ssh/authorized_keys &&  \
    # 最後に ssh を起動
    /usr/sbin/sshd -D
```


- \#1 
	- openssh-serverをインストールしている
		- これがSSHデーモンってことでいいのか？
	- `RUN mkdir /var/run/sshd` 
	これがないとエラーになる。必要なディレクトリってことはわかったけど、なんで必要なのかはわからなかった。

```
docker run  -p 10000:22 ssh_server
Missing privilege separation directory: /var/run/sshd
```


- \#2
	- RUN
		- [Dockerfile リファレンス — Docker-docs-ja 19.03 ドキュメント](https://docs.docker.jp/engine/reference/builder.html#run)
		- > RUN 命令は、現在のイメージの最上位の最新レイヤーにおいて、あらゆるコマンドを実行します。
	- `sed -i` を実行してる
		- [【 sed 】コマンド（基礎編その4）――文字列を置き換える／置換した行を出力する：Linux基本コマンドTips（56） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1610/17/news015.html)
		- `sed -i`は特定のファイルを編集する
			- [【 sed 】コマンド（応用編）――正規表現を使って文字を置き換える：Linux基本コマンドTips（57） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1610/18/news008.html)
			- > 　文字列の置き換えは、「s/置換前/置換後/」で行います。例えば、「s/jpg/jpeg/」で「jpg」を「jpeg」に置き換えることができます。
			- つまり
				- `/etc/ssh/sshd_config`ファイルに`PermitRootLogin prohibit-password`を`PermitRootLogin yes`
				- `/etc/ssh/sshd_config`ファイルに`#PasswordAuthentication yes`を`PasswordAuthentication no`に変更している
			- `/etc/ssh/sshd_config`
				-  [基礎から学ぶ！最初にやるべきSSHのセキュリティ設定【全コマンド例付き】 – Hacker’s High](https://hackers-high.com/linux/ssh-config-for-beginners/)
					- sshのサーバー側の設定ファイル
			- `PermitRootLogin prohibit-password`
				- ルートユーザーとしてパスワードでログインすることのみを無効化している
			- `PermitRootLogin yes`
				- ルートユーザーでログインすることを許可する
				- `PermitRootLogin prohibit-password`のままでも別によかったのか？？
					- 試してみたら`PermitRootLogin prohibit-password`のままでもいけた
			- `PermitRootLogin yes`
				- sshでrootによるログインを許可している
				- これがnoに設定されてるとssh接続用のユーザーを作成したりしないといけないのか
			- `PasswordAuthentication no`
				- パスワード認証によるsshアクセスを禁止している
- \#3
	- `/etc/pam.d/sshd` 
		- [openSUSE 13.1: 第2章 PAM を利用した認証](https://manual.geeko.jp/ja/cha.pam.html)
		- [PAM設定ファイルの意味と書き方メモ - Qiita](https://qiita.com/satken2/items/9a0604e1d4a78217897c)
			- PAM
				- ユーザー認証を行うための仕組み
			- > PAM の仕組みを使用するそれぞれのサービス (プログラム) に対して、 /etc/pam.d/ ディレクトリ内に別々の設定ファイルを 用意して使用します。たとえば sshd サービスに対する設定は、 /etc/pam.d/sshd ファイルで設定します。
	- [Docker: Set pam_loginuid to optional (#3027) · Issues · GitLab.org / GitLab FOSS · GitLab](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/3027)
		- `s@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g`これは何をしているんだろう
			

[SSH デーモン用サービスの Docker 化 — Docker-docs-ja 19.03 ドキュメント](http://docs.docker.jp/engine/examples/running_ssh_service.html)
[Dockerとは -Dockerの基本的な使い方- - ネットワークエンジニアを目指して](https://www.itbook.info/network/docker01.html)

- \#4
	- [Dockerfile リファレンス — Docker-docs-ja 19.03 ドキュメント](https://docs.docker.jp/engine/reference/builder.html#env)
	- NOTVISIBLEに"in users profile"`という値を設定している
		- [bash - Why set VISIBLE=NOW in /etc/profile? - Stack Overflow](https://stackoverflow.com/questions/36292317/why-set-visible-now-in-etc-profile)
		- [Unexplained elements in eg_sshd Dockerfile · Issue #9424 · docker/docker.github.io · GitHub](https://github.com/docker/docker.github.io/issues/9424)
		- ここもよくわからん


- \#5
	- これは公開鍵を接続するサーバーへコピーしているだけ
- \#6
	- [Dockerfile リファレンス — Docker-docs-ja 19.03 ドキュメント](https://docs.docker.jp/engine/reference/builder.html#expose)
- \#7
	- CMD
		- https://docs.docker.jp/engine/reference/builder.html#cmd
		- > シェル形式または exec 形式を用いる場合、CMD 命令は、イメージが起動されたときに実行するコマンドを指定します。
		- イメージが起動した時の処理を書いてるんだな
	- `mkdir ~/.ssh`
		- sshディレクトリを作成している
	- `mv ~/authorized_keys ~/.ssh/authorized_keys`
		- ローカルからコピーしてきた公開鍵を`~/.ssh/authorized_keys`に設置
	- `~/.ssh/authorized_keys`
		- [12.2.4. 鍵ベース認証の使用 Red Hat Enterprise Linux 6 | Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/s2-ssh-configuration-keypairs)
		- [公開鍵暗号を用いてのSSH接続（きほん） - Qiita](https://qiita.com/mukoya/items/f20def019e25dc162ca8#%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%A8%E7%A7%98%E5%AF%86%E9%8D%B5%E3%81%AE%E7%94%9F%E6%88%90)
		- サーバー側の公開鍵の置き場所が決まってるってことなのかな
	- `chmod 0600 ~/.ssh/authorized_keys`
		- `~/.ssh/authorized_keys`のパーミッションは`0600`にする必要があるらしい
		- [authorized_keysのパーミッション - アオミドロ草](http://bluingreen.hatenablog.com/entry/2017/03/22/221052)
	- `/usr/sbin/sshd -D`
		- SSHデーモンを動かしてるのか
		- [sshd(8) manページ](https://nxmnpg.lemoda.net/ja/8/sshd)
		- >  -D このオプションが指定されると sshd は切り離し (detach) をおこなわず、デーモンにはなりません。 これは sshd の監視を簡単にします。
		- -D の説明はよくわからなかった

### コマンドの意味を調べる

- `$ ssh-keygen -f ./id_rsa -t rsa -b 4096 -C ‘example@com’ -N ‘’`
	- [【 ssh-keygen 】コマンド――SSHの公開鍵と秘密鍵を作成する：Linux基本コマンドTips（327） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1908/02/news015.html)
	- `$ ssh-keygen -f ./id_rsa`
		- カレントディレクトリに`id_rsa`というファイル名で秘密鍵を作成`id_rsa.pub`という名前で公開鍵も作成される
	- `-t rsa`
		- 暗号化形式を指定rsa方式で作成している（デフォルトもrsa）
		- http://it-knowledge.tank.jp/ed25519-github/
		- [SSH は (RSA 鍵より) ED25519 鍵の方が強固で速い - らくがきちょう](https://sig9.hatenablog.com/entry/2020/01/11/000000)
		- `ed25519`で作るのが良さそう
	- `-b 4096`
		- 作成する鍵のビット数を指定
		- 4096bitで作るのが良さそう
	- `-C ‘example@com’`
		- コメント
	- ` -N ""`
		- パスフレーズを指定
		- 秘密鍵をパスフレーズで暗号化できるらしい
			- [SSH秘密鍵のパスフレーズは（つけるなら）11文字以上にしましょうねという話 - 本当は怖いHPC](https://freak-da.hatenablog.com/entry/20100901/p1)
			- [SSH - 秘密鍵をパスフレーズで暗号化する理由｜teratail](https://teratail.com/questions/76995)
			- [パスフレーズ暗号化／暗号鍵管理に関する私的メモ  |  HAJ WEBLOG](https://haj.tokyo/20190104022337755)


- `docker image build . -t ssh_server`
	- [build — Docker-docs-ja 19.03 ドキュメント](https://docs.docker.jp/engine/reference/commandline/build.html)
	- [Dockerfileとdocker buildコマンドでDockerイメージの作成：いまさら聞けないDocker入門（3）（1/2 ページ） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1407/08/news031.html)

	- `.` Dockerfileのあるディレクトリ
	- `-t ssh_server` イメージに名前をつける

- `docker run -d -p 10000:22 ssh_server`
	- [run — Docker-docs-ja 19.03 ドキュメント](https://docs.docker.jp/engine/reference/commandline/run.html)
	- `-d` コンテナをバックグラウンドで実行
	- `-p` コンテナのポートをホスト側に公開

- `ssh root@127.0.0.1 -p 10000 -I id_rsa`
	- [【 ssh 】コマンド――リモートマシンにログインしてコマンドを実行する：Linux基本コマンドTips（80） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1701/26/news015.html)
	- rootユーザーで`127.0.0.1`（ローカルホスト）に接続
	- `-p 10000`接続に使用するポート番号を指定、コンテナ側のポート22番がローカルの10000に公開されているので接続できる