Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate a certificate inside the enclave #2162

Merged
merged 3 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .github/workflows/manual-deploy-obscuro-gateway.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ jobs:
"GATEWAY_RATE_LIMIT_WINDOW"
"GATEWAY_MAX_CONCURRENT_REQUESTS_PER_USER"
"GATEWAY_KEY_EXCHANGE_URL"
"GATEWAY_TLS_DOMAIN"
)

for VAR_NAME in "${VAR_NAMES[@]}"; do
Expand Down Expand Up @@ -121,6 +122,7 @@ jobs:
echo "GATEWAY_RATE_LIMIT_WINDOW: $GATEWAY_RATE_LIMIT_WINDOW"
echo "GATEWAY_MAX_CONCURRENT_REQUESTS_PER_USER: $GATEWAY_MAX_CONCURRENT_REQUESTS_PER_USER"
echo "GATEWAY_KEY_EXCHANGE_URL: $GATEWAY_KEY_EXCHANGE_URL"
echo "GATEWAY_TLS_DOMAIN: $GATEWAY_TLS_DOMAIN"

- name: "Print GitHub variables"
# This is a useful record of what the environment variables were at the time the job ran, for debugging and reference
Expand Down Expand Up @@ -200,7 +202,7 @@ jobs:
uses: azure/CLI@v1
with:
inlineScript: |
az vm open-port -g Testnet -n "${{ env.VM_NAME }}" --port 80,81
az vm open-port -g Testnet -n "${{ env.VM_NAME }}" --port 80,81,443,444

# To overcome issues with critical VM resources being unavailable, we need to wait for the VM to be ready
- name: "Allow time for VM initialization"
Expand Down Expand Up @@ -357,20 +359,22 @@ jobs:
docker volume create "${{ env.VM_NAME }}-data"

# Start Ten Gateway Container
docker run -d -p 80:80 -p 81:81 --name "${{ env.VM_NAME }}" \
docker run -d -p 80:80 -p 81:81 -p 443:443 -p 444:444 --name "${{ env.VM_NAME }}" \
--device /dev/sgx_enclave --device /dev/sgx_provision \
-v "${{ env.VM_NAME }}-data:/data" \
-e OBSCURO_GATEWAY_VERSION="${{ github.run_number }}-${{ github.sha }}" \
-e OE_SIMULATION=0 \
"${{ env.DOCKER_BUILD_TAG_GATEWAY }}" \
ego run /home/ten/go-ten/tools/walletextension/main/main \
-host=0.0.0.0 -port=80 -portWS=81 -nodeHost="${{ env.L2_RPC_URL_VALIDATOR }}" -verbose=true \
-host=0.0.0.0 -port=443 -portWS=444 -nodeHost="${{ env.L2_RPC_URL_VALIDATOR }}" -verbose=true \
-logPath=sys_out -dbType=cosmosDB -dbConnectionURL="${{ secrets.COSMOS_DB_CONNECTION_STRING }}" \
-rateLimitUserComputeTime="${{ env.GATEWAY_RATE_LIMIT_USER_COMPUTE_TIME }}" \
-rateLimitWindow="${{ env.GATEWAY_RATE_LIMIT_WINDOW }}" \
-maxConcurrentRequestsPerUser="${{ env.GATEWAY_MAX_CONCURRENT_REQUESTS_PER_USER }}" \
-keyExchangeURL="${{ env.GATEWAY_KEY_EXCHANGE_URL }}" \
-insideEnclave=true \
-enableTLS=true \
-tlsDomain="${{ env.GATEWAY_TLS_DOMAIN }}"


# After starting the container, verify the volume mount
Expand All @@ -387,4 +391,5 @@ jobs:
ps aux;
"
'



8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ require (
github.com/urfave/cli/v2 v2.27.5
github.com/valyala/fasthttp v1.57.0
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40
golang.org/x/crypto v0.28.0
golang.org/x/crypto v0.29.0
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81
golang.org/x/sync v0.8.0
golang.org/x/sync v0.9.0
google.golang.org/grpc v1.67.1
google.golang.org/protobuf v1.35.1
gopkg.in/natefinch/lumberjack.v2 v2.2.1
Expand Down Expand Up @@ -173,8 +173,8 @@ require (
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/arch v0.11.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gotest.tools/v3 v3.5.1 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc=
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
Expand All @@ -437,6 +439,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -460,12 +464,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
4 changes: 4 additions & 0 deletions lib/gethfork/node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package node

import (
"crypto/tls"
"fmt"
"net"
"os"
Expand Down Expand Up @@ -171,6 +172,9 @@ type Config struct {

// TEN
ExposedURLParamNames []string

// TLS
TLSConfig *tls.Config
}

// IPCEndpoint resolves an IPC endpoint based on a configured value, taking into
Expand Down
1 change: 1 addition & 0 deletions lib/gethfork/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ func (n *Node) startRPC() error {
}); err != nil {
return err
}
server.tlsConfig = n.config.TLSConfig
servers = append(servers, server)
return nil
}
Expand Down
3 changes: 3 additions & 0 deletions lib/gethfork/node/rpc_server.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package node

import (
"crypto/tls"
"net/http"

gethlog "github.com/ethereum/go-ethereum/log"
Expand All @@ -20,6 +21,7 @@ type RPCConfig struct {
WsPort int
WsPath string
HTTPPath string
TLSConfig *tls.Config

// ExposedURLParamNames - url prams that are available in the services
ExposedURLParamNames []string
Expand Down Expand Up @@ -49,6 +51,7 @@ func NewServer(config *RPCConfig, logger gethlog.Logger) Server {
rpcConfig := Config{
Logger: logger,
ExposedURLParamNames: config.ExposedURLParamNames,
TLSConfig: config.TLSConfig,
}
if config.EnableHTTP {
rpcConfig.HTTPHost = config.Host
Expand Down
14 changes: 13 additions & 1 deletion lib/gethfork/node/rpcstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package node
import (
"compress/gzip"
"context"
"crypto/tls"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -92,6 +93,8 @@ type httpServer struct {
port int

handlerNames map[string]string

tlsConfig *tls.Config
}

const (
Expand Down Expand Up @@ -152,7 +155,16 @@ func (h *httpServer) start() error {
}

// Start the server.
listener, err := net.Listen("tcp", h.endpoint)
var listener net.Listener
var err error

if h.tlsConfig != nil {
// If TLS is enabled, use tls.Listen to create a TLS listener
listener, err = tls.Listen("tcp", h.endpoint, h.tlsConfig)
} else {
listener, err = net.Listen("tcp", h.endpoint)
}

if err != nil {
// If the server fails to start, we need to clear out the RPC and WS
// configuration so they can be configured another time.
Expand Down
2 changes: 2 additions & 0 deletions tools/walletextension/common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ type Config struct {
RateLimitMaxConcurrentRequests int
InsideEnclave bool // Indicates if the program is running inside an enclave
KeyExchangeURL string
EnableTLS bool
TLSDomain string
}
12 changes: 12 additions & 0 deletions tools/walletextension/main/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ const (
keyExchangeURLFlagName = "keyExchangeURL"
keyExchangeURLFlagDefault = ""
keyExchangeURLFlagUsage = "URL to exchange the key with another enclave. Default: empty"

enableTLSFlagName = "enableTLS"
enableTLSFlagDefault = false
enableTLSFlagUsage = "Flag to enable TLS/HTTPS"

tlsDomainFlagName = "tlsDomain"
tlsDomainFlagDefault = ""
tlsDomainFlagUsage = "Domain name for TLS certificate"
)

func parseCLIArgs() wecommon.Config {
Expand All @@ -101,6 +109,8 @@ func parseCLIArgs() wecommon.Config {
rateLimitMaxConcurrentRequests := flag.Int(rateLimitMaxConcurrentRequestsName, rateLimitMaxConcurrentRequestsDefault, rateLimitMaxConcurrentRequestsUsage)
insideEnclaveFlag := flag.Bool(insideEnclaveFlagName, insideEnclaveFlagDefault, insideEnclaveFlagUsage)
keyExchangeURL := flag.String(keyExchangeURLFlagName, keyExchangeURLFlagDefault, keyExchangeURLFlagUsage)
enableTLSFlag := flag.Bool(enableTLSFlagName, enableTLSFlagDefault, enableTLSFlagUsage)
tlsDomainFlag := flag.String(tlsDomainFlagName, tlsDomainFlagDefault, tlsDomainFlagUsage)
flag.Parse()

return wecommon.Config{
Expand All @@ -121,5 +131,7 @@ func parseCLIArgs() wecommon.Config {
RateLimitMaxConcurrentRequests: *rateLimitMaxConcurrentRequests,
InsideEnclave: *insideEnclaveFlag,
KeyExchangeURL: *keyExchangeURL,
EnableTLS: *enableTLSFlag,
TLSDomain: *tlsDomainFlag,
}
}
37 changes: 37 additions & 0 deletions tools/walletextension/walletextension_container.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package walletextension

import (
"crypto/tls"
"net/http"
"os"
"time"

Expand All @@ -21,6 +23,7 @@ import (
wecommon "github.com/ten-protocol/go-ten/tools/walletextension/common"
"github.com/ten-protocol/go-ten/tools/walletextension/keymanager"
"github.com/ten-protocol/go-ten/tools/walletextension/storage"
"golang.org/x/crypto/acme/autocert"
)

type Container struct {
Expand Down Expand Up @@ -67,6 +70,40 @@ func NewContainerFromConfig(config wecommon.Config, logger gethlog.Logger) *Cont
HTTPPath: wecommon.APIVersion1 + "/",
Host: config.WalletExtensionHost,
}

// check if TLS is enabled
if config.EnableTLS {
// Create autocert manager for automatic certificate management
// Generating a certificate consists of the following steps:
// generating a new private key
// domain ownership verification (HTTP-01 challenge since certManager.HTTPHandler(nil) is set)
// Certificate Signing Request (CRS) is generated
// CRS is sent to CA (Let's Encrypt) via ACME (automated certificate management environment) client
// CA verifies CRS and issues a certificate
// we store store certificate and private key (in memory and also in on a mounted volume attached to docker container - /data/certs/)

certManager := &autocert.Manager{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add the details about what happens in the library from the description here as a comment

Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(config.TLSDomain),
Cache: autocert.DirCache("/data/certs"),
}

// Create HTTP-01 challenge handler
httpServer := &http.Server{
Addr: ":http", // Port 80
Handler: certManager.HTTPHandler(nil),
}
go httpServer.ListenAndServe() // Start HTTP server for ACME challenges

tlsConfig := &tls.Config{
GetCertificate: certManager.GetCertificate,
MinVersion: tls.VersionTLS12,
}

// Update RPC server config to use TLS
cfg.TLSConfig = tlsConfig
}

rpcServer := node.NewServer(cfg, logger)

rpcServer.RegisterRoutes(httpapi.NewHTTPRoutes(walletExt))
Expand Down
Loading