{"id":26436168,"url":"https://github.com/nimatrueway/unbound-ssh","last_synced_at":"2026-04-19T14:05:42.359Z","repository":{"id":233374209,"uuid":"723564741","full_name":"nimatrueway/unbound-ssh","owner":"nimatrueway","description":"Convert any limited interactive shell session (ssh) into a fully-featured ssh, a webdav file sharing host, a port-forwarding agent, a vpn-server, etc.","archived":false,"fork":false,"pushed_at":"2024-11-11T23:26:41.000Z","size":79,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T08:15:18.265Z","etag":null,"topics":["bastion","file","gateway","interactive","port-forwarding","shell","ssh","transfer","vpn"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nimatrueway.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-11-26T04:06:30.000Z","updated_at":"2025-02-06T21:47:52.000Z","dependencies_parsed_at":"2024-04-17T02:41:18.318Z","dependency_job_id":"98bda1f8-4b32-4e37-8177-f66495cb9fbb","html_url":"https://github.com/nimatrueway/unbound-ssh","commit_stats":null,"previous_names":["nimatrueway/unbound-ssh"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/nimatrueway/unbound-ssh","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimatrueway%2Funbound-ssh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimatrueway%2Funbound-ssh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimatrueway%2Funbound-ssh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimatrueway%2Funbound-ssh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nimatrueway","download_url":"https://codeload.github.com/nimatrueway/unbound-ssh/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nimatrueway%2Funbound-ssh/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32009243,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["bastion","file","gateway","interactive","port-forwarding","shell","ssh","transfer","vpn"],"created_at":"2025-03-18T08:15:12.860Z","updated_at":"2026-04-19T14:05:42.341Z","avatar_url":"https://github.com/nimatrueway.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Unbound SSH\n\n\u003cp align=\"center\"\u003e\n    \u003cimg width=\"500\" src=\"logo.svg\" /\u003e\n\u003c/p\u003e\n\nunbound-ssh is a tool that allows you to work around the restrictions an ssh server set by an administrator. It only\nneeds an interactive shell access on the server to work, multi-hop servers are also supported.\n\nthe project is largely inspired by [trzsz](https://github.com/trzsz/trzsz-go)\nand [SaSSHimi](https://github.com/rsrdesarrollo/SaSSHimi) projects.\n\n# Mechanism\n\nWe do not distributed separate binaries for server and agent, so unbound-ssh binary needs to be launched on your laptop\n👨🏻‍💻 in\n**listen mode** and on the interactive ssh server 🖥️ in **spy mode**. The two process will then communicate in\nhex-encoded text (or other available codecs) through **STDIN**/**STDOUT** streams.\n\nUnbound SSH reads [config.toml](config.toml) to know what service to provide on\nwhat port. This file is needed in either **listen mode** or **spy mode**.\n\nFor your convenience we have created **preflight** scripts, which gets launched if you press `\u003cctrl+g\u003e` three times on a\nsafe directory on the server. The preflight script will upload the binary file (only if needed), config file and its\ndependencies (such as the certificate for embedded_ssh service) to the server. After that, you can go ahead and launch\nunbound-ssh in spy mode.\n\n# Example\n\n```bash\n# let `unbound-ssh listen` tap into the byte stream of your connection\n💻 laptop$ unbound-ssh listen -- ssh user@server.com\nConnecting to server.com...\n\n# trigger preflight script\n# (it uploads unbound-ssh binary, the config file and its dependencies to the local directory on server)\n🌩️ server$ \u003cctrl+g\u003e\u003cctrl+g\u003e\u003cctrl+g\u003e\n\n# run `unbound-ssh spy` on your server to connect\n🌩️ server$ ./unbound-ssh spy\n\n# 🎉 you're all good, now use the services you defined in config.toml\n# the following ⬇️ subsection will show you how to define services\n```\n\n# Configuration\n\nAside from tweaking parameters, Unbound SSH reads [config.toml](config.toml) to know what service to provide on\nwhat port. You are allowed to define more than one service.\n\n## [Embedded SSH](#embedded-ssh)\n\nIf the ssh you used to connect your server is too restrictive and does not allow port-forwarding, file\ntransfer, non-interactive command execution, etc you can have unbound-ssh to launch its own unrestricted ssh server 🌈\nand let you connect to it\nfrom your laptop.\n\n```toml\n[[service]]\ntype = \"embedded_ssh\"\n# binds to this host/port on your laptop\nbind = \"tcp://unbound-ssh.local:10691\"\n# continue reading to see how to create this\ncertificate = \"cert/unbound-ssh.local-key.pem\"\n```\n\nEncryption is mandatory for an SSH server so embedded_ssh needs a valid ssl certificate, you can\nleverage [txeh](https://github.com/txn2/txeh) and\n[mkcert](https://github.com/FiloSottile/mkcert) to define a local host and create a valid local certificate for it.\n\n```shell\n# define local host \"unbound-ssh.local\"\n# that resolves to \"127.0.0.1\" loopback address \nbrew install txn2/tap/txeh\nsudo txeh add 127.0.0.1 unbound-ssh.local\n\n# create a certificate for it\n# unbound ssh uses this to encrypt traffic\nbrew install mkcert\nmkcert -install\nmkdir cert; pushd cert; mkcert unbound-ssh.local; popd\n```\n\n## Embedded Webdav\n\nSince FTP [can not be served on simple tcp connection](https://www.jscape.com/blog/active-v-s-passive-ftp-simplified);\nalthough not impossible, I did not bother to implement it and\nopted for a webdav service for file transfer. Considering the fact that golang's ssh\nserver [does not support compression](https://github.com/golang/go/issues/31369), and you may not want to bother setting\nup certificates and pay for the encryption\noverhead that accompanies sftp, you can opt for a simple webdav server for fast quick file\ntransfer.\n\n```toml\n[[service]]\ntype = \"embedded_webdav\"\nbind = \"tcp://127.0.0.1:10690\"\n```\n\n## Port Forward\n\nFor the same reasons as above, you may want to simply launch a port-forward instead of a fully-fledged ssh server. This\nis how you can do it.\n\n```toml\n[[service]]\ntype = \"port_forward\"\nbind = \"tcp://127.0.0.1:10692\"\ndestination = \"tcp://my-database-server.us-east-1.rds.amazonaws.com:3306\"\n```\n\nif a correct host name is crucial to your use case (e.g. http, https) you can use `txeh` to define a local host and\nattach it to your loopback address pretty much like how it is done for the embedded ssh service.\n\n## Echo\n\nThis service is only for testing purposes. Spy agent simply echoes back the message you send to it.\n\n```toml\n[[service]]\ntype = \"echo\"\nbind = \"tcp://127.0.0.1:10689\"\n```\n\n# Supported Platforms\n\n- [x] Linux (x64, arm64)\n- [x] macOS (x64, arm64)\n- [ ] Windows (x64) _(no plan to support it, consider using WSL instead)_\n\n# Feature Comparison\n\n| Feature                        | unbound-ssh      | trzsz | SaSSHimi |\n|--------------------------------|------------------|-------|----------|\n| Port Forward                   | ✔                | ⨯     | ⨯        |\n| VPN                            | ✔ \u003csup\u003e[1]\u003c/sup\u003e | ⨯     | ⨯        |\n| File Transfer                  | ✔                | ✔     | ✔        |\n| Interactive-Only Shell Support | ✔                | ✔     | ⨯        |\n| Multi-Hop Servers              | ✔                | ✔     | ⨯        |\n| Agent Auto Install             | ✔                | ⨯     | ⨯        |\n| Tmux Support                   | ⨯ \u003csup\u003e[2]\u003c/sup\u003e | ✔     | ⨯        |\n| Windows Support                | ⨯ \u003csup\u003e[3]\u003c/sup\u003e | ✔     | ⨯        |\n\n1. through [sshuttle](https://github.com/sshuttle/sshuttle) over [embedded ssh server](#embedded-ssh)\n2. consider using multiple ssh sessions through [embedded ssh server](#embedded-ssh) instead\n3. consider using [WSL](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux) instead\n\n# Development\n\n[DEVELOPMENT.md](DEVELOPMENT.md)\n\n# Future Work\n\nMoved to [FUTUREWORK.md](FUTUREWORK.md)\n\n# Key Library Dependencies\n\n- [creack/pty](github.com/creack/pty) to create pty and interact with it\n- [hashicorp/yamux](github.com/hashicorp/yamux) to multiplex connections over a single duplex stream\n- [gliderlabs/ssh](github.com/gliderlabs/ssh) to power ssh server\n- [spf13/cobra](github.com/spf13/cobra) for process args processing\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimatrueway%2Funbound-ssh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnimatrueway%2Funbound-ssh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimatrueway%2Funbound-ssh/lists"}