1. sshの解説の前に
連載記事「Linux的な IBM i の使い方」の第2回は、ssh を取り上げます。題名通り、「IBM i を Linux的に使う」には必須の技術・知識となりますので、しっかり解説していきたいと思います。
連載の題名と前回の記事で、IBM i には2つの世界がありそうだなということは皆さんもうすうす感じておられることでしょう。ひとつは従来からのネイティブ環境、そうしてもうひとつは AIX/Linux 環境です。我々が IBM i を使用する際には、どちらの環境にアクセスするかをまず選択します。
まずネイティブ環境をみていきましょう。この環境にアクセスするには、主に2つのインターフェースを使用します。
- 5250 画面
- IBM Navigator for i
5250 画面を表示するにはエミュレータ・ソフトウェアが必要ですが、代表的なものは Access Client Solutions でしょう。Java で開発されたソフトウェアなので、Windows だけでなく、MacOS や Linux クライアントでも利用できます。ユーザーはこの画面を介して、ネイティブ環境で OS に指示を出すコマンドを直接・間接的に実行し、結果を画面に表示します。
IBM Navigator for i は、Webブラウザからアクセス可能なインターフェースで、IBM i の様々な情報にアクセスしたり、システム全体を含む OS の管理機能を実行することができます。インターフェースはブラウザなので、画面の展開や情報の参照はマウス操作で可能で、必要に応じてキーボードを操作して情報を入力することもできます。マウスのクリックで OS の機能を実行しますが、内部では対応するコマンドが実行されて結果をブラウザ画面に表示します。
では、IBM i の AIX/Linux 環境にアクセスするにはどうすれば良いのでしょうか。実は、これも2つのインターフェースがあります。
- 5250 画面から
- ssh プロトコルを経由して実行するシェルから
5250 画面から AIX/Linux 環境にアクセスするには、QP2TERM プログラムを実行(CALL QP2TERM)します。表示される画面は AIX/Linux の世界なので、IBM i ネイティブのコマンドではなく、AIX/Linux コマンドを実行します。
サンプルの画面では、「pwd」、「ls -la」というコマンドを実行し、結果を画面に表示させています。5250 インターフェースさえあれば簡単に AIX/Linux 環境にアクセスできるためとても便利ですが、あくまで 5250 を経由しているのでその制約は受けてしまいます(画面サイズの制約など)。
実は IBM i にはもうひとつ似た機能として QSH / STRQSH(QSHELL)コマンドがあります。これも QP2TERM プログラムと同じような画面が表示され、上記と同じコマンドが実行できます。
一見すると、こちらも AIX/Linux 環境にアクセスしているようにみえますが、これはまったく別物なので注意してください。QSH / STRQSH コマンドは、AIX/Linux 環境がインストールされていない IBM i でも実行可能なツールです。つまり、AIX/Linux 環境にアクセスしているのではなく、IBM i ネイティブ環境で同様の機能を提供しているにすぎません。
別の回で詳細を解説しますが、IBM i のファイルシステム IFS に AIX/Linux 環境で利用可能なコマンドでアスセスするインターフェースは、2つあるということですね。
前置きが長くなりました。AIX/Linux 環境にアクセスするもうひとつの方法が ssh です。では、ssh について深堀りをしていきましょう。
2. ssh とは
IBM i の AIX/Linux 環境にアクセスするもうひとつのインターフェースが ssh です。ssh は Secure SHell の略で、遠隔のコンピュータを操作するためのコマンドとその応答を暗号化された経路で送受信を行う仕組みです。Secure なので、通信経路は常に暗号化されます。クラウドで実行されているサーバーや、GitHub などのサービスとの通信は暗号化が必須ですが、https 同様 ssh もよく利用されているのでご存知の方も多いことでしょう。
遠隔コンピュータを操作するプロトコルとしては ssh の他に皆さんよくご存知の telnet もありますね。ACS に代表されるエミュレータ・ソフトウェアは IBM i で実行されている telnet サーバーにアクセスしますが、telnet は暗号化を前提に開発されたプロトコルではないため、特に遠隔のサーバーを管理する目的で telnet アクセスすることは現在では不適切とされています。もちろん、ブラウザがサーバーにアクセスする際の暗号化を実施するための SSL/TLS 通信を telnet サーバーでも実装することは可能で、そのようなケースでは telnet も暗号化して使用できます。ACS のエミュレータ構成ではその接続構成を行うことも可能です。少し整理しましょう。
- ssh は通信経路が暗号化される
- telnet は構成によっては暗号化通信ができる場合もある
ここで注意していただきたいのは、両者ともサーバーとクライアントの間でどのようにデータを送受信するかは決めていますが、送受信したデータをどのように使用するかまでは決めていません。例えば、IBM i の telnet サーバーは送受信するのは 5250 データ・ストリームですが、それを解釈してどのように表示するかはクライアント側の専用のソフトウェアにまかされます。IBM 提供の Access Client Solutions や各ベンダーが提供するエミュレータソフトウェアがこの役割を担います(厳密には telnet クライアントの機能 + 5250 データストリームの処理機能を持ったのがエミュレータソフトウェア)。
IBM i に ssh 接続すると以下を実現することができます。
- AIX/Linux 環境に接続して AIX コマンドを実行
- QSHELL で提供されるコマンドの利用
- オープンソース・ソフトウェアの利用
- 暗号化経路を利用してファイルの送受信(上記 sftp / scp)
上記に関しての詳細は、別途記事にて紹介して行く予定です。
3. 前提条件
では、IBM i に ssh 接続する際の前提条件をみていきましょう。今回記事を作成するにあたって使用した IBM i は以下のとおりです。
IBM i | 7.4 |
---|---|
累積PTF | C3313740 |
Technology Refresh | 9 |
QCCSID | 1399 |
IBM i 側の準備
IBM i 側には以下のライセンス・プログラムが導入されている必要があります。
No. | ライセンス | オプション | 記述 | 説明 |
---|---|---|---|---|
1 | 5770SS1 | 30 | QSHELL | QSH / STRQSHコマンド含む |
2 | 5770SS1 | 33 | PORTABLE APP SOLUTIONS ENVIRONMENT | AIX/Linux 環境 |
3 | 5733SC1 | *BASE | IBM PORTABLE UTILITIES FOR I | |
4 | 5733SC1 | 1 | OPENSSH, OPENSSL, ZLIB |
QSH / STRQSH コマンドを実行するだけであれば 5770SS1-30 があれば可能ですが、先ほど触れたように AIX/Linux 環境にアクセスすることはできません。この4つのライセンスは必須ライセンスと思ってください。これらが導入されているかどうかは、IBM i にサインオンし、GO LICPGM コマンドで表示されるメニューの「10. 導入済みライセンス・プログラムの表示」で確認することができます。
続いて、sshd を開始します。sshd はデーモンと呼ばれるプログラムで、クライアントからの ssh 接続要求を待つサーバーです。QSECOFR と同等の権限を持ったユーザーもしくは、特殊権限 *IOSYSCFG と、STRTCPSVR コマンドの使用権を持ったユーザーで実施します。
STRTCPSVR SERVER(*SSHD)
SSHD は QUSRWRK サブシステム内で QP0SPWP という名前のジョブで開始されます。開始されているかどうかは以下コマンドで確認してください。
WRKACTJOB SBS(QUSRWRK)
【補足】 QCCSID が 65535 システムの場合
システム値 QCCSID が 65535 の場合は上記コマンドでの SSHD サーバーの起動に失敗します。その際には、以下手順で起動するようにしてください。
CHGJOB CCSID(5035) SBMJOB CMD(QSH CMD('/usr/sbin/sshd')) JOBQ(QUSRNOMAX) CHGJOB CCSID(65535)
クライアント側の準備
クライアントには、OpenSSH が導入されている必要があります。Windows10/11 および MacOS ともに現在は標準でインストールされているはずですが、入っていない場合は手動でインストールを行ってください。
Windows の場合は、以下の手順で導入の確認およびインストールを実施します。
- 設定を選択する
- システムを選択する
- オプション機能を選択する
- 追加された機能で OpenSSH クライアントが表示されていることを確認する
もしインストールされていない場合は、画面上部の機能追加で追加してください。
4. 公開鍵アルゴリズムについて
ssh 通信では、公開鍵アルゴリズムを利用してサーバーの認証および必要に応じてクライアントの認証を行っています。公開鍵アルゴリズムとは、秘密鍵と公開鍵のペアを利用し、数学的な計算に基づいて暗号化と復号化を行う方式のことをいいます。
一般的に暗号化と言われた場合、最初に皆さんがイメージするのは共通鍵方式ではないでしょうか。これは秘密の情報を双方で共有し、その鍵を用いて暗号化と復号化を行うというものです。
共通鍵を使うというのは、メールでファイルを送信する際にファイルを圧縮してそれをパスワードで保護し、そのパスワードを何らかの形で相手に伝えて解凍してもらうケース(いわゆる PPAP)を想像してもらうとわかりやすいと思います。共通鍵暗号方式の共通鍵は PPAP の場合のパスワードに相当します。
PPAP の場合、問題はどのようにしてパスワード(共通鍵)を相手と共有するかですが、パスワードもメール本文に記載したり、別メールで送信したりするケースが多いと思います。ではメールが盗聴されてパスワードが盗まれてしまう可能性はないのでしょうか。当然そこまで考慮しないといけません。共通鍵暗号方式で送受信を安全に行う場合も、共通鍵をどのようにして共有するのかという問題を含んでいるのです。さらに、メールの相手によって秘密鍵を変えなければならず、かつそれを管理しなければなりません。
一方、公開鍵アルゴリズムは一方の鍵で暗号化したものは、ペアとなるもう一方の鍵でしか復号できないという性質を利用した暗号化方式です。ユーザーが鍵ペアを作成し、秘密鍵は自分以外誰にも見せないようにし、公開鍵を広く一般に公開します。
詳細はここでは省きますが、通信データを暗号化するために、直接公開鍵アルゴリズムを利用することはありません。ssh では、このアルゴリズムを
- サーバー認証
- ユーザー認証
の2つの目的で主に利用しています。仕組みを簡単に説明します。
サーバー認証
A さんのみが特定の秘密鍵にアクセスできる場合、例えば以下のやり取りで、B さんは自分が持っている公開鍵とペアになる秘密鍵を持っている人と通信を行っていることを確認することができます。
- B さんは A さんの秘密鍵とペアの公開鍵を持っている
- B さんは、自分で乱数を生成して A さんに送信する
- A さんは受け取った乱数を秘密鍵で暗号化して B さんに送り返す
- B さんは、A さんの公開鍵で復号化し、自分で生成した乱数と同じか確認する
鍵ペアの一方で暗号化したのもは、もう一方の鍵でしか復号できないという性質を思い出してください。B さんは自分で生成した乱数を 通信相手の公開鍵で復号できたということですから、自分が持っている公開鍵とペアになる秘密鍵を通信相手が確かに持っていると確信することができますね。
では、Bさんが通信している相手は確かにAさんであるとどうやって確認すればよいのでしょうか。上記でAさんが本物のAさんであるためには、B さんが持っている公開鍵が確かに A さんのものであり、改竄(かいざん)されていないことが大前提です。一般的に公開鍵は通信を経由して入手しますので、それが確かに A さんから送られたものであり、かつ通信経路上で改竄されてないということを B さんが確認できなければいけません。
通信経路を経由して送受信するデータが、通信経路上で改竄されていないかどうかを確認するのに使用されるのが一方向性ハッシュ関数と呼ばれるものです。ある値をこの関数にいれるとハッシュ値と呼ばれる計算された値が出力されます。
一般的な一方向性関数の特徴は以下の通りです。
- 入力されたデータの長さに関係なく、出力されるハッシュ値の長さは同じ
- 入力されたデータが同じ場合、出力されるハッシュ値も常に同じ値になる
- 入力されたデータのうち 1 ビットでも違えば出力されるハッシュ値は全く異なるものになる
- ハッシュ値からもとのデータを再現することはできない
一方向性関数は上記の特徴を備えているため、これをうまく利用すれば、データの改竄が行われていないということを確認することができます。仕組みをみてみましょう。
- A さんの公開鍵を A さんが一方向性関数を使って計算する
- B さんは通信経路で受け取った公開鍵を一方向性関数を使って計算する
入力される値が全く同じであれば出力されるハッシュ値も全く同じになるので、A の計算結果と B の計算結果が同じであれば、改竄されていないということを証明できます。
一方向性ハッシュ関数にはいくつかの種類がありますが、よく利用されているものに sha256 があります。この関数は、入力されたデータの長さに関係なく、必ず 256 ビット(32バイト)の値を出力します。
上図内のフィンガープリントとはいわゆるデジタル指紋のことです。ssh では、このフィンガープリントを比較して正しいサーバーにアクセスしているかどうかを確認します。フィンガープリントの生成には base64 が使用されます。これを使用することにより、どんな値でもアルファベットと数字と一部の記号に置き換えることができます
(上図はかなり簡略化してあり、実際はより複雑な手順でフィンガープリントが生成されます)。
それでは、公開鍵アルゴリズムが ssh 通信のサーバー認証にどのように活用されているかをみていきましょう。
先程の例で紹介した A をサーバーとして考えてみましょう。ユーザー B がどのようにして正しいサーバーにアクセスしているか(アクセスしているサーバーが確かに A サーバーである)ということをどのように確認すればよいでしょうか。
- A サーバーが公開鍵ペアを作成する
- B さんは通信前に事前にサーバーのフィンガープリントを入手する
- A サーバーが自分の公開鍵を B さんに送信する
- B さんは受け取った公開鍵のフィンガープリントを計算する
- 事前に入手したフィンガープリントと自分で計算したそれを比較して同じであれば受け取ったのは確かに A サーバーの公開鍵であることを B さんが確認できる
ここまでで、公開鍵が改竄されていないことが確認できたので、
- B が乱数を生成して A サーバーに送付
- A サーバーは自分の秘密鍵を使って乱数を暗号化し B に送り返す
- B はサーバーの公開鍵を使って受け取ったデータを復号化し、自分が送った乱数と比較する
という手順をたどり、復号化した乱数が確かに自分が送った乱数と同じであれば、相手が改竄されていない公開鍵とペアになる秘密鍵を持っているということを証明できますよね。
サーバーの公開鍵は意図的に鍵ペアを再作成しないかぎり変わることはないので、公開鍵のハッシュ値から生成されたフィンガープリントは事前に計算して広く公開することになります。例えば GitHub では、サイト上にフィンガープリントを公開しています。
IBM i のフィンガープリントを確認するには、ssh-keygen コマンドを使用します。IBM i にサインオンし、QP2TERM プログラムを実行して、以下コマンドを入力します。
cd /QOpenSys/QIBM/UserData/SC1/OpenSSH/etc ssh-keygen -l -f ./ssh_host_rsa_key.pub ssh-keygen -l -f ./ssh_host_ecdsa_key.pub ssh-keygen -l -f ./ssh_host_ed25519_key.pub
拡張子 .pub のファイルがサーバーの公開鍵です。ここでは公開アルゴリズムが3つありますが、クライアントで使用するプログラムによってどのアルゴリズムを利用するかが決められます。
cd /QOpenSys/QIBM/UserData/SC1/OpenSSH/etc # ssh-keygen -l -f ./ssh_host_rsa_key.pub 3072 SHA256:q8BQuYgUtP5Bqnp7a+NgMMQe0mcrOh+ZEqeHHhVLoH0 qsecofr@ (RSA) # ssh-keygen -l -f ./ssh_host_ecdsa_key.pub 256 SHA256:KJWbsRGUq75tyr1/ULExIhb714oRMQoKcp0X0u+i3gw qsecofr@ (ECDSA) # ssh-keygen -l -f ./ssh_host_ed25519_key.pub 256 SHA256:k8UgXVnDzu9oAC2Tm1e9n4aRJ1hLR3njbEQHb32M4Zc qsecofr@ (ED25519)
クライアントが最初にサーバーに ssh 接続する場合、公開鍵のフィンガープリントが画面に表示されます。クライアントは表示されたフィンガープリントと、サーバーが事前に公開しているフィンガープリントを比較して同じであれば、正しいサーバーにアクセスしているということがわかるという仕組みですね。
5. ssh 接続の実際
5250エミュレータで telnet 接続する場合、あらかじめ決められたホスト名もしくは IP アドレスに接続するよう構成しておき、サインオン画面が表示されているところからスタートします。サインオン画面には、通常右上にシステム名が表示されており、今自分がどのシステムにサインオンしているのかを目で確認することができます。いわば、目チェックでサーバーの確認を行っているわけです。
続いて、ユーザー名とパスワードを入力してサインオンを実行します。IBM i におけるユーザー認証は、ユーザー名と同様のユーザー・プロファイルに関連付けられたパスワードをユーザーが知っているかどうかで判定されます。正しいユーザーであると判定された場合はサインオンが許可されます。
通信自体は、先ほども触れた通り通常は暗号化されていないので、ユーザー名とパスワード、サインオン後のデータはすべてプレーンでネットワーク上を流れます。
では、ssh で接続する場合はどうなるでしょうか。
ssh の場合、5250 のようなサインオン画面はないので、例えば Windows の場合、コマンドプロンプト画面等から接続を開始することになります。今回はサーバー 172.23.0.238 に IP アドレスで接続する例です。
C:¥Users¥ogawa>ssh ogawa@172.23.0.238
ssh に続けて 「IBM i ユーザー名@サーバーの IP アドレス」と入力して実行すると、初回は以下のようなメッセージが表示されます。
The authenticity of host '172.23.0.238 (172.23.0.238)' can't be established. ECDSA key fingerprint is SHA256:KJWbsRGUq75tyr1/ULExIhb714oRMQoKcp0X0u+i3gw. Are you sure you want to continue connecting (yes/no/[fingerprint])?
「ECDSA key fingerprint is SHA256:…」は、
- サーバーとの通信で使用する公開鍵アルゴリズムは ECDSA
- サーバーの公開鍵のフィンガープリントは、「TYtjQgu89…」
となっているがそのままアクセスしますかと聞いています。この時点で、
- サーバーからの公開鍵を受信済
- 公開鍵から sha256 でハッシュ値を生成してさらにフィンガープリントを計算
ということを ssh クライアントが実行しています。では、ここからサーバー認証のステップです。
先ほどの話を思い出してください。ssh でアスセスするには事前にアクセス予定のサーバーの公開鍵のフィンガープリントを何らかの形で入手するとお伝えしました。その値と、ssh で初回アクセスした時に表示されるフィンガープリントを比較して、ユーザーがこのままアクセスして良いかを判断するのです。フィンガープリントが同じであれば、自分が受け取った公開鍵は、確かにそのサーバーのものであることが確認できます。
「接続を続けるか」との問いに yes で答えると、アクセスしているホスト名もしくは IP アドレス(今回は 172.23.0.238)と公開鍵を C:¥Users¥<ユーザー名>¥.ssh¥known_hosts ファイルに書いて、次のステップに進みます。ここまでのステップがサーバー認証です。2回目以降は、提示された公開鍵が known_hosts にあればその時点でサーバー認証は済んだものとみなされ、次のステップにいきます。
次のステップはユーザー認証です。ユーザー認証には、
- パスワード認証
- 公開鍵認証
の2種類があります。今回はページボリュームの関係でパスワード認証で説明します(ユーザーの公開鍵認証については連載の後続の記事のどこかで解説する予定です)。
パスワード認証の場合、パスワード入力を促す画面が表示されるので、指定したユーザーのパスワードを入力します。この時点で、指定したユーザー名と同じユーザープロファイルが存在し、かつパスワードが正しいかチェックが行われ、問題なければユーザー認証が完了し、シェル画面が表示されます(下図の $ プロンプト)。
ogawa@172.23.0.238's password: $
ssh を終了するには、exit を入力します。
C:\Users\ogawa>ssh ogawa@172.23.0.238 ogawa@172.23.0.238's password: $ exit Connection to 172.23.0.238 closed. C:\Users\ogawa>
まとめ
IBM i に ssh 接続するために必要な前提ライセンスと暗号アルゴリズムの基礎知識、サーバーとクライアントでの事前設定などを解説しましたがいかがでしたか。ssh の画面を表示するだけでも大変なステップが必要ですね。しかし、これらは一回設定してしまえば以降は ssh コマンドを実行するだけでアクセスすることができますので安心してください。
ssh 接続をした経験があるが、画面で表示される内容や用語についてはよくわかっていなかったという人も、今回の記事内容で「そういうことだったのか」という点がひとつでもあれば嬉しいです。
5250 telnet と ssh の違いについて簡単な表をまとめましたので参考にしてください。
プロトコル | 暗号化 | サーバー認証 | クライアント認証 | 用途 |
---|---|---|---|---|
5250 telnet | なし | なし SSL/TLSは構成すれば可能 |
パスワード | ネイティブ環境へのアクセス 業務プログラムの実行 |
ssh | あり | あり (sha256 / フィンガープリント) |
パスワード 共通鍵暗号 |
AIX/Linux環境へのアクセス オープンソースプログラムの実行 |
ssh はインターネット上のサーバーへのアクセスに使われているため、自分がアクセスしているサーバーが確かにそのサーバーであることを確認するサーバー認証はかかせません。またインターネットを経由するので、通信経路の暗号化も必須です。
IBM i が使っているのは OpenSSH です。他のプラットフォームでもよく利用されているので、インターネット上でも書籍でも多くの情報があります。今回解説した内容を基本知識として、色々と活用していただければと思います。
今回は、ssh で IBM i に接続するところで終わってしまいました。次回はシェルやコマンドなどについてさらに深く解説をしていく予定です。
お楽しみに!
参考文献
@IT. 『SSH(Secure SHell)とは』.
https://atmarkit.itmedia.co.jp/ait/articles/0401/01/news123.html
GutHub Docs. 『# GitHub の SSH キーフィンガープリント』.
https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
GIGAZINE. 『# SSHの公開鍵暗号には「RSA」「DSA」「ECDSA」「EdDSA」のどれを使えばよいのか?』.
https://gigazine.net/news/20200828-ssh-encryption-algorithm/
ウィキペディア. 『Base64』.
https://ja.wikipedia.org/wiki/Base64