diff --git a/crates/node/core/src/args/rpc_server.rs b/crates/node/core/src/args/rpc_server.rs index 5a2d32353b..07a0eb9330 100644 --- a/crates/node/core/src/args/rpc_server.rs +++ b/crates/node/core/src/args/rpc_server.rs @@ -94,6 +94,12 @@ pub struct RpcServerArgs { #[arg(long, default_value_t = constants::DEFAULT_IPC_ENDPOINT.to_string())] pub ipcpath: String, + /// Set the permissions for the IPC socket file, in octal format. + /// + /// If not specified, the permissions will be set by the system's umask. + #[arg(long = "ipc.permissions")] + pub ipc_socket_permissions: Option, + /// Auth server address to listen on #[arg(long = "authrpc.addr", default_value_t = IpAddr::V4(Ipv4Addr::LOCALHOST))] pub auth_addr: IpAddr, @@ -337,6 +343,7 @@ impl Default for RpcServerArgs { ws_api: None, ipcdisable: false, ipcpath: constants::DEFAULT_IPC_ENDPOINT.to_string(), + ipc_socket_permissions: None, auth_addr: Ipv4Addr::LOCALHOST.into(), auth_port: constants::DEFAULT_AUTH_PORT, auth_jwtsecret: None, diff --git a/crates/rpc/ipc/src/server/mod.rs b/crates/rpc/ipc/src/server/mod.rs index e9e00a7f6c..ece2eef780 100644 --- a/crates/rpc/ipc/src/server/mod.rs +++ b/crates/rpc/ipc/src/server/mod.rs @@ -139,7 +139,20 @@ where .to_fs_name::() .and_then(|name| ListenerOptions::new().name(name).create_tokio()) { - Ok(listener) => listener, + Ok(listener) => { + #[cfg(unix)] + { + // set permissions only on unix + use std::os::unix::fs::PermissionsExt; + if let Some(perms_str) = &self.cfg.ipc_socket_permissions { + if let Ok(mode) = u32::from_str_radix(&perms_str.replace("0o", ""), 8) { + let perms = std::fs::Permissions::from_mode(mode); + let _ = std::fs::set_permissions(&self.endpoint, perms); + } + } + } + listener + } Err(err) => { on_ready .send(Err(IpcServerStartError { endpoint: self.endpoint.clone(), source: err })) @@ -550,6 +563,8 @@ pub struct Settings { message_buffer_capacity: u32, /// Custom tokio runtime to run the server on. tokio_runtime: Option, + /// The permissions to create the IPC socket with. + ipc_socket_permissions: Option, } impl Default for Settings { @@ -562,6 +577,7 @@ impl Default for Settings { max_subscriptions_per_connection: 1024, message_buffer_capacity: 1024, tokio_runtime: None, + ipc_socket_permissions: None, } } } @@ -648,6 +664,12 @@ impl Builder { self } + /// Sets the permissions for the IPC socket file. + pub fn set_ipc_socket_permissions(mut self, permissions: Option) -> Self { + self.settings.ipc_socket_permissions = permissions; + self + } + /// Configure custom `subscription ID` provider for the server to use /// to when getting new subscription calls. /// @@ -768,6 +790,24 @@ mod tests { use tokio::sync::broadcast; use tokio_stream::wrappers::BroadcastStream; + #[tokio::test] + #[cfg(unix)] + async fn test_ipc_socket_permissions() { + use std::os::unix::fs::PermissionsExt; + let endpoint = &dummy_name(); + let perms = "0777"; + let server = Builder::default() + .set_ipc_socket_permissions(Some(perms.to_string())) + .build(endpoint.clone()); + let module = RpcModule::new(()); + let handle = server.start(module).await.unwrap(); + tokio::spawn(handle.stopped()); + + let meta = std::fs::metadata(endpoint).unwrap(); + let perms = meta.permissions(); + assert_eq!(perms.mode() & 0o777, 0o777); + } + async fn pipe_from_stream_with_bounded_buffer( pending: PendingSubscriptionSink, stream: BroadcastStream, diff --git a/crates/rpc/rpc-builder/src/config.rs b/crates/rpc/rpc-builder/src/config.rs index e2ae09e71c..602f4e275e 100644 --- a/crates/rpc/rpc-builder/src/config.rs +++ b/crates/rpc/rpc-builder/src/config.rs @@ -174,6 +174,7 @@ impl RethRpcServerConfig for RpcServerArgs { .max_request_body_size(self.rpc_max_request_size_bytes()) .max_response_body_size(self.rpc_max_response_size_bytes()) .max_connections(self.rpc_max_connections.get()) + .set_ipc_socket_permissions(self.ipc_socket_permissions.clone()) } fn rpc_server_config(&self) -> RpcServerConfig { diff --git a/docs/vocs/docs/pages/cli/reth/node.mdx b/docs/vocs/docs/pages/cli/reth/node.mdx index 6eba046f92..d059f35e40 100644 --- a/docs/vocs/docs/pages/cli/reth/node.mdx +++ b/docs/vocs/docs/pages/cli/reth/node.mdx @@ -287,6 +287,11 @@ RPC: [default: .ipc] + --ipc.permissions + Set the permissions for the IPC socket file, in octal format. + + If not specified, the permissions will be set by the system's umask. + --authrpc.addr Auth server address to listen on