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

feat(endpoint): added extra admin rpc endpoint for sensitive rpc calls #386

Open
wants to merge 27 commits into
base: main
Choose a base branch
from

Conversation

Trantorian1
Copy link
Collaborator

Pull Request type

  • Feature

What is the current behavior?

Currently, all rpc methods are implemented under a single endpoint. This poses issues as we want to add privilidged methods which allow node operators and developers to manipulate their node at a distance, and currently these methods would be exposed to users as well.

What is the new behavior?

A few changes have been made, in order of importance:

  • Added an extra admin endpoint running on port 9943. See here for when this endpoint is enabled (perhaps this need to be clearer?). Currently, only the MadarRpcWriteApi methods have been moved there but we plan to add more methods soon.
  • Removed the rate limiting layer from madara's rpc service. More on that below.
  • Updated RPC.md

Note

The idea is that node operators and developer will (and should!) be running their own proxy for handling features such as rate limiting, api tokens and the like. Separating admin methods into their own endpoint makes it easier to limit their access in this way.

Does this introduce a breaking change?

Yes. If you were relying on the madara_addDeclareV0Transaction rpc method, please note that this has been moved to the admin endpoint on port 9943.

Other information

I think it would be a good idea in the near future to bundle a sample proxy configuration with Madara which node operators and devs can use as a starting point to their own production environment. I am unfamiliar with this topic so if you are already using your own proxy with Madara for the reasons discussed above, please share!

This should be handled by an external proxy anyways.
This currently only contains the `MadaraWriteRpc` methods but will be
used to encapsulate any sensitive admin methods in the future.
@Trantorian1 Trantorian1 added the enhancement New feature or request label Nov 18, 2024
@Trantorian1 Trantorian1 self-assigned this Nov 18, 2024
Copy link
Member

@jbcaron jbcaron left a comment

Choose a reason for hiding this comment

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

great

@@ -185,6 +181,16 @@ impl RpcParams {
SocketAddr::new(listen_addr.into(), self.rpc_port)
}

pub fn addr_admin(&self) -> SocketAddr {
let listen_addr = if self.rpc_external {
Copy link
Member

Choose a reason for hiding this comment

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

a specific bind configuration is required for the admin interface
we may want to expose the normal rpc methods externally, while restricting the admin rpc methods to local access, even if they are on a different port

however, ensure that both normal and admin RPC methods remain accessible externally when running inside Docker

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yep, I'm assuming this is the responsibility of the node operator. For example, it might be worthwhile opening the admin methods to 0.0.0.0, but with a proxy requiring an admin api token and ip whitelist.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I see more clearly what you were talking about. I have updated the rpc-methods cli arg (which is now rpc-endpoints) to handle this:

  • Auto: admin and user are exposed on localhost by default. If rpc-external is true, user is exposed on 0.0.0.0 but admin stays exposed on localhost.
  • Safe: admin is disabled and is not exposed, even if rpc-external is set to false.
  • Unsafe: admin is exposed on 0.0.0.0 if rpc-external is set to true.

Comment on lines 42 to 53
let (rpcs, node_operator) = match (config.rpc_methods, config.rpc_external) {
(RpcMethods::Safe, _) => (true, false),
(RpcMethods::Unsafe, _) => (true, true),
(RpcMethods::Auto, false) => (true, true),
(RpcMethods::Auto, true) => {
tracing::warn!(
"Option `--rpc-external` will hide node operator endpoints. To enable them, please pass \
`--rpc-methods unsafe`."
);
(true, false)
}
};
Copy link
Member

Choose a reason for hiding this comment

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

ensure this logic is explicitly reflected in the CLI

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have updated the CLI docs to more accuratly reflect how this works 👍

RpcEndpoints::Auto | RpcEndpoints::Unsafe => (true, true),
};

let (read, write, trace, admin, ws) = (rpcs, rpcs, rpcs, node_operator, rpcs);
Copy link
Member

Choose a reason for hiding this comment

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

can you remove this atrocity
(it's my fault originally so i'm allowed to say that ahah)

Copy link
Member

@cchudant cchudant left a comment

Choose a reason for hiding this comment

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

would it make more sense if it worked like this:

  • --rpc-disabled disables the normal rpcs (unchanged)
  • --rpc-external makes the normal rpcs external
  • --node-operator-rpc enables the node operator rpcs (disabled by default, but i'm thinking in devnet it should be enabled by default tbh - but maybe for a later pr since we don't have any endpoint that specifically useful for devnet yet, like manual revert and stuff)
  • --unsafe-node-operator-rpc-external allows the node operator rpcs to listen to 0.0.0.0. this is very necessary in docker setups for example since your reverse proxy will have another local ip

that would mean we remove all of this --rpc-endpoints unsafe nonsense? this --rpc-endpoints thinggy is something i made by taking inspiration from substrate when we switched, that's how they do it - but contrary to them we chose to expose the node operator endpoints on another port, which i think makes this design a bit weird

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: In review
Development

Successfully merging this pull request may close these issues.

3 participants