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 1a28acb
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 7 deletions.
4 changes: 3 additions & 1 deletion docs/node/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ to use.
findSidebarItem('/node/testnet/'),
findSidebarItem('/node/run-your-node/prerequisites'),
findSidebarItem('/node/run-your-node/validator-node'),
findSidebarItem('/node/run-your-node/non-validator-node'),
findSidebarItem('/node/run-your-node/paratime-node'),
findSidebarItem('/node/run-your-node/paratime-client-node'),
findSidebarItem('/node/web3'),
findSidebarItem('/node/grpc'),
]} />
293 changes: 293 additions & 0 deletions docs/node/grpc.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
---
description: gRPC proxy for Oasis node
---

import DocCardList from '@theme/DocCardList';
import {findSidebarItem} from '@site/src/sidebarUtils';

# 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 exposes 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/

## See also

<DocCardList items={[findSidebarItem('/node/run-your-node'), findSidebarItem('/node/web3')]} />
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import DocCard from '@theme/DocCard';
import {findSidebarItem} from '@site/src/sidebarUtils';

# Non-validator Node

:::info
Expand Down Expand Up @@ -86,3 +89,6 @@ To ensure that your node is properly connected with the network, you can run the
oasis-node control status -a unix:/node/data/internal.sock
```

## See also

<DocCard item={findSidebarItem('/node/grpc')} />
15 changes: 9 additions & 6 deletions docs/node/run-your-node/validator-node.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import DocCard from '@theme/DocCard';
import DocCardList from '@theme/DocCardList';
import {findSidebarItem} from '@site/src/sidebarUtils';

# Validator Node
Expand Down Expand Up @@ -181,7 +181,7 @@ common:
data_dir: /node/data
# Logging.
#
# Per-module log levels are defined below. If you prefer just one unified
# Per-module log levels are defined below. If you prefer just one unified
# log level, you can use:
#
# log:
Expand All @@ -190,11 +190,11 @@ common:
level:
cometbft: warn
cometbft/context: error
# Per-module log levels. Longest prefix match will be taken.
# Per-module log levels. Longest prefix match will be taken.
# Fallback to "default", if no match.
default: debug
format: JSON
# By default logs are output to stdout. If you would like to output
# By default logs are output to stdout. If you would like to output
# logs to a file, you can use:
#
# file: /var/log/oasis-node.log
Expand Down Expand Up @@ -451,5 +451,8 @@ the node operator's name and the avatar.

# See also

<DocCard item={findSidebarItem('/general/manage-tokens/cli/')} />
<DocCard item={findSidebarItem('/core/oasis-node/cli')} />
<DocCardList items={[
findSidebarItem('/general/manage-tokens/cli/'),
findSidebarItem('/core/oasis-node/cli'),
findSidebarItem('/node/grpc')]}
/>
7 changes: 7 additions & 0 deletions docs/node/web3.md → docs/node/web3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
description: Web3 gateway for Emerald and Sapphire ParaTimes
---

import DocCardList from '@theme/DocCardList';
import {findSidebarItem} from '@site/src/sidebarUtils';

# Oasis Web3 Gateway for your EVM ParaTime

This guide will walk you through the steps needed to set up the Oasis Web3
Expand Down Expand Up @@ -272,3 +275,7 @@ extended downtime while the Web3 Gateway is reindexing the blocks.
[Testnet]: testnet/README.md
[testnet-emerald]: testnet/README.md#emerald
[testnet-sapphire]: testnet/README.md#sapphire

## See also

<DocCardList items={[findSidebarItem('/node/run-your-node'), findSidebarItem('/node/grpc'), ]} />
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 1a28acb

Please sign in to comment.