メインコンテンツまでスキップ

リソース API v1alpha1

Diagram showing the Resource API v1alpha1 shape from apiVersion, kind, metadata, spec, and status through API groups and generated schema validation contracts

routerd の設定は、最上位の Router と、型付きリソースの一覧で構成します。 このページは、現在の実装に合わせたリソース一覧です。 フェーズ 1.6 以降は RFC の表記に合わせ、DHCP 関連の Kind は DHCPv4*DHCPv6* を使います。 旧名の互換用別名はありません。

共通形

apiVersion: net.routerd.net/v1alpha1
kind: Interface
metadata:
name: wan
spec:
ifname: ens18
adminUp: true
フィールド意味
apiVersionAPI グループと版です。
kindリソース種別です。
metadata.name同じ種別内の名前です。
spec利用者が宣言する意図です。
statusrouterd または専用デーモンが観測した状態です。

API グループ

API グループ主な Kind
routerd.net/v1alpha1Router
net.routerd.net/v1alpha1インターフェース、ManagementAccess、再利用可能な IPAddressSet、DHCP、DNS、経路、トンネル、VIP、BGP、イベント、通信フローログ
firewall.routerd.net/v1alpha1FirewallZone, FirewallPolicy, FirewallRule, FirewallEventLog, ClientPolicy, PortForward, IngressService, LocalServiceRedirect
system.routerd.net/v1alpha1Hostname, Sysctl, SysctlProfile, Package, NTPClient, NTPServer, LogSink, ObservabilityPipeline, RouterdCluster, LogRetention, WebConsole
observability.routerd.net/v1alpha1Telemetry
plugin.routerd.net/v1alpha1プラグインマニフェスト
hybrid.routerd.net/v1alpha1TunnelInterface, OverlayPeer, HybridRoute, AddressMobilityDomain, CloudProviderProfile, RemoteAddressClaim
mobility.routerd.net/v1alpha1MobilityPool, MobilityMemberSet, SAMNodeSet, SAMTransportProfile

システム準備

Kind役割
Package他の resource から導出できない OS package だけを補う、限定的な override です。通常の runtime dependency は自動で導出されます。
Sysctlrouter resource からまだ導出できない sysctl 値を補う、限定的な escape hatch です。compare: exactcompare: atLeast で読み戻しの判定を選べます。
SysctlProfileルーター向けの sysctl 推奨値を補う、限定的な escape hatch です。通常の router sysctl は自動で導出されます。
Hostnameホスト名を設定します。
NTPClientOS の NTP クライアントを有効にします。DHCPv4 / DHCPv6 の状態から時刻サーバーを導出し、空なら public NTP サーバーへ戻せます。
NTPServerLAN 向けのローカル NTP サーバーを動かします。クライアント許可範囲は、静的な allowCIDRs に加えて、allowCIDRFromIPv6DelegatedAddress/<name>.addressDHCPv6PrefixDelegation/<name>.currentPrefix などの status field から導出できます。
LogSinklog event を syslog、OTLP、webhook、file、journald へ転送します。
ObservabilityPipelineOTLP の environment と、stdout / syslog / Loki への routerd event の転送を設定します。
RouterdClusterfile lease により、leader だけが host configuration を変更し、standby は status 観測に回ります。
LogRetentionイベント、DNS、通信フロー、firewall event log の保管期間を管理します。
WebConsole読み取り専用の Web 画面を、管理ネットワークで待ち受けます。

可観測性

Kind役割
Telemetry外部の OTLP エンドポイントを宣言し、生成されたサービスユニットに OpenTelemetry の環境変数を注入します。

Telemetry は、管理対象デーモンが出力する metrics、traces、logs の送信先エンドポイントを記述します。LogSink は、運用イベントや観測ログの転送経路を記述します。ログシンクが OTLP を使う場合は、collector のエンドポイントを重複して書かず、LogSink.spec.otlp.telemetryRefTelemetry リソースを参照してください。

インターフェース

Kind役割
Interfacerouterd が扱う安定した名前と OS のインターフェース名を結び付け、下流 resource 向けの link/address status も提供します。
ManagementAccess管理用インターフェースと apply 前の lockout チェックを宣言します。宣言時は、管理 IF の欠落、firewall zone による遮断、WebConsole の全アドレス待ち受けを検出すると、--allow-mgmt-lockout なしの apply を止めます。
PPPoESessionPPPoE 用の下位インターフェース設定を表します。
PPPoESessionrouterd-pppoe-client が管理する PPPoE セッションです。
WireGuardInterfaceWireGuard インターフェースを表します。peersFromSAMNodeSet から peer 定義を取り込めます。
WireGuardPeerWireGuard の相手を表します。
TailscaleNodeTailscale ノードを設定します。Exit node と subnet router の広告を管理対象 systemd ユニットで行います。
IPsecConnectionstrongSwan の cloud VPN 向け接続定義を表します。
VRFLinux VRF デバイスと経路表を表します。
VXLANTunnelVXLAN トンネルを表します。

PPPoESession.spec.enabled: false にすると、PPPoE の定義は残したまま、管理対象の pppd ユニットを停止・無効化します。 通常運用では PPPoE セッション枠を使わず、必要なときだけ手動で試験するフォールバック経路として使えます。

TailscaleNode は、初回登録用に authKey を使えます。 本番設定では authKeyEnvauthKeyFile を推奨します。 これにより、秘密値を YAML と Git 履歴に残さずに済みます。 どちらも未指定の場合、tailscaled はログイン済みとみなします。 routerd は、広告するノード設定だけを再適用します。 Tailscale の既定 UDP/41641 は予約済みとして扱います。 WireGuard の待ち受けポートには、別の番号を使ってください。 詳しい設定手順は、Tailscale の設定ガイドを参照してください。

WireGuardInterfaceprivateKeyFile を受け取れます。 秘密鍵を router YAML の外に置くためです。 WireGuardPeer も、任意の PSK 用に presharedKeyFile を受け取れます。 インラインの鍵フィールドは、主に例とテスト向けです。 FreeBSD では、routerd が rc.d サービスを生成します。 そのサービスは wg インターフェースを作成し、ファイルから秘密鍵を読み込み、 宣言された peer と static address を適用します。 WireGuardInterface.spec.peersFromSAMNodeSet/<name> を参照し、 SAMNodeSet.spec.nodes[].wireGuard から peer を導出します。同じ metadata.name の 静的 WireGuardPeer は生成 peer を override します。

Kernel module と、systemd-networkd/resolved の adoption drop-in は、router resource から自動で導出されます。削除済みの KernelModuleNetworkAdoptionLinkNixOSHost が config に残っている場合、routerd は黙って無視せず、エラーを返します。

WAN アドレスと委任

Kind役割
IPv4StaticAddress静的 IPv4 アドレスを付与します。
VirtualAddressIPv4 /32 または IPv6 /128 VIP を宣言します。spec.familyipv4 または ipv6 です。mode: vrrp は Linux では keepalived、FreeBSD では CARP を使います。
DHCPv4Clientrouterd-dhcpv4-client が DHCPv4 リース、IPv4 アドレス、任意のデフォルト経路を管理します。
DHCPv6AddressDHCPv6 IA_NA の意図を表します。
DHCPv6PrefixDelegationrouterd-dhcpv6-client が管理する DHCPv6-PD リースです。
DHCPv6PrefixDelegationLeaseSyncactive ノードの DHCPv6PrefixDelegation クライアントリースのスナップショットを standby ノードへ同期します。
DHCPv6InformationDHCPv6 情報要求の結果です。DNS、SNTP、ドメイン検索、AFTR 情報を観測します。
IPv6DelegatedAddress委任プレフィックスから LAN 側アドレスを導出します。
IPv6RAAddressRA/SLAAC で得る IPv6 アドレスを表します。

DHCPv6PrefixDelegation は、旧来の OS クライアント選択フィールドを持ちません。 DHCPv6-PD は routerd-dhcpv6-client が担当します。HA node 間で DHCPv6 client identity を固定する必要がある場合は、spec.clientDUID に plain hex の DUID を設定します。

LAN 側サービス

Kind役割
DHCPv4Serverdnsmasq の DHCPv4 service と任意のアドレスプールを提供します。
DHCPv4ServerLeaseSyncDHCPv4Server から導出された dnsmasq のリースファイルを同期します。
DHCPv4ReservationMAC アドレスごとの固定割り当てを表します。
DHCPv4Relaydnsmasq の DHCPv4 中継を表します。
IPv6RouterAdvertisementRA、PIO、RDNSS、DNSSL、M/O フラグ、MTU、優先度、寿命を生成します。
RogueRADetectorRA を送出する interface 上で観測された、自身以外の IPv6 Router Advertisement を status として表示する、自動導出の resource です。
DHCPv6Serverdnsmasq の DHCPv6/RA service です。statelessstatefulbothra-only を扱います。
DHCPv6ServerLeaseSyncDHCPv6Server から導出された dnsmasq のリースファイルを同期します。
DNSZoneローカル権威ゾーンを表します。手動レコードと DHCP リース由来のレコードを扱います。
DNSResolverrouterd-dns-resolver のデーモンインスタンス、待ち受け、キャッシュ、メトリクス、query log を表します。
DNSForwarder1 つの resolver に対する DNS の match rule です。DNSZone を応答するか、名前付きの DNSUpstream へ転送します。
DNSUpstreamudptcpdotdoh のいずれかで、1 つの上流エンドポイントを表します。状態由来の address、bootstrap resolver、TLS 名、送信元 interface も指定できます。

Android は DHCPv6 の DNS だけでは名前解決を完結できないため、IPv6 LAN では IPv6RouterAdvertisement.spec.rdnss を設定します。

dnsmasq は、DHCPv4、DHCPv6、中継、RA だけを担当します。 DNS の待ち受けと応答は DNSResolver が担当します。 LAN の DNS suffix は、DHCPv4Server.spec.domainFromIPv6RouterAdvertisement.spec.dnsslFromDHCPv6Server.spec.domainSearchFrom から DNSZone/<name>.zone を参照することで、ローカルゾーンと一致させられます。 DNSResolver.spec.listen[].sources には、その listener が使う DNSForwarder 名を並べます。 省略した listener は、その resolver を参照するすべての DNSForwarder を使います。 user YAML の DNSResolver.spec.sources は受け付けません。旧来のインライン source は DNSForwarderDNSUpstream に分割してください。

DNSForwarder.spec.match には、home.example や、既定の上流を表す . を指定します。 spec.zoneRefs は local の DNSZone を応答し、spec.upstreamsDNSUpstream へ転送します。 DNSSEC validation は DNSForwarder.spec.dnssecValidate に書きます。

DNSUpstream.spec.protocoludptcpdotdoh のいずれかです。 addressFrom では、DHCPv6Information/<name>.dnsServers などから UDP の上流 address を導出できます。 sourceInterface は Linux で送信先 interface を束縛し、bootstrap は DoH/DoT のエンドポイント名の解決に使う補助 resolver です。

DS-Lite、経路、NAT

Kind役割
DSLiteTunnelAFTR へ ip6tnl トンネルを張ります。AFTR は IPv6 を直接指定するか、FQDN、または DHCPv6 情報から得ます。
TunnelInterfacehybrid overlay delivery 用の trusted Linux L3 underlay tunnel device を作ります。modeipipgre、IPIP-over-UDP の fou / gue を受け付けます。fou / gue では encapSportencapDport が必須です。
OverlayPeeron-prem または cloud の overlay peer と、それに到達する local underlay を表します。
HybridRoutedefault ではない remote IPv4 prefix を、OverlayPeer 経由の managed IPv4Route に lower します。
MobilityPoolCloudEdge mobility intent です。pool prefix、federation group、node-to-site membership または membersFrom source、BGP delivery policy、再利用可能な cloud capture profile、local value expansion、provider trap placement を宣言し、routerd は observed fact と BGP best path から BGP /32 advertisement と provider trap action plan を導出します。
MobilityMemberSet共有される identity-only MobilityPool member(nodeRefsiterole、任意の placement/maintenance)をまとめます。leaf は MobilityPool.spec.membersFrom で import し、local capture/discovery だけを inline に残せます。
SAMNodeSet共有される SAM fabric node identity registry です。node identity、任意の site/role、Event Federation endpoint、SAM transport endpoint、秘密を含まない WireGuard peer identity を集約します。後続 controller はここから EventPeer、WireGuardPeer、SAM transport peer、MobilityPool member を生成します。
SAMTransportProfileこの router の安定した selfNodeRef、inner tunnel prefix、underlay interface、BGP router、SAM transport peer を宣言します。peersFromSAMNodeSet から topology と peer endpoint を取り込めます。routerd は peer ごとの TunnelInterface、endpoint /32 IPv4RouteBGPPeerDynamicConfigPart として導出します。
AddressMobilityDomainhand-authored selective-address config の IPv4 prefix を定義する低レベル互換 SAM resource です。現在の CloudEdge Mobility の主な authoring surface ではありません。
CloudProviderProfiledeclarative address capture planning 用の provider capability と external-command auth を記述します。
RemoteAddressClaim1 つの mobile IPv4 /32、capture mechanism、legacy OverlayPeer route delivery を宣言する低レベル互換 SAM resource です。
IPAddressSet直接指定したアドレスや FQDN から、再利用可能な IP address set を定義します。Linux nftables renderer はこれを named set として出力し、redirect、NAT、policy routing から参照できます。
IPv4RouteIPv4 経路を追加します。DS-Lite 経由の既定経路や、明示的な破棄経路にも使います。
ClusterNetworkRouteKubernetes の Pod / Service CIDR を、worker の next hop 経由の static IPv4 route に展開します。
BGPRouterローカルの BGP router を宣言します。現在の backend は長寿命の routerd-bgp GoBGP デーモンで、import policy は default deny です。
BGPPeerBGPRouter にぶら下がる、GoBGP 管理の BGP peer を宣言します。Kubernetes BGP speaker などに使います。
BFDBFD session の intent を宣言します。Linux では routerd が FRR bfdd 設定を render し、観測した BFD 状態を記録します。参照先 GoBGP peer は BFD false-down では deconfigure しません。
NAT44Rulenftables の routerd_nat テーブルで IPv4 NAPT を行います。
NAT44SessionSyncactive node から standby node へ、選択した NAT44 conntrack session を SSH 越しに同期します。
PortForwardWAN 側の IPv4 TCP/UDP ポートを、1 つの内部 IPv4 宛先へ DNAT します。
IngressServiceWAN 側の IPv4 TCP/UDP サービスを公開します。複数 backend、TCP/HTTP health check、failover / sourceHash / random selection を受け付けます。
LocalServiceRedirectLAN 側 client から IPAddressSet 宛てに出る IPv4/IPv6 通信を、router の local port へ redirect します。平文 DNS/NTP の集約を想定し、DoH や DoT の port には触れません。
EgressRoutePolicy既定経路の選択、mark ベースの IPv4 policy routing、複数 target への hash 分散を表します。

CloudEdge Mobility の operator-authored surface は MobilityPoolMobilityMemberSetSAMNodeSetSAMTransportProfile です。MobilityPool は address ownership/capture intent、 MobilityMemberSet は再利用する共有 member list、 SAMNodeSet は生成される peer の write-once node identity registry、 SAMTransportProfile は transport/BGP intent を担当します。federation event は observed fact、BGP best path は mobility ownership/delivery view です。mobility planner は BGP /32 advertisement と provider trap action plan を導出します。 operator は per-address path や capture procedure を手書きしません。 AddressMobilityDomainRemoteAddressClaim は MobilityPool BGP path 外の 低レベル互換 Kind として残っています。

CloudEdge Mobility では、自 site は完全に宣言し、remote site は identity-only に 保ちます。remote member は通常 nodeRefsiterole、必要なら placement / maintenance だけを持ちます。これは BGP peering と同じ形で、各 node は peer が 誰かを知ればよく、remote provider の NIC や subnet の詳細を知る必要はありません。 spec.profiles.cloudCaptures は self-site cloud capture の再利用可能な default、 spec.values は non-secret な local identifier、capture.targetFromownershipDiscovery.subnetRefFrom はそれらの local 値を generated provider action target と discovery scope に投影するための field です。member に明示した field は profile default より優先されます。 members[].placement は同一 provider の cloud router を deterministic な active/standby capture group にまとめます。members[].maintenance.drain を true にすると、その member は active 選出から外れます。placement projection を 揃えるため、mobility demo の全 node に同じ MobilityPool の identity と placement set を配ります。古い remote-full inline style は pre-release 互換として まだ受け付けますが、remote member が local capture/discovery detail を持つ場合は routerctl validate、plan、apply が warning を表示します。将来の pre-release では remote member の identity-only 化を必須にする可能性があります。

MobilityPool.spec.deliveryPolicy.mode の既定は bgp です。Provider action plan は review artifact であり、action journal に import され、ProviderActionPolicy、 approval、allowlist、executor plugin gate を通った場合だけ実行できます。

EgressRoutePolicy は、CIDR 指定に加えて destinationSetRefsexcludeDestinationSetRefs を持ちます。これにより、FQDN-backed な宛先 set を policy resource にアドレス展開せず、経路制御や除外条件として使えます。 mode: priority は既定経路の failover、mode: mark は 1 つの mark 付き route table、mode: hash または candidates[].targets は複数 route table への source/destination の hash 分散に使います。

routerd は、reverse path filter sysctl、tunnel MTU、RA MTU、TCP MSS clamp を router role、tunnel、firewall zone、RA/DHCPv6 resource から自動で導出します。 config では LAN/WAN と tunnel の intent を宣言し、IPv4ReversePathFilterPathMTUPolicy は書きません。 trusted overlay path で non-TCP IPv4 の PMTU blackhole を避ける必要がある場合だけ、 OverlayPeer.spec.pathMTU.forceFragmentIPv4 または TunnelInterface.spec.pathMTU.forceFragmentIPv4 により default-off の Linux nftables routerd_forcefrag table を有効化できます。これは派生した forwarded path 上の過大 IPv4 packet だけの DF を消します。対応する overlay underlay は wireguardipipgrefougue だけです。 tailscale0 のように外部が管理する source interface が低い MTU を持つ場合は、 Interface.spec.mtu を設定します。routerd はその source path にだけ使い、 無関係な LAN path を低い MTU に引っ張りません。

EgressRoutePolicyexcludeDestinationCIDRs を持ちます。これにより、LAN 内部、管理網、HGW LAN、RFC 1918 の内部網などを policy routing の対象から外せます。

ClusterNetworkRoute は、Kubernetes node 向けの補助 resource です。 spec.pods.cidrsspec.services.cidrs に Pod / Service CIDR を並べ、 spec.via[] に worker または VIP の next hop を指定すると、routerd は 対応する IPv4StaticRoute の intent を生成します。同じ weight は同じ metric として扱われ、複数 next hop の ECMP に使えます。異なる weight は metric の差に 変換され、優先経路とフォールバック経路を表します。

FirewallRule は、宛先 CIDR に加えて destinationSetRefsexcludeDestinationSetRefs を持ちます。これにより、再利用可能な FQDN-backed set を各 rule にアドレス展開せず、許可・拒否・reject の条件として使えます。 stateful rule expression は、sourcePortsdestinationPorts、ICMP / ICMPv6 の type matching、rateLimitconnLimit も扱えます。port は単一の destination port の shorthand として引き続き受け付けますが、新しい例では destinationPorts を使います。

NAT44Rule は、outboundInterfacesourceCIDRstranslation による単純な source NAT と、typeegressInterface または egressPolicyRefsourceRanges による policy-aware NAT を扱います。さらに destinationCIDRsdestinationSetRefsexcludeDestinationCIDRsexcludeDestinationSetRefs を持ちます。これにより、 インターネット向け通信だけをマスカレードし、静的経路を持つプライベート宛先や 再利用可能な address set は NAT しない構成にできます。

NAT44SessionSync は、選択した SNAT address に対して conntrack --dump -o extended を実行し、tuple と conntrack mark を standby target へ復元します。active-to-standby の HA 同期を想定しており、通常は spec.when で active node に限定します。

PortForwardIngressService は、Linux nftables と FreeBSD pf に DNAT を生成します。 spec.hairpin.enabled: truespec.hairpin.interfaces を指定すると、LAN クライアントから WAN アドレス経由で同じサービスへ到達するための hairpin NAT も生成します。 hairpin には listen.address または listen.addressFrom が必須で、routerd は LAN 側の DNAT と、戻り経路用の masquerade/NAT reflection を生成します。 listen.addressFrom と backend の addressFrom は、IPv4StaticAddress/<name>.addressVirtualAddress/<name>.address のような、静的に描画できるアドレスリソースを参照できます。 IngressService では、spec.hairpin.mode の未指定を auto として扱います。 listen address と選択済み backend が、listen interface に宣言された同じ prefix 上に ある場合、routerd は、LAN client が VIP を使うために必要な、同一 interface の戻り SNAT を自動生成します。YAML に listen interface の prefix が宣言されていない場合でも、 private IPv4 の listen/backend address が同じ /24 にあれば、hairpin が必要と判断します。 これは Live ISO のように、boot 環境から interface address を引き継ぐ構成をカバーするためです。 抑止する場合は spec.hairpin.mode: off、明示指定する場合は manualinterfaces を使います。 VirtualAddress.spec.vrrp.authentication は、keepalived では auth_pass、 FreeBSD CARP では pass として描画されます。本番構成では routerd YAML に 共有 secret を残さないため、VirtualAddress.spec.vrrp.authenticationFrom を優先してください。authenticationFrom.file は local の secret file、 authenticationFrom.env は環境変数を読み、base64: true で base64 値を decode します。生成済みの keepalived/CARP 設定や host interface state は secret として扱ってください。 VRRP authentication は VRRPv3(RFC 5798)では deprecated です。routerd は L2 隔離を前提にするため、 authentication は、周辺ネットワークの方針で必要な場合や、単純な誤設定対策に限って使ってください。 IngressService は、複数 backend、TCP/HTTP health check、failoversourceHashrandom selection を受け付けます。runtime controller は backend の FQDN を解決し、 DNS が一時的に失敗した場合は、直前の解決済み IPv4 にフォールバックします。healthy なバックエンドが 複数ある場合、Linux nftables は sourceHash では jhash ip saddrrandom では numgen random で分配します。healthy な backend が 1 つだけになった場合は failover に 降格します。validator は、IngressServiceLocalServiceRedirect、routerd 管理デーモンの listen port が同じ interface/protocol で衝突する設定を拒否します。

IPAddressSet は、直接指定した IPv4/IPv6 address を apply 時に nftables の named set へ 出力します。FQDN の A/AAAA record は runtime controller が解決し、参照されている set を、firewall、NAT、policy table 全体を reload せずにその場で更新します。次回の更新は、 観測した最小 DNS TTL の半分を基本とし、60 秒より短くはしません。refreshInterval は、 より積極的に更新したい場合の上限として使えます。

IPAddressSet.spec.names は、完全一致の DNS 名だけを扱います。microsoft.commicrosoft.com 自体の A/AAAA record を意味し、www.microsoft.comlogin.microsoft.com*.microsoft.com、さらに深いサブドメインは含みません。 ワイルドカードや suffix 形式のサービス判定には、単純な FQDN 解決ではなく、 DNS query の観測や provider エンドポイント feed を扱う、別のリソースが必要です。

BGPRouterBGPPeer は、長寿命の routerd-bgp デーモンを使います。 routerd は resource spec を local gRPC Unix socket 経由で型付きの GoBGP API object に 直接 map し、ListPeerListPath で status を観測します。FRR の text config、 frr-reload.pyvtysh の parse、GoBGP の file config は使いません。 apply は host artifact の render だけを行い、 BGP は routerd serve の管理として status に出します。routerctl show bgp は、保存された GoBGP の観測から router、peer、message counter、route selection state、直近の error を 表示します。prefix status には、bestvalidinstalledstalenextHop、 observed community が含まれます。spec.importPolicy.allowedPrefixes に一致する 学習済みの IPv4 best path は、routerd 所有の protocol/metric で kernel FIB に投入されます。 既定では、GoBGP import policy が受理した eBGP next-hop を、学習元の peer address に 書き換えます(spec.importPolicy.nextHopRewrite: peer-address)。これは旧 FRR の set ip next-hop peer-address と同じ意味で、広告 next-hop が downstream speaker を 指す Kubernetes edge 経路でも、peer address の ECMP として投入できます。広告された next-hop を そのまま kernel に入れたい場合だけ、nextHopRewrite: unchanged を指定してください。 同一 prefix の equal best path は、ECMP の next-hop として入ります。

BGPRouter.spec.convergenceProfile: fast は、graceful restart の stale-path 保持よりも 速い収束を優先する Kubernetes/edge router 向けです。fast profile は peer timer を 短くし、spec.gracefulRestart.enabled が明示されていない場合は graceful restart を 無効化します。import policy は default deny です。Kubernetes LoadBalancer pool など、 受け入れたい prefix を spec.importPolicy.allowedPrefixes に列挙してください。 BGPPeer.spec.ebgpMultihop は、loopback peering や、lab から本番 router への 検証のように、直結でない eBGP session に使います。未指定、01 は、直結 eBGP の既定動作です。2 から 255 を指定すると、その peer group の GoBGP multihop TTL として設定します。 router ID は TCP の source address と同一である必要はありませんが、peer 側には、実際に host が使う BGP source address を設定する必要があります。LAN に複数の address がある 場合は、Linux なら ip route get <peer-address> で source address を確認し、明確な理由が なければ router ID もその運用上の source address に寄せると、混乱を避けられます。

BGPRouter は、connected/static IPv4 route を個別の allowedPrefixes 付きで広告できます。 BGPRouter.spec.exportPolicy.allowedPrefixes または redistribute の allow-list に明示された prefix だけが、GoBGP の local path として追加されます。BGP community policy は router または peer に communities.sendcommunities.acceptcommunities.set.in/out として宣言でき、 GoBGP が報告する observed route community は status に保存されます。watcher は既定で 15 秒間隔、prefix status は 4096 entries が上限です。BGPRouter.spec.watcherpollIntervalmaxPrefixespeerStateChangeThrottle を調整できます。validation は、 3 秒未満の interval と、1,000,000 以上の prefix cap を拒否します。GoBGP MVP は router ごとに 1 つの BGPRouter を support し、spec.vrf は未対応です。 multi-router、VRF、BFD resource は、黙って無視せず Pending として報告します。 spec.listen.addressspec.listen.port は、routerd-bgp の GoBGP listener を bind します。

VirtualAddressmode: vrrp は、Linux では keepalived、FreeBSD では CARP を使います。 spec.family: ipv4 は IPv4 /32spec.family: ipv6 は IPv6 /128 を要求します。 IPv6 VIP は keepalived VRRPv3 の family inet6 として描画され、FreeBSD では inet6 の CARP alias になります。 Linux VRRP は明示的な unicast peer を使い、既定は nopreempt です。 FreeBSD CARP は親 interface 上の multicast advertisement を使うため、 spec.vrrp.peers は FreeBSD では無視されます。preempt: true は、自動 failback が必要な場合だけ使います。advertisement や failback の低レベルな timing は、resource ごとの field ではなく、routerd の profile 既定値で扱います。trackBGPRouterBGPPeerIngressService などの状態に応じて priority を下げられます。既定では、unhealthy が 3 回連続で penalty を適用し、healthy が 2 回連続で解除します。spec.hostname は、DNSResolver が配信する 対応する DNSZone へ VIP を自動公開できます。IPv4 VIP は A record、IPv6 VIP は AAAA record になります。外部の AD DNS などが名前を管理する場合は、 spec.externalDNS: true を設定してください。routerd は hostname 構文だけを検証し、 DNSZone の coverage warning と自動公開を行いません。routerctl show vrrp は、role、 priority、peer、transition からの経過時間を表示します。

本番向け VRRP tuning

制御プレーン VIP のように自動 failback が必要な場所だけ、preempt: true を 使います。家庭 LAN や DS-Lite 周辺の VIP では、優先 owner に戻すことよりも安定性を 優先し、既定の non-preemptive な挙動を使うのが扱いやすいです。backup が VIP を 持ったあとは、その node が落ちるか、明示的に移動するまで保持します。完全な resource fragment は examples/vrrp-tuning-presets.yaml を参照してください。

BGPPeer.spec.password は、GoBGP peer の TCP MD5 authentication password として 渡されます。 本番構成では routerd YAML に共有 secret を残さないため、BGPPeer.spec.passwordFrom を優先してください。passwordFrom.file は local の root-owned secret file、 passwordFrom.env は環境変数を読み、base64: true で base64 値を decode します。

IngressService は、複数バックエンド、TCP のヘルスチェック、フェイルオーバー方針を扱います。 ランタイムコントローラーがバックエンドの FQDN を解決し、DNS 失敗時は直前の解決済み IPv4 を フォールバックとして使います。Linux の nftables は、次回の NAT 調整時に、status の active backend を転送先に使います。既存の conntrack は消さないため、既存の flow は 旧 backend に残り、新規の flow が選択済みの backend へ向かいます。spec.hostname は、 listen address の A record として DNSResolver に自動反映できます。外部の DNS が名前を 管理する場合は、spec.externalDNS: true を設定してください。 routerctl show ingress は、active backend と backend ごとの health を表示します。 routerctl show ingress --verbose は、live dataplane の ip_forward、nftables の DNAT/SNAT rule 数、該当する conntrack flow 数も表示します。DETAIL column には、 hairpinMode、hairpin が必要か、期待される nftables SNAT rule が present/missing のどちらか、も出します。Ingress、NAT 系、DS-Lite、IPv6 PD/RA、routing resource から、 forwarding、redirect suppression、reverse path filter exception、interface ごとの RA 受信など、 必要なランタイムの sysctl を導出します。routerctl apply は派生設定をプランしレンダリングしますが、 ホスト側への変更は明示的な Sysctl / SysctlProfile のエスケープハッチだけに限定します。 派生したランタイム設定の適用は、routerd serve のコントローラー調整ループが担当します。 保守中は routerctl drain ingress/<service> backend=<name> --duration 10m で、backend を runtime state 上の drain 状態にできます。controller は、duration が切れるか routerctl undrain ingress/<service> backend=<name> で解除されるまで、該当する backend を reason Drained の unhealthy として扱います。

LocalServiceRedirect は、Linux nftables の preroutingredirect rule を生成します。 指定した interface から入ってきた packet と、IPAddressSet 宛先だけを対象にします。 router 自身が発信する通信や health check は、この hook を通りません。

例:

apiVersion: firewall.routerd.net/v1alpha1
kind: PortForward
metadata:
name: web-admin
spec:
listen:
interface: wan
addressFrom:
resource: IPv4StaticAddress/wan-ip
field: address
protocol: tcp
port: 8443
target:
address: 172.18.1.88
port: 443
hairpin:
enabled: true
mode: manual
interfaces:
- lan

DS-Lite、IPv4 既定経路、NAT44 は、実際の lab で動作確認済みです。

状態連携

Kind役割
HealthChecktarget、protocol、cadence、threshold から到達性 probe の intent を宣言します。EgressRoutePolicy の candidate/target から参照されると、routerd が health-check デーモン、source binding、socket mark を自動で導出します。
EgressRoutePolicy準備完了の候補の中から、重みの高い外向き経路を選びます。destinationCIDRs と、candidate の gatewaySourcegateway を持ちます。
EventGroupCloudEdge Event Federation の bus identity を宣言します。peersFromSAMNodeSet から push peer を導出でき、静的 EventPeer は override として残せます。
EventPeerbootstrap または明示 override 用の静的 Event Federation push peer を宣言します。
EventSubscriptionfederation event を match して、DynamicConfigPart を発行する plugin を呼び出します。
EventRuleイベント列に対して、all_of、any_of、sequence、window、absence、throttle、debounce、count を評価します。
DerivedEvent複数リソースの状態から仮想イベントを発行します。
SelfAddressPolicy自ホストアドレスの選択方針を表します。

HealthCheck.spec.enabled: false にすると、デーモンユニットは生成しますが、停止・無効化します。 EgressRoutePolicy の候補にも enabled: false を指定できます。 無効化した候補は、最後の観測状態が Healthy のままでも選択されません。 mode: priority でも、candidate の weight が選択の第一キーで、priority は tie-break と policy-rule の priority です。candidate を削除すると、ledger-owned な policy-route の rule/table も削除されます。

spec.when

spec.when を持つ resource は、routerd の local state store に対する predicate が一致したときだけ有効になります。従来の単一 predicate 構文も引き続き使えます。

when:
state:
wan.ipv6.mode:
equals: pd-ready

AND は all、OR は any で表します。任意の深さで nest できます。

when:
any:
- all:
- state:
dslite.a.health:
status: set
- state:
wan.ipv6.mode:
in: [pd-ready, address-only]
- state:
pppoe.health:
equals: healthy

when node は、stateallany のどれか 1 つだけを持ちます。 state は state variable 名を key にし、existsequalsincontainsstatusfor で照合します。要素が 1 つの all は、単一 predicate 構文と等価です。 状態管理専用の resource kind は公開しません。条件付きの activation は、依存する resource の spec.when に直接書きます。

HealthCheck.spec.sourceInterface は、実行時に OS のインターフェース名へ解決されます。 Linux では SO_BINDTODEVICE を使います。fwmark を指定した場合は、 SO_MARK も設定します。HealthCheckEgressRoutePolicy の candidate や target から参照されている場合は、routerd がその route target の mark から SO_MARK を自動で導出します。 直接の fwmark 指定は、route target に紐づかない低レベルな probe 向けです。 FreeBSD では、指定したインターフェースから送信元アドレスを選びます。 FreeBSD には、Linux と同じ socket option がないためです。

システム

Kind役割
Hostnameホスト名を管理します。
Sysctlsysctl 値を管理します。
NTPClientNTP クライアント設定を管理します。serverFromDHCPv4Client.status.ntpServersDHCPv6Information.status.sntpServers を参照できます。
LogSinkログの送信先を表します。
WebConsole状態、イベント、IPv4/IPv6 のコネクション観測を表示する、読み取り専用画面です。

Telemetry は、routerd 自身と管理対象デーモンの metrics / traces / logs を OpenTelemetry のエンドポイントへ出すための resource です。LogSink は、運用イベント や観測ログの転送経路を表します。OTLP へログ転送する場合は、collector のエンドポイントを 重複して書かず、LogSink.spec.otlp.telemetryRefTelemetry を参照してください。

WebConsole.spec.listenAddressFrom は、ほかのリソースの状態から HTTP の待ち受けアドレスを導出します。 たとえば、Interface/mgmt.status.ipv4Addresses を参照できます。 管理アドレスを DHCP、IPAM、別の宣言リソースから得る場合は、固定の listenAddress ではなく、こちらを使います。

Status provides の契約

addressFromgatewayFromdnsServerFromdependsOn[].field などの参照フィールドは、参照先の kind がこの contract で宣言した field だけを参照できます。存在しない resource や、provides に無い field は、 validator がエラーにします。

KindProvides
BFDpeer (string), phase (string)
BGPPeeracceptedPrefixes (int), address (string), observedAt (timestamp), phase (string), state (string)
BGPRouteracceptedPrefixes (int), establishedPeers (int), observedAt (timestamp), peers (objectList), phase (string), prefixes (int)
Bridgeifname (string), members (stringList), phase (string)
ClientPolicyphase (string)
ClusterNetworkRoutephase (string), pods (stringList), services (stringList)
DHCPv4ClientcurrentAddress (string), defaultGateway (string), device (string), dnsServers (stringList), domain (string), expiresAt (timestamp), gateway (string), interface (string), leaseTime (int), ntpServers (stringList), phase (string), rebindAt (timestamp), renewAt (timestamp)
DHCPv4Relayphase (string)
DHCPv4Reservationaddress (string), hostname (string), phase (string)
DHCPv4ServerconfigPath (string), dnsServers (stringList), domain (string), dryRun (bool), interface (string), ntpServers (stringList), phase (string)
DHCPv4ServerLeaseSynccommand (string), dryRun (bool), phase (string), sourceCount (int), sources (objectList), syncedAt (timestamp), targetCount (int), targets (objectList)
DHCPv6Addressaddress (string), interface (string), phase (string)
DHCPv6InformationaftrName (string), dnsServers (stringList), domainSearch (stringList), phase (string), sntpServers (stringList), source (string)
DHCPv6PrefixDelegationaftrName (string), currentPrefix (string), dnsServers (stringList), domainSearch (stringList), interface (string), phase (string), sntpServers (stringList)
DHCPv6PrefixDelegationLeaseSynccommand (string), dryRun (bool), phase (string), sourceCount (int), sources (objectList), syncedAt (timestamp), targetCount (int), targets (objectList)
DHCPv6ServerconfigPath (string), dnsServers (stringList), dryRun (bool), interface (string), phase (string), sntpServers (stringList)
DHCPv6ServerLeaseSynccommand (string), dryRun (bool), phase (string), sourceCount (int), sources (objectList), syncedAt (timestamp), targetCount (int), targets (objectList)
DNSForwarderphase (string), resolver (string), upstreams (stringList)
DNSResolverlistenAddresses (stringList), listeners (int), phase (string), sources (int), updatedAt (timestamp)
DNSUpstreamaddress (string), phase (string), url (string)
DNSZonependingRecords (objectList), phase (string), records (int), updatedAt (timestamp), zone (string)
DSLiteTunnelaftrIPv6 (string), aftrName (string), device (string), dryRun (bool), innerLocalIPv4 (string), innerRemoteIPv4 (string), interface (string), localIPv6 (string), localInterface (string), mtu (int), phase (string), tunnelName (string)
AddressMobilityDomainmode (string), peerRef (string), phase (string), prefix (string)
CloudProviderProfilecapabilities (stringList), phase (string), provider (string)
DerivedEventphase (string), topic (string)
EgressRoutePolicyadvisory (bool), candidates (objectList), dryRun (bool), family (string), lastTransitionAt (timestamp), phase (string), role (string), selectedCandidate (string), selectedDevice (string), selectedGateway (string), selectedGatewaySource (string), selectedInterface (string), selectedMetric (int), selectedRouteTable (int), selectedSource (string), selectedTargets (int), selectedWeight (int), updatedAt (timestamp)
EventGroupgroup (string), listenAddress (string), listenPort (int), nodeName (string), peers (int), peersFrom (objectList), pendingSources (stringList), phase (string)
EventRulephase (string), topic (string)
FirewallEventLogpath (string), phase (string), sinks (stringList)
FirewallPolicyphase (string)
FirewallRuleaction (string), phase (string)
FirewallZoneinterfaces (stringList), phase (string)
HealthCheckconsecutiveFailed (int), lastCheckedAt (timestamp), phase (string), protocol (string), role (string), sourceAddress (string), sourceInterface (string), target (string)
Hostnamehostname (string), phase (string)
HybridRoutedefaultRouteUntouched (bool), estimatedMTU (int), peerRef (string), phase (string), routes (objectList)
IPAddressSetaddresses (stringList), ipv4Addresses (stringList), ipv6Addresses (stringList), phase (string), updatedAt (timestamp)
IPsecConnectionphase (string)
IPv4Routedestination (string), device (string), dryRun (bool), gateway (string), metric (int), phase (string), type (string)
IPv4StaticAddressaddress (string), dryRun (bool), ifname (string), interface (string), phase (string)
IPv4StaticRoutedestination (string), gateway (string), interface (string), phase (string)
IPv6DelegatedAddressaddress (string), dryRun (bool), interface (string), phase (string), prefixSource (string)
IPv6RAAddressaddress (string), interface (string), phase (string)
IPv6RouterAdvertisementconfigPath (string), dryRun (bool), interface (string), phase (string), prefix (string), rdnss (stringList)
RogueRADetectorinterface (string), observedRouters (string), packetsSeen (string), phase (string), rogueCount (string), selfMAC (string)
IPv6StaticRoutedestination (string), gateway (string), interface (string), phase (string)
IngressServiceactiveBackend (object), activeBackends (objectList), backends (objectList), dryRun (bool), healthyBackends (int), hostname (string), listenAddress (string), observedAt (timestamp), phase (string), totalBackends (int)
Interfaceaddresses (stringList), ifname (string), ipv4Addresses (stringList), ipv6Addresses (stringList), macAddress (string), phase (string)
Inventoryhost (object), phase (string)
LocalServiceRedirectphase (string)
LogRetentionphase (string), targets (objectList), updatedAt (timestamp)
LogSinkphase (string), type (string)
ManagementAccessinterfaces (stringList), phase (string)
MobilityMemberSetmemberCount (int)
MobilityPooldynamicSource (string), generatedActions (int), generatedBGPPaths (int), generatedBGPTraps (int), groupRef (string), memberSet (object), membersFrom (objectList), pendingSources (stringList), placementActive (bool), placementActiveNode (string), placementGroup (string), plannerPhase (string), plannerReason (string), prefix (string), resolvedMemberCount (int), deliveryMode (string), discoverySelfPrivateIPs (stringList)
SAMNodeSetnodeCount (int)
SAMTransportProfiledynamicSource (string), generatedBGPPeers (int), generatedEndpointRoutes (int), generatedTunnels (int), innerPrefix (string), peers (objectList), peersFrom (objectList), pendingSources (stringList), phase (string), selfNode (string), topologyNodeRefs (stringList)
NAT44RuledryRun (bool), egressInterface (string), phase (string), snatAddress (string)
NAT44SessionSyncdeleteFailed (int), deleteOK (int), dryRun (bool), insertFailed (int), insertOK (int), mode (string), phase (string), sessionCount (int), snatAddresses (stringList), syncedAt (timestamp), targetCount (int), targets (objectList)
NTPClientphase (string), servers (stringList), source (string), updatedAt (timestamp)
NTPServerallowCIDRs (stringList), listenAddresses (stringList), phase (string), servers (stringList), source (string), updatedAt (timestamp)
ObservabilityPipelinephase (string), signals (stringList)
OverlayPeernodeID (string), phase (string), role (string), underlayInterface (string), underlayType (string)
TunnelInterfacedryRun (bool), encapDport (int), encapSport (int), ifname (string), interface (string), local (string), mode (string), mtu (int), phase (string), remote (string), ttl (int)
PPPoESessionconnectedAt (timestamp), currentAddress (string), device (string), dnsServers (stringList), dryRun (bool), gateway (string), interface (string), peerAddress (string), phase (string)
PackagedryRun (bool), packages (stringList), phase (string)
PortForwarddryRun (bool), listenAddress (string), phase (string), target (object)
RouterdClusterleader (string), leaseExpiresAt (timestamp), phase (string)
SelfAddressPolicyaddress (string), phase (string), source (string)
RemoteAddressClaimaddress (string), captureType (string), deliveryMode (string), domainRef (string), ownerSide (string), peerRef (string), phase (string)
SysctldryRun (bool), key (string), phase (string), value (string)
SysctlProfiledryRun (bool), phase (string), profile (string)
TailscaleNodeadvertiseRoutes (stringList), peerCount (int), phase (string), tailnetName (string)
Telemetryphase (string), signals (stringList)
TrafficFlowLogpath (string), phase (string), sinks (stringList)
VRFifname (string), members (stringList), phase (string), routeTable (int)
VXLANSegmentifname (string), phase (string), vni (int)
VXLANTunnelifname (string), phase (string), vni (int)
VirtualAddressaddress (string), dryRun (bool), hostname (string), ifname (string), phase (string), priority (int), role (string), virtualRouterID (int)
WebConsolelistenAddress (string), phase (string), port (int)
WireGuardInterfacefwmark (int), listenPort (int), peerCount (int), peersFrom (objectList), pendingSources (stringList), phase (string), publicKey (string), selfNodeRef (string)
WireGuardPeerhandshakeAgeSeconds (int), latestEndpoint (string), latestHandshake (timestamp), phase (string), transferRxBytes (int), transferTxBytes (int)

ファイアウォール

Kind役割
FirewallZoneインターフェースをゾーンへ割り当て、untrusttrustmgmt の役割を設定します。
FirewallPolicy拒否ログなど、全体の設定を表します。
FirewallRule役割の組み合わせでは表せない例外を表します。送信元 CIDR、宛先 CIDR、IPAddressSet 宛先参照で範囲を絞れます。
ClientPolicyMAC アドレスでクライアントを分類し、Linux nftables でゲスト隔離を行います。
PortForward単一宛先の ingress DNAT ルールを追加します。routerd が firewall table も管理している場合は、内部の forward accept も生成します。任意の hairpin mode では、LAN 側の DNAT と戻り経路の SNAT も生成します。
IngressServicePortForward と同じ ingress DNAT を追加します。複数 backend、選択方針、health check の intent を受け付け、runtime の failover state は controller path で扱います。任意の hairpin mode も PortForward と同じです。
LocalServiceRedirect明示的な IPAddressSet 宛ての通信を local service へ redirect します。firewall renderer は、送信元 zone から該当する local input port への開口も生成します。

状態を持つフィルターは、nftables の inet routerd_filter テーブルに生成します。 確立済みの通信、loopback、必要な ICMPv6 は常に許可します。 DHCP、DNS、DS-Lite などに必要な開口は、routerd が内部で生成します。

ClientPolicy は、mode: include では「一覧に書いた MAC アドレスを guest として扱う」動作です。 mode: exclude では「一覧に書いた MAC アドレスを trusted とし、対象インターフェース上の残りを guest として扱う」動作です。 spec.macs は短縮形です。classification[] は構造化された形式で、各 entry は mode: trusted|guest|isolated と、match.macsmatch.ouiPrefixesmatch.hostnamePatternsmatch.dhcpFingerprints の selector を持ちます。 match field は OR として評価します。ipv4Reservation は、Ethernet source address を 直接 match できない platform で、address ベースの rendering を安定させるためにも使えます。 spec.isolation では、internet 許可、LAN/mgmt 拒否、mDNS/SSDP/NetBIOS discovery 拒否といった、典型的な guest の intent を表現できます。 FreeBSD pf は同じ MAC ベースの routed filtering モデルを持たないため、このリソースは FreeBSD では未対応として扱います。

管理面(Management plane)

ManagementAccess は、非 dry-run の apply で運用者が自分自身を締め出すのを 防ぐため、routerd が到達可能なまま保つべき管理インターフェースと管理元 CIDR を 宣言します。ManagementAccess が 1 つでも存在すると、適用前検証が以下を 確認し、--allow-mgmt-lockout 未指定なら 適用を中止します。validate / plan / show は影響を受けず、dry-run の apply は判定結果を表示するだけで中止しません。

apiVersion: net.routerd.net/v1alpha1
kind: ManagementAccess
metadata:
name: home-mgmt
spec:
interfaces: [mgmt0]
allowSourceCIDRs:
- 192.168.100.0/24
- fd00:100::/64
requireWebConsoleBound: true # 既定値

適用前検証の項目は以下のとおりです。

チェック失敗条件
インターフェースの存在interfaces[] で宣言した IF が Interface リソースに存在しない(管理 IF が削除・改名されている)。
ファイアウォール経由の自分宛て到達性FirewallZone が 1 つでも存在し(ファイアウォール有効)、宣言された管理 IF がロール mgmt / trustFirewallZone に属していない。input チェーンの policy drop がルーター自身宛ての SSH を落とします。
WebConsole の待ち受けアドレスWebConsole が有効で 0.0.0.0 / :: に bind されている。requireWebConsoleBound: true(既定)では不合格、false では警告として扱います。

同じチェックは routerctl doctor mgmt でも実行できます(apply はしない)。

spec.allowSourceCIDRs は現状情報的な扱いで(status と doctor 表示に使う)、firewall ガードによる強制はまだ行いません。

--allow-mgmt-lockout緊急用の上書きフラグです。管理 IF を新 VLAN に移すなど、ブロックされる構成を意図的に適用する場合(かつ PVE console 等の復旧手段が用意できている場合)に限り使います。通常運用では使いません。

名前変更の要点

フェーズ 1.6 で、次のように名前を整理しました。

旧名現在の名前
IPv4DHCPServerDHCPv4Server
IPv4DHCPReservationDHCPv4Reservation
IPv4DHCPScopeDHCPv4Server
IPv6DHCPAddressDHCPv6Address
IPv6PrefixDelegationDHCPv6PrefixDelegation
IPv6DHCPServer / IPv6DHCPv6ServerDHCPv6Server
IPv6DHCPScopeDHCPv6Server
DHCPRelayDHCPv4Relay

バイナリ名も、routerd-dhcpv4-clientrouterd-dhcpv6-client です。