ASCII.jp マイクロソフト版OpenSSHをサーバーとして動作させる

ASCII.jp マイクロソフト版OpenSSHをサーバーとして動作させる

  • 沿って huawei
  • 12/04/2022

今回はMicrosoft版OpenSSHでサーバーを動作させる。なお、前回紹介したOpenSSHのインストールやパスの設定はすでに済んでいるという前提なので、記事を参照のうえ、パス設定などを進めてほしい。

Windows 10でもローカルのユーザー名が必要なので注意

サーバーをインストールする場合、ちょっと注意することがある。Windows 8以来、ユーザーアカウントにMicrosoftアカウントが利用できるようになったが、Microsoft版のOpenSSHでは、コマンドの引数に、Microsoftアカウントではなく、「内部ユーザー名」とでも呼ばれるユーザー名を使わねばならない。

具体的には、Windowsのログオン時にコマンドプロンプトでwhoamiコマンドを実行したときに表示されるユーザー名が「内部ユーザー名」である。

ワークグループ運用の場合には、ユーザー名にはMicrosoftアカウントではなく、whoamiコマンドで表示される「内部ユーザー名」を用いる

ssh.exeコマンドなどでログインユーザーを指定するには、サーバー側のユーザーアカウントの「内部ユーザー名」を使う必要がある。簡易的にはユーザーのホームフォルダ(C:\Users以下にあるフォルダ)のフォルダ名が「内部ユーザー名」に相当する。

Windows 8などからアップグレードしたPCの場合、内部ユーザー名に漢字が使われていることがある。Microsoft版OpenSSHでは、漢字の内部ユーザー名も利用可能だが、LinuxなどからSSHでログインする場合には注意されたい。

また内部ユーザー名は、すべてのマシンでMicrosoftアカウントと1対1で対応するわけではないので、同じMicrosoftアカウントでも、マシンごとに内部ユーザー名が違っている可能性がある。このためログオン時には注意されたい。また、後述するが、SSHでは、ログイン時にパスワードを使わず、公開鍵認証も可能だが、このとき、サーバー側では指定された「内部ユーザー名」から、ユーザーのホームフォルダを判定して、ホームフォルダ以下にあるファイルで認証する。

筆者の環境では、サーバー側とクライアント側で同一のMicrosoftアカウントに対する内部ユーザー名が違っていて、しかもサーバー側では内部ユーザー名が漢字になっていた。このとき、ssh.exeは、漢字の内部ユーザー名を使ってログイン(パスワード認証、公開鍵認証)することが可能だ。しかし、漢字のユーザー名はコマンドラインでの操作が面倒になる。

そこで、サーバー側にクライアント側の内部ユーザー名と同じローカルアカウントを作ってみた。これでもログインは可能である。ただし、サーバーとクライアントのWindowsは違うユーザーと認識しているため、リモートファイル操作などには注意が必要だ。こうした運用が可能であるため、サーバーとクライアントで内部ユーザー名が同一になるようにユーザーアカウントを作り直す必要はないだろう。

公開鍵認証を用いる

SSHでは、ログオンの際にユーザーによるパスワード認証ではなく、公開鍵暗号を使った認証が可能だ。これは、サーバー側に公開鍵を置き、クライアント側の秘密鍵と組合せてユーザー認証する方式で、暗号化されているとはいえネットワーク内をパスワードが流れないためよりセキュリティが高く、かつ、パスワード入力なしでログインが可能という使い勝手の良さがメリットとなる。

公開鍵暗号とは、暗号化を「秘密鍵」で行ない、「公開鍵」で解読する暗号化方式で非対称暗号などと呼ばれる。公開鍵で解読できるということは、秘密鍵を持っていることになるため、相手が正しいことを認証できる。また、公開鍵から秘密鍵を推測することは不可能なので、公開鍵自体が漏洩しても問題がない。

公開鍵認証は、これを使ってユーザーの認証(正しい秘密鍵を持っている)をする。認証操作などはソフトウェア側ですべて行なわれる。ただし、このためには秘密鍵を安全に保管する必要がある。

基本的には、秘密鍵自体を暗号化してファイルに保存するが、このときに付けるパスワードをOpenSSHでは「パスフレーズ」と呼ぶ。どうしてそう呼ばれるのかというと、長い文章を使うことが可能になっているからだ。認証時にこのパスフレーズを入力して、OpenSSHに秘密鍵を一時的に利用させる。

複数のサーバーを使う、複数のセッションを開く場合などには、毎回パスフレーズを入力するのは面倒なので、ssh-agentと呼ばれるソフトウェアを使い、秘密鍵をメモリ上で管理する。複数のセッションを用いる場合などに便利だが、今回の解説では割愛させていただく。インターネット上にはLinux用としてOpenSSHの資料などが多数あるので、それらを参考にしていただきたい。

さて、この公開鍵認証では、一般的にRSA公開鍵暗号方式を使い、秘密鍵と公開鍵を作り、ユーザーのホームフォルダ以下にある「.ssh」フォルダに保存する。また、これらのファイルは、他人には読めないようにするなど適切なアクセス管理する必要がある。Windowsでは、こうしたアクセス管理は、ACL(Access Control List)で実行され、コマンドラインからはicaclsコマンドを使うが、OpenSSHに付属のPowerShellスクリプトでまとめて処理することが可能だ。

OpenSSHサーバーを設定する前にクライアントの設定を済ませておく

ここでは、サーバー設定に入る前に、クライアント側の設定を先に済ませておく。ここでは、クライアントマシンをPC1、ユーザーのMicrosoftアカウントを「user001@example.com」、内部ユーザー名を「user001」とする。ホスト名やユーザー名、およびパスなどは、自身の環境に合わせて書き換える必要があることに注意してほしい。

Windows 10にサインインし、PowerShellを管理者権限で起動する。起動したらC:\OpenSSHフォルダへ移動し、

cd c:\openssh\

以下のコマンドを実行する。

ssh-keygenコマンドを実行して、各ユーザーの秘密鍵、公開鍵ファイルを作成する。保存先フォルダはデフォルトのままでよい。実行後、OpenSSH付属のPowerShellスクリプトを起動してパーミッションを変更する

なお、PowerShellを使う場合には、カレントディレクトリのコマンドを実行するためには、明示的に「.\」を先頭に付ける必要がある。

.\ssh-keygen -t rsa

このとき、ファイルの保存先としてユーザーのホームフォルダ以下の.sshフォルダ(c:\users\user001\.ssh)が指定されているはずである。他の場所でもいいが、あとで思い出せなくなる可能性もあるので、デフォルト値を使うことをお勧めする。なお、内部ユーザー名に漢字が使われている場合、表示が化けることがあるが、エラーがでない限り、正しいフォルダが使われるようだ。

次にパスフレーズを聞いてくる。これは、ログインに使うパスワードではなく、秘密鍵ファイルを暗号化するためのもの。同じパスフレーズを2回入力すればコマンドは終了する。なお、パスフレーズを聞かれたときにエンターキーのみとしてパスフレーズを空に指定することも可能だが、秘密鍵が漏洩する危険性があることを認識しておいてほしい。

コマンドの実行後に.sshフォルダを見ると、「id_rsa」と「id_rsa.pub」という2つのファイルができているはずだ。そこで、以下のコマンド(1行なので注意)を実行してファイルのアクセス権を修正する(PowerShellならば、ファイル名をフルパスで指定すればよい)。

Powershell -executionpolicy bypass -File C:\openssh\FixUserFilePermissions.ps1

結果としてid_rsaやid_rsa.pubが表示されれば問題ないはずだ。

ASCII.jp マイクロソフト版OpenSSHをサーバーとして動作させる

OpenSSHサーバーの設定

歴史的な経緯から、OpenSSHのサーバーは「sshd」という名前になっている。サーバー側の設定では、ホスト名がPC1であると仮定し、ログインを受け付けるユーザーはクライアントと同じ「user001@example.com」(内部ユーザー名はuser001)とする。作業は、user001@example.comでWindowsにサインインして実行すると仮定する。また、サーバー側でも同様にインストール先フォルダはC:\OpenSSHで、パス設定は終了しているとする。

まずは、PowerShellを管理者で起動し、OpenSSHフォルダへ移動する。次に、以下のコマンドでsshdサーバーをサービスとしてインストールする。

サーバー設定では、installスクリプトでsshd.exeなどをサービスとして登録、ファイアウォールへのルール追加、ホスト認証鍵の生成をする

powershell -ExecutionPolicy Bypass -File install-sshd.ps1

次に、sshd用にファイアウオール通過のルールを設定するため、以下のコマンドを実行する(すべて1行、インストール先フォルダなどに注意)。

New-NetFirewallRule -Protocol TCP -LocalPort 22 -Direction Inbound -Action Allow -DisplayName OpenSSH -Program C:\OpenSSH\sshed.exe

次にホストの認証キーを作るため以下のコマンドを実行する。

.\ssh-keygen.exe -A

次に以下のコマンドでインストールされたsshdサービスをPCの起動時に自動的に実行するように設定する(コントロールパネルの管理者ツール→サービスでGUIでの設定も可能)。

Set-Service sshd -StartupType Automatic

公開鍵認証のために、sshd_configファイルを編集する。編集には、メモ帳が利用できる(S-JIS/ASCII形式で行末がCR-LFでもsshd.exeは動作する)。ファイルを開いたら、「#PubkeyAuthentication yes」という行を捜し、行頭の“#”(注釈の意味)を削除して、ファイルを保存する。元の行をコピーして、それを書き換える方が安全だ。

sshd_configファイルを編集し、PubkeyAUthenticationをyesに設定しておく

次に、ログオンするユーザーのホームフォルダ以下に.sshフォルダを作って公開鍵ファイルを置くのだが、ユーザーが正しく認識されていることを確認するため、ssh-keygen -t rsaコマンドを実行して、サーバー側でもRSA暗号キーを作り「FixUserFilePermissions.ps1」を実行するのが一番簡単である(前記のクライアント側の設定を参照)。

次に公開鍵ファイル「id_rsa.pub」の内容を.sshフォルダにおいたauthorized_keysファイルに追加する。authorized_keysファイルが存在していないならid_rsa.pubファイルを.ssh以下にコピーしてリネームしてもかまわない(パスは自分の環境に合わせること)。

●authorized_keysファイルがなかったとき(公開鍵ファイルはC:\tempにあると仮定)copy c:\temp\id_rsa.pub c:\users\user001\.ssh\authorized_keys

すでにファイルがある場合、エディタでファイルを開いてCopy&Pasteで貼り付けてもいい(メモ帳は勝手にワードラップすることがあるので注意)。PowerShellからは、以下のようにする。

クライアントで作成した公開鍵ファイルをユーザーフォルダ下の.sshにauthorized_keysに追加

●authorized_keysファイルが存在していたとき(公開鍵ファイルはC:\tempにあると仮定)get-content c:\temp\id_rsa.pub | add-content c:\users\user001\.ssh\authorized_keys

その後で、authorized_keysファイルのアクセス権を以下のコマンドで変更する。

最後に付属のPowerShellスクリプトを実行して必要なファイルのパーミッションを設定する

C:\OpenSSH\FixHostFilePermissions.ps1 -Confirm:$false

これは、ホスト認証キーに加えて各ユーザーの.sshフォルダにあるauthorized_keysのチェックも行う。このため、authorized_keysを新規作成したら再度実行する。

最後にsshdサービスを再起動する。

restart-service sshd

これで、PC1からPC2へのOpenSSH接続で、公開鍵認証が可能になる。なお、サーバー側に公開鍵を設定しないと、パスワード認証となる。

実際にリモートログインしてみる

これで、クライアントは、公開鍵暗号で認証させることが可能になる。すでにSSHサーバーがあるなら、作成した公開鍵ファイルをサーバー側に設定して、以下のコマンドでログオンできるようになる。rsa公開鍵認証を使う場合、Microsoft版OpenSSHでは以下のコマンドを使う。

ssh.exe -i c:\users\user001\.ssh\id_rsa user001@PC2

このように「-i」オプションの次には、秘密鍵ファイルへのフルパスを記述する。また、ログインするユーザー名とログイン先サーバー名を“@”でつないで、「user001@PC2」のように指定する。

いわゆるWindowsのドメイン運用(アクティブディレクトリ)の場合、「user@msdomain」、「msdomain\user」としてユーザー名を指定する。このとき、「@」を使ったsshのユーザー名とホスト名の指定方法である「user@msdomain@host」や「msdomain\user@host」もそのまま利用可能だ。こうした指定を可能にしているため、Microsoft版OpenSSHでは、Microsoftアカウントをユーザー名として指定できないわけだ。

サーバー側の設定がうまくいっていれば、パスワードを聞かずにそのままログインできるはずである。なお、初めてサーバーと接続する場合、サーバーのホスト認証鍵を登録するかどうかを聞かれるので「yes」で応答する。

このサーバーのホスト認証鍵は、各ユーザーごとに記録され、次回以降の接続では、認証鍵を使って相手ホストが正しいものであるかどうかを確認する。この情報は、各ユーザーフォルダ以下の.sshフォルダにあるknown_hostsファイルに記録されていく。

パスワード認証はできるが、公開鍵認証が「Permission denied」でエラーになる場合、ローカルファイルのid_rsaやサーバー側のauthorized_keysファイルのアクセス権設定が間違っている可能性がある。その場合はMicrosoft版OpenSSh付属の「Fix」で始まるPowerShellスクリプトファイルを実行してパーミッションを正しいものにする。

ssh.exeは、-vオプションを付けることでログイン時の状況を表示するとともに、サーバーのOpenSSH\logsフォルダには、sshdが出力するログファイルが存在する。また、設定ファイルなどを変更したあとは、必ずサービスとして動作しているsshdを再起動する必要がある。

ASCII倶楽部とは

表示形式: PC ⁄ スマホ