NEWS
押さえておきたい!RPGの新機能 押さえておきたい!RPGの新機能
2020.12.15

【第18回】sshによるIBM iからPCプログラムの実行 ‐ セキュアなRUNRMTCMDの代替策 ‐

【第18回】sshによるIBM iからPCプログラムの実行 ‐ セキュアなRUNRMTCMDの代替策 ‐
02/18/2020 ロブ・ベーレント

多くの人がPCのOSをWindows 10に、あるいはサーバーPCのOSをWindows 2019に更新し始めるにつれ、それらの新しいOS上でIBM Client Access for Windowsが最早サポートされないことに彼らは気付きつつあります。
単純な解決策は、しばしばiACSと呼ばれるIBM i Access Client Solutionsに移行することです。iACSについての詳細はこちらをご覧ください。

iACSから欠落した機能は、IBM iからRUNRMTCMDコマンドによってPC上でコマンドを実行するリモート・コマンド・デーモンです。
RUNRMTCMDコマンドには多くの課題、とりわけパスワードが平文で送られるという問題がありました。
このデーモンはセキュリティ上のリスクと見做され、いかなるWindowsサーバーへのアクセスも許されませんでした。
結局私たちはその場しのぎの回避策を講じました。一つはWindowsクライアントに対してRUNRMTCMDコマンドを使用し、そこからWindowsサーバーと通信する方法でした。

時の経過と共に、私たちはsshを取り入れ、サポートされているWindowsのバージョン上のすべてのWindowsベースのクライアントとサーバーを入手し、Client Access for WindowsをiACSで置き換える決断をしました。
RUNRMTCMDコマンドを使用する代わりに、Windowsマシン上でコマンドを実行するためにsshを使おうとしました。

これを試すために私は自分のWindows 10クライアントを最初のターゲットにすることにしました。
この場合、私のWindows 10はsshサーバーつまりターゲットであり、IBM iはsshクライアントでした。

私の目標の1つは、公開鍵/秘密鍵のペアを使ってパスワードを使わずにこれを行う事でした。
これは、パスワードを絶対に変更しないユーザーを使う方法や、新しいパスワードに合わせてスクリプトを変更しなければならない方法よりも実にずっと理に適っています。

IBM i上のクライアント設定作業

DSPSFWRSCコマンドを実行すると、以下のようにロードされたソフトウェアが表示されるはずです。

Resource
ID Option Feature Description
5770SS1 33 5111 Portable App Solutions Environment
5733SC1 *BASE 5050 IBM Portable Utilities for i
5733SC1 1 5050 OpenSSH, OpenSSL, zlib

この内のあるものはQSHELL(5770SS1-30)で実行できますが、この記事ではPASEにこだわることにします。

すべてのユーザーIDは8文字以下でなければなりません。
私たちはこの規則に従うことを職場の標準として実施していますが、これを見るまでその理由を思い出せませんでした。
私たちはQPWDLVLを3にしているので、私たちのパスワードはもっと長いものです。
私のユーザープロファイルはROBです。あなたの状況に合う様に以下の修正を行います。

あなたのホームディレクトリが存在し、正しい権限があることを確認してください。

 CALL QP2TERM
> mkdir /home/ROB
  mkdir: 0653-358 Cannot create /home/ROB.
  /home/ROB: Do not specify an existing file.
  $
> chmod 755 /home/ROB
  $ 

パスフレーズのないDSAまたはRAS鍵のペアを作成します。DSAまたはRSA鍵のペアを作るには次のコマンドを使います:

ssh-keygen -t dsa -N ""
ssh-keygen -t rsa -N ""

私は以下のコマンドを使用しました。結局、私は省略時値のid_rsaとは違う名前を付けました。
こうすることで、複数のキーを設定し始め、名前にソース・システムやターゲット・システムの名前を含めたときに、作業が容易になるかもしれないと私は推測しました。
これをブランクのままにしてEnterキーを押すと、.sshというサブディレクトリも作成されますが、ファイルはid_rsaおよびid_rsa.pubになります。
私がやったように、これらの名前を変更すると混乱する人も出てくるでしょう。

> ssh-keygen -t rsa -N ""
公開/非公開RSAキー・ペアを生成中。
キーを保管するファイルを入力しなさい(/home/ROB/.ssh/id_rsa):
> /home/ROB/.ssh/GDI_GDL57          
ディレクトリ '/home/ROB/.ssh' を作成しました。
あなたのIDは/home/ROB/.ssh/GDI_GDL57に保管されました。
あなたの公開鍵は/home/ROB/.ssh/GDI_GDL57.pubに保管されました。
  ...
  $
> chmod 600 /home/ROB/.ssh/GDI_GDL57
  $ 

DSPUSRPRF ROB

あなたのホームディレクトリが/home/ROBのような名前ではない場合、このような名前に変更することをお勧めします(再度言いますが、ROBの部分はあなたのユーザープロファイル名にしてください)。

CHGUSRPRF USRPRF(ROB) HOMEDIR('/home/ROB')
 

CHGUSRPRFコマンドを実行しなければならない場合、実行後にサインオフして再度サインオンし直してください。

CRTUSRPRFコマンドのHOMEDIRパラメーターの省略時値は*USRPRFであり、/home/USRPRFがHOMEDIRの値になります。
ここで、USRPRFはユーザープロファイル名です。私の場合は/home/ROBとなります。
私は接続情報を保管するのにCONFIGファイルを使うのが好きです。
その利点はここで説明されています。そうするには以下のようにします:

CALL QP2TERM
> touch ~/.ssh/config    
  $
> chmod 600 ~/.ssh/config
  $
 

PASEにはファイルを編集するための素晴らしいユーティリティがあることを知ってはいますが、ここでは私の知っているやり方にこだわります。

F21=CLコマンド入力
EDTF '/home/ROB/CONFIG'

私たちのWindowsドメインはdekko-1です。以下のコマンドを使い、IBM iからPCに対してpingコマンドを実行することができます。

PING RMTSYS('GDL57.dekko-1')
************Beginning of data**************
Host gdl57                                  
    HostName gdl57.dekko-1                  
    User rob                                
    IdentityFile ~/.ssh/GDI_GDL57           
 ************End of Data********************
 

Windows 10またはWindowsサーバー2019の設定作業

このウェブサイトの指示に従って作業を行います。どのみちこのプロセスの多くの場面で、結局はPowerShellを使うことになるので、すべての作業でPowerShellだけを使い、GUIは迂回することにします。

管理者としてPowerShellを立ち上げます。私はWindows 10の下部にある検索バーが好きです。ですから、私はそこに単にpowershellと打鍵します。しかし、Enterキーは押しません。そうするとリストの上部近くにPowerShellが表示されます。それを右クリックして「管理者として実行」を選択します。

最初にsshが導入されているかを調べましょう:

PS C:\WINDOWS\system32> Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
Name  : OpenSSH.Client~~~~0.0.1.0
State : NotPresent
Name  : OpenSSH.Server~~~~0.0.1.0
State : NotPresent
 

それでは、sshを導入しましょう:

Add-WindowsCapability-Online -NameOpenSSH.Client~~~~0.0.1.0
Add-WindowsCapability-Online -NameOpenSSH.Server~~~~0.0.1.0
Get-WindowsCapability-Online | ? Name -like 'OpenSSH*'
 

今やクライアントとサーバーどちらも導入済みの状態になっています。

OpenSSH-Server-In-TCPという名前のファイアウォール規則が存在し、Enabled=Trueに設定されていることを確認します。

Get-NetFirewallRule-Name*ssh*

存在しない場合には次のコマンドを実行します:

New-NetFirewallRule-Namesshd-DisplayName'OpenSSH Server (sshd)'-EnabledTrue-DirectionInbound-ProtocolTCP-ActionAllow-LocalPort22

次に自動的にsshdが開始されるよう設定します:

Set-Service-Namesshd-StartupType'Automatic'
 

sshdを開始します:

Start-Servicesshd
 

IBM i上に作成した/home/ROB/.ssh/GDI_GDL57.pubというファイルを覚えていますか?
これは公開鍵/秘密鍵のペアの公開鍵部分です。それをこのPC上に取得する必要が有ります。
もしFTPを使うならバイナリーモードで転送してください。このファイルをPCに追加する必要が有ります。
ユーザーがローカル管理者グループに入っているかどうかによって、ファイルは2つの場所のどちらかに置かれます。

ユーザーがローカル管理者グループに入っていない場合:

ROBというユーザーをあなたにとって適切なユーザーに置き換え、C:\Users\rob\.sshに鍵が保管されます。

.sshというフォルダーを探し、存在しなければ作成します:

Windowsエクスプローラーは「.ssh」という名前のフォルダーを決して作らせてくれないという事に注意してください。
代わりに名前の後ろに追加の点を付けた「.ssh.」という名前を使います。
この追加の点は削除され、正しく「.ssh」と名付けられたフォルダーが出来上がります。

この.sshディレクトリにauthorized_keysというファイルがない場合、これを作成するためにIBM iからコピーしたファイルを単にコピーすることができます。
authorized_keysというファイルが存在する場合には、IBM iからコピーしたファイルの内容を既存のauthorized_keysの最終行の後ろに新たな行として付け加えます。

ユーザーがローカル管理者グループに入っている場合:

公開鍵はC:\ProgramData\ssh に保管されます。

このsshというディレクトリにadministrators_authorized_keysというファイルが存在しない場合、administrators_authorized_keysを作成するためにIBM iからコピーしたファイルを単にコピーすることができます。
administrators_authorized_keysが存在する場合には、IBM iからコピーしたファイルの内容を既存のadministrators_authorized_keysの最後の行の後ろに新しい行として付け加えます。

注:ファイルをコピーするためにiACSを使用する際にいくつかの問題が発生しました。
その理由は/home/ROB内に.sshというディレクトリが発見できなかったからです。
直接そのディレクトリに移ればファイルを見つけることはできましたが、それをコピーすることはできませんでした。
FileZillaを試したところ、PC上のターゲット・デレクトリに対する権限が原因でコピーできなかったことが分かりました。
そのファイルをPC上の別のディレクトリに置き、次にそれをコピーするためにWindowsファイル・エクスプローラーを使わなければなりませんでした。
それでも管理者権限を使用する必要が有りました。

PowerShellセッションの実行に戻ります:

$acl = Get-Acl C:\ProgramData\ssh\administrators_authorized_keys
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule("Administrators","FullControl","Allow")
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","Allow")
$acl.SetAccessRule($administratorsRule)
$acl.SetAccessRule($systemRule)
$acl | Set-Acl
 

接続をテストする

CALL QP2TERM

> ssh gdl57 'dir \users\rob\*.* >\users\rob\diroutput3.txt'
  ssh: ホストgdl57 ポート22に接続:接続が拒否されました。
  $
 

「接続が拒否されました」というメッセージが出された理由を調べるために、私はPowerShellに戻りました。

Get-Service sshd
Status   Name               DisplayName
------   ----               -----------
Stopped  sshd               OpenSSH SSH Server
Set-Service -Name sshd -StartupType 'Automatic'
Start-Service sshd
Get-Service sshd
Status   Name               DisplayName
------   ----               -----------
Running  sshd               OpenSSH SSH Server
 

それからQP2TERMに戻って再度試行しました。

> ssh gdl57 'dir \users\rob\*.* >\users\rob\diroutput3.txt'
 

 ホスト’gdl57.dekko-1 (10.10.2.71)’の信頼性が立証できません。  ECDSAキーの指紋はSHA256:euodvI3161T4admEYhBIaF8Zfv1ZBhur7gt4gNKAXHIです。  接続を継続したいですか(yes/no/[fingerprint])?

> yes                                                                        
 警告:既知ホストリストに'gdl57.dekko-1' (ECDSA)を恒久的に追加しました。
  $ 
 

これにより、IBM i上の/home/ROB/.ssh/known_hostsというファイルが更新されました。

これでPCの/users/robというディレクトリにdiroutput3.txtというファイルが見つかります。

できる限りQP2TERMを使って作業を行いましたが、本番用にパラメーターを渡すのにとてつもなく時間がかかりました。ですので、本番用には代わりにqshellを使用します。

QSH CMD('ssh gdl57 "dir \users\rob\*.* >\users\rob\diroutput3.txt"')

今やこれをRUNRMTCMDコマンドの代りに使用することができます。

参考資料

いいねと思ったらシェア
twitter
facebook
hatena
押さえておきたい!RPGの新機能 目次を見る

この連載は…

押さえておきたい!RPGの新機能
関連記事
【第20回】RPGの基礎:配列
【第20回】RPGの基礎:配列
【第33回】IWSを使ってウェブサービスを作る
【第33回】IWSを使ってウェブサービスを作る
【第19回】RPG可変長フィールド入門
【第19回】RPG可変長フィールド入門
あなたにオススメの連載
できるIBM i 温故知新編
7記事
できるIBM i 温故知新編
IBM i の”新”必須言語 〜FFRPG入門〜
14記事
IBM i の”新”必須言語 〜FFRPG入門〜
IBM i アプリの第二の柱 OSS
15記事
IBM i アプリの第二の柱 OSS
PAGE TOP