Skip to content

Commit

Permalink
docs: Add gRPC proxy chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
matevz committed Feb 19, 2024
1 parent e0347b5 commit 02c81d8
Show file tree
Hide file tree
Showing 2 changed files with 291 additions and 0 deletions.
286 changes: 286 additions & 0 deletions docs/node/grpc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
---
description: gRPC proxy for Oasis node
---

# gRPC proxy for your Oasis node

The Oasis node API is exposed via the [gRPC protocol]. It enables communication
with external applications such as the Oasis CLI, dApps running in your browser
that need to perform actions on the consensus layer or a ParaTime, services for
monitoring and controlling your node and similar.

:::tip Web3 gateway

The Oasis gRPC **is not related to the standardized Web3 JSON-RPC API**. For
EVM-compatible dApps configure a [Web3 gateway] instead which is also compatible
with other Ethereum tooling.

:::

The gRPC proxy may perform the following:

- makes gRPC available to in-browser applications via gRPC-Web,
- filters out control methods such as shutting down your node,
- authentication,
- load balances the traffic to multiple Oasis nodes.

This chapter will show you how to set up a **public** gRPC endpoint using Envoy
so that it exposes only a **safe subset of the [Oasis RPC services]**. The
final section presents an alternative approach to communicate with your node by
**securely tunnelling the Unix socket over the network**, so it can safely be
used by the client, but **does not filter out any services**.

:::danger Never expose the UNIX socket directly!

The `oasis-node` deliberately exposeses the RPC interface only via an AF_LOCAL
socket called `internal.sock` located in the node's data directory.
This socket should **never be directly exposed over the network** as it has no
authentication and allows full control—including shutting down your node.

:::

[gRPC protocol]: https://github.com/oasisprotocol/oasis-core/blob/master/docs/oasis-node/rpc.md
[Web3 gateway]: web3.md
[Oasis RPC services]: https://github.com/oasisprotocol/oasis-core/blob/master/docs/oasis-node/rpc.md#services

## gRPC Proxy with Envoy {#envoy}

Let's set up a typical public Oasis endpoint using the [Envoy HTTP proxy] with
the following behavior:

- whitelisted methods for checking the network status, performing queries and
submitting transactions,
- no control methods allowed and no queries that are CPU or I/O intensive,
- lives on `grpc.my-oasis-node.com` with TLS-enabled connection and certificates
that you already have from Let's Encrypt,
- `internal.sock` of the Oasis node is accessible at `/node/data/internal.sock`.

Envoy already has built-in support for gRPC so after installing Envoy, simply
put the configuration below inside your `envoy.yaml` and then execute the proxy
with `envoy -c envoy.yaml`.

```yaml title="envoy.yaml"
# Envoy gRPC-web proxy configuration
---
admin:
address:
socket_address:
address: "127.0.0.1"
port_value: 10000
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: "0.0.0.0"
port_value: 443
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress_http
access_log:
- name: envoy.file_access_log
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /dev/stdout
route_config:
virtual_hosts:
- name: vh_0
domains:
- "*"
routes:
- match:
safe_regex:
regex: "\
/oasis-core\\.(\
Beacon/(\
ConsensusParameters|\
GetBaseEpoch|\
GetBeacon|\
GetEpoch|\
GetEpochBlock|\
GetFutureEpoch)|\
Consensus/(\
EstimateGas|\
GetBlock|\
GetChainContext|\
GetGenesisDocument|\
GetNextBlockState|\
GetSignerNonce|\
GetStatus|\
GetTransactions|\
GetTransactionsWithResults|\
GetUnconfirmedTransactions|\
SubmitTx)|\
Governance/(\
ActiveProposals|\
ConsensusParameters|\
GetEvents|\
PendingUpgrades|\
Proposal|\
Proposals|\
Votes)|\
NodeController/(\
GetStatus)|\
Registry/(\
ConsensusParameters|\
GetEntity|\
GetEvents|\
GetNode|\
GetNodeByConsensusAddress|\
GetNodeStatus|\
GetRuntime|\
GetRuntimes)|\
RootHash/(\
ConsensusParameters|\
GetEvents|\
GetGenesisBlock|\
GetLastRoundResults|\
GetLatestBlock|\
GetRuntimeState)|\
RuntimeClient/(\
CheckTx|\
GetBlock|\
GetEvents|\
GetGenesisBlock|\
GetLastRetainedBlock|\
GetTransactions|\
GetTransactionsWithResults|\
Query|\
SubmitTx|\
SubmitTxMeta|\
SubmitTxNoWait|\
WatchBlocks)|\
Scheduler/(\
ConsensusParameters|\
GetCommittees|\
GetValidators)|\
Staking/(\
Account|\
Allowance|\
CommonPool|\
ConsensusParameters|\
DebondingDelegationInfosFor|\
DebondingDelegationsFor|\
DebondingDelegationsTo|\
DelegationInfosFor|\
DelegationsFor|\
DelegationsTo|\
GetEvents|\
GovernanceDeposits|\
LastBlockFees|\
Threshold|\
TokenSymbol|\
TokenValueExponent|\
TotalSupply))\
"
route:
cluster: oasis_node_grpc
timeout: "0s"
max_stream_duration:
grpc_timeout_header_max: "0s"
- match:
prefix: /oasis-core
direct_response:
status: 404
body:
inline_string: Only some methods are allowed on this proxy.
typed_per_filter_config:
envoy.filters.http.cors:
"@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy
expose_headers: grpc-status,grpc-message,grpc-status-details-bin
allow_origin_string_match:
- exact: '*'
allow_headers: content-type,x-grpc-web,x-user-agent
max_age: '1728000'
http_filters:
- name: envoy.health_check
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
pass_through_mode: false
headers:
- name: :path
string_match:
exact: /health
- name: envoy.filters.http.grpc_web
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.cors
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
alpn_protocols:
- h2,http/1.1
tls_certificates:
- certificate_chain:
filename: /etc/letsencrypt/live/grpc.my-oasis-node.com/fullchain.pem
private_key:
filename: /etc/letsencrypt/live/grpc.my-oasis-node.com/privkey.pem
clusters:
- name: oasis_node_grpc
connect_timeout: 0.25s
load_assignment:
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
pipe:
path: /node/data/internal.sock
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
layered_runtime:
layers:
- name: static
static_layer:
re2:
max_program_size:
error_level: 1000000
```
[Envoy HTTP proxy]: https://www.envoyproxy.io/
## Tunnel Unix socket via SSH
SSH supports forwarding a Unix socket over a secure layer. The command below
will establish a secure shell to the `my-oasis-node.com` server and then tunnel
the `internal.sock` file inside the data directory to a Unix socket inside your
home folder:

```shell
ssh [email protected] -L /home/user/oasis-node-internal.sock:/node/data/internal.sock
```

The `/home/user/oasis-node-internal.sock` can now be used to safely connect to
the Oasis node **as if it was running locally without filtering any services**.
For example, using the [Oasis CLI]:

```shell
oasis network add-local my-oasis-node unix:/home/user/oasis-node-internal.sock
```

```shell
oasis network status --network my-oasis-node
```

:::tip Permanent SSH channel

To make a tunneled Unix socket over SSH permanent, consider using [autossh].

:::

[Oasis CLI]: https://github.com/oasisprotocol/cli/blob/master/docs/network.md#add-local
[autossh]: https://www.harding.motd.ca/autossh/
5 changes: 5 additions & 0 deletions sidebarNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,10 @@ export const sidebarNode: SidebarsConfig = {
label: 'Web3 Gateway',
id: 'node/web3',
},
{
type: 'doc',
label: 'gRPC Proxy',
id: 'node/grpc',
},
],
};

0 comments on commit 02c81d8

Please sign in to comment.