nitriding

package module
v1.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2022 License: MPL-2.0 Imports: 38 Imported by: 3

README

Nitriding

GoDoc

This package helps with building Go-based Web applications on top of AWS Nitro Enclaves. The package provides the following features:

  1. Automatically obtains an HTTPS certificate (either self-signed or via Let's Encrypt) for clients to securely connect to your enclave over the Internet.

  2. Automatically exposes an HTTPS endpoint for remote attestation. After having audited your enclave's source code, your users can conveniently verify the enclave by using a tool like verify-enclave and running:

    make verify CODE=/path/to/code/ ENCLAVE=https://example.com/attest
    
  3. Provides an API for the enclave application to securely share confidential key material with an identical, remote enclave.

  4. Starts a proxy component that transparently translates between IP and VSOCK, so you can write IP-based networking code without having to worry about the enclave's constrained VSOCK interface.

  5. Automatically initializes the enclave's entropy pool using the Nitro hypervisor.

To learn more about nitriding's trust assumptions, architecture, and build system, take a look at our research paper.

Configuration

Nitriding's configuration object contains comments that explain the purpose of each variable.

Example

Use the following "hello world" example to get started. The program instantiates a new Web server that's listening on port 8443, for the domain example.com. It also registers an HTTP handler for the path /hello-world which, when accessed, simply responds with the string "hello world".

Note that in order for this example to work, you need to set up two programs on the parent EC2 instance:

  1. viproxy by running:

    export CID=5 # The CID you assigned when running "nitro-cli run-enclave --enclave-cid X ...".
    export IN_ADDRS=":8443,:80,3:80"
    export OUT_ADDRS="${CID}:8443,${CID}:80,127.0.0.1:1080"
    viproxy
    
  2. A SOCKS proxy, e.g. this one.

That said, here is the enclave application:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/brave/nitriding"
)

func helloWorldHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "hello world")
}

func main() {
	enclave := nitriding.NewEnclave(
		&nitriding.Config{
			FQDN:    "example.com",
			Port:    8443,
			UseACME: true,
		},
	)
	enclave.AddRoute(http.MethodGet, "/hello-world", helloWorldHandler)
	if err := enclave.Start(); err != nil {
		log.Fatalf("Enclave terminated: %v", err)
	}
}

Development

To test and lint the code, run:

make

Documentation

Overview

Package nitriding implements a lightweight framework to build networked Go applications that run in AWS Nitro Enclaves.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RequestKeys

func RequestKeys(addr string, keyMaterial any) error

RequestKeys asks a remote enclave to share its key material with us, which is then written to the provided variable.

This is only necessary if you intend to scale enclaves horizontally. If you will only ever run a single enclave, ignore this function.

Types

type Config

type Config struct {
	// SOCKSProxy must be set if
	//   1) your enclave application should obtain a Let's Encrypt-signed
	//      certificate (i.e., if UseACME is set to true)
	// or if
	//   2) your enclave application makes HTTP requests over the Internet.
	// If so, set SOCKSProxy to "socks5://127.0.0.1:1080".
	SOCKSProxy string

	// FQDN contains the fully qualified domain name that's set in the HTTPS
	// certificate of the enclave's Web server, e.g. "example.com".
	FQDN string

	// Port contains the TCP port that the Web server should listen on, e.g.
	// 8443.  Note that the Web server listens for this port on the private
	// VSOCK interface.  This is not an Internet-facing port.
	Port int

	// UseACME must be set to true if you want your enclave application to
	// request a Let's Encrypt-signed certificate.  If this is set to false,
	// the enclave creates a self-signed certificate.
	UseACME bool

	// Debug can be set to true to see debug messages, i.e., if you are
	// starting the enclave in debug mode by running:
	//
	//   nitro-cli run-enclave --debug-mode ....
	//
	// Do not set this to true in production because printing debug messages
	// for each HTTP request slows down the enclave application, and you are
	// not able to see debug messages anyway unless you start the enclave using
	// nitro-cli's "--debug-mode" flag.
	Debug bool

	// FdCur and FdMax set the soft and hard resource limit, respectively.  The
	// default for both variables is 65536.
	FdCur uint64
	FdMax uint64

	// AppURL should be set to the URL of the software repository that's
	// running inside the enclave, e.g., "https://github.com/foo/bar".  The URL
	// is shown on the enclave's index page, as part of instructions on how to
	// do remote attestation.
	AppURL string
}

Config represents the configuration of our enclave service.

type Enclave

type Enclave struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Enclave represents a service running inside an AWS Nitro Enclave.

func NewEnclave

func NewEnclave(cfg *Config) *Enclave

NewEnclave creates and returns a new enclave with the given config.

func (*Enclave) AddRoute

func (e *Enclave) AddRoute(method, pattern string, handlerFn http.HandlerFunc)

AddRoute adds an HTTP handler for the given HTTP method and pattern.

func (*Enclave) KeyMaterial

func (e *Enclave) KeyMaterial() (any, error)

KeyMaterial returns the key material or, if none was registered, an error.

func (*Enclave) SetKeyMaterial

func (e *Enclave) SetKeyMaterial(keyMaterial any)

SetKeyMaterial registers the enclave's key material (e.g., secret encryption keys) as being ready to be synchronized to other, identical enclaves. Note that the key material's underlying data structure must be marshallable to JSON.

This is only necessary if you intend to scale enclaves horizontally. If you will only ever run a single enclave, ignore this function.

func (*Enclave) Start

func (e *Enclave) Start() error

Start starts the Nitro Enclave. If it bootstraps correctly, this function won't return because it starts an HTTPS server. If something goes wrong, the function returns an error.

Directories

Path Synopsis
cmd module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL