tech:ssh
差分
このページの2つのバージョン間の差分を表示します。
— | tech:ssh [2023/05/13 15:15] (現在) – 作成 - 外部編集 127.0.0.1 | ||
---|---|---|---|
行 1: | 行 1: | ||
+ | ====== sshに関して ====== | ||
+ | 技術メモなどに色々バラバラに書いていたssh関係を一度まとめる。 | ||
+ | 詳細は色々な本などにあるだろうし、過去記事のまとめ程度に抑えておく。 | ||
+ | ===== ssh とは ===== | ||
+ | sshは、Secure Shell から名前をとった、リモート端末との通信を行うためのプロトコル、コマンドのことをいう。 | ||
+ | * 大本に、rsh(remote shell)がある。rshは、Remote Shellから名前をとったもの | ||
+ | * 他に、telnetやrloginなどもある。何れにしても暗号化などの保護はない。なお、telnetにSSL/ | ||
+ | * rshには、通信保護の機構はなく、通信内容はRPCを利用し、生データが流れていた | ||
+ | * sshでは、RPCを利用することをやめ、ssh daemonとssh client間で暗号化された通信路を用いてデータをやりとりする | ||
+ | |||
+ | sshはRFCにより仕様が規定および公開されている。(20190925時点で調べたもの。今ではもっとあるんだろうけど、面倒だから調べてない) | ||
+ | * [[ https:// | ||
+ | * [[ https:// | ||
+ | * [[ https:// | ||
+ | * [[ https:// | ||
+ | * [[ https:// | ||
+ | * [[ https:// | ||
+ | * [[ https:// | ||
+ | |||
+ | ===== 機能関係 ===== | ||
+ | 以下、[[https:// | ||
+ | |||
+ | 対象とする実装は、[[ https:// | ||
+ | |||
+ | ^ Option ^ Config Param name ^ default ^ descriptions ^ | ||
+ | | -A/-a | | ||
+ | | -D | ||
+ | | -e | EscapeChar | ||
+ | | ::: | ::: | ::: | none: エスケープ文字を禁止する。(Binary Dataに対して透過になる) | | ||
+ | | -F | ||
+ | | -f | ||
+ | | -J | ||
+ | | ::: | ::: | ::: | 対象ホストの名前解決ができなければならない | | ||
+ | | -L | LocalForward | ||
+ | | -l | User | | login名 | | ||
+ | | -N | ||
+ | | -n | ||
+ | | -O | ||
+ | | ::: | ::: | ::: | forward: port forwardを要求 / cancel: port forwardをキャンセル | | ||
+ | | ::: | ::: | ::: | exit: Master Processを終了する / stop: これ以上の分岐を禁止する | | ||
+ | | -o | ||
+ | | -M | ControlMaster | ||
+ | | -Q | ||
+ | | ::: | ::: | ::: | mac(メッセージ認証コードの種類)/ | ||
+ | | ::: | ::: | ::: | key-plain(証明書ではない鍵の形式)/ | ||
+ | | -q | ||
+ | | -R | RemoteForward | ||
+ | | -S | ControlPath | ||
+ | | -T/-t | RequestTTY | ||
+ | | -X/-x | ForwardX11 | ||
+ | | -y | ||
+ | | | BatchMode | ||
+ | | | CheckHostIP | ||
+ | | | ConnectionAttmpts | 1 | 接続試行回数 | | ||
+ | | | ConnectTimeout | ||
+ | | | ControlPath | ||
+ | | | ControlPersist | ||
+ | | ::: | ::: | ::: | yes / 0 : MasterはBackgroundに移行し、永続的に保持される | | ||
+ | | ::: | ::: | ::: | 数値(秒) / 時間形式 : idleな時間が指定値を越えると接続が終了 | | ||
+ | | ::: | ::: | ::: | OpenSSH 5.6以降でのみ利用可能 | | ||
+ | | | ForwardAgent | ||
+ | | | IdentityFile | ||
+ | | ::: | ::: | ::: | force: 常に要求 /auto: loginセッションの時だけ要求する | | ||
+ | |||
+ | ==== ControlMaster ==== | ||
+ | * Masterになる場合、 '' | ||
+ | * Masterの接続を流用する場合、'' | ||
+ | * ControlPathに指定されたSocket Fileがない場合には、通常の接続が行われる | ||
+ | * '' | ||
+ | * ControlPathの引数にはEscape Sequenceが利用できる | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | ==== ControlMasterに関するCommand line ==== | ||
+ | * '' | ||
+ | * Masterとして動作し、RemoteのTTYを掴む。 | ||
+ | * 制御用socketは(FreeBSDの場合)''/ | ||
+ | * 制御用socketのファイル名を取得する方法がない | ||
+ | * '' | ||
+ | * Masterとして動作し、RemoteのTTYを掴む。 | ||
+ | * 制御用socketは'' | ||
+ | * '' | ||
+ | * Masterとして動作し、Socketを作成した後sshはBackgroundに | ||
+ | * 制御用socketは'' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ==== shell scriptとssh ==== | ||
+ | shell scriptにおいて、ファイルから1行ずつ読み込んで処理をするような場合、以下のようにかける。 | ||
+ | |||
+ | <code bash> | ||
+ | while read line; do | ||
+ | echo ${line} | ||
+ | done < file | ||
+ | </ | ||
+ | |||
+ | ところが、この手を使ってsshを実行すると、なぜか最初の行しか実行されない | ||
+ | |||
+ | <code bash> | ||
+ | while read line; do | ||
+ | ssh xxx.xxx.xxx.xxx ${line} # XXX 期待通りに動かない | ||
+ | done < file | ||
+ | </ | ||
+ | |||
+ | 原因はsshコマンド実行に伴う標準入力の切替と考えられる。 | ||
+ | sshコマンドを実行すると、ローカルホストのstdinからの入力を終了し、sshで指定したリモートホストのstdinからの入力受付を開始する。 | ||
+ | 従って、ローカルホストのファイルの読込みを終了させた上でsshコマンドを実行し、再びreadコマンドを実行しようとしていると考えられる。もちろん、この時点で既にファイルがcloseされている為、whileが終了してしまう。 | ||
+ | |||
+ | 対策は、sshに'' | ||
+ | |||
+ | この原因がちっともわからず、数時間を無駄にしてしまった。 | ||
+ | |||
+ | <code bash> | ||
+ | while read line; do | ||
+ | ssh -n xxx.xxx.xxx.xxx ${line} # これで/ | ||
+ | done < file | ||
+ | </ | ||
+ | |||
+ | このほかに、for文で '' | ||
+ | |||
+ | <code bash> | ||
+ | IFS=$' | ||
+ | for line in `cat file`; do # while readの代わりにcatで読み込ませる | ||
+ | ssh -n xxx.xxx.xxx.xxx ${line} | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | あと、whileはちょっと特殊な制御文で、場合によってはwhile内で変数設定しているはずなのにloopをでてくると変数が空のようなことが起こる。 | ||
+ | これは、Whileと他のコマンドを組み合わせた場合、組み合わせ方次第で処理がsubshellがわで処理されてしまう事が原因である。 | ||
+ | shellでpipelineを用いて実行した処理は、subshellで処理される。while loopの内部でpipelineを利用すると、whileブロック全体がsubshellで処理されるため、whileブロックの内部と外部で変数の共有が出来ない。 | ||
+ | このような場合、whileに対して出力をredirectしてやることで解決できる。 | ||
+ | |||
+ | <code bash> | ||
+ | while read line; do | ||
+ | OUT=`echo ${line} | sed ' | ||
+ | done < $1 | ||
+ | echo ${OUT} | ||
+ | </ | ||
+ | |||
+ | なお、/ | ||
+ | |||
+ | ===== sftpとscp関連 ===== | ||
+ | scpには様々な問題があるということで、scpはDeprecatedになっており、sftpを利用したファイル転送を利用すべきである。 | ||
+ | |||
+ | というわけで、メモ | ||
+ | |||
+ | [[http:// | ||
+ | [[http:// | ||
+ | |||
+ | 要するに、/ | ||
+ | |||
+ | ちなみに、sshd_configに ForceCommand internal-sftp を追加しないと、passwdに記載されているshellを実行しようとするので注意。 | ||
+ | |||
+ | ===== sshと二要素認証 ===== | ||
+ | 参考 | ||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | 要するに、BSDでは、上記patchを当てないと出来ないが、RSA AuthenticationとChallenge Response Authenticationを組み合わせて二要素認証にするという話。 | ||
+ | |||
+ | / | ||
+ | |||
+ | < | ||
+ | ChallengeResponseAuthentication yes | ||
+ | RSAAuthentication yes | ||
+ | |||
+ | RequiredAuthentications2 publickey, | ||
+ | </ | ||
+ | |||
+ | Password Authenticationを使う事は出来ないっぽいけど、まだ試してない。 | ||
+ | |||
+ | ===== sshdでPublickeyをauthorized_keys以外から持ってくる ===== | ||
+ | |||
+ | ちょっと某所で sshd でのPublickey Authentication時のPublickeyを~/ | ||
+ | |||
+ | ==== 問題 ==== | ||
+ | * '' | ||
+ | * sshd_configに以下の記述 | ||
+ | * '' | ||
+ | * '' | ||
+ | * pubkey.shは以下の通り | ||
+ | * <code - pubkey.sh> | ||
+ | #!/bin/bash -e | ||
+ | echo " | ||
+ | </ | ||
+ | * ssh -v の結果 | ||
+ | * < | ||
+ | Permission denied (publickey, | ||
+ | </ | ||
+ | |||
+ | ==== 解決 ==== | ||
+ | * sshdのlogを見ると、'' | ||
+ | * 色々調べてみると、以下が判明 | ||
+ | * sshdは以下の条件のうち一つでも満たすと、上記エラーを吐く | ||
+ | - 他人に書き換えられる可能性のあるDirectoryに設置されている(/ | ||
+ | - Ownerがrootではない | ||
+ | - Owner以外が書き換えることができる(g+wとかo+wだとまずい) | ||
+ | - AuthorizedKeysCommandUser に指定されたUser Accountで実行できない | ||
+ | * というわけで、以下のように修正 | ||
+ | * Scriptを''/ | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * sshdを再起動 | ||
+ | |||
+ | ==== 結論 ==== | ||
+ | * この手法を使えば、LDAPでsshの公開鍵を引っ張ってくることができそうだ | ||
+ | * OpenSSHはSecurity的に相当細かくCheckしているので、ある程度はこの手法を利用しても安全性を確保できそうだ | ||
+ | * 意外と問題の原因が分かりにくいので、追いかけるのが大変 | ||
+ | * 俺はエスパーじゃないので、何をどうしたいのか説明してくれ | ||
+ | |||
+ | ===== sshの秘密鍵をOS-XのKeychain Accessに登録 ===== | ||
+ | |||
+ | OS-Xで'' | ||
+ | そういえば、むかーしむかしに見たような気もする。 | ||
+ | |||
+ | < | ||
+ | -K When adding identities, each passphrase will also be stored in your | ||
+ | keychain. | ||
+ | be removed from your keychain. | ||
+ | </ | ||
+ | |||
+ | つまり、'' | ||
+ | |||
+ | ===== OS-Xでsshdの待ち受けポートを変更する ===== | ||
+ | |||
+ | MacOS-Xでリモートアクセスを許可すると、sshで接続できるようになる。 | ||
+ | |||
+ | しかし、/ | ||
+ | |||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | このSockServiceNameの文字列sshを待ち受けたいport番号にかえればOK。なお、この例では65535にしているが、ポート番号は適当にどうぞ。 | ||
+ | |||
+ | なお、当然、この変更を行った後で | ||
+ | < | ||
+ | % sudo launchctl unload / | ||
+ | % sudo launchctl load / | ||
+ | </ | ||
+ | を実行する事。そうしないと、変更が反映されないよ。ま、再起動でもいいけどね。 | ||
+ | |||
+ | ===== sshとcron ===== | ||
+ | |||
+ | Backupを取得するに際して、Backupを元々のServerに置いておいたら、Disk破損の時に一気に死ぬ。 | ||
+ | で、そんな事態は救われないので、BackupをRemoteに置いておくために、Backup Scriptまで作ったわけだが、Serverの内側でcronなどでBackupを取得するのは設定ミスとか管理の分散とかが起こってうれしくない。 | ||
+ | というわけで、remoteからsshを利用してBackupを取得するようにscriptを作ったのだが、 | ||
+ | < | ||
+ | Pseudo-terminal will not be allocated because stdin is not a terminal. | ||
+ | </ | ||
+ | などといいうErrorが出た。で、これはptyの割り付けないremoteからのコマンドは実行できないということでsshが吐き出すErrorである。 | ||
+ | |||
+ | しかし、shell scriptには'' | ||
+ | |||
+ | で、困りに困って調べてみたら、出てました。man ssh | ||
+ | < | ||
+ | | ||
+ | grams on a remote machine, which can be very useful, e.g. when implementing menu ser- | ||
+ | | ||
+ | </ | ||
+ | |||
+ | よく見たら、'' | ||
+ | |||
+ | 要するに、'' | ||
+ | |||
+ | わかりにくいからメモにしておく。 | ||
+ | |||
+ | 教訓は、RTFM ... orz. | ||
+ | |||
+ | ===== 古いNetwork機器に対するssh接続 ===== | ||
+ | うちの環境にはいまだに古いAlaxalAのL2 SwitchやApresiaのL3 Switchがあるのだが、これが古いssh protocolをしゃべる。 | ||
+ | そのため、2023/ | ||
+ | |||
+ | その解消のためには、~/ | ||
+ | |||
+ | < | ||
+ | # for AlaxalA AX2430S | ||
+ | Host [IP Address] [alias name] ... | ||
+ | HostKeyAlgorithms | ||
+ | KexAlgorithms | ||
+ | |||
+ | # for Apressia | ||
+ | Host [IP Address] [alias name] ... | ||
+ | KexAlgorithms | ||
+ | </ |
tech/ssh.txt · 最終更新: 2023/05/13 15:15 by 127.0.0.1