mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-28 02:03:32 +00:00
Add client authentication to Web3Signer validators (#3170)
## Issue Addressed Web3Signer validators do not support client authentication. This means the `--tls-known-clients-file` option on Web3Signer can't be used with Lighthouse. ## Proposed Changes Add two new fields to Web3Signer validators, `client_identity_path` and `client_identity_password`, which specify the path and password for a PKCS12 file containing a certificate and private key. If `client_identity_path` is present, use the certificate for SSL client authentication. ## Additional Info I am successfully validating on Prater using client authentication with Web3Signer and client authentication.
This commit is contained in:
@@ -475,6 +475,8 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
|
||||
url: web3signer.url,
|
||||
root_certificate_path: web3signer.root_certificate_path,
|
||||
request_timeout_ms: web3signer.request_timeout_ms,
|
||||
client_identity_path: web3signer.client_identity_path,
|
||||
client_identity_password: web3signer.client_identity_password,
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -124,6 +124,8 @@ fn import_single_remotekey<T: SlotClock + 'static, E: EthSpec>(
|
||||
url,
|
||||
root_certificate_path: None,
|
||||
request_timeout_ms: None,
|
||||
client_identity_path: None,
|
||||
client_identity_password: None,
|
||||
},
|
||||
};
|
||||
handle
|
||||
|
||||
@@ -457,6 +457,8 @@ impl ApiTester {
|
||||
url: format!("http://signer_{}.com/", i),
|
||||
root_certificate_path: None,
|
||||
request_timeout_ms: None,
|
||||
client_identity_path: None,
|
||||
client_identity_password: None,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -40,6 +40,8 @@ fn web3signer_validator_with_pubkey(pubkey: PublicKey) -> Web3SignerValidatorReq
|
||||
url: web3_signer_url(),
|
||||
root_certificate_path: None,
|
||||
request_timeout_ms: None,
|
||||
client_identity_path: None,
|
||||
client_identity_password: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use eth2_keystore::Keystore;
|
||||
use lighthouse_metrics::set_gauge;
|
||||
use lockfile::{Lockfile, LockfileError};
|
||||
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
|
||||
use reqwest::{Certificate, Client, Error as ReqwestError};
|
||||
use reqwest::{Certificate, Client, Error as ReqwestError, Identity};
|
||||
use slog::{debug, error, info, warn, Logger};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs::{self, File};
|
||||
@@ -88,6 +88,11 @@ pub enum Error {
|
||||
/// Unable to read the root certificate file for the remote signer.
|
||||
InvalidWeb3SignerRootCertificateFile(io::Error),
|
||||
InvalidWeb3SignerRootCertificate(ReqwestError),
|
||||
/// Unable to read the client certificate for the remote signer.
|
||||
MissingWeb3SignerClientIdentityCertificateFile,
|
||||
MissingWeb3SignerClientIdentityPassword,
|
||||
InvalidWeb3SignerClientIdentityCertificateFile(io::Error),
|
||||
InvalidWeb3SignerClientIdentityCertificate(ReqwestError),
|
||||
UnableToBuildWeb3SignerClient(ReqwestError),
|
||||
/// Unable to apply an action to a validator.
|
||||
InvalidActionOnValidator,
|
||||
@@ -238,6 +243,8 @@ impl InitializedValidator {
|
||||
url,
|
||||
root_certificate_path,
|
||||
request_timeout_ms,
|
||||
client_identity_path,
|
||||
client_identity_password,
|
||||
} => {
|
||||
let signing_url = build_web3_signer_url(&url, &def.voting_public_key)
|
||||
.map_err(|e| Error::InvalidWeb3SignerUrl(e.to_string()))?;
|
||||
@@ -254,6 +261,20 @@ impl InitializedValidator {
|
||||
builder
|
||||
};
|
||||
|
||||
let builder = if let Some(path) = client_identity_path {
|
||||
let identity = load_pkcs12_identity(
|
||||
path,
|
||||
&client_identity_password
|
||||
.ok_or(Error::MissingWeb3SignerClientIdentityPassword)?,
|
||||
)?;
|
||||
builder.identity(identity)
|
||||
} else {
|
||||
if client_identity_password.is_some() {
|
||||
return Err(Error::MissingWeb3SignerClientIdentityCertificateFile);
|
||||
}
|
||||
builder
|
||||
};
|
||||
|
||||
let http_client = builder
|
||||
.build()
|
||||
.map_err(Error::UnableToBuildWeb3SignerClient)?;
|
||||
@@ -294,6 +315,19 @@ pub fn load_pem_certificate<P: AsRef<Path>>(pem_path: P) -> Result<Certificate,
|
||||
Certificate::from_pem(&buf).map_err(Error::InvalidWeb3SignerRootCertificate)
|
||||
}
|
||||
|
||||
pub fn load_pkcs12_identity<P: AsRef<Path>>(
|
||||
pkcs12_path: P,
|
||||
password: &str,
|
||||
) -> Result<Identity, Error> {
|
||||
let mut buf = Vec::new();
|
||||
File::open(&pkcs12_path)
|
||||
.map_err(Error::InvalidWeb3SignerClientIdentityCertificateFile)?
|
||||
.read_to_end(&mut buf)
|
||||
.map_err(Error::InvalidWeb3SignerClientIdentityCertificateFile)?;
|
||||
Identity::from_pkcs12_der(&buf, password)
|
||||
.map_err(Error::InvalidWeb3SignerClientIdentityCertificate)
|
||||
}
|
||||
|
||||
fn build_web3_signer_url(base_url: &str, voting_public_key: &PublicKey) -> Result<Url, ParseError> {
|
||||
Url::parse(base_url)?.join(&format!("api/v1/eth2/sign/{}", voting_public_key))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user