Skip to content

Commit fc49911

Browse files
committed
add tls proxy
1 parent a17d6e6 commit fc49911

File tree

15 files changed

+1088
-26
lines changed

15 files changed

+1088
-26
lines changed

.katana/tls/cert.pem

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIBZDCCAQqgAwIBAgIUEnUejjrDt8sswv9NtxzVTTTAwIowCgYIKoZIzj0EAwIw
3+
ITEfMB0GA1UEAwwWcmNnZW4gc2VsZiBzaWduZWQgY2VydDAgFw03NTAxMDEwMDAw
4+
MDBaGA80MDk2MDEwMTAwMDAwMFowITEfMB0GA1UEAwwWcmNnZW4gc2VsZiBzaWdu
5+
ZWQgY2VydDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBHonFxLBX1vkZUkZDU7
6+
x2mSBOx1CDfPnfVEbAF34v/FVYgHdlgNTamW/yOtF7PD18QuX/w8Y6uhjCQdWIhm
7+
J7mjHjAcMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATAKBggqhkjOPQQDAgNI
8+
ADBFAiEAs+RsjJzmR0l4fSM8iFJwh7iMAO+XPI+UuXlOlIksdtUCIDUWrAkteEDd
9+
qVy9fYUXVEs3C4NCgwheMWx+Ou2KnQ2r
10+
-----END CERTIFICATE-----

.katana/tls/key.pem

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCgYPu3crCGNMbpIB
3+
8IsC9riM7bZAi8D8Iszr+0UuUxihRANCAAQR6JxcSwV9b5GVJGQ1O8dpkgTsdQg3
4+
z531RGwBd+L/xVWIB3ZYDU2plv8jrRezw9fELl/8PGOroYwkHViIZie5
5+
-----END PRIVATE KEY-----

Cargo.lock

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,12 @@ bytes = "1.10"
178178
http = "1.3"
179179
http-body = "1.0"
180180
hyper = "0.14.27"
181+
hyper-util = { version = "0.1", features = ["client", "client-legacy", "http1", "tokio"] }
181182
jsonrpsee = { version = "0.25", default-features = false }
182-
rustls = "0.23"
183+
rcgen = "0.13"
184+
rustls = { version = "0.23", features = ["ring"] }
185+
rustls-pemfile = "2.2"
186+
tokio-rustls = { version = "0.26", features = ["ring"] }
183187
tower = "0.5"
184188
tower-http = { version = "0.6", features = [ "trace", "cors", "timeout" ] }
185189
tower-service = "0.3"

crates/cli/src/args.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,42 @@ impl SequencerNodeArgs {
263263

264264
let cors_origins = self.server.http_cors_origins.clone();
265265

266+
// Build TLS config
267+
let tls = if let (Some(cert_path), Some(key_path)) =
268+
(&self.server.tls_cert, &self.server.tls_key)
269+
{
270+
// Use explicitly provided certificate paths
271+
Some(katana_node::config::rpc::TlsConfig {
272+
cert_path: cert_path.clone(),
273+
key_path: key_path.clone(),
274+
is_self_signed: false,
275+
})
276+
} else if self.server.https {
277+
// Auto-generate self-signed certificate for development
278+
let tls_dir = std::path::PathBuf::from(".katana/tls");
279+
280+
// Check if certificates already exist
281+
let cert_path = tls_dir.join("cert.pem");
282+
let key_path = tls_dir.join("key.pem");
283+
284+
if cert_path.exists() && key_path.exists() {
285+
info!(target: LOG_TARGET, "Using existing self-signed certificates from .katana/tls/");
286+
} else {
287+
info!(target: LOG_TARGET, "Generating self-signed certificates for HTTPS...");
288+
let (cert, key) = katana_rpc_server::tls::generate_self_signed_cert(&tls_dir)
289+
.context("failed to generate self-signed certificates")?;
290+
info!(target: LOG_TARGET, cert = %cert.display(), key = %key.display(), "Self-signed certificates generated");
291+
}
292+
293+
Some(katana_node::config::rpc::TlsConfig {
294+
cert_path,
295+
key_path,
296+
is_self_signed: true,
297+
})
298+
} else {
299+
None
300+
};
301+
266302
Ok(RpcConfig {
267303
apis: modules,
268304
port: self.server.http_port,
@@ -278,6 +314,7 @@ impl SequencerNodeArgs {
278314
max_event_page_size: Some(self.server.max_event_page_size),
279315
max_proof_keys: Some(self.server.max_proof_keys),
280316
max_call_gas: Some(self.server.max_call_gas),
317+
tls,
281318
})
282319
}
283320

crates/cli/src/options.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#[cfg(feature = "server")]
1111
use std::net::IpAddr;
1212
use std::num::NonZeroU128;
13+
use std::path::PathBuf;
1314

1415
use clap::Args;
1516
use katana_genesis::Genesis;
@@ -188,6 +189,29 @@ pub struct ServerOptions {
188189
#[arg(default_value_t = DEFAULT_RPC_MAX_CALL_GAS)]
189190
#[serde(default = "default_max_call_gas")]
190191
pub max_call_gas: u64,
192+
193+
/// Enable HTTPS with auto-generated self-signed certificates.
194+
///
195+
/// When this flag is set, Katana will automatically generate a self-signed certificate
196+
/// and private key for development purposes. The certificates will be stored in the
197+
/// `.katana/tls` directory.
198+
///
199+
/// Note: This is for development only. For production, use `--http.tls-cert` and
200+
/// `--http.tls-key` with proper certificates from a trusted CA.
201+
#[arg(long = "https")]
202+
#[arg(conflicts_with_all = ["tls_cert", "tls_key"])]
203+
#[serde(default)]
204+
pub https: bool,
205+
206+
/// Path to TLS certificate file (PEM format) for HTTPS.
207+
#[arg(long = "http.tls-cert", value_name = "PATH")]
208+
#[arg(requires = "tls_key")]
209+
pub tls_cert: Option<PathBuf>,
210+
211+
/// Path to TLS private key file (PEM format) for HTTPS.
212+
#[arg(long = "http.tls-key", value_name = "PATH")]
213+
#[arg(requires = "tls_cert")]
214+
pub tls_key: Option<PathBuf>,
191215
}
192216

193217
#[cfg(feature = "server")]
@@ -205,6 +229,9 @@ impl Default for ServerOptions {
205229
max_response_body_size: None,
206230
timeout: None,
207231
max_call_gas: DEFAULT_RPC_MAX_CALL_GAS,
232+
https: false,
233+
tls_cert: None,
234+
tls_key: None,
208235
}
209236
}
210237
}
@@ -246,6 +273,15 @@ impl ServerOptions {
246273
if self.max_call_gas == DEFAULT_RPC_MAX_CALL_GAS {
247274
self.max_call_gas = other.max_call_gas;
248275
}
276+
if !self.https {
277+
self.https = other.https;
278+
}
279+
if self.tls_cert.is_none() {
280+
self.tls_cert = other.tls_cert.clone();
281+
}
282+
if self.tls_key.is_none() {
283+
self.tls_key = other.tls_key.clone();
284+
}
249285
}
250286
}
251287
}

crates/node/src/config/rpc.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::HashSet;
22
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
3+
use std::path::PathBuf;
34
use std::time::Duration;
45

56
use katana_rpc_server::cors::HeaderValue;
@@ -36,6 +37,17 @@ pub enum RpcModuleKind {
3637
Cartridge,
3738
}
3839

40+
/// TLS configuration for HTTPS support.
41+
#[derive(Debug, Clone, PartialEq, Eq)]
42+
pub struct TlsConfig {
43+
/// Path to the TLS certificate file (PEM format).
44+
pub cert_path: PathBuf,
45+
/// Path to the TLS private key file (PEM format).
46+
pub key_path: PathBuf,
47+
/// Whether this is using auto-generated self-signed certificates.
48+
pub is_self_signed: bool,
49+
}
50+
3951
/// Configuration for the RPC server.
4052
#[derive(Debug, Clone, PartialEq, Eq)]
4153
pub struct RpcConfig {
@@ -53,6 +65,8 @@ pub struct RpcConfig {
5365
pub max_proof_keys: Option<u64>,
5466
pub max_event_page_size: Option<u64>,
5567
pub max_call_gas: Option<u64>,
68+
/// TLS configuration for HTTPS support (optional).
69+
pub tls: Option<TlsConfig>,
5670
}
5771

5872
impl RpcConfig {
@@ -79,6 +93,7 @@ impl Default for RpcConfig {
7993
max_event_page_size: Some(DEFAULT_RPC_MAX_EVENT_PAGE_SIZE),
8094
max_proof_keys: Some(DEFAULT_RPC_MAX_PROOF_KEYS),
8195
max_call_gas: Some(DEFAULT_RPC_MAX_CALL_GAS),
96+
tls: None,
8297
}
8398
}
8499
}

crates/node/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,18 @@ impl Node {
326326
rpc_server = rpc_server.max_response_body_size(max_response_body_size);
327327
}
328328

329+
if let Some(ref tls_config) = config.rpc.tls {
330+
let tls = if tls_config.is_self_signed {
331+
katana_rpc_server::tls::TlsConfig::new_self_signed(
332+
&tls_config.cert_path,
333+
&tls_config.key_path,
334+
)
335+
} else {
336+
katana_rpc_server::tls::TlsConfig::new(&tls_config.cert_path, &tls_config.key_path)
337+
};
338+
rpc_server = rpc_server.tls(tls);
339+
}
340+
329341
// --- build feeder gateway server (optional)
330342

331343
let gateway_server = if let Some(gw_config) = &config.gateway {

crates/rpc/rpc-server/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,17 @@ anyhow.workspace = true
2828
auto_impl.workspace = true
2929
futures.workspace = true
3030
http.workspace = true
31+
hyper.workspace = true
3132
jsonrpsee = { workspace = true, features = [ "client", "server" ] }
3233
metrics.workspace = true
34+
rcgen.workspace = true
35+
rustls = {workspace = true, features = [ "ring"]}
36+
rustls-pemfile.workspace = true
3337
serde_json.workspace = true
3438
starknet = { workspace = true, optional = true }
3539
thiserror.workspace = true
3640
tokio.workspace = true
41+
tokio-rustls = {workspace = true, features = [ "ring"]}
3742
tower.workspace = true
3843
tower-http = { workspace = true, features = [ "cors", "trace" ] }
3944
tracing.workspace = true

0 commit comments

Comments
 (0)