mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
misc fixes
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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),
|
||||
})),
|
||||
|
||||
@@ -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
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user