owned this note
owned this note
Published
Linked with GitHub
---
title: Providing an Ethereum endpoint
description:
author: "Mario Havel"
tags: ["clients", "geth", "nodes", "hosting", "balancing"]
skill: intermediate
lang: en
sidebar: true
published:
---
Ethereum client gives you direct access to data in the Ethereum network and allows you to interact with it. There are [many services](https://ethereum.org/en/developers/docs/nodes-and-clients/nodes-as-a-service/) that provide public free or paid access to Ethereum client JSON-RPC. This tutorial will explain how to securely provide an own public endpoint for your Ethereum clients.
## Prerequisties {#prerequisites}
This tutorial assumes you are familiar with running your own Ethereum client, understand its API endpoints and how to use them.
Check out [Run a node](https://ethereum.org/en/run-a-node/), [Nodes and clients](https://ethereum.org/en/developers/docs/nodes-and-clients/), and [JSON-RPC](https://ethereum.org/en/developers/docs/apis/json-rpc/) for more information.
## Intro to the stack {#intro}
As an Ethereum user, developer, or service provider, you can setup your own instance of the Ethereum client to use Ethereum in a trustless manner. Using Ethereum directly without relying on third parties is always the recommended approach.
If you spun client on your own machine, you might need to access it from anywhere, not just locally on machine where it's running.
This tutorial will guide you through the setup of tools for creating a public endpoint which serves as a proxy, filter, and also a balancer for your Ethereum clients.

The software stack explained in this tutorial.
Setup in this tutorial will result in multiple connected services handling the RPC data:
* End users (a wallet, Ethereum application) can securely connect to an adress via https.
* Their requests are handled by Nginx which proxys them to a Dshackle instance.
* [Dshackle](https://github.com/emeraldpay/dshackle) filters and balances requests to chosen endpoints with the Ethereum execution client's RPC.
## Client configuration {#client-config}
Let's start with proper configuration of your Ethereum client software. User facing RPC endpoint is served by an execution layer client. All clients can serve their JSON-RPC endpoint reachable via http or websockets. This can be enabled in the client's configuration. The default port where RPC is bound is 8545. Ports and addresses can also be configured for your needs, for example, if you are running multiple clients at the same machine.
Client configuration also allows choosing which namespaces or methods are allowed. For security reasons, disable at least `admin` namespace. If your node is not in archive mode, it's also discouraged to enable `debug`. However, filtering and enabling only specified calls can be done later with Dshackle.
Each client handles configuration differently with various syntaxes and defualts. For details, refer to the documentation of the chosen client. Here are general examples of basic configurtion of various execution client to enable http and websockets RPC, specify a port and enabled namespaces:
```
geth --http --http.port 8552 --http.corsdomain "*" --http.api web3,eth,txpool,net,debug --ws --ws.api web3,eth,txpool,net,debug
erigon --http --http.port 8545 --http.corsdomain "*" --ws --http.api web3,eth,txpool,net,debug,admin,trace,erigon
besu --rpc-http-enabled=true --rpc-http-apis=ADMIN,DEBUG,ETH,NET,TRACE,TXPOOL,WEB3 --rpc-http-port=8545 --rpc-http-cors-origins=* --host-allowlist=* --rpc-ws-enabled=true --rpc-ws-apis=ADMIN,DEBUG,ETH,NET,TRACE,TXPOOL,WEB3 --rpc-ws-port=8546
Nethermind.Runner --JsonRpc.Enabled --JsonRpc.Port 8545 --JsonRpc.EnabledModules 'Eth, TxPool, Web3, Net'
```
After configuring and executing the client, make sure that the endpoint is enabled and responds to RPC requests.
You can test whether RPC is reachable via a simple call with `curl`:
```
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
--data'{"jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":1}'
```
Use this for testing whether the API is properly reachable at any stage of this tutorial.
### Proxy
You might want to run the public facing service on a different machine than your node. For example a small and cheap cloud instance. This is recommended if the network with your node doesn't support a static public address. It also ensures more security and privacy by not leaking the address of your machine. You can setup simple proxy forwarding using ssh.
To do this, establish ssh connection from the machine where the client is running locally to the remote server:
```
autossh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R localhost:8545:localhost:8545 username@remoteserver
```
This assumes the default port of JSON-RPC. Change it to suit your setup. The first specified port is listening on a remote machine, and the second is local, where Ethereum client is running. Using different ports on remote machine enables you to bind multiple services there.
The command above is holding the connection until it's kill. Make sure it's always running on background, for example as [system service](https://linuxhandbook.com/create-systemd-services/) or in `screen`.
The RPC endpoint is now reachable on the remote machine and requests are securely forwarded to the client on local machine.
## Setting up services {#services}
To setup all services for providing public RPC endpoint, we will use an automatized Docker setup from this repository. You just need to configure it based on your parameters and everything will run automatically just by executing one command. To be specific, it spins up Dshackle with redis database for caching and configures nginx as proxy with certbot which enables https connection.
The whole stack will be running inh Docker. For a smooth deployment, ensure that [Docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/linux/) are installed and properly configured in your system.
Clone this repository and make yourself familiar with its contents. It includes Docker script of the whole stack and configuration of individual componenets. We need to config some of those first
### Dshackle configuration
Frist important part to configure is Dshackle.
Dshackle is software which serves as a filter and balancer for Ethereum client APIs. RPC requests sent to your server will be handled by Dshackle which forwards it to your client(s). Dshackle comes with many useful features and options. Learn more about them in the [documentation](https://github.com/emeraldpay/dshackle/tree/master/docs).
The main Dshackle config file can be found in `dshackle_conf/dshackle.yaml`
This is an example file which enables multiple networks and you should modify it to fit your needs. If you don't wish to use other networks than mainnet, e.g. testnets or L2s and disable metrics,
1. The first part defines the gRPC endpoint. It might offer better performance, but we won't be using it in this tutorial. You can just set the default and don't expose it.
2. `proxy` part configures the JSON-RPC we will work with. This is where requests are sent from outside and handled by Dshackle. Bind it to `localhost` and an arbitrary port.
3. In `cluster` you can configure various `upstreams` which represent Ethereum clients where Dshackle sents requests and recieves responses. For each upstream, you can also define the methods that are allowed. This filtering is recommended for the security of your public endpoint. Some methods, e.g. from admin or debug namespaces, can be abused by attackers. If you setup multiple upstreams, Dshackle will act like a balancer and divide requests to different clients.
4. Finally, in `connection` of each upstream, you define where these requests are sent - RPC endpoint of your nodes.
```
version: v1
port: 2449
tls:
enabled: false
monitoring:
enabled: false
jvm: false
extended: false
prometheus:
enabled: true
bind: 0.0.0.0
port: 8081
path: /metrics
cache:
redis:
enabled: true
host: redis
password: ""
proxy:
host: 0.0.0.0
port: 8080
tls:
enabled: false
routes:
- id: mainnet
blockchain: ethereum
cluster:
defaults:
- chains:
- ethereum
include:
- "eth_main.yaml"
- "eth_archive.yaml"
- "eth_public.yaml"
```
In the example below, we configure Dshackle with listening JSON-RPC enabled on port `1337` and send requests with some safe methods allowed to a single Geth archive node on `localhost:8545`. Check also [Quick start example in docs](https://github.com/emeraldpay/dshackle/blob/master/docs/02-quick-start.adoc#configuration) for more config examples.
In this example, the client's RPC endpoint is local. This means it is running on the same machine or the client's endpoint is forwarded as a proxy to this server. The upstream connection doesn't have to be local. Dshackle can also connect to remote nodes. For example, you can create a balancer with multiple public or own endpoints.
Now let's configure individual upstreams.
### Web server
In our setup, neither Dshackle or client is reachable publicly. Everything is configured only to bind at system's localhost and is not accesible publicly via internet. Now, we will setup nginx server which will handle traffic from public and direct it to Dshackle.
Nginx is versatile tool which gives you lot of options. This setup uses it for proxy, header modifier and TLS setup.
### https
The last step is to enable and enforce https for your endpoint. An encrypted TLS connection is necessary to protect the user's data. We will setup nginx to handle it using certbot.
And follow instructions. Add your information, domain name, and SSL will be configured with Nginx automatically.
## Using it {#usage}
Now you are ready to use your client via public endpoint. Don't forget to test the whole setup with call to your public address. If you don't receive a respond, debug services by making sure each is running, configured properly and accepting these calls locally.
You can configure your public JSON-RPC address in any tool you are using, for example wallets. Start using it with [Metamask](https://metamask.zendesk.com/hc/en-us/articles/360043227612-How-to-add-a-custom-network-RPC) or any wallet which enables custom RPC. Point your consensus or L2 clients to this endpoit or use developer tools like Truffle, Hardhat with it.
Also, make sure to share this endpoint with your community! Instead of relying on a few centralized services, people can use providers within their communities to enable a truly decentralized web3 future.