mirror of
https://github.com/YuzuZensai/netbird-kubernetes-operator.git
synced 2026-09-13 18:59:09 +00:00
Bumps [github.com/netbirdio/netbird](https://github.com/netbirdio/netbird) from 0.66.4 to 0.69.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/netbirdio/netbird/releases">github.com/netbirdio/netbird's releases</a>.</em></p> <blockquote> <h2>v0.69.0</h2> <h2>Release Notes for v0.69.0</h2> <h3>What's New</h3> <p><strong>Reverse Proxy IP Reputation Integration</strong> Now you can use CrowdSec to block malicious traffic based on IP reputation on your exposed service in the reverse proxy.</p> <p>This feature requires self-hosted installations to add another container to their deployment. See instructions in the <a href="https://docs.netbird.io/selfhosted/migration/enable-reverse-proxy#step-7-optional-enable-crowd-sec-ip-reputation">reverse proxy migration documentation</a>.</p> <blockquote> <p>For Cloud users, support is coming soon.</p> </blockquote> <p>Learn more about <a href="https://docs.netbird.io/manage/reverse-proxy">here</a>.</p> <p><strong>macOS p2p connectivity improvements</strong> We've improved macOS p2p connectivity with a better routing exclusion mechanism to avoid loops. Now the client doesn't add /32 routes per remote candidate addresses avoiding limitations on accessing remote peer's local addresses via tunnel connections. Learn more about <a href="https://redirect.github.com/netbirdio/netbird/pull/5918">this change</a>.</p> <blockquote> <p>To use the old behavior run:</p> <p><code>sudo netbird service reconfigure --service-env "NB_USE_LEGACY_ROUTING=true"</code></p> </blockquote> <h4>Client Improvements</h4> <ul> <li>Added <strong>PCP support</strong>. This change adds support for the PCP protocol to the client to improve the rate of P2P connectivity. <a href="https://redirect.github.com/netbirdio/netbird/pull/5219">netbirdio/netbird#5219</a></li> <li>Added <strong>--disable-networks flag</strong> to block network selection for users.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5896">netbirdio/netbird#5896</a></li> <li>Fixed <strong>clearing service env vars with --service-env ""</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5893">netbirdio/netbird#5893</a></li> <li>Guarded against <strong>container DNAT bypass of ACL rules in iptables</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5697">netbirdio/netbird#5697</a></li> <li>Populated <strong>NetworkAddresses on iOS for posture checks</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5900">netbirdio/netbird#5900</a></li> <li>Reconnected <strong>conntrack netlink listener on error</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5885">netbirdio/netbird#5885</a></li> <li>Replaced <strong>exclusion routes with scoped default + IP_BOUND_IF on macOS</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5918">netbirdio/netbird#5918</a></li> <li>Fixed <strong>incorrect SSH client config combining Host and Match directives</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5903">netbirdio/netbird#5903</a></li> <li>Fixed <strong>WGIface.Close deadlock when DNS filter hook re-enters GetDevice</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5916">netbirdio/netbird#5916</a></li> </ul> <h4>Management Improvements</h4> <ul> <li>Enforced <strong>peer or peer groups requirement for network routers</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5894">netbirdio/netbird#5894</a></li> <li>Reused <strong>single cache store across all management server consumers</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5889">netbirdio/netbird#5889</a></li> <li>Fixed <strong>lint error on Google Workspace integration</strong>.<br /> <a href="https://redirect.github.com/netbirdio/netbird/pull/5907">netbirdio/netbird#5907</a></li> </ul> <h4>Proxy Enhancements</h4> <ul> <li>Added <strong>CrowdSec IP reputation integration for reverse proxy</strong>.</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/netbirdio/netbird/commit/3098f48b25e2a613d8f70466243d992c498e0fd2"><code>3098f48</code></a> [client] fix ios network addresses mac filter (<a href="https://redirect.github.com/netbirdio/netbird/issues/5906">#5906</a>)</li> <li><a href="https://github.com/netbirdio/netbird/commit/7f023ce8014084385e677e67c541677336e25431"><code>7f023ce</code></a> [client] Android debug bundle support (<a href="https://redirect.github.com/netbirdio/netbird/issues/5888">#5888</a>)</li> <li><a href="https://github.com/netbirdio/netbird/commit/e3611265159bd372f77ca404d32c86127e036525"><code>e361126</code></a> [client] Fix WGIface.Close deadlock when DNS filter hook re-enters GetDevice ...</li> <li><a href="https://github.com/netbirdio/netbird/commit/95213f715714177b7c9672b3f264f84c9a31cf04"><code>95213f7</code></a> [client] Use Match host+exec instead of Host+Match in SSH client config (<a href="https://redirect.github.com/netbirdio/netbird/issues/5903">#5903</a>)</li> <li><a href="https://github.com/netbirdio/netbird/commit/2e0e3a3601d90a5d7a6b39dc16ebde2522fdf580"><code>2e0e3a3</code></a> [client] Replace exclusion routes with scoped default + IP_BOUND_IF on macOS ...</li> <li><a href="https://github.com/netbirdio/netbird/commit/8ae8f2098fb4bb7a9177b3f2d8d908a413b8fc49"><code>8ae8f20</code></a> [management] chores: fix lint error on google workspace (<a href="https://redirect.github.com/netbirdio/netbird/issues/5907">#5907</a>)</li> <li><a href="https://github.com/netbirdio/netbird/commit/a39787d6796ee26e1f6ad9c67ea33a9da7bf8d66"><code>a39787d</code></a> [infrastructure] Add CrowdSec LAPI container to self-hosted setup script (<a href="https://redirect.github.com/netbirdio/netbird/issues/5880">#5880</a>)</li> <li><a href="https://github.com/netbirdio/netbird/commit/53b04e512af0d94f619e870467115c43d200830b"><code>53b04e5</code></a> [management] Reuse a single cache store across all management server consumer...</li> <li><a href="https://github.com/netbirdio/netbird/commit/633dde8d1f5985afc52071462c42857cb844b9ac"><code>633dde8</code></a> [client] Reconnect conntrack netlink listener on error (<a href="https://redirect.github.com/netbirdio/netbird/issues/5885">#5885</a>)</li> <li><a href="https://github.com/netbirdio/netbird/commit/7e4542adde54ebe71a3a47f5228c5915c9c1052a"><code>7e4542a</code></a> fix(client): populate NetworkAddresses on iOS for posture checks (<a href="https://redirect.github.com/netbirdio/netbird/issues/5900">#5900</a>)</li> <li>Additional commits viewable in <a href="https://github.com/netbirdio/netbird/compare/v0.66.4...v0.69.0">compare view</a></li> </ul> </details> <br /> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Philip Laine <philip.laine@gmail.com>
274 lines
7.3 KiB
Go
274 lines
7.3 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
|
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
|
corev1 "k8s.io/api/core/v1"
|
|
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/api/meta"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
|
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
|
|
|
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
|
"github.com/netbirdio/kubernetes-operator/internal/gatewayutil"
|
|
"github.com/netbirdio/kubernetes-operator/internal/util"
|
|
)
|
|
|
|
const (
|
|
HTTPRouteFinalizer = "gateway.netbird.io/httproute"
|
|
)
|
|
|
|
type HTTPRouteReconciler struct {
|
|
client.Client
|
|
|
|
Netbird *netbird.Client
|
|
ClusterDNS string
|
|
}
|
|
|
|
// nolint:gocyclo
|
|
func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
|
logger := ctrl.Log.WithName("HTTPRoute").WithValues("namespace", req.Namespace, "name", req.Name)
|
|
|
|
hr := gatewayv1.HTTPRoute{}
|
|
err := r.Get(ctx, req.NamespacedName, &hr)
|
|
if err != nil {
|
|
return ctrl.Result{}, client.IgnoreNotFound(err)
|
|
}
|
|
|
|
if !hr.DeletionTimestamp.IsZero() {
|
|
return r.reconcileDelete(ctx, hr)
|
|
}
|
|
|
|
for _, parent := range hr.Spec.ParentRefs {
|
|
gw, err := gatewayutil.GetParentGateway(ctx, r.Client, parent, hr.Namespace, GatewayControllerName)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
if gw == nil {
|
|
continue
|
|
}
|
|
if !meta.IsStatusConditionTrue(gw.Status.Conditions, string(gatewayv1.GatewayConditionProgrammed)) {
|
|
logger.Info("gateway is not ready", "name", gw.ObjectMeta.Name)
|
|
continue
|
|
}
|
|
nbrp, err := gatewayutil.GetGatewayRoutingPeer(ctx, r.Client, *gw)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
|
|
if controllerutil.AddFinalizer(&hr, HTTPRouteFinalizer) {
|
|
err = r.Client.Update(ctx, &hr)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
}
|
|
|
|
// Create network resources.
|
|
svcIdx := map[string]corev1.Service{}
|
|
for _, rule := range hr.Spec.Rules {
|
|
for _, ref := range rule.BackendRefs {
|
|
key := client.ObjectKey{Namespace: hr.Namespace, Name: string(ref.Name)}
|
|
var svc corev1.Service
|
|
err := r.Client.Get(ctx, key, &svc)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
svcIdx[svc.Name] = svc
|
|
}
|
|
}
|
|
|
|
for _, svc := range svcIdx {
|
|
nbResource := netbirdiov1.NBResource{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: svc.Name,
|
|
Namespace: svc.Namespace,
|
|
},
|
|
}
|
|
_, err := controllerutil.CreateOrUpdate(ctx, r.Client, &nbResource, func() error {
|
|
err = controllerutil.SetControllerReference(&svc, &nbResource, r.Scheme(), controllerutil.WithBlockOwnerDeletion(false))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = controllerutil.SetOwnerReference(&hr, &nbResource, r.Scheme())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
nbResource.Spec = netbirdiov1.NBResourceSpec{
|
|
Name: svc.Name,
|
|
NetworkID: *nbrp.Status.NetworkID,
|
|
Address: fmt.Sprintf("%s.%s.%s", svc.Name, svc.Namespace, r.ClusterDNS),
|
|
Groups: []string{},
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
}
|
|
|
|
targets := []api.ServiceTarget{}
|
|
for _, svc := range svcIdx {
|
|
var nbResource netbirdiov1.NBResource
|
|
err := r.Client.Get(ctx, client.ObjectKeyFromObject(&svc), &nbResource)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
ready := func() bool {
|
|
for _, cond := range nbResource.Status.Conditions {
|
|
if cond.Type == netbirdiov1.NBSetupKeyReady && cond.Status == corev1.ConditionTrue {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}()
|
|
if !ready {
|
|
return ctrl.Result{RequeueAfter: 1 * time.Second}, nil
|
|
}
|
|
|
|
target := api.ServiceTarget{
|
|
Enabled: true,
|
|
Path: nil,
|
|
TargetId: *nbResource.Status.NetworkResourceID,
|
|
Protocol: "http",
|
|
TargetType: "domain",
|
|
}
|
|
targets = append(targets, target)
|
|
}
|
|
|
|
// Create proxy service.
|
|
proxyServices, err := r.Netbird.ReverseProxyServices.List(ctx)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
for _, hostname := range hr.Spec.Hostnames {
|
|
proxyReq := api.PostApiReverseProxiesServicesJSONRequestBody{
|
|
Domain: string(hostname),
|
|
Enabled: true,
|
|
Name: string(hostname),
|
|
PassHostHeader: util.Ptr(false),
|
|
RewriteRedirects: util.Ptr(false),
|
|
Targets: &targets,
|
|
}
|
|
|
|
err := func() error {
|
|
for _, proxyService := range proxyServices {
|
|
if proxyService.Domain != string(hostname) {
|
|
continue
|
|
}
|
|
_, err := r.Netbird.ReverseProxyServices.Update(ctx, proxyService.Id, proxyReq)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
_, err := r.Netbird.ReverseProxyServices.Create(ctx, proxyReq)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}()
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
}
|
|
}
|
|
|
|
return ctrl.Result{}, nil
|
|
}
|
|
|
|
func (r *HTTPRouteReconciler) reconcileDelete(ctx context.Context, hr gatewayv1.HTTPRoute) (ctrl.Result, error) {
|
|
// Index all proxy services.
|
|
proxyServices, err := r.Netbird.ReverseProxyServices.List(ctx)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
proxyIdx := map[string]string{}
|
|
for _, proxyService := range proxyServices {
|
|
proxyIdx[proxyService.Domain] = proxyService.Id
|
|
}
|
|
|
|
for _, parent := range hr.Spec.ParentRefs {
|
|
gw, err := gatewayutil.GetParentGateway(ctx, r.Client, parent, hr.Namespace, GatewayControllerName)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
if gw == nil {
|
|
continue
|
|
}
|
|
|
|
// Remove the resource from the resource.
|
|
svcIdx := map[string]corev1.Service{}
|
|
for _, rule := range hr.Spec.Rules {
|
|
for _, ref := range rule.BackendRefs {
|
|
key := client.ObjectKey{Namespace: hr.Namespace, Name: string(ref.Name)}
|
|
var svc corev1.Service
|
|
err := r.Client.Get(ctx, key, &svc)
|
|
if kerrors.IsNotFound(err) {
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
svcIdx[svc.Name] = svc
|
|
}
|
|
}
|
|
for _, svc := range svcIdx {
|
|
var nbResource netbirdiov1.NBResource
|
|
err = r.Client.Get(ctx, client.ObjectKeyFromObject(&svc), &nbResource)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
err = controllerutil.RemoveOwnerReference(&hr, &nbResource, r.Scheme())
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
|
|
if len(nbResource.OwnerReferences) > 1 {
|
|
err = r.Client.Update(ctx, &nbResource)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
} else {
|
|
// TODO: Precondition that nothing has changed.
|
|
err := r.Client.Delete(ctx, &nbResource)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove the target from the proxy service.
|
|
for _, hostname := range hr.Spec.Hostnames {
|
|
id, ok := proxyIdx[string(hostname)]
|
|
if !ok {
|
|
continue
|
|
}
|
|
err = r.Netbird.ReverseProxyServices.Delete(ctx, id)
|
|
if err != nil && !netbird.IsNotFound(err) {
|
|
return ctrl.Result{}, err
|
|
}
|
|
}
|
|
}
|
|
|
|
if controllerutil.RemoveFinalizer(&hr, HTTPRouteFinalizer) {
|
|
err := r.Client.Update(ctx, &hr)
|
|
if err != nil {
|
|
return ctrl.Result{}, err
|
|
}
|
|
}
|
|
return ctrl.Result{}, nil
|
|
}
|
|
|
|
// SetupWithManager sets up the controller with the Manager.
|
|
func (r *HTTPRouteReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
|
return ctrl.NewControllerManagedBy(mgr).
|
|
For(&gatewayv1.HTTPRoute{}).
|
|
Complete(r)
|
|
}
|