-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,285 @@ | ||
--- | ||
description: gRPC proxy for Oasis node | ||
--- | ||
|
||
# gRPC proxy for your Oasis node | ||
|
||
The Oasis node API is exposed via the [gRPC interface]. It enables communication | ||
with external applications such as the Oasis CLI, dApps running in your browser | ||
and need to perform actions on the consensus layer or on a non-EVM | ||
ParaTime, monitoring and controlling the node and similar. | ||
|
||
:::tip Web3 gateway | ||
|
||
The Oasis gRPC **is not related to the standardized Web3 interface**. For | ||
EVM-compatible dApps we suggest that you set up a [Web3 gateway] instead and | ||
which is also compatible with other Ethereum tooling. | ||
|
||
::: | ||
|
||
The gRPC proxy performs the following: | ||
|
||
- transforms the gRPC into HTTP methods so that you can access the Oasis node | ||
directly from your browser, | ||
- 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 which **securely tunnels a Unix | ||
socket over the network**, so it can safely be used by the client, but **does | ||
not filter out any services**. | ||
|
||
:::danger Never expose RPC 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. | ||
The socket should **never be directly exposed over the network** as it has no | ||
authentication and allows full control—including shutting down your node. | ||
|
||
::: | ||
|
||
[gRPC interface]: 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 and no control methods and queries that are CPU and | ||
I/O intensive, | ||
- lives on `grpc.my-oasis-node.com` with TLS-enabled connection and Let's | ||
encrypt certificates. | ||
- `internal.sock` of the Oasis node 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/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters