{"id":13764154,"url":"https://github.com/appleboy/easyssh-proxy","last_synced_at":"2025-05-14T07:08:10.196Z","repository":{"id":41570879,"uuid":"83750646","full_name":"appleboy/easyssh-proxy","owner":"appleboy","description":"easyssh-proxy provides a simple implementation of some SSH protocol features in Go","archived":false,"fork":false,"pushed_at":"2024-12-07T06:29:08.000Z","size":327,"stargazers_count":330,"open_issues_count":13,"forks_count":64,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-05-06T18:35:16.016Z","etag":null,"topics":["golang","proxy","ssh","ssh-proxycommand"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/appleboy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":["https://www.paypal.me/appleboy46"]}},"created_at":"2017-03-03T02:58:14.000Z","updated_at":"2025-02-23T06:17:32.000Z","dependencies_parsed_at":"2023-11-24T22:32:17.126Z","dependency_job_id":"ea88f2a8-d388-4d77-9553-721804f1cff0","html_url":"https://github.com/appleboy/easyssh-proxy","commit_stats":{"total_commits":134,"total_committers":15,"mean_commits":8.933333333333334,"dds":"0.12686567164179108","last_synced_commit":"2d3a277d8c1a34df0f0bf63489e418755abda277"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appleboy%2Feasyssh-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appleboy%2Feasyssh-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appleboy%2Feasyssh-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appleboy%2Feasyssh-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/appleboy","download_url":"https://codeload.github.com/appleboy/easyssh-proxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253517481,"owners_count":21920851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","proxy","ssh","ssh-proxycommand"],"created_at":"2024-08-03T15:01:16.899Z","updated_at":"2025-05-14T07:08:10.177Z","avatar_url":"https://github.com/appleboy.png","language":"Go","readme":"# easyssh-proxy\n\n[![GoDoc](https://godoc.org/github.com/appleboy/easyssh-proxy?status.svg)](https://pkg.go.dev/github.com/appleboy/easyssh-proxy)\n[![Lint and Testing](https://github.com/appleboy/easyssh-proxy/actions/workflows/testing.yml/badge.svg)](https://github.com/appleboy/easyssh-proxy/actions/workflows/testing.yml)\n[![codecov](https://codecov.io/gh/appleboy/easyssh-proxy/branch/master/graph/badge.svg)](https://codecov.io/gh/appleboy/easyssh-proxy)\n[![Go Report Card](https://goreportcard.com/badge/github.com/appleboy/easyssh-proxy)](https://goreportcard.com/report/github.com/appleboy/easyssh-proxy)\n[![Sourcegraph](https://sourcegraph.com/github.com/appleboy/easyssh-proxy/-/badge.svg)](https://sourcegraph.com/github.com/appleboy/easyssh-proxy?badge)\n\n[繁體中文](./README.zh-tw.md)\n\neasyssh-proxy provides a simple implementation of some SSH protocol features in Go.\n\n## Feature\n\nThis project is forked from [easyssh](https://github.com/hypersleep/easyssh) but add some features as the following.\n\n- [x] Support plain text of user private key.\n- [x] Support key path of user private key.\n- [x] Support Timeout for the TCP connection to establish.\n- [x] Support SSH ProxyCommand.\n\n```bash\n     +--------+       +----------+      +-----------+\n     | Laptop | \u003c--\u003e  | Jumphost | \u003c--\u003e | FooServer |\n     +--------+       +----------+      +-----------+\n\n                         OR\n\n     +--------+       +----------+      +-----------+\n     | Laptop | \u003c--\u003e  | Firewall | \u003c--\u003e | FooServer |\n     +--------+       +----------+      +-----------+\n     192.168.1.5       121.1.2.3         10.10.29.68\n```\n\n## Usage\n\nYou can see detailed examples of the `ssh`, `scp`, `Proxy`, and `stream` commands inside the [`examples`](./_examples/) folder.\n\n### MakeConfig\n\nAll functionality provided by this package is accessed via methods of the MakeConfig struct.\n\n```go\n  ssh := \u0026easyssh.MakeConfig{\n    User:    \"drone-scp\",\n    Server:  \"localhost\",\n    KeyPath: \"./tests/.ssh/id_rsa\",\n    Port:    \"22\",\n    Timeout: 60 * time.Second,\n  }\n\n  stdout, stderr, done, err := ssh.Run(\"ls -al\", 60*time.Second)\n  err = ssh.Scp(\"/root/source.csv\", \"/tmp/target.csv\")\n  stdoutChan, stderrChan, doneChan, errChan, err = ssh.Stream(\"for i in {1..5}; do echo ${i}; sleep 1; done; exit 2;\", 60*time.Second)\n```\n\nMakeConfig takes in the following properties:\n\n| property          | description                                                                                                                                    |\n| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |\n| user              | The SSH user to be logged in with                                                                                                              |\n| Server            | The IP or hostname pointing of the server                                                                                                      |\n| Key               | A string containing the private key to be used when making the connection                                                                      |\n| KeyPath           | The path pointing to the SSH key file to be used when making the connection                                                                    |\n| Port              | The port to use when connecting to the SSH daemon of the server                                                                                |\n| Protocol          | The tcp protocol to be used: `\"tcp\", \"tcp4\" \"tcp6\"`                                                                                            |\n| Passphrase        | The Passphrase to unlock the provided SSH key (leave blank if no Passphrase is required)                                                       |\n| Password          | The Password to use to login the specified user                                                                                                |\n| Timeout           | The length of time to wait before timing out the request                                                                                       |\n| Proxy             | An additional set of configuration params that will be used to SSH into an additional server via the server configured in this top-level block |\n| Ciphers           | An array of ciphers (e.g. aes256-ctr) to enable for the SSH connection                                                                         |\n| KeyExchanges      | An array of key exchanges (e.g. ecdh-sha2-nistp384) to enable for the SSH connection                                                           |\n| Fingerprint       | The expected fingerprint to be returned by the SSH server, results in a fingerprint error if they do not match                                 |\n| UseInsecureCipher | Enables the use of insecure ciphers and key exchanges that are insecure and can lead to compromise, [see ssh](#ssh)                            |\n\nNOTE: Please view the reference documentation for the most up to date properties of [MakeConfig](https://pkg.go.dev/github.com/appleboy/easyssh-proxy#MakeConfig) and [DefaultConfig](https://pkg.go.dev/github.com/appleboy/easyssh-proxy#DefaultConfig)\n\n### ssh\n\nSee [examples/ssh/ssh.go](./_examples/ssh/ssh.go)\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"time\"\n\n  \"github.com/appleboy/easyssh-proxy\"\n)\n\nfunc main() {\n  // Create MakeConfig instance with remote username, server address and path to private key.\n  ssh := \u0026easyssh.MakeConfig{\n    User:   \"appleboy\",\n    Server: \"example.com\",\n    // Optional key or Password without either we try to contact your agent SOCKET\n    // Password: \"password\",\n    // Paste your source content of private key\n    // Key: `-----BEGIN RSA PRIVATE KEY-----\n    // MIIEpAIBAAKCAQEA4e2D/qPN08pzTac+a8ZmlP1ziJOXk45CynMPtva0rtK/RB26\n    // 7XC9wlRna4b3Ln8ew3q1ZcBjXwD4ppbTlmwAfQIaZTGJUgQbdsO9YA==\n    // -----END RSA PRIVATE KEY-----\n    // `,\n    KeyPath: \"/Users/username/.ssh/id_rsa\",\n    Port:    \"22\",\n    Timeout: 60 * time.Second,\n\n    // Parse PrivateKey With Passphrase\n    Passphrase: \"1234\",\n\n    // Optional fingerprint SHA256 verification\n    // Get Fingerprint: ssh.FingerprintSHA256(key)\n    // Fingerprint: \"SHA256:mVPwvezndPv/ARoIadVY98vAC0g+P/5633yTC4d/wXE\"\n\n    // Enable the use of insecure ciphers and key exchange methods.\n    // This enables the use of the the following insecure ciphers and key exchange methods:\n    // - aes128-cbc\n    // - aes192-cbc\n    // - aes256-cbc\n    // - 3des-cbc\n    // - diffie-hellman-group-exchange-sha256\n    // - diffie-hellman-group-exchange-sha1\n    // Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.\n    // UseInsecureCipher: true,\n  }\n\n  // Call Run method with command you want to run on remote server.\n  stdout, stderr, done, err := ssh.Run(\"ls -al\", 60*time.Second)\n  // Handle errors\n  if err != nil {\n    panic(\"Can't run remote command: \" + err.Error())\n  } else {\n    fmt.Println(\"don is :\", done, \"stdout is :\", stdout, \";   stderr is :\", stderr)\n  }\n}\n```\n\n### scp\n\nSee [examples/scp/scp.go](./_examples/scp/scp.go)\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  \"github.com/appleboy/easyssh-proxy\"\n)\n\nfunc main() {\n  // Create MakeConfig instance with remote username, server address and path to private key.\n  ssh := \u0026easyssh.MakeConfig{\n    User:     \"appleboy\",\n    Server:   \"example.com\",\n    Password: \"123qwe\",\n    Port:     \"22\",\n  }\n\n  // Call Scp method with file you want to upload to remote server.\n  // Please make sure the `tmp` floder exists.\n  err := ssh.Scp(\"/root/source.csv\", \"/tmp/target.csv\")\n\n  // Handle errors\n  if err != nil {\n    panic(\"Can't run remote command: \" + err.Error())\n  } else {\n    fmt.Println(\"success\")\n  }\n}\n```\n\n### SSH ProxyCommand\n\nSee [examples/proxy/proxy.go](./_examples/proxy/proxy.go)\n\n```go\n  ssh := \u0026easyssh.MakeConfig{\n    User:    \"drone-scp\",\n    Server:  \"localhost\",\n    Port:    \"22\",\n    KeyPath: \"./tests/.ssh/id_rsa\",\n    Timeout: 60 * time.Second,\n    Proxy: easyssh.DefaultConfig{\n      User:    \"drone-scp\",\n      Server:  \"localhost\",\n      Port:    \"22\",\n      KeyPath: \"./tests/.ssh/id_rsa\",\n      Timeout: 60 * time.Second,\n    },\n  }\n```\n\nNOTE: Properties for the Proxy connection are not inherited from the Jumphost. You must explicitly specify them in the DefaultConfig struct.\n\ne.g. A custom `Timeout` length must be specified for both the Jumphost (intermediary server) and the destination server.\n\n### SSH Stream Log\n\nSee [examples/stream/stream.go](./_examples/stream/stream.go)\n\n```go\nfunc main() {\n  // Create MakeConfig instance with remote username, server address and path to private key.\n  ssh := \u0026easyssh.MakeConfig{\n    Server:  \"localhost\",\n    User:    \"drone-scp\",\n    KeyPath: \"./tests/.ssh/id_rsa\",\n    Port:    \"22\",\n    Timeout: 60 * time.Second,\n  }\n\n  // Call Run method with command you want to run on remote server.\n  stdoutChan, stderrChan, doneChan, errChan, err := ssh.Stream(\"for i in {1..5}; do echo ${i}; sleep 1; done; exit 2;\", 60*time.Second)\n  // Handle errors\n  if err != nil {\n    panic(\"Can't run remote command: \" + err.Error())\n  } else {\n    // read from the output channel until the done signal is passed\n    isTimeout := true\n  loop:\n    for {\n      select {\n      case isTimeout = \u003c-doneChan:\n        break loop\n      case outline := \u003c-stdoutChan:\n        fmt.Println(\"out:\", outline)\n      case errline := \u003c-stderrChan:\n        fmt.Println(\"err:\", errline)\n      case err = \u003c-errChan:\n      }\n    }\n\n    // get exit code or command error.\n    if err != nil {\n      fmt.Println(\"err: \" + err.Error())\n    }\n\n    // command time out\n    if !isTimeout {\n      fmt.Println(\"Error: command timeout\")\n    }\n  }\n}\n```\n","funding_links":["https://www.paypal.me/appleboy46"],"categories":["Software Packages","Go Tools","DevOps Tools","軟件包","软件包","Go","Go 工具"],"sub_categories":["DevOps Tools","DevOps 工具","devops 工具","代码分析","DevOps工具"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappleboy%2Feasyssh-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappleboy%2Feasyssh-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappleboy%2Feasyssh-proxy/lists"}