{"id":13671468,"url":"https://github.com/lobbyboy-ssh/lobbyboy","last_synced_at":"2025-04-27T18:31:18.727Z","repository":{"id":38325267,"uuid":"417871645","full_name":"lobbyboy-ssh/lobbyboy","owner":"lobbyboy-ssh","description":"A lobby boy will create a VPS server when you need one, and destroy it after using it.","archived":false,"fork":false,"pushed_at":"2025-04-07T16:45:24.000Z","size":812,"stargazers_count":238,"open_issues_count":16,"forks_count":10,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-04-07T17:42:23.571Z","etag":null,"topics":["bastion-host","jumpserver","ssh","ssh-server","vps-managment"],"latest_commit_sha":null,"homepage":"","language":"Python","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/lobbyboy-ssh.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":"2021-10-16T15:39:39.000Z","updated_at":"2025-01-07T02:59:47.000Z","dependencies_parsed_at":"2024-02-17T09:29:11.436Z","dependency_job_id":"92bda66e-eff9-45e0-8d63-3e8bbcbedb99","html_url":"https://github.com/lobbyboy-ssh/lobbyboy","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lobbyboy-ssh%2Flobbyboy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lobbyboy-ssh%2Flobbyboy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lobbyboy-ssh%2Flobbyboy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lobbyboy-ssh%2Flobbyboy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lobbyboy-ssh","download_url":"https://codeload.github.com/lobbyboy-ssh/lobbyboy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251187135,"owners_count":21549593,"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":["bastion-host","jumpserver","ssh","ssh-server","vps-managment"],"created_at":"2024-08-02T09:01:10.397Z","updated_at":"2025-04-27T18:31:18.231Z","avatar_url":"https://github.com/lobbyboy-ssh.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Lobbyboy\n\n\u003e What is a lobby boy? A lobby boy is completely invisible, yet always in sight.\n\u003e A lobby boy remembers what people hate. A lobby boy anticipates the client's\n\u003e needs before the needs are needed. A lobby boy is, above all, discreet to a\n\u003e fault.\n\u003e\n\u003e \u003cp align='right'\u003e--The Grand Budapest Hotel\u003c/p\u003e\n\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/lobbyboy-ssh/lobbyboy/main.svg)](https://results.pre-commit.ci/latest/github/lobbyboy-ssh/lobbyboy/main)\n[![Test](https://github.com/lobbyboy-ssh/lobbyboy/actions/workflows/unittest.yaml/badge.svg?branch=main)](https://github.com/lobbyboy-ssh/lobbyboy/actions/workflows/unittest.yaml)\n\n\u003ca href=\"https://badge.fury.io/py/lobbyboy\"\u003e\u003cimg src=\"https://badge.fury.io/py/lobbyboy.svg\" alt=\"PyPI version\"\u003e\u003c/a\u003e\n\u003cimg src=\"https://badgen.net/badge/python/3.7%20%7C%203.8%20%7C%203.9/\" alt=\"Python version\"\u003e\n[![codecov](https://codecov.io/gh/lobbyboy-ssh/lobbyboy/branch/main/graph/badge.svg?token=2HC7YDQBGT)](https://codecov.io/gh/lobbyboy-ssh/lobbyboy)\n\n**This project is still under testing, it worked but may have bugs.**\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [What is lobbyboy?](#what-is-lobbyboy)\n* [Key Features](#key-features)\n* [Installation](#installation)\n* [Run server](#run-server)\n  * [Generate a key pair for authentication](#generate-a-key-pair-for-authentication)\n* [Deployment](#deployment)\n  * [Systemd Example](#systemd-example)\n  * [Run in Docker](#run-in-docker)\n* [Providers](#providers)\n  * [Builtin Providers](#builtin-providers)\n    * [Vagrant Provider](#vagrant-provider)\n    * [Footloose Provider](#footloose-provider)\n    * [DigitalOcean Provider](#digitalocean-provider)\n    * [Linode Provider](#linode-provider)\n    * [Ignite(Firecracker) Provider](#ignitefirecracker-provider)\n    * [Multipass Provider](#multipass-provider)\n  * [Write Your Own Providers](#write-your-own-providers)\n  * [Publish Your Own Providers](#publish-your-own-providers)\n* [FAQ](#faq)\n* [I Want to Know More!](#i-want-to-know-more)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## What is lobbyboy?\n\nWell, lobbyboy is a ssh server. Yes, like `sshd`. But instead of spawn a new\nshell on the server like sshd, when you ssh to lobbyboy, lobbyboy will create a\nnew server(VPS) from available providers(meaning to say, DigitalOcean, AWS, GCP,\nVultr, etc), then redirect you to the newly created servers. Of course, if\nlobbyboy finds any servers available already, he will just ask if you want to\nenter the existing server, or still want to create a new one.\n\n![](./docs/images/lobbyboy.png)\n\n## Key Features\n\n- talks in SSH2 protocol, no need to install any software of configs for\n  client-side, just ssh to lobbyboy!\n- extendable provider: just implement 3 methods, then lobbyboy can work with any\n  provider!\n- destroy the server when you no longer needed.\n- manage ssh keys for you\n\n## Installation\n\nInstall libkrb5-dev first, this is a dependency for gssapi support.\n\n```bash\napt install libkrb5-dev\n```\n\nInstall via pip:\n\n```bash\npip install lobbyboy\n```\n\n## Run server\n\nFirst, generate a config file:\n\n```bash\nlobbyboy-config-example \u003e config.toml\n# Edit your config before running!\n```\n\nRun the server with:\n\n```bash\nlobbyboy-server -c config.toml\n```\n\nYou can ssh to Lobbyboy now, if you keep the default user `Gustave` in default\nconfig. You can ssh to Lobbyboy via:\n\n```bash\nssh Gustave@127.0.0.1 -p 12200\n# Enter the default password \"Fiennes\"(without quotes)\nWelcome to Lobbyboy 0.2.2!\nThere are 1 available servers:\n  0 - Create a new server...\n  1 - Enter vagrant lobbyboy-41 127.0.0.1 (0 active sessions)\nPlease input your choice (number):\n```\n\nYou may want to change the password in `config.toml` or use a public key for\nauthentication. The latter is recommended in a production environment.\n\n### Generate a key pair for authentication\n\nGenerate a key pair:\n\n```bash\nssh-keygen -f lobbyboy_key\n```\n\nAdd the content of `lobbyboy_key.pub` to the end of `authorized_keys` under\n`[user.Gustave]` table. Now you can ssh to the lobbyboy server via:\n\n```bash\nssh Gustave@127.0.0.1 -i lobbyboy_key\n```\n\n## Deployment\n\nLobbyboy is supposed to be a server daemon, so you can manage it by\nsystemd/[supervisord](http://supervisord.org/) or put it into a docker.\n\n### Systemd Example\n\n```ini\n[Unit]\nDescription=Lobbyboy Server\n\n[Service]\nUser=me\nGroup=me\nExecStart=/path/to/lobbyboy-server -c /path/to/lobbyboy/config.toml\nRestart=on-failure\nWorkingDirectory=/path/to/lobbyboy/\n\n[Install]\nWantedBy=multi-user.target\n```\n\n### Run in Docker\n\n```bash\n# Generate a config file\ndocker run --rm ghcr.io/lobbyboy-ssh/lobbyboy lobbyboy-config-example \u003e lobbyboy_config.toml\n# Run the docker container\ndocker run -v `pwd`/lobbyboy_config.toml:/app/config.toml -p \"12200:12200\" -d ghcr.io/lobbyboy-ssh/lobbyboy\n```\n\nThe lobbyboy server should be active on 12200 port and you can connect to it\nwith\n\n```\nssh Gustave@127.0.0.1 -p 12200\n```\n\nThe default password for user `Gustave` is `Fiennes`. **Please change it when\nyou deployed it into production, and consider use ssh key to auth instead of\npassword.**\n\n## Providers\n\n// TBD\n\n### Builtin Providers\n\nLobbyboy current support multiple Providers:\n\n- Vagrant (Need vagrant and virtualbox to be installed)\n- Footlosse, in another words, containers (Need\n  [footloose](https://github.com/weaveworks/footloose) and docker to be\n  installed)\n- DigitalOcean\n- Linode\n- [Ignite](https://github.com/weaveworks/ignite) (Runs Firecracker VM)\n- [multipass](https://multipass.run)\n\nDifferent Providers support different configs, please see the\n[example config](https://github.com/laixintao/lobbyboy/blob/main/lobbyboy/conf/lobbyboy_config.toml)\nfor more detail.\n\n#### Vagrant Provider\n\nVagrant Provider won't cost you any money, [vagrant](https://www.vagrantup.com/)\nis a software runs on your computer along with virtual machine providers,\nvagrant can provision and control your VM.\n\nThis provider can help you to create a new Vagrant instance when you login to\nLobbyboy, and destroy the server when you no longer use it.\n\nSupported Features:\n\n- Create new Vagrant instances\n- You can configure your VM via `vagrantfile` config (see the config\n  [example](./lobbyboy/conf/lobbyboy_config.toml)).\n\n#### Footloose Provider\n\n[footloose](https://github.com/weaveworks/footloose) can make your docker\ncontainers(or Firecracker with [ignite](https://github.com/weaveworks/ignite))\nact like virtual machine, so you can ssh to it.\n\nSupported feature:\n\n- Configurable base image\n- Create a docker container and redirect you in\n\n#### DigitalOcean Provider\n\nThis Provider will create\n[Droplet](https://docs.digitalocean.com/products/droplets/) from DigitalOcean.\n\nSupported Features:\n\n- Create a new ssh key every time create a droplet.\n- Ask user to input region/droplet size/image when creating.\n- User can save favorite Droplet region/size/image in configs to quick create.\n- Destroy droplet when it is not in use.\n\n#### Linode Provider\n\nThis Provider will create [Node](https://www.linode.com/docs/products/compute/)\nfrom Linode.\n\nSupported Features:\n\n- Create a new ssh key every time create a droplet.\n- Ask user to input region/node type/image when creating.\n- User can save favorite node region/type/image in configs to quick create.\n- Destroy node when it is not in use.\n\nPlease see\n[configs](https://github.com/laixintao/lobbyboy/blob/main/lobbyboy/conf/lobbyboy_config.toml)\nto check available options.\n\n#### Ignite(Firecracker) Provider\n\nSupported Features:\n\n- Create a new Firecracker virtual machine\n- Destroy node when it is not in use.\n\n#### Multipass Provider\n\nSupported Features:\n\n- Create a new virtual machine\n- Destroy node when it is not in use.\n\n![](./docs/images/do-preview.png)\n\n### Write Your Own Providers\n\nProviders are VPS vendors, by writing new providers, lobbyboy can work with any\nVPS vendors.\n\nTo make a new Provider work, you need to extend base class\n`lobbyboy.provider.BaseProvider``, implement 2 methods:\n\n```python\n    def is_available(self) -\u003e bool:\n        \"\"\"\n        Override this method to check for requirements of this provider\n\n        Returns:\n            bool: True if this provider is available, False to disable it\n        \"\"\"\n        return True\n\n    def create_server(self, channel: Channel) -\u003e LBServerMeta:\n        \"\"\"\n        Args:\n            channel: paramiko channel\n\n        Returns:\n            LBServerMeta: server meta info\n        \"\"\"\n        ...\n\n\n    def destroy_server(self, meta: LBServerMeta, channel: Channel = None) -\u003e bool:\n        \"\"\"\n        Args:\n            meta: LBServerMeta, we use this to locate one server then destroy it.\n            channel: Note that the channel can be None.\n                     If called from server_killer, channel will be None.\n                     if called when user logout from server, channel is active.\n\n        Returns:\n            bool: True if destroy successfully, False if not.\n        \"\"\"\n        ...\n```\n\nThen add your Provider to your config file.\n\nThose 3 configs are obligatory, as lobbyboy has to know when should he destroy\nyour spare servers. You can add more configs, and read them from\n`self.provider_config` from code, just remember to add docs about it :)\n\n```toml\n[provider.\u003cyour provider name\u003e]\nload_module = \"lobbyboy.contrib.provider.\u003cyour provider module name\u003e::\u003cProvider Class\u003e\"\nmin_life_to_live = \"1h\"\nbill_time_unit = \"1h\"\n```\n\n### Publish Your Own Providers\n\n// TBD\n\n## FAQ\n\nQ: Can I use lobbyboy as a proxy, like adding it to my `ProxyCommand` in ssh\nconfig?\n\nA: No. Lobbyboy works like a reverse proxy, meaning to say, for ssh client, it\njust like a ssh server(sshd maybe), ssh client get a shell from lobbyboy, and\ndoesn't know if it is local shell or it is a nested shell which runs another\nssh. (but you know it, right? :D )\n\n## I Want to Know More!\n\n- [介绍 Lobbyboy 项目](https://www.kawabangga.com/posts/4576) (in Chinese)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flobbyboy-ssh%2Flobbyboy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flobbyboy-ssh%2Flobbyboy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flobbyboy-ssh%2Flobbyboy/lists"}