Skip to content

Commit

Permalink
chore: HTTPS server in Nitro
Browse files Browse the repository at this point in the history
  • Loading branch information
ibukanov committed Jun 26, 2024
1 parent 47fa552 commit 6ad71e9
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 28 deletions.
55 changes: 55 additions & 0 deletions docker-compose.payments.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
services:
redis:
image: redis:7.0
restart: always
#ports:
# - '6379:6379'
command: redis-server --save 20 1 --loglevel verbose --requirepass idBocFijvo --user redis
#volumes:
# - redis-cache:/data

# Access to localstack:
# export AWS_DEFAULT_REGION=us-east-1
# export AWS_SECRET_ACCESS_KEY=test
# export AWS_ACCESS_KEY_ID=test
# export AWS_ENDPOINT_URL=http://localhost:4566

localstack:
container_name: localstack
image: localstack/localstack
ports:
- "127.0.0.1:4566:4566" # LocalStack Gateway
- "127.0.0.1:4510-4559:4510-4559" # external services port range
environment:
# LocalStack configuration: https://docs.localstack.cloud/references/configuration/
- DEBUG=0
#volumes:
#- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
# Access to Docker is not necessary with S3.
# - "/var/run/docker.sock:/var/run/docker.sock"

worker:
image: bat-go-repro:latest
command: bat-go serve payments worker
environment:
- REDIS_ADDR=redis:6379
- REDIS_USER=user
- REDIS_PASS=idBocFijvo
- DEBUG=1
- ENVIRONMENT=development
- NITRO_API_BASE=http://web.payment-dev.svc.cluster.local

service:
image: bat-go-repro:latest
command: bat-go serve nitro inside-enclave --egress-address none --log-address none --upstream-url http://0.0.0.0:8080
environment:
- ENCLAVE_MOCKING=1
- AWS_REGION="us-west-2"
- DEBUG=1
ports:
- "18080:8080"
- "18443:8443"

volumes:
redis-cache:
driver: local
2 changes: 1 addition & 1 deletion libs/nitro/aws/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func NewAWSConfig(ctx context.Context, proxyAddr string, region string) (aws.Con
})

return config.LoadDefaultConfig(context.TODO(),
config.WithHTTPClient(&client),
config.WithHTTPClient(client),
config.WithRegion(region),
config.WithCredentialsProvider(provider),
config.WithLogger(applicationLogger),
Expand Down
11 changes: 11 additions & 0 deletions libs/nitro/mocking.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package nitro

var enclaveMocking bool

func MockEnclave() {
enclaveMocking = true
}

func EnclaveMocking() bool {
return enclaveMocking
}
4 changes: 2 additions & 2 deletions nitro-shim/scripts/start-proxies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ echo "cid is ${CID}"
# it's now time to set up proxy tools
if [ "${service}" = "/payments" ]; then
# setup inbound traffic proxy
export IN_ADDRS=":8080"
export OUT_ADDRS="${CID}:8080"
export IN_ADDRS=":8080,:8443"
export OUT_ADDRS="${CID}:8080,${CID}:8443"
echo "${IN_ADDRS} to ${OUT_ADDRS}"
# next startup the proxy
/enclave/viproxy > /tmp/viproxy.log &
Expand Down
6 changes: 5 additions & 1 deletion services/cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ func init() {

// address - sets the address of the server to be started
ServeCmd.PersistentFlags().String("address", ":8080",
"the default address to bind to")
"the address to bind to the HTTP server")
ServeCmd.PersistentFlags().String("address2", ":8443",
"the address to bind the HTTPS server")
cmdutils.Must(viper.BindPFlag("address", ServeCmd.PersistentFlags().Lookup("address")))
cmdutils.Must(viper.BindEnv("address", "ADDR"))
cmdutils.Must(viper.BindEnv("address2", "ADDR2"))

ServeCmd.PersistentFlags().Bool("enable-job-workers", true,
"enable job workers (defaults true)")
Expand Down Expand Up @@ -81,6 +84,7 @@ func SetupRouter(ctx context.Context) *chi.Mux {
Str("build_time", ctx.Value(appctx.BuildTimeCTXKey).(string)).
Str("ratios_service", viper.GetString("ratios-service")).
Str("address", viper.GetString("address")).
Str("address2", viper.GetString("address2")).
Str("environment", viper.GetString("environment")).
Msg("server starting")
}
Expand Down
70 changes: 66 additions & 4 deletions services/nitro/nitro.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ package nitro

import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"math/big"
"net/http"
"runtime/debug"
"strconv"
Expand Down Expand Up @@ -157,27 +163,83 @@ func RunNitroServerInEnclave(cmd *cobra.Command, args []string) error {
logger.Info().Msg("payments routes setup")

// setup listener
listenAddress := viper.GetString("address")
httpListenAddress := viper.GetString("address")

httpsListenAddress := viper.GetString("address2")

// setup vsock listener
httpListener, err := nitro.Listen(ctx, listenAddress)
httpListener, err := nitro.Listen(ctx, httpListenAddress)
if err != nil {
logger.Panic().Err(err).Msg("listening on vsock port failed")
}
httpsListener, err := nitro.Listen(ctx, httpsListenAddress)
if err != nil {
logger.Panic().Err(err).Msg("listening on vsock port failed")
}
logger.Info().Msg("vsock listener setup")

tlsCertificate, err := createSelfSignedCertificate()
if err != nil {
logger.Panic().Err(err).Msg("failed to create a self-signed certoificate")
}

// setup server
srv := http.Server{
Handler: chi.ServerBaseContext(ctx, r),
ReadTimeout: 3 * time.Second,
WriteTimeout: 20 * time.Second,
}
srv.TLSConfig.Certificates = []tls.Certificate{tlsCertificate}

logger.Info().Msg("starting server")
// run the server in another routine
logger.Fatal().Err(srv.Serve(httpListener)).Msg("server shutdown")

errChan := make(chan error, 2)
go func() {
errChan <- srv.Serve(httpListener)
}()
go func() {
errChan <- srv.ServeTLS(httpsListener, "", "")
}()
err = <-errChan
logger.Fatal().Err(err).Msg("server shutdown")
return nil
}

func createSelfSignedCertificate() (tls.Certificate, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return tls.Certificate{}, err
}
keyUsage := x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
timeNow := time.Now()

// Allow the client clock to be off by 1 min
notBefore := timeNow.Add(-time.Minute)
notAfter := timeNow.AddDate(10, 0, 0)
serialNumber := big.NewInt(1)
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Brave Software"},
},
NotBefore: notBefore,
NotAfter: notAfter,

KeyUsage: keyUsage,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
template.DNSNames = []string{"nitro.localdomain"}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, privateKey.PublicKey, privateKey)
if err != nil {
return tls.Certificate{}, err
}
return tls.Certificate{
Certificate: [][]byte{derBytes},
PrivateKey: privateKey,
}, nil
}

// RunNitroServerOutsideEnclave - start up all the services which are outside
func RunNitroServerOutsideEnclave(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
Expand Down
43 changes: 23 additions & 20 deletions services/payments/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,29 +222,32 @@ func NewService(ctx context.Context) (context.Context, *Service, error) {
return nil, nil, errors.New("no egress addr for payments service")
}

pcrs, err := nitro.GetPCRs()
if err != nil {
logger.Fatal().Err(err).Msg("could not retrieve nitro PCRs")
return nil, nil, errors.New("could not retrieve nitro PCRs")
}
store, err := NewVerifierStore()
if err != nil {
logger.Fatal().Err(err).Msg("could not create verifier store")
return nil, nil, errors.New("could not create verifier store")
}

service := &Service{
baseCtx: ctx,
awsCfg: awsCfg,
publicKey: hex.EncodeToString(pcrs[2]),
signer: nitro.Signer{},
verifierStore: store,
egressAddr: egressAddr,
baseCtx: ctx,
awsCfg: awsCfg,
signer: nitro.Signer{},
egressAddr: egressAddr,
}

// create the kms encryption key for this service for bootstrap operator shares
if err := service.configureKMSEncryptionKey(ctx); err != nil {
return nil, nil, fmt.Errorf("could not create kms secret encryption key: %w", err)
if !nitro.EnclaveMocking() {
pcrs, err := nitro.GetPCRs()
if err != nil {
logger.Fatal().Err(err).Msg("could not retrieve nitro PCRs")
return nil, nil, errors.New("could not retrieve nitro PCRs")
}
service.publicKey = hex.EncodeToString(pcrs[2])

verifierStore, err := NewVerifierStore()
if err != nil {
logger.Fatal().Err(err).Msg("could not create verifier store")
return nil, nil, errors.New("could not create verifier store")
}
service.verifierStore = verifierStore

// create the kms encryption key for this service for bootstrap operator shares
if err := service.configureKMSEncryptionKey(ctx); err != nil {
return nil, nil, fmt.Errorf("could not create kms secret encryption key: %w", err)
}
}

go func() {
Expand Down

0 comments on commit 6ad71e9

Please sign in to comment.