WindowsにOpenSSHサーバ/クライアントを導入しteratermでcmd/pwshのログを取得可能にする

# コマンドプロンプトやpowershellでもログ取得しながら作業したい
普段teraterm等でsshして作業する際、ログをとりながら作業することが多いです。
cmd/pwshは標準でログを取りながら作業ができなく不便です。
ログは作業後に手動でコンソールを全選択→テキスト等に保存する必要があります。
他のサーバと同じようにローカル環境でもteratermから操作・ログ取得ができるよう設定しました。

# 実現方式

OpenSSHを用いてローカル環境にSSHサーバ/クライアントを導入し、teratermからsshでlocalhostに
接続することで実現します。ssh接続はID/PASSはめんどくさいので鍵認証で接続します。
今回は管理者権限を使うことを想定し設定します。

端末環境は以下の通り。

プロセッサ　　　　11th Gen Intel(R) Core(TM) i7-11700 @ 2.50GHz   2.50 GHz
実装ＲＡＭ　　　　16.0 GB (15.9 GB 使用可能)
システムの種類　　64 ビット オペレーティング システム、x64 ベース プロセッサ

エディション　　　Windows 10 Home
バージョン　　　　22H2
インストール日　　2021/‎09/‎19
ＯＳビルド　　　　19045.2913　Windows Feature Experience Pack 1000.19041.1000.0

PowerShell　　　　7.3.4

# OpenSSHについて
OpenSShクライアント/サーバはwindowsに標準で準備されているため、
Windowsの設定→アプリ→アプリと機能→オプション機能→左上「+」機能の追加
からインストールできます。
私は苦手なpowershellの練習も兼ねてpwshから導入しました。

# OpenSSHのインストール
管理者権限でPowerShellを起動します。
```Powershell.exe
1.ホームディレクトリへ移動
　cd ~

2.OpenSSHの導入状態確認
　Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

#実行結果
Name  : OpenSSH.Client~~~~0.0.1.0
State : NotPresent

Name  : OpenSSH.Server~~~~0.0.1.0
State : NotPresent

```

未インストールならState行が「NotPresent」、インストール済みなら「Installed」が
出力されます。

```
1.ホームディレクトリへ移動
　cd ~

2.OpenSSHの導入状態確認
　Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

3.念のためディレクトリもないことを確認
　dir $env:ALLUSERSPROFILE | Select-String "ssh"
　dir $env:USERPROFILE | Select-String "ssh"
```

※既にインストール済みなら読み替えるorアンインストール・ディレクトリ削除で対応ください。

```
4.OpenSSHサーバインストール
　Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

5.OpenSSHサーバディレクトリ生成確認
　dir $env:ALLUSERSPROFILE | Select-String "ssh"

6.サーバ秘密鍵がないことを確認
　dir $env:ALLUSERSPROFILE\ssh

7.OpenSSHクライアントインストール
　Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

8.OpenSSHのサーバ/クライアントインストールを確認
　Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

#実行結果
Name  : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name  : OpenSSH.Server~~~~0.0.1.0
State : Installed
```

サーバ/クライアントともに「installed」になっていればOK。

# サーバ認証鍵の作成（OpesSSHServerの起動登録）
サーバ認証鍵を設定します。
OpenSSHサーバを開始すると自動的にサーバ認証鍵が生成されます。

```Powershell.exe
9.OpenSSHサーバのステータス確認
　Get-Service -Name sshd | Select-Object -Property Name, StartType, Status

#実行結果
Name StartType  Status
---- ---------  ------
sshd    Manual Stopped

上記はsshサーバ（sshd）がインストール済みだが開始していない状態。

10.スタートアップをAutomatic（OS起動時に自動起動）に変更
　Set-Service -Name sshd -StartupType Automatic
　Get-Service -Name sshd | Select-Object -Property Name, StartType, Status

#実行結果
Name StartType  Status
---- ---------  ------
sshd Automatic Stopped

StartTypeがAutomaticに変わっていればOK。

11.sshdの開始
　Start-Service sshd
　Get-Service -Name sshd | Select-Object -Property Name, StartType, Status

#実行結果
Name StartType  Status
---- ---------  ------
sshd Automatic Running

StatusがRunningに変わっていればOK。

12.サーバ秘密鍵の生成確認
　dir $env:ALLUSERSPROFILE\ssh

#実行結果
    Directory: C:\ProgramData\ssh

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2023/04/30    18:19                logs
-a---          2023/04/30    18:19           1401 ssh_host_dsa_key
-a---          2023/04/30    18:19            623 ssh_host_dsa_key.pub
-a---          2023/04/30    18:19            525 ssh_host_ecdsa_key
-a---          2023/04/30    18:19            195 ssh_host_ecdsa_key.pub
-a---          2023/04/30    18:19            432 ssh_host_ed25519_key
-a---          2023/04/30    18:19            115 ssh_host_ed25519_key.pub
-a---          2023/04/30    18:19           2622 ssh_host_rsa_key
-a---          2023/04/30    18:19            587 ssh_host_rsa_key.pub
-a---          2023/04/29    22:53           2297 sshd_config
-a---          2023/04/30    18:19              7 sshd.pid

こんな感じでたくさんできてればOK。
```
サーバ認証鍵（ホスト キー）は2回目以降の接続でいつもと同じサーバだよね、という確認に使われます。

# クライアント認証鍵の設定
クライアント認証鍵を設定します。秘密鍵・公開鍵のsshキーペアを作成し、
公開鍵をサーバに登録します。

```Powershell.exe
13.OpenSSHクライアント用ディレクトリの作成・移動
　mkdir $env:USERPROFILE\.ssh
　cd ~\.ssh

　※フォルダ名は別でも問題ないですがlinux系だと.sshで生成されます。

14.sshキーペアの作成
　ssh-keygen -t ed25519 -f openssh-key >>keygen.txt

　※今回はpassphraseなし（空欄のままenter）で作成。

15.sshキーペア、フィンガープリントの生成確認
　dir .\
　type .\keygen.txt

SHA：から始まる文字列（フィンガープリント）とrandomart imageが確認できればOK。

16.後で比較するためにフィンガープリントと公開鍵を変数に格納します。
　$fingerprint = Select-String "SHA256:" keygen.txt | % { $_.Line }
　$fingerprint
　$publickey = type openssh-key.pub
　$publickey

17.OpenSSHクライアントのステータス確認
　Get-Service -Name ssh-agent | Select-Object -Property Name, StartType, Status

#実行結果
Name      StartType  Status
----      ---------  ------
ssh-agent  Disabled Stopped

sshdと比べるとStartTypeが「Disabled」のはず。

18.このままだとクライアントを起動できないのでStartTypeを「Manual」に変更
　Set-Service -Name ssh-agent -StartupType Manual
　Get-Service -Name ssh-agent | Select-Object -Property Name, StartType, Status

#実行結果
Name      StartType  Status
----      ---------  ------
ssh-agent    Manual Stopped

StartTypeが「Manual」に変わっていればOK。

19.OpenSSHクライアントの起動確認
　Start-Service ssh-agent
　Get-Service -Name ssh-agent | Select-Object -Property Name, StartType, Status

#実行結果
Name      StartType  Status
----      ---------  ------
ssh-agent    Manual Running

Statusが「running」に変わっていればOK。

20.ssh-agent（windowsのopensshクライアント）にクライアント秘密鍵を登録
　ssh-add .\openssh-key
　ssh-add -l

21.ssh-agentに登録した秘密鍵が生成した秘密鍵と同一か確認
　ssh-add -l >>addedfingerprint.txt
　sls .\addedfingerprint.txt -Pattern $fingerprint

　フィンガープリントの文字列がハイライトされていればOK。

22.sshdへクライアント公開鍵を登録
　#localhostへssh接続（OSのパスワードで認証）
　ssh localhost
　#PowerShellへ変更
　pwsh
　#sshdへ公開鍵を登録
　scp $env:USERPROFILE\.ssh\openssh-key.pub localhost:$env:ALLUSERSPROFILE\ssh\administrators_authorized_keys
　dir $env:ALLUSERSPROFILE\ssh

administrators_authorized_keysがあればOK。

23.ssh接続で管理者権限を使えるように、公開鍵に対してアクセス権限を設定
　icacls $env:ALLUSERSPROFILE\ssh\administrators_authorized_keys /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
　icacls $env:ALLUSERSPROFILE\ssh\administrators_authorized_keys

#実行結果
C:\ProgramData\ssh\administrators_authorized_keys NT AUTHORITY\SYSTEM:(F)
                                                  BUILTIN\Administrators:(F)

NT AUTHORITY\SYSTEM:(F)、BUILTIN\Administrators:(F)が設定されていればOK。
「C:\ProgramData」の部分は環境変数：ALLUSERSPROFILEを変更している場合は読み替えてください。

24.作業ファイルの削除
　#localhost上のPowershellからexit
　exit
　#ssh接続を終了
　exit
　#作業ファイルの確認
　dir ~\.ssh
　#削除
　Remove-Item ~\.ssh\*.txt
　dir ~\.ssh
　#Powershell終了
　exit
```

# Teraterm起動時の引数設定
上記で鍵交換によるSSH接続にてcmd/pwshの操作ができるようになりましたが、毎度ユーザ名や鍵ファイルの指定をするのは面倒なので、teratermのショートカットにユーザ名や鍵を設定します。

25.teratermのショートカット設定
　#teratermのショートカットを作成
　#ショートカットのプロパティからリンク先を設定します。
![ショートカット設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588792/9798f923-ddb0-5a23-5105-910e3dae15e3.jpeg)

赤枠の部分を以下のように設定します。
```teraterm.lnk
%ProgramFiles(x86)%\teraterm\ttermpro.exe localhost /ssh2 /auth=publickey /user=%username% /keyfile=%USERPROFILE%\.ssh\openssh-key
```
※%ProgramFiles(x86)%\teraterm\ttermpro.exeの部分はteratermのインストールディレクトリに適宜読み替えてください。

これで
・teratermからcmd/pwshの起動
・ログ取得を行いながらの作業
・管理者権限の実行
ができるようになりました。

# 「23.ssh接続で管理者権限を使えるように、公開鍵に対してアクセス権限を設定」でやっていること

administrators_authorized_keysは不正なクライアントが接続できないようファイル内の公開鍵とクライアントの秘密鍵の照合に使われます。このファイルが編集可能な場合、追加の認証としてOSのパスワードを要求されます。（鍵にパスフレーズはなくとも）そのため、適切なアクセス権の設定が必要です。

```
icacls $env:ALLUSERSPROFILE\ssh\administrators_authorized_keys /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"

icacls：アクセス権操作コマンド
$env:ALLUSERSPROFILE\ssh\administrators_authorized_keys:対象ファイル/ディレクトリの指定

/inheritance:r：
・デフォルトで継承されるアクセス権の削除
　ファイル作成時はコピー元ファイルや格納フォルダと同一のアクセス権が継承されます。
　このオプションで明示的に継承されたアクセス権を削除します。

/grant "Administrators:F" 
/grant "SYSTEM:F"
・対象ファイル/ディレクトリに、あるユーザのアクセス権を付与します。
　今回は「管理者」と「システム」に対してのみ（:F）でフルコントロールアクセス権を
　付与しています。
```

# 参考
https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse
https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_keymanagement
https://proengineer.internous.co.jp/content/columnfeature/5205
https://bizlog.tech/ps-env-variable/
http://ne21.net/windows-select-string/
https://learn.microsoft.com/ja-jp/powershell/module/Microsoft.PowerShell.Utility/Select-String?view=powershell-7.3
https://atmarkit.itmedia.co.jp/ait/articles/1607/06/news028.html
https://tech.sanwasystem.com/entry/2016/07/05/185717
https://qiita.com/szly/items/54885a0594f29985d0c5
https://www.unixuser.org/~euske/doc/openssh/book/chap3.html
https://atmarkit.itmedia.co.jp/ait/articles/1908/02/news015.html
https://qiita.com/naka_toshinori/items/c9ea1efc89686ed3d018
https://tech.guitarrapc.com/entry/2013/04/17/220445
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/icacls
https://atmarkit.itmedia.co.jp/ait/articles/1407/17/news130.html
https://hyp.llc/tips/too-many-authentication-failures/

# 一言
やりたいことに対しての労力を考えようと思いました。