{"id":22968304,"url":"https://github.com/fyralabs/chisel-operator","last_synced_at":"2025-10-11T11:08:10.285Z","repository":{"id":167166058,"uuid":"639195565","full_name":"FyraLabs/chisel-operator","owner":"FyraLabs","description":"Kubernetes Operator for Chisel","archived":false,"fork":false,"pushed_at":"2025-09-27T06:12:13.000Z","size":791,"stargazers_count":124,"open_issues_count":14,"forks_count":13,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-09-27T08:34:58.461Z","etag":null,"topics":["chisel","inlets","inlets-pro","inletsdev","k8s","k8s-operator","kubernetes","kubernetes-operator","tunnel","tunneling"],"latest_commit_sha":null,"homepage":"https://chisel.fyralabs.com","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FyraLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"FyraLabs"}},"created_at":"2023-05-11T01:07:23.000Z","updated_at":"2025-09-27T06:12:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"4d7c5b05-070d-4c4f-9214-94d0cacd5eb1","html_url":"https://github.com/FyraLabs/chisel-operator","commit_stats":null,"previous_names":["fyralabs/chisel-operator"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/FyraLabs/chisel-operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FyraLabs%2Fchisel-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FyraLabs%2Fchisel-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FyraLabs%2Fchisel-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FyraLabs%2Fchisel-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FyraLabs","download_url":"https://codeload.github.com/FyraLabs/chisel-operator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FyraLabs%2Fchisel-operator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007029,"owners_count":26084226,"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","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","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":["chisel","inlets","inlets-pro","inletsdev","k8s","k8s-operator","kubernetes","kubernetes-operator","tunnel","tunneling"],"created_at":"2024-12-14T21:16:56.551Z","updated_at":"2025-10-11T11:08:10.279Z","avatar_url":"https://github.com/FyraLabs.png","language":"Rust","funding_links":["https://github.com/sponsors/FyraLabs"],"categories":[],"sub_categories":[],"readme":"# Chisel Kubernetes Operator ⚒️\n\nUse a VPS (or any other machine) as a reverse proxy for your Kubernetes cluster, without paying the extra 25$ a month!\n\nThis is a Kubernetes operator for Chisel. It allows you to use Chisel as a LoadBalancer provider for your Kubernetes cluster, similar to [inlets-operator](https://github.com/inlets/inlets-operator)\n\nView the documentation: https://chisel.fyralabs.com\n\n## Features\n\n- Automatic provisioning of exit nodes on cloud providers\n- Free and open-source\n- TCP and UDP support\n- **INFINITE** tunnels! (You can create as many tunnels as you want, as long as you have enough bandwidth)\n- Use any machine as an exit node\n- Hybrid cloud support (You can use multiple cloud providers at once)\n\n## TODO\n\n- [x] Authentication\n- [x] Multiple tunnel services per exit node (so you don't have to pay for multiple VMs)\n- [x] Extra configuration options\n- [x] TCP/UDP support\n- [ ] Multiple IPs per exit node\n- [x] Multiple exit nodes support\n- [x] Cloud provisioner (like inletsctl/inlets-operator)\n\n## Why?\n\n### The issue\n\nIf you want to expose a service to the internet, you need a public IP address.\n\nHowever, if you're running a cluster inside a NATed network (like a home network), you can't just expose your service to the internet. You need to port forward your service to the internet. This might be fine, but then there's another problem:\n\nThe world's running out of IPv4 addresses. This means that ISPs are starting to charge extra for public IP addresses, and most home networks are locked behind a CGNAT, and requires you to pay extra for a public IP address.\n\nYou could just use an IPv6 address, but most ISPs don't support IPv6 yet, and K8s with IPv6 is kind of a pain to set up.\n\n\u003e Disclaimer: We are not responsible for any problems arising from abuse of this software. Please proxy responsibly.\n\u003e See [LICENSE.md](LICENSE.md) for more details.\n\n### The other issue\n\nYou might say, \"What about Inlets?\" Inlets is a great solution, but it comes with a couple caveats:\n\n- You need to pay for an inlets PRO license to even use it (It's a proprietary solution)\n- You still need to pay for the exit node on top of the inlets PRO license\n\n### The solution\n\nIntroducing the Fyra Labs Chisel Operator! This operator provides a replacement for inlets, but free and open-source!\n\nThis operator makes use of the [Chisel] tunnel to expose your services to the internet through SSH. And you can use any machine as an exit node!\n\n[Chisel]: https://github.com/jpillora/chisel\n\nSince Chisel routes traffic through SSH, all traffic is encrypted and secure. The Chisel Operator also supports automatic provisioning of exit nodes on cloud providers, so you get basically the same functionality, but free!\n\n---\n\nWhile this code is free and open-source, we still accept donations! If you really like this project, please consider donating to us on [GitHub Sponsors](https://github.com/sponsors/FyraLabs) :3\n\n## How does it work?\n\nThis operator works similarly to inlets-operator. It watches for `LoadBalancer` services, then allocates an exit node's IP address for that service and creates a Chisel client deployment on that node. The Chisel client will then connect to the Chisel server running on the exit node, and the service will be exposed on the exit node's IP address.\n\n## Alternatives\n\n### SaaS solutions\n\n- [Cloudflare (Argo) Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps) - Cloudflare's solution to this problem. It is free and also open-source, but it only works on Cloudflare-managed domains and requires you to use Cloudflare's DNS service. But it comes with a couple caveats:\n  - Only HTTP and HTTPS is supported for exposing services. If you want to expose a TCP service, you must connect to it through Cloudflare Tunnel on the client.\n  - According to Cloudflare's [Terms of Service](https://www.cloudflare.com/terms/), you are not allowed to use Cloudflare's proxies to stream video or audio content. This means that you cannot use Cloudflare Tunnel to expose your Plex or Jellyfin server, or any other media streaming service. This is also the reason I started this project.\n- [ngrok](https://ngrok.com/) - ngrok is a proprietary solution that allows you to expose your local service to the internet. It is free to use, but it comes with a couple caveats:\n  - Only HTTP and HTTPS is supported for exposing services. TCP traffic is supported through a paid plan.\n  - Limited bandwidth\n  - Custom domains are only available on a paid plan\n\n### Self-hosted solutions\n\n- Run Chisel manually on your exit node - This is the most straightforward solution. You can simply run Chisel manually on your exit node without using this operator. However, this solution is hard to automate, which is the point of this project.\n- [frp](https://github.com/fatedier/frp) - Fast reverse proxy, requires manual configuration of server and client.\n- [inlets](https://inlets.dev/) - Bite the bullet and pay for an inlets PRO license. inlets-pro allows you to automatically provision exit nodes on cloud providers, but it is a proprietary solution and requires you to pay a monthly fee.\n- [rathole](https://github.com/rapiz1/rathole) - Similar to frp, written in Rust.\n\n### VPNs and overlay networks\n\n- [Tailscale](https://tailscale.com/) - VPN solution that allows you to connect your devices in one big overlay network. Also has Funnel, a reverse proxy solution that allows you to expose your local service to the internet. Self-hostable control plane is available, but default is to use Tailscale's hosted control plane.\n- ZeroTier - Similar to Tailscale, Under BSD license, Can connect to multiple networks at once.\n\n---\n\nFind more alternatives [here](https://github.com/anderspitman/awesome-tunneling)\n\n## How do I use it?\n\nThere are two ways to use this operator:\n\n- Manually provision the exit (reverse proxy) node, and let the operator manage the Chisel client deployment\n- Let the operator provision exit nodes on a cloud provider of your choice. The operator currently supports the following cloud providers:\n  - DigitalOcean\n  - Linode (Currently only on regions with Metadata services)\n  - AWS\n\n## Cluster Installation\nInstall using the Kustomize config from the stable branch:\n\n```bash\nkubectl apply -k https://github.com/FyraLabs/chisel-operator?ref=stable\n```\n\nOr if you would like to go straight to the latest commit:\n\n```bash\nkubectl apply -k https://github.com/FyraLabs/chisel-operator\n```\n\nA Helm chart is also available as an OCI artifact. You can install it using the following command:\n\n```bash\nhelm install chisel-operator oci://ghcr.io/fyralabs/chisel-operator/chisel-operator\n```\n\n## Usage\n\n### Restricting reconciliation to a LoadBalancer class\n\nBy default the operator watches every Kubernetes service of type `LoadBalancer`. If you only want it to manage services that target a specific [`loadBalancerClass`](https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class), set the `LOAD_BALANCER_CLASS` environment variable (or the `loadBalancerClass` Helm value) to the class name you want the operator to handle. Only services whose `spec.loadBalancerClass` matches that string will be reconciled; other services will be ignored.\n\nWhen deploying a filtered operator you must also add the same `loadBalancerClass` to each Service you expect it to control:\n\n```yaml\napiVersion: v1\nkind: Service\nmetadata:\n  name: whoami\nspec:\n  type: LoadBalancer\n  loadBalancerClass: my.chisel.class\n```\n\n### Operator-managed exit nodes\n\nThis operator can automatically provision exit nodes on cloud providers.\n\nTo use this feature, you must first create a `ExitNodeProvisioner` resource. This resource contains the configuration for the cloud provider, and the operator will use this resource to provision exit nodes.\n\n```yaml\napiVersion: chisel-operator.io/v1\nkind: ExitNodeProvisioner\nmetadata:\n  name: digitalocean\n  namespace: default\nspec:\n  # Cloud provider configuration, must be one per resource\n  # Valid values are DigitalOcean, Linode, AWS\n  DigitalOcean:\n    # Reference to a secret containing the DigitalOcean API token\n    # with key `DIGITALOCEAN_TOKEN`\n    # Must be in the same namespace as the ExitNodeProvisioner\n    auth: digitalocean\n    region: sgp1\n```\n\nNow, you can go with one of the two routes:\n\n#### Automatic provisioning per service\n\nChisel Operator can automatically allocate cloud exit nodes for services,\nif you set an annotation on a `LoadBalancer` service.\n\n```yaml\napiVersion: v1\nkind: Service\nmetadata:\n  name: whoami\n  annotations:\n    # If the provisioner is in another namespace, you need to specify that\n    # for example, with a namespace of example, the value would be example/digitalocean\n    chisel-operator.io/exit-node-provisioner: \"digitalocean\"\nspec:\n  selector:\n    app: whoami\n  ports:\n    - port: 80\n      targetPort: 80\n  type: LoadBalancer\n```\n\nThis will create a new `ExitNode` resource named after the service, and the operator will automatically allocate an exit node for that service.\n\nThis is useful if you want to just allocate an entire exit node for a single service.\n\n#### Manually-allocated, but operator-managed exit nodes\n\nYou can also manually allocate exit nodes, but still let the operator manage the Chisel client deployment. This is useful if you want to allocate a single exit node for multiple services, in case you're on a budget and don't want to pay for multiple exit nodes for each service.\n\nTo do this, create an `ExitNode` resource with the annotation `chisel-operator.io/exit-node-provisioner` set to the name (and namespace if the provisioner is in a different namespace) of the `ExitNodeProvisioner` resource.\n\n```yaml\napiVersion: chisel-operator.io/v1\nkind: ExitNode\nmetadata:\n  name: my-exit-node\n  namespace: default\n  annotations:\n    # If the provisioner is in another namespace, you need to specify that\n    # for example, with a namespace of example, the value would be example/digitalocean\n    chisel-operator.io/exit-node-provisioner: \"digitalocean\"\nspec:\n  # IP address of exit node\n  # In this case, we will leave this as a blank string, and let the operator allocate an IP address for us\n  host: \"\"\n  # Control plane socket port\n  port: 9090\n  # Name of the secret containing the auth key\n  # This is not required, but recommended\n  # If not set, the operator will automatically generate a secret for you\n  # auth: cloud-test-auth\n```\n\nNow, to use this exit node, you can create a `LoadBalancer` service with the annotation `chisel-operator.io/exit-node-name` set to the name of the `ExitNode` resource.\n\n```yaml\napiVersion: v1\nkind: Service\nmetadata:\n  name: whoami\n  annotations:\n    chisel-operator.io/exit-node-name: \"cloud-test\"\nspec:\n  selector:\n    app: whoami\n  ports:\n    - port: 80\n      targetPort: 80\n  type: LoadBalancer\n```\n\n\u003e NOTE: You can also use this for manually-provisioned exit nodes\n\n\u003e NOTE: If you do not specify the annotation, the operator will allocate the first available exit node for you.\n\n### Provisioning Chisel manually\n\n\u003e NOTE: You can skip this step if you're using the cloud provisioner.\n\nTo install Chisel, install the Chisel binary on the machine using this script:\n\n```bash\ncurl https://i.jpillora.com/chisel! | bash\n```\n\n**OPTIONAL:** You should create a systemd service for Chisel so it can run in the background. Create a file called `/etc/systemd/system/chisel.service` with the following contents:\n\n```ini\n[Unit]\nDescription=Chisel Tunnel\nWants=network-online.target\nAfter=network-online.target\nStartLimitIntervalSec=0\n\n[Install]\nWantedBy=multi-user.target\n\n[Service]\nRestart=always\nRestartSec=1\nUser=root\n# You can add any additional flags here\n# This example uses port 9090 for the tunnel socket. `--reverse` is required for our use case.\n# `foo:bar` is an example of the authentication credentials.\n# The format is `username:password`.\n# You may also create an auth file with the `--authfile` flag.\nExecStart=/usr/local/bin/chisel server --port=9090 --reverse --auth foo:bar\n```\n\nThen run `systemctl daemon-reload` and `systemctl enable --now chisel.service` to enable and start the service.\n\n## Best Practices\n\nYou should always secure your Chisel server with a username and password. You can authenticate to the server by creating a secret in the same namespace as the `ExitNode` with a key called `auth`, and setting the `auth` field in the `ExitNode` to the name of the secret. The secret should be a string of `username:password` in plain text.\n\nCurrently, you should use the public IP address of your exit node as the `host` field in the `ExitNode` resource. This is because the operator currently does not support using a domain name as the `host` field. This will be fixed in the future.\n\n### Exposing services\n\nIt is recommended you use an Ingress controller to expose your services. This greatly simplifies the process for exposing other services, as you only need to expose the Ingress controller's HTTP(S) ports.\n\n## How do I contribute?\n\nFeel free to open a pull request or an issue if you have any suggestions or improvements. We're open to any ideas!\n\n## Legal\n\nFyra Labs disclaims all liability related to usage of chisel-operator. Please proxy responsibly. See [LICENSE.md](LICENSE.md) for additional details. Contact abuse@fyralabs.com with complaints.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffyralabs%2Fchisel-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffyralabs%2Fchisel-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffyralabs%2Fchisel-operator/lists"}