👌

とある研究室のためのSSH接続大全

に公開

こんにちは。とうとう研究室にぶち込まれてしまったykcです。研究室でSSH接続をする機会があったので全制覇をするがごとくWindows版とubuntu版のSSHの手順などをまとめていきます。対戦よろしくお願いします。

あと、いつもお願いしているように誤りを見つけた場合はぜひ@ykc_crsまでご連絡ください。

SSH接続(Secure Shell接続)とは

リモートサーバーなどに安全にログインするためのプロトコル。ここでいう安全とはたとえ通信が傍受されていたとしても、内容がわからず漏洩しないということ。

SSH接続を確立するための公開鍵認証の署名

接続元(あるいは接続先)がなりすましではなく本物であることを証明する仕組み。

秘密鍵(private key)と公開鍵(public key)と呼ばれるものを用いて署名を行う。
一般に、暗号化通信とはデータは公開鍵で暗号化し、秘密鍵でのみ復号することができるので、秘密鍵の所有者のみ中身がわかるという仕組み。
SSHではこれを応用し、公開鍵と秘密鍵を使った電子署名の仕組みによって、クライアントの正当性を確認する。

もっとも有名なRSA暗号は「掛け算は簡単にできるが、ある数の素因数分解を求めることは困難」という数学的性質を用いている。秘密鍵は素因数、公開鍵を実際にかけ合わせた数になる。

認証方式

SSH接続の認証方法は3つほど存在する。

  • password : ユーザー名とパスワードを使用して認証する方式
  • publickey : 公開鍵と秘密鍵を使って認証する方式
  • keyboard-interactive : サーバーがクライアントに複数の質問を投げて回答を見て認証する方式

password認証

windowsの場合
設定でユーザーアカウントとPCのデバイス名を確認することができる

公開鍵認証(publickey)

公開鍵と秘密鍵によって接続元(あるいは接続先)がなりすましではなく本物であることを証明する仕組み。

<!-- 具体的には

  1. クライアントがリクエストを送る。
  2. サーバーがランダムな値を生成し、公開鍵で暗号化したものをクライアントに送る。
  3. クライアントは復号してランダムな値を取り出し、ハッシュ値というものを求める。
  4. ハッシュ値をサーバー側に送る。
  5. サーバー側がランダムな値から求めたハッシュ値がクライアントのものと一致することを確認して本物と識別する。 -->

keyboard-interactive認証

パスワードに加えてGoogle Authenticatorなどを用いた二要素認証を実装することができる。

初回接続時のfingerprint確認

先ほどは、サーバーがクライアントを検証(本物か判断)している説明をした。一方で、この前にサーバーとクライアントが入れ替わってクライアントがサーバーが正しいか判断している。気づいていないと思うが、初回の接続時にこのサーバーを信頼するかと聞かれている。それはこのサーバーが本物で今後の接続にも問題ないよね?という確認が行われている。

SSH接続の具体的なやり方

windowsの場合

前提

  • PowerShell(7以降)を(Microsft Store)最新版のPowerShellが従来のものとまったく異なるもので配布されている模様。古いほうはコマンドを試していないためサポートしない。
  • 隠しファイル(.sshなど)をあらかじめ見えるようにエクスプローラーの設定を変更しておくこと
  • 事前にopenssh-serverをインストールしておくこと。以下に簡単な手順を示す。
  1. 設定アプリ > システム > オプション機能に入る。
  2. 「オプション機能を追加する」からOpenSSHサーバーを追加する
  3. インストール後PCを再起動する。

1. ssh-serverの有効化

  1. PowerShellでssh-serverの起動状況を確認
    Get-Service -Name sshd
    
  2. 起動していない場合は以下のコマンドで起動
    Start-Service -Name sshd
    
    再起動の場合は以下のコマンド
    Restart-Service -Name sshd
    
  3. サーバーが自動で起動するように設定
    Set-Service -Name sshd -StartupType Automatic
    

2. 初回接続

初めにクライアントからサーバーへssh接続を行うというコマンドを入力する

  1. 同じwifiに接続する。

  2. PowerShellを開き、以下のコマンドを入力

    ①DNSサーバーがあるタイプwifiにつながっている場合

    ssh username@hostname
    

    ②DNSサーバーのないwifiの場合はipアドレスを利用する

    ssh username@ip_address
    
  3. fingerprintについて聞かれる。yキーを押した後、(ここは間違っているかもしれないがyesの意思を示せればよい)enterキーで進める。

  4. 初回はpassword認証で接続する。アクセスするアカウントのパスワードを入力してログインする。

3. 公開鍵認証の準備

  1. 新しいPowreShellを開き、以下のコマンドを入力して公開鍵と秘密鍵を生成する。ed25519という楕円曲線暗号を用いた高速かつ安全性の高いアルゴリズムを利用する。

    ssh-keygen -t ed25519
    
  2. 保存場所を聞かれるため、問題ない場合はenterで抜ける

    Enter file in which to save the key (C:\Users\<ユーザー名>\.ssh\id_ed25519):
    
  3. 次にパスフレーズを聞かれる。何もパスワードを入れたくない場合はそのままenter。

    Enter passphrase (empty for no passphrase): 
    

    再度確認されるためそれもenter。

    Enter same passphrase again: 
    

    大量のlogが表示されて鍵生成が完了すると、id_ed25519という秘密鍵とid_ed25519.pubという公開鍵が生成される

    秘密鍵は絶対に公開してはならない。

4. サーバー側の設定

  1. 生成された公開鍵を転送サーバーPCに転送し、以下のファイルに追記

    C:\Users\<ユーザー名>\.ssh\authorized_keys
    

    microsoft公式の説明には以下のようなコマンドが紹介されている。内容はssh接続して接続先のコマンドプロンプトでカギを追加という内奥になっている。したがって、実行場所はクライアントPCのPowerShellになるのでお間違いなく。

    # Get the public key file generated previously on your client.
    $authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ecdsa.pub
    
    # Generate the PowerShell command to run remotely that copies the public key file generated previously on your client to the authorized_keys file on your server.
    $remotePowershell = "powershell New-Item -Force -ItemType Directory -Path $env:USERPROFILE\.ssh; Add-Content -Force -Path $env:USERPROFILE\.ssh\authorized_keys -Value '$authorizedKey'"
    
    # Connect to your server and run the PowerShell command by using the $remotePowerShell variable.
    ssh username@domain1@contoso.com $remotePowershell
    

    引用 - Windows用OpenSSHでのキーベース認証より

  2. ファイルのアクセス権限を限定

    .sshファイルにアクセスできる権限を限定する。プロパティ > セキュリティから

    • ユーザー :フルコントロール
    • SYSTEM :フルコントロール(自分の場合は削除した)
    • Administrators:フルコントロール

    そのほかの権限は削除。
    また、詳細設定に進み、アクセス許可の継承の無効化をクリックし継承を無効化する。

    authorized_keysのアクセス権限も同様に編集する。

    • ユーザー :フルコントロール
    • SYSTEM :フルコントロール(自分の場合は削除した)
    • Administrators:フルコントロール
  3. 認証方式の設定(マストではない)
    管理者権限を付与したエディターを用いてC:\ProgramData\ssh\sshd_configを開く。以下の点をコメントアウトから有効化し編集してからssh-server再起動するとpassword認証を無効化して公開鍵認証のみを有効化できる。なお、ここまでやらなくてもたいていは公開鍵認証から始めてくれる。

    PasswordAuthentication no
    PubkeyAuthentication yes
    

5. 接続

公開鍵を使って接続する場合は次のようにコマンドを打つ。

ssh -i .ssh/id_ed25519 username@hostname(あるいはip_address)

あとはC:\Users<ユーザー名>.ssh\configで次の設定をしてあげるとコマンドが短くすることができる。

Host hostmane(名前解決ができない環境ではipアドレスを使用すること)
  HostName hostname(名前解決ができない環境ではipアドレスを使用すること)
  User username
  Port 22
  IdentityFile ~/.ssh/id_ed25519

この場合は次も様なコマンドで行けるようになる。

ssh hostname(Hostに記述したもののみ有効)

6.トラブルが起きたときは

まずはログを確認しよう。opensshの場合は、debugレベルがdebug1からdebug3まである

クライアントの場合

接続コマンドに -vvvオプションを入れる。vの数がdebugレベルに対応している。

サーバーの場合

管理者権限を付与したエディターを用いてC:\ProgramData\ssh\sshd_configを開く。以下の点をコメントアウトから有効化し編集してからssh-server再起動する。

# SyslogFacility AUTH
# LogLevel INFO

LOCAL0はC:\ProgramData\ssh\logsにlogを出力する設定。

SyslogFacility LOCAL0
LogLevel Debug3

テンプレトラブル(windows版)

  1. 権限の変更忘れや消しすぎ
  2. サーバーの(再)起動忘れ

Ubuntuの場合

後日掲載予定

Discussion