Golang: ローカル SSH Config を読み取りリモートサーバーに接続する
James Reed
Infrastructure Engineer · Leapcell

Goアプリケーションを開発する際、SSH経由でリモートサーバーに接続する必要がある場合、ローカルのSSH構成を活用することでプロセスを効率化できます。このアプローチにより、Goアプリケーションは事前定義された接続設定を利用できるようになり、一貫性と効率が向上します。
Key Takeaways
- Goアプリケーションは
~/.ssh/config
を利用してSSH接続を効率化できます。 github.com/kevinburke/ssh_config
パッケージは、GoでSSH構成ファイルを解析するのに役立ちます。golang.org/x/crypto/ssh
パッケージを使用すると、GoでSSHクライアントを実装できます。
ローカルSSH構成ファイルの理解
SSHクライアント構成ファイル(通常は~/.ssh/config
にあります)を使用すると、ユーザーはさまざまなホストの接続パラメーターを定義できます。このファイルの標準的なエントリは次のようになります。
Host example HostName example.com User your-username Port 22 IdentityFile ~/.ssh/id_rsa
この構成では、次のようになります。
- Host: ホストのエイリアス。SSHコマンドのショートカットとして使用されます。
- HostName: リモートサーバーの実際のドメインまたはIPアドレス。
- User: SSH接続のユーザー名。
- Port: SSHサービスが実行されているポート(デフォルトは22)。
- IdentityFile: 認証用の秘密鍵へのパス。
これらの設定を構成すると、簡略化されたコマンドを使用してリモートサーバーに接続できます。
ssh example
GoでのSSH構成の統合
GoアプリケーションにこれらのSSH構成を読み取って利用させるには、次の手順に従います。
-
SSH構成ファイルの読み取り:
~/.ssh/config
ファイルを開いて解析し、必要なホスト構成を取得します。 -
ホスト情報の抽出: アプリケーションが接続する必要がある特定のホストエントリを識別し、
HostName
、User
、Port
、IdentityFile
などのパラメーターを抽出します。 -
GoでSSHクライアントを構成する: 抽出されたパラメーターを使用して、Goアプリケーション内でSSHクライアントを設定します。
Goでのソリューションの実装
Goのgolang.org/x/crypto/ssh
パッケージは、SSHクライアントの実装を容易にします。ただし、SSH構成ファイルはネイティブに解析しません。このギャップを埋めるには、github.com/kevinburke/ssh_config
パッケージを使用できます。このパッケージは、SSH構成ファイルを解析する機能を提供します。
まず、パッケージをインストールします。
go get github.com/kevinburke/ssh_config
次に、次のコードを実装してSSH接続を設定します。
package main import ( "fmt" "io/ioutil" "log" "os" "path/filepath" "github.com/kevinburke/ssh_config" "golang.org/x/crypto/ssh" ) func main() { host := "example" // SSH構成で定義されたエイリアス // SSH構成ファイルの場所 sshConfigPath := filepath.Join(os.Getenv("HOME"), ".ssh", "config") // SSH構成ファイルを開いて解析する configFile, err := os.Open(sshConfigPath) if err != nil { log.Fatalf("SSH構成ファイルを開けませんでした: %v", err) } defer configFile.Close() sshConfig, err := ssh_config.Decode(configFile) if err != nil { log.Fatalf("SSH構成ファイルの解析に失敗しました: %v", err) } // ホストの関連構成を抽出する hostname := sshConfig.Get(host, "HostName") if hostname == "" { log.Fatalf("ホストのHostNameが見つかりません: %s", host) } user := sshConfig.Get(host, "User") if user == "" { user = os.Getenv("USER") // 指定されていない場合は現在のユーザーをデフォルトにする } port := sshConfig.Get(host, "Port") if port == "" { port = "22" // デフォルトのSSHポート } identityFile := sshConfig.Get(host, "IdentityFile") if identityFile == "" { identityFile = filepath.Join(os.Getenv("HOME"), ".ssh", "id_rsa") // デフォルトキー } // 秘密鍵を読み取る key, err := ioutil.ReadFile(identityFile) if err != nil { log.Fatalf("秘密鍵を読み取れません: %v", err) } // 秘密鍵の署名者を作成する signer, err := ssh.ParsePrivateKey(key) if err != nil { log.Fatalf("秘密鍵の解析に失敗しました: %v", err) } // SSHクライアント構成を設定する clientConfig := &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 単純化のため。ホストキーの検証の実装を検討してください } // SSHサーバーに接続する connection, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", hostname, port), clientConfig) if err != nil { log.Fatalf("ダイヤルに失敗しました: %v", err) } defer connection.Close() // これで、'connection' を使用してリモートサーバーと対話できます // たとえば、セッションを開きます: session, err := connection.NewSession() if err != nil { log.Fatalf("セッションの作成に失敗しました: %v", err) } defer session.Close() // リモートサーバーでコマンドを実行する output, err := session.CombinedOutput("uname -a") if err != nil { log.Fatalf("コマンドの実行に失敗しました: %v", err) } fmt.Println(string(output)) }
FAQs
SSH構成を使用すると、セキュリティが向上し、ハードコードされた資格情報が回避され、環境全体で一貫性が確保されます。
github.com/kevinburke/ssh_config
パッケージは、SSH構成をプログラムで読み取って抽出できます。
パーサーは、SSHの標準的な優先順位規則に従って、最も具体的な一致を使用します。
重要な考慮事項
-
HostKeyCallback: 上記の例では、
ssh.InsecureIgnoreHostKey()
は単純化のために使用されており、ホストキーの検証をバイパスします。本番アプリケーションの場合は、セキュリティを確保するために適切なホストキーの検証を実装します。 -
エラー処理: SSH構成ファイルが欠落しているエントリまたは不正な情報を含むシナリオを管理するために、堅牢なエラー処理を確保してください。
-
セキュリティ: 常に秘密鍵を保護し、アプリケーション内に機密情報をハードコーディングしないでください。
GoアプリケーションをローカルのSSH構成と統合することで、既存の構成を活用し、開発環境全体で一貫性を維持しながら、SSH接続をより効率的に管理できます。
Goプロジェクトのトップチョイス、Leapcellにお任せください。
Leapcellは、Webホスティング、非同期タスク、およびRedis向けの次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、またはRustで開発します。
無制限のプロジェクトを無料でデプロイ
- リクエストや料金なしで、使用量に対してのみ支払います。
比類のない費用対効果
- アイドル料金なしの従量課金制。
- 例:$25で、平均応答時間60msで694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOpsの統合。
- 実用的な洞察を得るためのリアルタイムメトリックとロギング。
容易なスケーラビリティと高いパフォーマンス
- 高い同時実行性を容易に処理するための自動スケーリング。
- 運用オーバーヘッドはゼロ — 構築に集中するだけです。
詳細については、ドキュメントをご覧ください。
Xでフォローしてください:@LeapcellHQ