go-http
This project provides examples of how to use the Ziti GoLang SDK to both host and consume HTTP services over an
OpenZiti overlay network using a variety of libraries. The Ziti SDK provides
ZitiTransport
which implements http.Transport
and edge.Conn
instances which can be used as net.Listener
instances. Hosting and consuming HTTP APIs over a private overlay network with no open ports adds a layer of defense
against most OWASP API attack vectors.
Links to the different projects and their example OpenZiti integrations can be found below.
Servers
Clients
The Main Magic
GoLang’s built in HTTP facilitates provide excellent methods for hooking into them. With the use of the OpenZiti SDK it essentially boils down to the following patterns that work for the standard GoLang HTTP client and server. These can then be adjusted to fit into any framework/library that uses the GoLang HTTP packages.
The OpenZiti GoLang SDK provides ZitiTransport
,
which can be used as an http.Transport
, and edge.Listener
, that can be used as a net.Listener
. ZitiTransport
can be used to create http.Client
instances and edge.Listener
can be used to with http.Serve(listener,...)
calls.
The rest of the GoLang HTTP machinery handles all the HTTP interactions unknowingly over an OpenZiti network.
This same pattern can be used to inject any kind of custom networking you wish!
If you want to deep dive, the ZitiTransport
definition can be found here
and edge.Listen()
can be found here.
Client
Before:
client := http.DefaultClient
resp, err := client.Get("http://" + args.ServiceName)
After:
client := sdk_golang.NewHttpClient(ctx, nil)
resp, err := client.Get("http://" + args.ServiceName)
Server
Before:
if err := http.Serve(listener, http.HandlerFunc(handler)); err != nil {
log.Fatalf("serving failed: %v", err)
}
After:
listener, err = ctx.Listen(args.ServiceName)
if err := http.Serve(listener, http.HandlerFunc(handler)); err != nil {
log.Fatalf("https serving failed: %v", err)
}
Example CLI Arguments
Each example uses the same command line argument processing. This processing takes in two or four arguments that specify the Ziti Identity configuration file and OpenZiti service name. The two additional arguments are paths to a x509 certificate and key in PEM format. If specified for a server, the server will be hosted as an HTTPS service using the provided certificate and key files for the server’s identity. For a client, the x509 certificate and key will be used as the client certificate and key used to initiate the TLS connection over the OpenZiti network.
ziti-server-gin <serviceName> <identityConfig> [<certificate> <key>]
However, HTTPS when working with OpenZiti is not necessary. See the next section!
A Note on HTTPS
Hosting an HTTPS server over OpenZiti means that a TLS handshake will occur. A TLS handshake requires that the server presents a certificate with a SAN IP or a SAN DNS entry that matches the address the client used to access the service. For OpenZiti this means that a SAN DNS that matches the OpenZiti service name must be present.
If the service will only be hosted over OpenZiti, HTTPS is an extra layer of security that can safely be omitted. OpenZiti connections are inherently end-to-end encrypted and the data plane across an OpenZiti network is additionally encrypted on each leg of transit. Additionally, the controller has already verified all clients and hosts before they “dial” (connect) or “bind” (host).
Setting Up The Examples
In order to run these examples, an OpenZiti network must be up and running. This includes a controller and router. Additionally, a service, service host and client will need to be created. The host and client identities will need policies to access and host the service. To set up an OpenZiti network, please see the quickstart guides.
You will need the Ziti CLI from the main Ziti repository installed and on your path.
- Login
ziti edge login "https://localhost:1280/edge/management/v1" -c $controllerCa -u $user -p $password
- Create the Service
ziti create service myHttpService -a httpService
- Create the identities
ziti create identity service httpServer -a httpServer -o server.jwt
> createsserver.jwt
ziti create identity user httpClient -a httpClient -o client.jwt
> createsclient.jwt
- Create policies
ziti create service-policy httpServers Bind --identity-roles #httpServer --service-roles #httpService
ziti create service-policy httpClients Dial --identity-roles #httpClient --service-roles #httpService
- Enroll your identities
ziti edge enroll server.jwt
> createsserver.json
ziti edge enroll client.jwt
> createsclient.json
- Start an example
ziti-server-gin myHttpService server.json