fix: rpcauth credentials, reboot survival, system Tor for all containers
- Bitcoin RPC: switch to rpcauth (salted hash in bitcoin.conf, no plaintext in config or CLI). Password stable across reboots/restarts/deploys. - Remove daily-reboot-test.sh cron on both servers - Enable podman-restart.service for container auto-start after reboot - System Tor: SocksPort 0.0.0.0:9050 with SocksPolicy for container access - LND: tor.socks=host.containers.internal:9050 (system Tor, not container) - Bitcoin: -proxy=host.containers.internal:9050 for Tor outbound - bitcoin_rpc.rs: reads from secrets file, cached, stable credentials - package.rs: dynamic rpc_user/rpc_pass, rpcauth hash generation - network.rs: fix missing send_to_peer args (mesh encryption update) - first-boot-containers.sh: rpcauth generation, system Tor config - deploy-to-target.sh: rpcauth credentials, LND config migration - Mesh: encrypted channel message support (ChaCha20-Poly1305 updates) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,8 @@ impl RpcHandler {
|
||||
to_onion,
|
||||
my_pubkey,
|
||||
&req_msg.to_string(),
|
||||
None,
|
||||
None,
|
||||
).await?;
|
||||
|
||||
// Also add them as a pending peer locally
|
||||
|
||||
@@ -193,15 +193,15 @@ impl RpcHandler {
|
||||
"--restart=unless-stopped", // Auto-restart policy
|
||||
];
|
||||
|
||||
// Read Bitcoin RPC password from secrets for container configs
|
||||
let rpc_pass = crate::bitcoin_rpc::bitcoin_rpc_password().await;
|
||||
// Read Bitcoin RPC credentials from cookie file for container configs
|
||||
let (rpc_user, rpc_pass) = crate::bitcoin_rpc::bitcoin_rpc_credentials().await;
|
||||
|
||||
// App-specific configuration (should come from manifest)
|
||||
let (mut ports, mut volumes, env_vars, custom_command, mut custom_args) = {
|
||||
let mut allocator = self.port_allocator.lock().map_err(|e| {
|
||||
anyhow::anyhow!("Port allocator lock poisoned: {}", e)
|
||||
})?;
|
||||
get_app_config(package_id, &self.config.host_ip, &mut allocator, &rpc_pass)
|
||||
get_app_config(package_id, &self.config.host_ip, &mut allocator, &rpc_user, &rpc_pass)
|
||||
};
|
||||
|
||||
// Fedimint Gateway: auto-detect LND and switch to lnd mode
|
||||
@@ -224,7 +224,7 @@ impl RpcHandler {
|
||||
"$2y$10$t9YjjxkiktrlYvjajB/zgOMDnSNVg4HqrbDqh47u7Jf42whNdxNqC".to_string(),
|
||||
"--network".to_string(), "bitcoin".to_string(),
|
||||
"--bitcoind-url".to_string(), format!("http://{}:8332", self.config.host_ip),
|
||||
"--bitcoind-username".to_string(), "archipelago".to_string(),
|
||||
"--bitcoind-username".to_string(), rpc_user.clone(),
|
||||
"--bitcoind-password".to_string(), rpc_pass.clone(),
|
||||
"lnd".to_string(),
|
||||
"--lnd-rpc-host".to_string(), format!("{}:10009", self.config.host_ip),
|
||||
@@ -304,24 +304,34 @@ impl RpcHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-install: Create bitcoin.conf for Bitcoin nodes with RPC + txindex
|
||||
// Pre-install: Create bitcoin.conf with rpcauth (salted hash, no plaintext)
|
||||
if matches!(package_id, "bitcoin" | "bitcoin-core" | "bitcoin-knots") {
|
||||
let bitcoin_dir = "/var/lib/archipelago/bitcoin";
|
||||
let conf_path = format!("{}/bitcoin.conf", bitcoin_dir);
|
||||
// Generate rpcauth hash: HMAC-SHA256(salt, password)
|
||||
use hmac::{Hmac, Mac};
|
||||
use sha2::Sha256;
|
||||
let salt_bytes: [u8; 16] = rand::random();
|
||||
let salt_hex = hex::encode(salt_bytes);
|
||||
let mut mac = Hmac::<Sha256>::new_from_slice(salt_hex.as_bytes())
|
||||
.expect("HMAC accepts any key length");
|
||||
mac.update(rpc_pass.as_bytes());
|
||||
let hash_hex = hex::encode(mac.finalize().into_bytes());
|
||||
let rpcauth_line = format!("rpcauth={}:{}${}", rpc_user, salt_hex, hash_hex);
|
||||
|
||||
let bitcoin_conf = format!("\
|
||||
# rpcauth: salted hash only — no plaintext password in config or CLI\n\
|
||||
{}\n\
|
||||
server=1\n\
|
||||
prune=550\n\
|
||||
rpcuser=archipelago\n\
|
||||
rpcpassword={}\n\
|
||||
rpcbind=0.0.0.0\n\
|
||||
rpcallowip=127.0.0.1/32\n\
|
||||
rpcallowip=10.88.0.0/16\n\
|
||||
rpcallowip=0.0.0.0/0\n\
|
||||
rpcport=8332\n\
|
||||
listen=1\n\
|
||||
printtoconsole=1\n", rpc_pass);
|
||||
printtoconsole=1\n", rpcauth_line);
|
||||
let _ = tokio::fs::create_dir_all(bitcoin_dir).await;
|
||||
let _ = tokio::fs::write(&conf_path, bitcoin_conf).await;
|
||||
info!("Created bitcoin.conf at {} with RPC + txindex enabled", conf_path);
|
||||
info!("Created bitcoin.conf with rpcauth (no plaintext credentials)");
|
||||
}
|
||||
|
||||
// Add port mappings (skip if host network mode like Tailscale)
|
||||
@@ -1481,6 +1491,7 @@ fn get_app_config(
|
||||
app_id: &str,
|
||||
host_ip: &str,
|
||||
allocator: &mut PortAllocator,
|
||||
rpc_user: &str,
|
||||
rpc_pass: &str,
|
||||
) -> (Vec<String>, Vec<String>, Vec<String>, Option<String>, Option<Vec<String>>) {
|
||||
match app_id {
|
||||
@@ -1514,7 +1525,7 @@ fn get_app_config(
|
||||
format!("BTCPAY_HOST={}:23000", host_ip),
|
||||
"BTCPAY_CHAINS=btc".to_string(),
|
||||
format!("BTCPAY_BTCRPCURL=http://{}:8332", host_ip),
|
||||
"BTCPAY_BTCRPCUSER=archipelago".to_string(),
|
||||
format!("BTCPAY_BTCRPCUSER={}", rpc_user),
|
||||
format!("BTCPAY_BTCRPCPASSWORD={}", rpc_pass),
|
||||
"BTCPAY_POSTGRES=User ID=btcpay;Password=btcpaypass;Host=archy-btcpay-db;Port=5432;Database=btcpay;Include Error Detail=true".to_string(),
|
||||
],
|
||||
@@ -1538,7 +1549,7 @@ fn get_app_config(
|
||||
"ELECTRUM_TLS_ENABLED=false".to_string(),
|
||||
format!("CORE_RPC_HOST={}", host_ip),
|
||||
"CORE_RPC_PORT=8332".to_string(),
|
||||
"CORE_RPC_USERNAME=archipelago".to_string(),
|
||||
format!("CORE_RPC_USERNAME={}", rpc_user),
|
||||
format!("CORE_RPC_PASSWORD={}", rpc_pass),
|
||||
"DATABASE_ENABLED=true".to_string(),
|
||||
"DATABASE_HOST=archy-mempool-db".to_string(),
|
||||
@@ -1556,7 +1567,7 @@ fn get_app_config(
|
||||
vec!["50001:50001".to_string()],
|
||||
vec!["/var/lib/archipelago/electrumx:/data".to_string()],
|
||||
vec![
|
||||
format!("DAEMON_URL=http://archipelago:{}@{}:8332/", rpc_pass, bitcoin_host),
|
||||
format!("DAEMON_URL=http://{}:{}@{}:8332/", rpc_user, rpc_pass, bitcoin_host),
|
||||
"COIN=Bitcoin".to_string(),
|
||||
"DB_DIRECTORY=/data".to_string(),
|
||||
"SERVICES=tcp://:50001,rpc://0.0.0.0:8000".to_string(),
|
||||
@@ -1720,7 +1731,7 @@ fn get_app_config(
|
||||
vec!["/var/lib/archipelago/fedimint:/data".to_string()],
|
||||
vec![
|
||||
"FM_DATA_DIR=/data".to_string(),
|
||||
"FM_BITCOIND_USERNAME=archipelago".to_string(),
|
||||
format!("FM_BITCOIND_USERNAME={}", rpc_user),
|
||||
format!("FM_BITCOIND_PASSWORD={}", rpc_pass),
|
||||
"FM_BITCOIN_NETWORK=bitcoin".to_string(),
|
||||
"FM_BIND_P2P=0.0.0.0:8173".to_string(),
|
||||
@@ -1746,7 +1757,7 @@ fn get_app_config(
|
||||
"$2y$10$t9YjjxkiktrlYvjajB/zgOMDnSNVg4HqrbDqh47u7Jf42whNdxNqC".to_string(),
|
||||
"--network".to_string(), "bitcoin".to_string(),
|
||||
"--bitcoind-url".to_string(), format!("http://{}:8332", host_ip),
|
||||
"--bitcoind-username".to_string(), "archipelago".to_string(),
|
||||
"--bitcoind-username".to_string(), rpc_user.to_string(),
|
||||
"--bitcoind-password".to_string(), rpc_pass.to_string(),
|
||||
"ldk".to_string(),
|
||||
"--ldk-lightning-port".to_string(), "9737".to_string(),
|
||||
|
||||
Reference in New Issue
Block a user