feat: federate 3 servers with Tor, fix inter-node auth (FED-DEPLOY-02)
- Add tor-hostnames fallback for reading onion addresses when system Tor owns hidden_service directories (permissions 700) - Exempt federation.peer-joined, federation.get-state, and federation.peer-address-changed from auth/CSRF (inter-node RPC) - Set up system Tor with AppArmor overrides on archipelago-2 and 3 - All 3 servers federated and syncing successfully Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,10 @@ const UNAUTHENTICATED_METHODS: &[&str] = &[
|
||||
"auth.login.backup",
|
||||
"auth.isOnboardingComplete",
|
||||
"health",
|
||||
// Inter-node RPC: called by federated peers over Tor, no session cookies
|
||||
"federation.peer-joined",
|
||||
"federation.peer-address-changed",
|
||||
"federation.get-state",
|
||||
];
|
||||
|
||||
pub struct RpcHandler {
|
||||
|
||||
@@ -540,6 +540,22 @@ fn is_real_onion_address(s: &str) -> bool {
|
||||
pub fn read_tor_address(app_id: &str) -> Option<String> {
|
||||
let service = tor_service_name(app_id)?;
|
||||
let base = std::env::var("TOR_DATA_DIR").unwrap_or_else(|_| "/var/lib/archipelago/tor".to_string());
|
||||
|
||||
// Try readable hostname copy first (when system Tor owns hidden_service dirs)
|
||||
let hostnames_path = std::path::Path::new(&base)
|
||||
.parent()
|
||||
.unwrap_or(std::path::Path::new("/var/lib/archipelago"))
|
||||
.join("tor-hostnames")
|
||||
.join(service);
|
||||
if let Some(addr) = std::fs::read_to_string(&hostnames_path)
|
||||
.ok()
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| s.ends_with(".onion") && !s.is_empty())
|
||||
{
|
||||
return Some(addr);
|
||||
}
|
||||
|
||||
// Fall back to hidden_service directory
|
||||
let path = std::path::Path::new(&base)
|
||||
.join(format!("hidden_service_{}", service))
|
||||
.join("hostname");
|
||||
|
||||
Reference in New Issue
Block a user