client: Replace unsafe_rpc_expose with an RpcMethods enum (#5729)

* client: Replace `unsafe_rpc_expose` with an `RpcMethods` enum

which can be either Default, Safe or Unsafe. The idea is to have the
following:
|                       | --rpc-external=false  | --rpc-external=true   |
|---------------------  |-------------------    |-----------------      |
| --rpc-methods=Default |                       | unsafe calls denied   |
| --rpc-methods=Safe    | unsafe calls denied   | unsafe calls denied   |
| --rpc-methods=Unsafe  |                       |                       |
Since the previous `unsafe-rpc-expose` option was confusing.

* client: Only warn against exposing externally unsafe RPC method set

* Apply suggestions from code review

Co-Authored-By: Cecile Tonglet <cecile.tonglet@cecton.com>

* cli: Rephrase doc comment for rpc_methods config

* Improve debuggability of build_spec_works

...by printing to stderr the stderr of the command. This is normally
suppressed for succesful tests but not for failing ones - if that's the
case then it's useful to see the test failure reason inline rather than
having to execute the command separately ourselves.

* Rename RpcMethods::{Default => Auto} variant

* Update bin/node/cli/tests/build_spec_works.rs

Co-authored-by: Benjamin Kampmann <ben.kampmann@googlemail.com>
Co-authored-by: Cecile Tonglet <cecile.tonglet@cecton.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Igor Matuszewski
2020-05-06 11:30:54 +02:00
committed by GitHub
parent d40bf3cf36
commit 9acf88f58b
8 changed files with 95 additions and 39 deletions
+31 -19
View File
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use crate::arg_enums::RpcMethods;
use crate::error::{Error, Result};
use crate::params::ImportParams;
use crate::params::KeystoreParams;
@@ -80,16 +81,24 @@ pub struct RunCmd {
/// Listen to all RPC interfaces.
///
/// Same as `--rpc-external`.
#[structopt(long = "unsafe-rpc-external")]
#[structopt(long)]
pub unsafe_rpc_external: bool,
/// Don't deny potentially unsafe RPCs when listening on external interfaces.
/// RPC methods to expose.
///
/// Default is false. This allows exposing RPC methods publicly (same as `--unsafe-{rpc,ws}-external` )
/// but will allow doing so even on validator nodes, which is prohibited by default.
/// Please do this if you know what you're doing.
#[structopt(long = "unsafe-rpc-expose")]
pub unsafe_rpc_expose: bool,
/// - `Unsafe`: Exposes every RPC method.
/// - `Safe`: Exposes only a safe subset of RPC methods, denying unsafe RPC methods.
/// - `Auto`: Acts as `Safe` if RPC is served externally, e.g. when `--{rpc,ws}-external` is passed,
/// otherwise acts as `Unsafe`.
#[structopt(
long,
value_name = "METHOD SET",
possible_values = &RpcMethods::variants(),
case_insensitive = true,
default_value = "Auto",
verbatim_doc_comment
)]
pub rpc_methods: RpcMethods,
/// Listen to all Websocket interfaces.
///
@@ -406,7 +415,7 @@ impl CliConfiguration for RunCmd {
let interface = rpc_interface(
self.rpc_external,
self.unsafe_rpc_external,
self.unsafe_rpc_expose,
self.rpc_methods,
self.validator
)?;
@@ -417,15 +426,15 @@ impl CliConfiguration for RunCmd {
let interface = rpc_interface(
self.ws_external,
self.unsafe_ws_external,
self.unsafe_rpc_expose,
self.rpc_methods,
self.validator
)?;
Ok(Some(SocketAddr::new(interface, self.ws_port.unwrap_or(9944))))
}
fn unsafe_rpc_expose(&self) -> Result<bool> {
Ok(self.unsafe_rpc_expose)
fn rpc_methods(&self) -> Result<sc_service::config::RpcMethods> {
Ok(self.rpc_methods.into())
}
fn transaction_pool(&self) -> Result<TransactionPoolOptions> {
@@ -462,23 +471,26 @@ pub fn is_node_name_valid(_name: &str) -> std::result::Result<(), &str> {
fn rpc_interface(
is_external: bool,
is_unsafe_external: bool,
is_unsafe_rpc_expose: bool,
rpc_methods: RpcMethods,
is_validator: bool,
) -> Result<IpAddr> {
if is_external && is_validator && !is_unsafe_rpc_expose {
if is_external && is_validator && rpc_methods != RpcMethods::Unsafe {
return Err(Error::Input(
"--rpc-external and --ws-external options shouldn't be \
used if the node is running as a validator. Use `--unsafe-rpc-external` if you understand \
the risks. See the options description for more information."
used if the node is running as a validator. Use `--unsafe-rpc-external` \
or `--rpc-methods=unsafe` if you understand the risks. See the options \
description for more information."
.to_owned(),
));
}
if is_external || is_unsafe_external {
log::warn!(
"It isn't safe to expose RPC publicly without a proxy server that filters \
available set of RPC methods."
);
if rpc_methods == RpcMethods::Unsafe {
log::warn!(
"It isn't safe to expose RPC publicly without a proxy server that filters \
available set of RPC methods."
);
}
Ok(Ipv4Addr::UNSPECIFIED.into())
} else {