{"_id":"@arpadegyed/burrow","_rev":"2-41d9484c5fba5fa8551aa6d2937dc143","name":"@arpadegyed/burrow","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@arpadegyed/burrow","version":"1.0.0","keywords":["ssh","tunnel","burrow","typescript"],"author":{"name":"Arpad Egyed"},"license":"Apache-2.0","_id":"@arpadegyed/burrow@1.0.0","maintainers":[{"name":"arpadegyed","email":"arpad.egyed@gmail.com"}],"homepage":"https://github.com/aegyed/burrow#readme","bugs":{"url":"https://github.com/aegyed/burrow/issues"},"bin":{"burrow":"dist/main.js"},"dist":{"shasum":"837480e6cd2fd53f853a2a1849d925f66c3e9302","tarball":"https://registry.npmjs.org/@arpadegyed/burrow/-/burrow-1.0.0.tgz","fileCount":25,"integrity":"sha512-EM3iIyumVtglhtaiOnr1dbL6ynPL2BMFPxkDrZhM5dO0DnV4gnzr6lQz1jfxJKyxHOTuRFhjE3jmY1O5jyTFEA==","signatures":[{"sig":"MEQCIDwJ+CyK+EbQp39MxU/TP60ajqmMHHlAfZi9rtYZeaboAiB3696REoLqoYo2gN0fE4lR1CMYndWX26xwu7mTOLyRXQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":179267},"jest":{"rootDir":"src","testRegex":".*\\.spec\\.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"testEnvironment":"node","coverageDirectory":"../coverage","collectCoverageFrom":["**/*.(t|j)s"],"moduleFileExtensions":["js","json","ts"]},"gitHead":"882aabbe07d0c5c821c36e4411bb5840ee59202a","scripts":{"lint":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","test":"jest","build":"nest build","start":"nest start","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","prepare":"npm run build","test:cov":"jest --coverage","test:e2e":"jest --config ./test/jest-e2e.json","start:dev":"nest start --watch","start:prod":"node dist/main","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:watch":"jest --watch","start:debug":"nest start --debug --watch"},"_npmUser":{"name":"arpadegyed","email":"arpad.egyed@gmail.com"},"repository":{"url":"git+https://github.com/aegyed/burrow.git","type":"git"},"_npmVersion":"10.9.2","description":"Burrow is a simple tool to start many preconfigured SSH tunnels at once","directories":{},"_nodeVersion":"20.18.0","dependencies":{"rxjs":"^7.8.1","ssh2":"^1.16.0","js-yaml":"^4.1.0","@nestjs/core":"^10.0.0","@nestjs/common":"^10.0.0","reflect-metadata":"^0.2.0","@nestjs/platform-express":"^10.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","prettier":"^3.0.0","supertest":"^7.0.0","ts-loader":"^9.4.3","typescript":"^5.1.3","@nestjs/cli":"^10.0.0","@types/jest":"^29.5.2","@types/node":"^20.3.1","@types/ssh2":"^1.15.4","@types/express":"^5.0.0","@types/js-yaml":"^4.0.9","tsconfig-paths":"^4.2.0","@nestjs/testing":"^10.0.0","@types/supertest":"^6.0.0","@nestjs/schematics":"^10.0.0","source-map-support":"^0.5.21","eslint-config-prettier":"^9.0.0","eslint-plugin-prettier":"^5.0.0","@typescript-eslint/parser":"^8.0.0","@typescript-eslint/eslint-plugin":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/burrow_1.0.0_1754667039369_0.35536247785232744","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@arpadegyed/burrow","version":"1.0.1","description":"Burrow is a simple tool to start many preconfigured SSH tunnels at once","repository":{"type":"git","url":"git+https://github.com/aegyed/burrow.git"},"keywords":["ssh","tunnel","burrow","typescript"],"author":{"name":"Arpad Egyed"},"license":"Apache-2.0","bugs":{"url":"https://github.com/aegyed/burrow/issues"},"homepage":"https://github.com/aegyed/burrow#readme","scripts":{"build":"nest build","prepare":"npm run build","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","start":"nest start","start:dev":"nest start --watch","start:debug":"nest start --debug --watch","start:prod":"node dist/main","lint":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","test":"jest","test:watch":"jest --watch","test:cov":"jest --coverage","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:e2e":"jest --config ./test/jest-e2e.json"},"bin":{"burrow":"dist/main.js"},"dependencies":{"@nestjs/common":"^10.0.0","@nestjs/core":"^10.0.0","@nestjs/platform-express":"^10.0.0","js-yaml":"^4.1.0","reflect-metadata":"^0.2.0","rxjs":"^7.8.1","ssh2":"^1.16.0","yargs":"^17.7.2"},"devDependencies":{"@nestjs/cli":"^10.0.0","@nestjs/schematics":"^10.0.0","@nestjs/testing":"^10.0.0","@types/express":"^5.0.0","@types/jest":"^29.5.2","@types/js-yaml":"^4.0.9","@types/node":"^20.3.1","@types/ssh2":"^1.15.4","@types/supertest":"^6.0.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","eslint":"^8.0.0","eslint-config-prettier":"^9.0.0","eslint-plugin-prettier":"^5.0.0","jest":"^29.5.0","prettier":"^3.0.0","source-map-support":"^0.5.21","supertest":"^7.0.0","ts-jest":"^29.1.0","ts-loader":"^9.4.3","ts-node":"^10.9.1","tsconfig-paths":"^4.2.0","typescript":"^5.1.3"},"jest":{"moduleFileExtensions":["js","json","ts"],"rootDir":"src","testRegex":".*\\.spec\\.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"collectCoverageFrom":["**/*.(t|j)s"],"coverageDirectory":"../coverage","testEnvironment":"node"},"_id":"@arpadegyed/burrow@1.0.1","gitHead":"96ec7e97ccb99f3b6987b6d4565d523ee4be8979","_nodeVersion":"20.18.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-c8L3FZXgUYwuheX9Sjtb5D6sCaOhoPpkaU6N4uN6ys0QhgzbrzgzU0yuheh3kAieGgXFLK7DHkyWGu6YVDEoZQ==","shasum":"491af17196719d8025ccb9dcf716904bae73c7ad","tarball":"https://registry.npmjs.org/@arpadegyed/burrow/-/burrow-1.0.1.tgz","fileCount":25,"unpackedSize":179292,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFBZuNQrqFWo8IG9b7rwPiz4u5yAG1Q+/vVkPM3Ho2x+AiBI0NxOeWktYZH3xb5Dwt5Y4N+i1wtORL5roHI0Z6hNSQ=="}]},"_npmUser":{"name":"arpadegyed","email":"arpad.egyed@gmail.com"},"directories":{},"maintainers":[{"name":"arpadegyed","email":"arpad.egyed@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/burrow_1.0.1_1754667673959_0.7154154764593752"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-08T15:30:39.237Z","modified":"2025-08-08T15:41:14.321Z","1.0.0":"2025-08-08T15:30:39.567Z","1.0.1":"2025-08-08T15:41:14.140Z"},"bugs":{"url":"https://github.com/aegyed/burrow/issues"},"author":{"name":"Arpad Egyed"},"license":"Apache-2.0","homepage":"https://github.com/aegyed/burrow#readme","keywords":["ssh","tunnel","burrow","typescript"],"repository":{"type":"git","url":"git+https://github.com/aegyed/burrow.git"},"description":"Burrow is a simple tool to start many preconfigured SSH tunnels at once","maintainers":[{"name":"arpadegyed","email":"arpad.egyed@gmail.com"}],"readme":"# Burrow\r\n\r\n## Introduction\r\nI fed up with opening many separate Putty windows for so much SSH tunnels that I needed for my work,\r\nand instead I wanted to create a simple tool that has a single configuration for all of them and can be started with a single command\r\nand automatically reconnects whenever needed.\r\n\r\nThis simple application uses [ssh2](https://www.npmjs.com/package/ssh2) and [net](https://nodejs.org/api/net.html) to create SSH connections, and set up tunnels over them from a straightforward\r\n`yaml` or `json` configuration file.n\r\nIt starts listening on configured ports on your machine and forwards incoming connections via the specified SSH connections, to your destination hosts.\r\nIt automatically connects to the appropriate SSH server and initiates the port forward whenever a connection is made to one of the configured\r\nlistening addresses, always trying to reconnect if existing connection is lost.\r\n\r\nThis is not an interactive app. You will not be able to manually enter passwords, and in fact why would you, if you have so much tunnels to start\r\nthat you need `burrow` to set up your environment?\r\n\r\nIt requires private key based authentication either directly referencing the private key or using SSH authentication agent.\r\nOptionally, you may enter your passwords in the configuration, although if I were you I would never do that.\r\n\r\n## Requirements\r\n\r\n- [node.js](https://nodejs.org) -- v20.3.1 or newer\r\n\r\n## Installation\r\n\r\n```bash\r\n$ npm i -g @arpadegyed/burrow\r\n```\r\n\r\n## Configuration\r\n\r\nThe configuration can be provided in `json` or `yaml` format according to your taste.\r\n\r\nBy default, the application will look for the configuration in your home directory with the `.burrowConfig.yml`, `.burrowConfig.yaml`, or `.burrowConfig.json`, however you may use the `--burrow-config-path path/to/your/config.yml` parameter to have it anywhere you like.\r\n\r\nThe configuration is hierarchical, first you define your SSH connections, and under each you provide your tunnel configurations to be set up over them.\r\n\r\nThe application will check the configuration at start, and stops on most problems that may prevent it from starting up correctly,\r\nhowever it has never been tested with all possible configurations.\r\nIf your settings follow any of the examples below, it should work fine.\r\n\r\n### Sample configurations:\r\n\r\n`.burrowConfig.yml:`\r\n```yaml\r\nsshConnections: # list of your SSH connections\r\n  - name: 'Dev server' # name your connection as you like, duplicate names not allowed!\r\n    connectConfig: # SSH connection configuration (not all options listed, many of those may not even work properly!)\r\n      username: 'someone' # username on target SSH server\r\n      host: 'dev.local' # target SSH server name or IP address\r\n      agent: 'pageant' # SSH authentication agent - Path to ssh-agent's UNIX socket,  on Windows use 'pageant' for authenticating with Pageant or (actual) path to a Cygwin UNIX socket.\r\n      keepaliveInterval: 30000 # How often (in milliseconds) to send SSH-level keepalive packets to the server (in a similar way as OpenSSH's ServerAliveInterval config option). Set to 0 to disable. Default: 0\r\n    tunnels: # list of your tunnels over current SSH connection\r\n      - name: 'DEV DB' # name your tunnel as you like, duplicate names not allowed!\r\n        forwardOptions:\r\n          listenOptions: # if not defined, the listening address will be taken from the local TCP server\r\n            host: 'localhost' # can be ommitted, defaults to localhost\r\n            port: 5432 # the port to listen for connections\r\n          destinationAddress: 'localhost' # destination host address and port that is accessible from the SSH server\r\n          destinationPort: 5432 # port is mandatory\r\n      - name: 'DEV Redis'\r\n        forwardOptions:\r\n          listenOptions:\r\n            port: 9122\r\n          # omitting destinationAddress will default to localhost \r\n          destinationPort: 9121\r\n      - name: 'DEV App'\r\n        forwardOptions:\r\n          # not providing listenOptions will start listening on random local port\r\n          destinationAddress: '10.0.45.44'\r\n          destinationPort: 8080\r\n  - name: 'UAT server'\r\n    connectConfig:\r\n      username: 'someone'\r\n      host: 'uat.local'\r\n      privateKeyPath: 'path/to/private.key' # you may use OpenSSH private keys directly, providing the path to them. Agent serves you better in my opinion, especially if you use passphrase. \r\n      passphrase: 'whatever' # passphrase for your private key\r\n    tunnels:\r\n      - name: 'UAT DB'\r\n        forwardOptions:\r\n          listenOptions:\r\n            port: 5432\r\n          destinationAddress: 'pg.uat.local'\r\n          destinationPort: 5432\r\n      - name: 'UAT app'\r\n        forwardOptions:\r\n          listenOptions:\r\n            port: 8082\r\n          destinationAddress: 'app.uat.local'\r\n          destinationPort: 8080\r\n```\r\n\r\n`.burrowConfig.json:`\r\n```json\r\n{\r\n  \"sshConnections\": [\r\n    {\r\n      \"name\": \"portal\",\r\n      \"connectConfig\": {\r\n        \"username\": \"someone\",\r\n        \"host\": \"192.168.0.11\",\r\n        \"agent\": \"pageant\",\r\n        \"keepaliveInterval\": 30000\r\n      },\r\n      \"tunnels\": [\r\n        {\r\n          \"name\": \"ESB HTTPS\",\r\n          \"forwardOptions\": {\r\n            \"listenOptions\": {\r\n              \"port\": 11443\r\n            },\r\n            \"destinationAddress\": \"esb.local\",\r\n            \"destinationPort\": 11443\r\n          }\r\n        },\r\n        {\r\n          \"name\": \"ESB HTTP\",\r\n          \"forwardOptions\": {\r\n            \"listenOptions\": {\r\n              \"port\": 11080\r\n            },\r\n            \"destinationAddress\": \"esb.local\",\r\n            \"destinationPort\": 11080\r\n          }\r\n        }\r\n      ]\r\n    },\r\n    {\r\n      \"name\": \"Backend\",\r\n      \"connectConfig\": {\r\n        \"username\": \"someone\",\r\n        \"host\": \"backend.local\",\r\n        \"agent\": \"pageant\",\r\n        \"keepaliveInterval\": 30000\r\n      },\r\n      \"tunnels\": [\r\n        {\r\n          \"name\": \"ORACLE\",\r\n          \"forwardOptions\": {\r\n            \"listenOptions\": {\r\n              \"port\": 1521\r\n            },\r\n            \"destinationAddress\": \"oradb\",\r\n            \"destinationPort\": 1521\r\n          }\r\n        },\r\n        {\r\n          \"name\": \"APP 1 HTTP\",\r\n          \"forwardOptions\": {\r\n            \"listenOptions\": {\r\n              \"port\": 8080\r\n            },\r\n            \"destinationAddress\": \"app1.local\",\r\n            \"destinationPort\": 8080\r\n          }\r\n        },\r\n        {\r\n          \"name\": \"APP 2 HTTP\",\r\n          \"forwardOptions\": {\r\n            \"listenOptions\": {\r\n              \"port\": 8081\r\n            },\r\n            \"destinationAddress\": \"app2.local\",\r\n            \"destinationPort\": 8080\r\n          }\r\n        },\r\n        {\r\n          \"name\": \"APP 3 HTTP\",\r\n          \"forwardOptions\": {\r\n            \"listenOptions\": {\r\n              \"port\": 8082\r\n            },\r\n            \"destinationAddress\": \"app3.local\",\r\n            \"destinationPort\": 8080\r\n          }\r\n        },\r\n        {\r\n          \"name\": \"LoadBalancer HTTPS\",\r\n          \"forwardOptions\": {\r\n            \"listenOptions\": {\r\n              \"port\": 1443\r\n            },\r\n            \"destinationAddress\": \"app-lb.local\",\r\n            \"destinationPort\": 443\r\n          }\r\n        }\r\n      ]\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n## How to run\r\n\r\n```shell\r\n# start all tunnels with configuration on default path (~/.burrowConfig.[yml|yaml|json])\r\n$ burrow [all]\r\n\r\n# start all tunnels with custom configuration and most debug logs\r\n# log levels: 0 and below = off, 1 = fatal, 2 = error, 3 = warn, 4 = log (default), 5 = debug, 6 and above = verbose\r\n$ burrow --burrow-config-path \"path/to/your/config.yml\" --log-level 5\r\n\r\n# start a single tunnel from default configuration with all logging turned off\r\n$ burrow single \"DEV DB\" --log-level 0\r\n```\r\n\r\nUse `Ctrl+C` to stop\r\n\r\n## License\r\n\r\n[Apache Licence 2.0](http://www.apache.org/licenses/LICENSE-2.0).\r\n","readmeFilename":"README.md"}