Octelium can very easily operate as a scalable self-hosted, free and open source alternative to ngrok, Cloudflare Tunnel and similar tunneling-based remote access commercial products to provide client-less as well as client-based remote access to your HTTP-based internal/private resources running behind NAT from anywhere.
Let's assume that the User who is supposed to serve the internal resource has the name john
. Let's create the User john
in users.yaml
file as follows:
Now we assume the the HTTP-based resource (e.g. web app, API, etc...) to be served from john
's machine is listening to the address localhost:8080
. We simply create the Service for our internal resource with the name svc1
in separate services.yaml
file as follows:
1kind: Service2metadata:3name: svc14spec:5mode: HTTP6isPublic: true7isAnonymous: true8config:9upstream:10url: http://localhost:808011user: john
You can now apply the creation of both the User and Service as follows (read more here):
export OCTELIUM_DOMAIN=<DOMAIN>octeliumctl apply /PATH/TO/YAML_FILE_OR_PARENT_DIRECTORY
Now for john
to actually serve the Service svc1
from his side, john
needs to connect to the Cluster via the octelium connect
CLI command and adds the --serve
flag as follows:
export OCTELIUM_DOMAIN=<DOMAIN>octelium connect --serve svc1
You can also serve multiple Services simultaneously as follows:
octelium connect --serve svc1 --serve svc2
Also you can also serve all Services assigned to be served by the User via the --serve-all
flag as follows:
octelium connect --serve-all
You can have several octelium
clients serving the same Service upstream. In such case, the Service will load balance among all the upstreams served by all the available connected octelium
clients. For example, you might use this to serve an upstream from a deployment in remote Kubernetes cluster that runs multiple replicas octelium
containers or when you want to have a Service whose upstreams can be running in several clouds/servers. In fact you can even have a single Service that has multiple upstreams served by multiple User (read more here).
You are not restricted to serving upstreams from just remote private networks, you can also deploy your containers and serve them as Octelium Services (read more about managed containers here). Here is an example:
1kind: Service2metadata:3name: anonymous-nginx4spec:5mode: WEB6isPublic: true7isAnonymous: true8config:9upstream:10container:11image: nginx12port: 80
You can also use your Docker images stored in private container registries (see a more detailed example here). Here is an example:
1kind: Service2metadata:3name: my-webapp4spec:5mode: WEB6isPublic: true7isAnonymous: true8config:9upstream:10container:11port: 300012image: ghcr.io/<ORG>/<IMAGE>:<TAG>13command:14- npm15args:16- run17- start18replicas: 319credentials:20usernamePassword:21username: <USERNAME>22password:23fromSecret: registry-password
Back to our initial example, the above Service configuration, namely the isAnonymous
field, allows access for anonymous access over the internet. This could be useful for hosting and testing public websites, APIs, webhooks, etc.... However, you might want to only restrict the Service access to the Cluster's Users. You can do so by removing the isAnonymous
field and adding Policies for who is allowed to access the Service (read more about Policies and access control here). Here is an example:
1kind: Service2metadata:3name: svc14spec:5mode: HTTP6isPublic: true7config:8upstream:9url: http://localhost:808010user: john11authorization:12policies: ["allow-all"]
The above configuration allows access only for any authenticated User. However, you might want to control access in a more fine-grained way and not just allow access to all Users. Octelium actually provides a rich layer-7 aware, identity-based, context-aware ABAC access control on a per-request basis where you can control access based on the HTTP request's path, method, and even serialized JSON body content using policy-as-code with CEL and Open Policy Agent (OPA) (You can read more in detail about Policies and access control here). Here is another more detailed example:
1kind: Service2metadata:3name: svc14spec:5mode: HTTP6isPublic: true7config:8upstream:9url: http://localhost:808010user: john11authorization:12inlinePolicies:13- spec:14rules:15- effect: ALLOW16condition:17all:18of:19- match: ctx.user.spec.email.endsWith("@example.com")20- match: ctx.request.http.path.startsWith("/prefix1")21- match: ctx.request.http.method in ["GET", "POST"]
Now authorized Users, once authenticated for example by Github OAuth2, OpenID Connect or SAML IdentityProviders such as Okta or Azure AD/Microsoft Entra ID (read more here), can access the Service svc1
either via the client-based private mode via the octelium connect
command (read more here) as follows:
export OCTELIUM_DOMAIN=<DOMAIN># Now connect to the Cluster via the detached modeoctelium connect -d# ORsudo -E octelium connectcurl http://svc1:8080
Authorized Users can also access the Service via the client-less (i.e. BeyondCorp) mode (read more here). For example, if the Service is a web app, HUMAN
Users (read more about User management here) can simply access the Service via their browsers at the public URL https://svc1.<DOMAIN>
. Authorized WORKLOAD
Users can also access the Service in a client-less way via standard OAuth2 client credential flow (read more here) or even directly via bearer access tokens (read more here).
Octelium also provides OpenTelemetry-ready, application-layer L7 aware visibility and access logging in real time (see an example for HTTP here). You can read more about visibility here.
This was a very short guide to show you how to use Octelium to deploy, scale, route and provide secure access as well as anonymous public access to any webapp containers. Here are a few more related features that you might be interested in:
- Routing not just by request paths, but also by header keys and values, request body content including JSON (read more here).
- Request/response header manipulation (read more here).
- Cross-Origin Resource Sharing (CORS) (read more here).
- gRPC mode (read more here).
- Secret-less access to upstreams and injecting bearer, basic, or custom authentication header credentials (read more here).
- Application layer-aware ABAC access control via policy-as-code using CEL and Open Policy Agent (read more here).
- OpenTelemetry-ready, application-layer L7 aware auditing and visibility (read more here).