Skip to content

Commit

Permalink
Include tenant namespaces in DNS access policies
Browse files Browse the repository at this point in the history
  • Loading branch information
caseydavenport committed Oct 23, 2023
1 parent ae5a9f5 commit af6f536
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 30 deletions.
49 changes: 45 additions & 4 deletions pkg/controller/tiers/tiers_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"github.com/tigera/operator/pkg/controller/options"
"github.com/tigera/operator/pkg/controller/status"
"github.com/tigera/operator/pkg/controller/utils"
"github.com/tigera/operator/pkg/render"
rmeta "github.com/tigera/operator/pkg/render/common/meta"
"github.com/tigera/operator/pkg/render/common/networkpolicy"
"github.com/tigera/operator/pkg/render/tiers"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -36,9 +38,11 @@ import (

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
)

// The Tiers controller reconciles Tiers and NetworkPolicies that are shared across components or do not directly
Expand Down Expand Up @@ -74,16 +78,23 @@ func Add(mgr manager.Manager, opts options.AddOptions) error {
{Name: tiers.ClusterDNSPolicyName, Namespace: "kube-system"},
})

if opts.MultiTenant {
if err = c.Watch(&source.Kind{Type: &operatorv1.Tenant{}}, &handler.EnqueueRequestForObject{}); err != nil {
return fmt.Errorf("tiers-controller failed to watch Tenant resource: %w", err)
}
}

return add(mgr, c)
}

// newReconciler returns a new reconcile.Reconciler
func newReconciler(mgr manager.Manager, opts options.AddOptions) reconcile.Reconciler {
r := &ReconcileTiers{
client: mgr.GetClient(),
scheme: mgr.GetScheme(),
provider: opts.DetectedProvider,
status: status.New(mgr.GetClient(), "tiers", opts.KubernetesVersion),
client: mgr.GetClient(),
scheme: mgr.GetScheme(),
provider: opts.DetectedProvider,
status: status.New(mgr.GetClient(), "tiers", opts.KubernetesVersion),
multiTenant: opts.MultiTenant,
}
r.status.Run(opts.ShutdownContext)
return r
Expand All @@ -98,6 +109,7 @@ type ReconcileTiers struct {
status status.StatusManager
tierWatchReady *utils.ReadyFlag
policyWatchesReady *utils.ReadyFlag
multiTenant bool
}

// add adds watches for resources that are available at startup.
Expand Down Expand Up @@ -164,6 +176,35 @@ func (r *ReconcileTiers) prepareTiersConfig(ctx context.Context, reqLogger logr.
DNSEgressCIDRs: tiers.DNSEgressCIDR{},
}

// Determine the namespaces that should be allowed to access the DNS service. For single tenant clusters, this is a
// well-known list of namespaces that contain product code.
namespaces := []string{
common.CalicoNamespace,
render.GuardianNamespace,
render.ComplianceNamespace,
render.DexNamespace,
render.ElasticsearchNamespace,
render.LogCollectorNamespace,
render.IntrusionDetectionNamespace,
render.KibanaNamespace,
render.ManagerNamespace,
render.ECKOperatorNamespace,
render.PacketCaptureNamespace,
render.PolicyRecommendationNamespace,
common.TigeraPrometheusNamespace,
rmeta.APIServerNamespace(operatorv1.TigeraSecureEnterprise),
}
if r.multiTenant {
// For multi-tenant clusters, we need to include well-known namespaces as well as per-tenant namespaces.
tenantNamespaces, err := utils.TenantNamespaces(ctx, r.client)
if err != nil {
r.status.SetDegraded(operatorv1.ResourceReadError, "Error querying tenant namespaces", err, reqLogger)
return nil, &reconcile.Result{RequeueAfter: utils.StandardRetry}
}
namespaces = append(namespaces, tenantNamespaces...)
}
tiersConfig.CalicoNamespaces = namespaces

// node-local-dns is not supported on openshift
if r.provider != operatorv1.ProviderOpenShift {
nodeLocalDNSExists, err := utils.IsNodeLocalDNSAvailable(ctx, r.client)
Expand Down
39 changes: 13 additions & 26 deletions pkg/render/tiers/tiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

v3 "github.com/tigera/api/pkg/apis/projectcalico/v3"
operatorv1 "github.com/tigera/operator/api/v1"
"github.com/tigera/operator/pkg/common"
"github.com/tigera/operator/pkg/render"
rmeta "github.com/tigera/operator/pkg/render/common/meta"
"github.com/tigera/operator/pkg/render/common/networkpolicy"
Expand All @@ -32,25 +31,6 @@ const (
NodeLocalDNSPolicyName = networkpolicy.TigeraComponentPolicyPrefix + "node-local-dns"
)

// TODO: Needs to be updated for multi-tenancy.
var TigeraNamespaceSelector = createNamespaceSelector(
common.CalicoNamespace,
render.GuardianNamespace,
render.ComplianceNamespace,
render.DexNamespace,
render.ElasticsearchNamespace,
render.LogCollectorNamespace,
render.IntrusionDetectionNamespace,
render.KibanaNamespace,
render.ManagerNamespace,
render.ECKOperatorNamespace,
render.PacketCaptureNamespace,
render.PolicyRecommendationNamespace,
common.TigeraPrometheusNamespace,
rmeta.APIServerNamespace(operatorv1.TigeraSecureEnterprise),
"tigera-skraper",
)

var defaultTierOrder = 100.0

func Tiers(cfg *Config) render.Component {
Expand All @@ -60,6 +40,11 @@ func Tiers(cfg *Config) render.Component {
type Config struct {
Openshift bool
DNSEgressCIDRs DNSEgressCIDR

// CalicoNamespaces contains a list of namespaces running Calico components. This must be
// populated dynamically by the controller in order to correctly capture the set of namespaces
// that require inclusion in policy generated by this component.
CalicoNamespaces []string
}

type DNSEgressCIDR struct {
Expand Down Expand Up @@ -115,6 +100,9 @@ func (t tiersComponent) allowTigeraTier() *v3.Tier {
}
}

// allowTigeraClusterDNSPolicy creates a NetworkPolicy that applies to the DNS pods in the cluster and
// inserts an Ingress rule to ensure all Tigera components can access the DNS pods. It defers other ingress
// to subsequent tiers using a Pass rule.
func (t tiersComponent) allowTigeraClusterDNSPolicy() *v3.NetworkPolicy {
var dnsPolicySelector string
var dnsPolicyNamespace string
Expand All @@ -141,7 +129,7 @@ func (t tiersComponent) allowTigeraClusterDNSPolicy() *v3.NetworkPolicy {
Action: v3.Allow,
Source: v3.EntityRule{
NamespaceSelector: "all()",
Selector: TigeraNamespaceSelector,
Selector: createNamespaceSelector(t.cfg.CalicoNamespaces...),
},
},
{
Expand All @@ -158,9 +146,10 @@ func (t tiersComponent) allowTigeraClusterDNSPolicy() *v3.NetworkPolicy {
}
}

// allowTigeraNodeLocalDNSPolicy creates a NetworkPolicy that applies to all Tigera component namespaces and
// allows egress access to the given DNS egress CIDRs containing the Service ClusterIP(s) of the in-cluster DNS
// service. This ensures Tigera components access to the node-local DNS instance.
func (t tiersComponent) allowTigeraNodeLocalDNSPolicy() *v3.GlobalNetworkPolicy {
nodeLocalDNSPolicySelector := TigeraNamespaceSelector

nodeLocalDNSPolicy := &v3.GlobalNetworkPolicy{
TypeMeta: metav1.TypeMeta{Kind: "GlobalNetworkPolicy", APIVersion: "projectcalico.org/v3"},
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -169,7 +158,7 @@ func (t tiersComponent) allowTigeraNodeLocalDNSPolicy() *v3.GlobalNetworkPolicy
Spec: v3.GlobalNetworkPolicySpec{
Order: &networkpolicy.AfterHighPrecendenceOrder,
Tier: networkpolicy.TigeraComponentTierName,
Selector: nodeLocalDNSPolicySelector,
Selector: createNamespaceSelector(t.cfg.CalicoNamespaces...),
Egress: []v3.Rule{},
Types: []v3.PolicyType{v3.PolicyTypeEgress},
},
Expand All @@ -189,14 +178,12 @@ func (t tiersComponent) allowTigeraNodeLocalDNSPolicy() *v3.GlobalNetworkPolicy
if len(t.cfg.DNSEgressCIDRs.IPV4) > 0 {
IPV4Rule := egressRuleTemplate
IPV4Rule.Destination.Nets = append(IPV4Rule.Destination.Nets, t.cfg.DNSEgressCIDRs.IPV4...)

nodeLocalDNSPolicy.Spec.Egress = append(nodeLocalDNSPolicy.Spec.Egress, IPV4Rule)
}

if len(t.cfg.DNSEgressCIDRs.IPV6) > 0 {
IPV6Rule := egressRuleTemplate
IPV6Rule.Destination.Nets = append(IPV6Rule.Destination.Nets, t.cfg.DNSEgressCIDRs.IPV6...)

nodeLocalDNSPolicy.Spec.Egress = append(nodeLocalDNSPolicy.Spec.Egress, IPV6Rule)
}

Expand Down

0 comments on commit af6f536

Please sign in to comment.