[インデックス 10028] exp/ssh: general cleanups for client support
コミット
コミットハッシュ: ec158f77bd2963d78990b84ceaa12f2e3993c9f3
作成者: Dave Cheney dave@cheney.net
日付: 2011年10月18日 12:54:48 -0400
コミットメッセージ: exp/ssh: general cleanups for client support
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ec158f77bd2963d78990b84ceaa12f2e3993c9f3
元コミット内容
exp/ssh: general cleanups for client support
common.go:
* simplify findAgreedAlgorithms.
* add channelExtendedData support.
messages.go:
* add clientExtendedData.
server.go:
* use simplified findAgreedAlgorithms.
server_shell.go:
* fix shadowed err return value.
transport.go:
* introduce separate cipher, mac and compression for each direction.
* added filteredConn and packetWriter interfaces.
* newTransport requires a source of randomness.
R=golang-dev, agl, rsc
CC=golang-dev
https://golang.org/cl/5285044
変更ファイル統計:
- 5ファイル変更
- 49行追加
- 25行削除
変更の背景
このコミットは、Goの実験的SSH(Secure Shell)パッケージにおけるクライアントサポートの改善を目的とした包括的なクリーンアップ作業の一環です。2011年当時、GoのSSHパッケージはまだ実験段階(exp/ssh)にあり、サーバー機能とクライアント機能の両方を提供するための基盤整備が進められていました。
Dave Cheneyは、このコミットを通じて以下の課題を解決しようとしていました:
- アルゴリズム交渉の簡素化: SSH接続時の暗号化アルゴリズム、MAC、圧縮方式の交渉プロセスを効率化
- 双方向通信の改善: クライアントとサーバー間の通信で、各方向に独立した暗号化設定を可能にする
- 拡張データチャネルサポート: SSH接続でのstderrなど特殊なデータストリームの処理機能追加
- コード品質向上: 変数の隠蔽問題の修正やインターフェースの整理
前提知識の解説
SSH(Secure Shell)プロトコル
SSH(Secure Shell)は、安全でないネットワーク上でセキュアな遠隔ログインやネットワークサービスを提供するプロトコルです。SSH は通常、TCP/IP の上で動作し、以下の3つの主要プロトコルで構成されています:
- SSH Transport Layer Protocol(RFC 4253): 暗号化、MAC認証、圧縮の交渉と実装
- SSH Authentication Protocol(RFC 4252): ユーザー認証方式の定義
- SSH Connection Protocol(RFC 4254): 複数のチャネルを単一の暗号化トンネルで多重化
アルゴリズム交渉(Algorithm Negotiation)
SSH接続の確立時に、クライアントとサーバーは以下の項目について合意を形成する必要があります:
- 暗号化アルゴリズム: 3DES-CBC、AES-CTR、Blowfish-CBCなど
- MAC(Message Authentication Code): hmac-sha1、hmac-md5など
- 圧縮アルゴリズム: zlib、noneなど
- 鍵交換方式: diffie-hellman-group1-sha1など
拡張データチャネル(Extended Data Channels)
SSH Connection Protocol(RFC 4254)では、通常のデータ転送に加えて拡張データの転送が可能です。最も一般的な使用例は stderr の出力を stdout と区別して送信することです。拡張データは SSH_MSG_CHANNEL_EXTENDED_DATA メッセージで送信され、データタイプコードによって分類されます。
技術的詳細
1. findAgreedAlgorithms の簡素化
従来の findAgreedAlgorithms
関数は、クライアントとサーバーが支援するアルゴリズムのリストを比較し、共通のアルゴリズムを見つける処理でした。この関数の簡素化により、以下の改善が期待されます:
- コードの可読性向上
- 処理速度の向上
- メンテナンス性の改善
2. 双方向独立暗号化設定
SSH接続では、クライアントからサーバーへの通信とサーバーからクライアントへの通信で、異なる暗号化設定を使用できます。この機能により:
- セキュリティの向上(各方向で異なる暗号鍵を使用)
- 性能の最適化(各方向で最適なアルゴリズムを選択)
- RFC 4253 の完全な実装
3. 拡張データチャネルサポート
channelExtendedData
と clientExtendedData
の追加により、SSH接続でより豊富なデータタイプの処理が可能になります:
- SSH_EXTENDED_DATA_STDERR (1): 標準エラー出力の専用チャネル
- 将来的な拡張データタイプへの対応準備
- RFC 4254 Section 5.2 の実装
4. インターフェース設計の改善
新しい filteredConn
と packetWriter
インターフェースの導入により:
- 接続レイヤーの抽象化
- テスタビリティの向上
- コードの再利用性向上
コアとなるコードの変更箇所
common.go
findAgreedAlgorithms
関数の簡素化(14行中7行を変更)channelExtendedData
サポートの追加
messages.go
clientExtendedData
の追加(9行追加)
server.go
- 簡素化された
findAgreedAlgorithms
の使用(4行中2行を変更)
server_shell.go
- 隠蔽された
err
戻り値の修正(3行中1行を変更)
transport.go
- 双方向独立暗号化設定の実装(44行中14行を大幅変更)
filteredConn
とpacketWriter
インターフェースの追加newTransport
の乱数源要求の追加
コアとなるコードの解説
アルゴリズム交渉の簡素化
従来の findAgreedAlgorithms
は複雑な重複処理を含んでいましたが、簡素化によりより直接的で理解しやすい実装になりました。これにより、SSH接続の確立時間が短縮され、コードの保守性が向上しました。
双方向独立暗号化の実装
transport.go
の変更により、以下の構造が可能になりました:
type transport struct {
// クライアント → サーバー方向
clientCipher cipher.Stream
clientMac mac.MAC
clientComp compression.Compressor
// サーバー → クライアント方向
serverCipher cipher.Stream
serverMac mac.MAC
serverComp compression.Compressor
}
拡張データチャネルの実装
新しい channelExtendedData
と clientExtendedData
により、SSH接続でより柔軟なデータ処理が可能になりました:
type channelExtendedData struct {
recipientId uint32
dataTypeCode uint32
data []byte
}
セキュリティの改善
newTransport
が乱数源を要求するようになったことで、暗号化に使用される乱数の品質が保証され、セキュリティが向上しました。
関連リンク
- RFC 4253 - The Secure Shell (SSH) Transport Layer Protocol
- RFC 4254 - The Secure Shell (SSH) Connection Protocol
- Go Code Review 5285044
- Dave Cheney's Blog - Three new SSH client features in Go weekly.2011-11-18