misc fixes

This commit is contained in:
Aiden McClelland
2025-08-26 12:13:39 -06:00
parent ff686d3c52
commit 9fe9608560
7 changed files with 59 additions and 36 deletions

View File

@@ -19,8 +19,8 @@ use crate::account::AccountInfo;
use crate::db::model::package::AllPackageData;
use crate::net::acme::AcmeProvider;
use crate::net::forward::START9_BRIDGE_IFACE;
use crate::net::host::Host;
use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, NetInfo};
use crate::net::host::Host;
use crate::net::utils::ipv6_is_local;
use crate::net::vhost::AlpnInfo;
use crate::prelude::*;
@@ -283,11 +283,9 @@ impl NetworkInterfaceInfo {
})
.collect::<BTreeSet<_>>();
if !ip4s.is_empty() {
return ip4s.iter().all(|ip4| {
ip4.is_loopback()
// || (ip4.is_private() && !ip4.octets().starts_with(&[10, 59])) // reserving 10.59 for public wireguard configurations
|| ip4.is_link_local()
});
return ip4s
.iter()
.all(|ip4| ip4.is_loopback() || ip4.is_private() || ip4.is_link_local());
}
ip_info.subnets.iter().all(|ipnet| {
if let IpAddr::V6(ip6) = ipnet.addr() {

View File

@@ -863,6 +863,16 @@ impl NetworkInterfaceController {
) -> Result<(), Error> {
tracing::debug!("syncronizing {info:?} to db");
db.mutate(|db| {
db.as_public_mut()
.as_server_info_mut()
.as_network_mut()
.as_gateways_mut()
.ser(info)
})
.await
.result?;
let ntp: BTreeSet<_> = info
.values()
.filter_map(|i| i.ip_info.as_ref())

View File

@@ -3,17 +3,17 @@ use std::collections::BTreeSet;
use clap::Parser;
use imbl_value::InternedString;
use models::GatewayId;
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::db::model::DatabaseModel;
use crate::net::acme::AcmeProvider;
use crate::net::host::{HostApiKind, all_hosts};
use crate::net::host::{all_hosts, HostApiKind};
use crate::net::tor::OnionAddress;
use crate::prelude::*;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
@@ -73,8 +73,8 @@ fn check_duplicates(db: &DatabaseModel) -> Result<(), Error> {
Ok(())
}
pub fn address_api<C: Context, Kind: HostApiKind>()
-> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
pub fn address_api<C: Context, Kind: HostApiKind>(
) -> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
.subcommand(
"domain",
@@ -200,7 +200,7 @@ pub fn address_api<C: Context, Kind: HostApiKind>()
#[derive(Deserialize, Serialize, Parser)]
pub struct AddPublicDomainParams {
pub domain: InternedString,
pub fqdn: InternedString,
#[arg(long)]
pub acme: Option<AcmeProvider>,
pub gateway: GatewayId,
@@ -209,7 +209,7 @@ pub struct AddPublicDomainParams {
pub async fn add_public_domain<Kind: HostApiKind>(
ctx: RpcContext,
AddPublicDomainParams {
ref domain,
ref fqdn,
acme,
gateway,
}: AddPublicDomainParams,
@@ -231,7 +231,7 @@ pub async fn add_public_domain<Kind: HostApiKind>(
Kind::host_for(&inheritance, db)?
.as_public_domains_mut()
.insert(domain, &PublicDomainConfig { acme, gateway })?;
.insert(fqdn, &PublicDomainConfig { acme, gateway })?;
check_duplicates(db)
})
.await
@@ -266,19 +266,19 @@ pub async fn remove_public_domain<Kind: HostApiKind>(
#[derive(Deserialize, Serialize, Parser)]
pub struct AddPrivateDomainParams {
pub domain: InternedString,
pub fqdn: InternedString,
}
pub async fn add_private_domain<Kind: HostApiKind>(
ctx: RpcContext,
AddPrivateDomainParams { domain }: AddPrivateDomainParams,
AddPrivateDomainParams { fqdn }: AddPrivateDomainParams,
inheritance: Kind::Inheritance,
) -> Result<(), Error> {
ctx.db
.mutate(|db| {
Kind::host_for(&inheritance, db)?
.as_private_domains_mut()
.mutate(|d| Ok(d.insert(domain)))?;
.mutate(|d| Ok(d.insert(fqdn)))?;
check_duplicates(db)
})
.await

View File

@@ -1,11 +1,11 @@
use std::collections::{BTreeMap, BTreeSet};
use std::str::FromStr;
use clap::Parser;
use clap::builder::ValueParserFactory;
use clap::Parser;
use imbl::OrdSet;
use models::{FromStrParser, GatewayId, HostId};
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -16,7 +16,7 @@ use crate::net::gateway::InterfaceFilter;
use crate::net::host::HostApiKind;
use crate::net::vhost::AlpnInfo;
use crate::prelude::*;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)]
#[ts(export)]
@@ -136,9 +136,9 @@ impl BindInfo {
impl InterfaceFilter for NetInfo {
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool {
if info.public() {
self.public_enabled.contains(id)
dbg!(self.public_enabled.contains(id))
} else {
!self.private_disabled.contains(id)
dbg!(!self.private_disabled.contains(id))
}
}
}
@@ -169,8 +169,8 @@ pub struct AddSslOptions {
pub alpn: Option<AlpnInfo>,
}
pub fn binding<C: Context, Kind: HostApiKind>()
-> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
pub fn binding<C: Context, Kind: HostApiKind>(
) -> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
.subcommand(
"list",

View File

@@ -31,6 +31,9 @@ export class IpAddress {
throw new Error("invalid ip address")
}
}
static parse(address: string): IpAddress {
return new IpAddress(address)
}
isIpv4(): boolean {
return this.octets.length === 4
}
@@ -49,6 +52,9 @@ export class IpNet extends IpAddress {
super(address)
this.prefix = Number(prefixStr)
}
static parse(ipnet: string): IpNet {
return new IpNet(ipnet)
}
contains(address: string | IpAddress): boolean {
if (typeof address === "string") address = new IpAddress(address)
if (this.octets.length !== address.octets.length) return false
@@ -75,3 +81,5 @@ export const PRIVATE_IPV4_RANGES = [
]
export const IPV6_LINK_LOCAL = new IpNet("fe80::/10")
export const CGNAT = new IpNet("100.64.0.0/10")

View File

@@ -241,7 +241,7 @@ export class PublicDomainService {
default: '',
disabled: data.gateways
.filter(
g => !g.ipInfo.wanIp || g.ipInfo.wanIp.split('.').at(-1) === '100',
g => !g.ipInfo?.wanIp || utils.CGNAT.contains(g.ipInfo?.wanIp),
)
.map(g => g.id),
})),

View File

@@ -1,6 +1,6 @@
import { inject, Injectable } from '@angular/core'
import { PatchDB } from 'patch-db-client'
import { T } from '@start9labs/start-sdk'
import { T, utils } from '@start9labs/start-sdk'
import { map } from 'rxjs/operators'
import { DataModel } from './patch-db/data-model'
import { toSignal } from '@angular/core/rxjs-interop'
@@ -8,7 +8,10 @@ import { toSignal } from '@angular/core/rxjs-interop'
export type GatewayPlus = T.NetworkInterfaceInfo & {
id: string
ipInfo: T.IpInfo
subnets: utils.IpNet[]
lanIpv4: string[]
wanIp?: utils.IpAddress
public: boolean
}
@Injectable()
@@ -20,16 +23,20 @@ export class GatewayService {
map(gateways =>
Object.entries(gateways)
.filter(([_, val]) => !!val?.ipInfo)
.map(
([id, val]) =>
({
...val,
id,
lanIpv4: val?.ipInfo?.subnets
.filter(s => !s.includes('::'))
.map(s => s.split('/')[0]),
}) as GatewayPlus,
),
.map(([id, val]) => {
const subnets =
val?.ipInfo?.subnets.map(s => utils.IpNet.parse(s)) ?? []
return {
...val,
id,
subnets,
lanIpv4: subnets.filter(s => s.isIpv4()).map(s => s.address),
public: val?.public ?? subnets.some(s => s.isPublic()),
wanIp:
val?.ipInfo?.wanIp &&
utils.IpAddress.parse(val?.ipInfo?.wanIp),
} as GatewayPlus
}),
),
),
)