mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
feat: NAT hairpinning, DNS static servers, clear service error on install
- Add POSTROUTING MASQUERADE rules for container and host hairpin NAT - Allow bridge subnet containers to reach private forwards via LAN IPs - Pass bridge_subnet env var from forward.rs to forward-port script - Use DB-configured static DNS servers in resolver with DB watcher - Fall back to resolv.conf servers when no static servers configured - Clear service error state when install/update completes successfully - Remove completed TODO items
This commit is contained in:
@@ -3,18 +3,16 @@ use std::net::{IpAddr, SocketAddrV4};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::Duration;
|
||||
|
||||
use ipnet::IpNet;
|
||||
|
||||
use futures::channel::oneshot;
|
||||
use iddqd::{IdOrdItem, IdOrdMap};
|
||||
use rand::Rng;
|
||||
use imbl::OrdMap;
|
||||
use ipnet::{IpNet, Ipv4Net};
|
||||
use rand::Rng;
|
||||
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::process::Command;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::GatewayId;
|
||||
use crate::context::{CliContext, RpcContext};
|
||||
use crate::db::model::public::NetworkInterfaceInfo;
|
||||
use crate::prelude::*;
|
||||
@@ -22,6 +20,7 @@ use crate::util::Invoke;
|
||||
use crate::util::future::NonDetachingJoinHandle;
|
||||
use crate::util::serde::{HandlerExtSerde, display_serializable};
|
||||
use crate::util::sync::Watch;
|
||||
use crate::{GatewayId, HOST_IP};
|
||||
|
||||
pub const START9_BRIDGE_IFACE: &str = "lxcbr0";
|
||||
const EPHEMERAL_PORT_START: u16 = 49152;
|
||||
@@ -254,7 +253,12 @@ pub async fn add_iptables_rule(nat: bool, undo: bool, args: &[&str]) -> Result<(
|
||||
if nat {
|
||||
cmd.arg("-t").arg("nat");
|
||||
}
|
||||
let exists = cmd.arg("-C").args(args).invoke(ErrorKind::Network).await.is_ok();
|
||||
let exists = cmd
|
||||
.arg("-C")
|
||||
.args(args)
|
||||
.invoke(ErrorKind::Network)
|
||||
.await
|
||||
.is_ok();
|
||||
if undo != !exists {
|
||||
let mut cmd = Command::new("iptables");
|
||||
if nat {
|
||||
@@ -444,14 +448,13 @@ impl InterfaceForwardEntry {
|
||||
continue;
|
||||
}
|
||||
|
||||
let src_filter =
|
||||
if reqs.public_gateways.contains(gw_id) {
|
||||
None
|
||||
} else if reqs.private_ips.contains(&IpAddr::V4(ip)) {
|
||||
Some(subnet.trunc())
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let src_filter = if reqs.public_gateways.contains(gw_id) {
|
||||
None
|
||||
} else if reqs.private_ips.contains(&IpAddr::V4(ip)) {
|
||||
Some(subnet.trunc())
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
keep.insert(addr);
|
||||
let fwd_rc = port_forward
|
||||
@@ -713,7 +716,14 @@ async fn forward(
|
||||
.env("dip", target.ip().to_string())
|
||||
.env("dprefix", target_prefix.to_string())
|
||||
.env("sport", source.port().to_string())
|
||||
.env("dport", target.port().to_string());
|
||||
.env("dport", target.port().to_string())
|
||||
.env(
|
||||
"bridge_subnet",
|
||||
Ipv4Net::new(HOST_IP.into(), 24)
|
||||
.with_kind(ErrorKind::ParseNetAddress)?
|
||||
.trunc()
|
||||
.to_string(),
|
||||
);
|
||||
if let Some(subnet) = src_filter {
|
||||
cmd.env("src_subnet", subnet.to_string());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user