Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions config/networkpolicy/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resources:
- networkpolicy.yaml

namespace: openshift-adp

# Add common labels to all NetworkPolicy resources
commonLabels:
app.kubernetes.io/name: oadp-operator
app.kubernetes.io/part-of: oadp-operator
90 changes: 90 additions & 0 deletions config/networkpolicy/networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: oadp-default-deny-labelled
labels:
app.kubernetes.io/name: oadp-networkpolicy
app.kubernetes.io/component: network-security
app.kubernetes.io/part-of: oadp-operator
app.kubernetes.io/managed-by: olm
spec:
# Limited Default Deny Policy:
# This policy selects pods managed by oadp-operator and blocks all traffic by default,
# except for the specific ingress/egress rules defined below.
# It allows OADP to coexist with other workloads in the same namespace.
podSelector:
matchLabels:
app.kubernetes.io/managed-by: "oadp-operator"
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector: {}
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-monitoring
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-user-workload-monitoring
ports:
- protocol: TCP
port: 8085
- protocol: TCP
port: 8443
- ports:
- protocol: TCP
port: 9443
Comment on lines +36 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Restrict the webhook ingress rule to the API server.

The ingress rule on port 9443 lacks a from clause, meaning it allows traffic from any source on this port. Since this is documented as a webhook for API server validation/mutation (line 65 of README), restrict it to the Kubernetes API server to reduce attack surface:

  - ports:
    - protocol: TCP
      port: 9443
+   from:
+   - podSelector: {}
+     namespaceSelector:
+       matchLabels:
+         kubernetes.io/metadata.name: default

Alternatively, if the webhook needs to accept traffic from pods within the same namespace, document this decision explicitly.

Would you like me to refine this rule further or provide additional security-hardened options?

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- ports:
- protocol: TCP
port: 9443
- ports:
- protocol: TCP
port: 9443
from:
- podSelector: {}
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
🤖 Prompt for AI Agents
In config/networkpolicy/networkpolicy.yaml around lines 32-34, the ingress rule
allowing TCP port 9443 has no `from` clause (allowing all sources); restrict it
to only the Kubernetes API server by adding a `from` selector that targets the
API server pods or control-plane CIDR (e.g., namespaceSelector + podSelector
matching the kube-system API server pods, or an ipBlock matching the cluster
control-plane IPs); alternatively, if the webhook must accept traffic from
same-namespace pods, add a `from` clause limiting sources to that namespace
(namespaceSelector matching the webhook namespace) and document the decision.

egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 6443
# Explicitly allow access to DNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-dns
podSelector:
matchLabels:
dns.operator.openshift.io/daemonset-dns: default
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- protocol: UDP
port: 5353
- protocol: TCP
port: 5353
# Explicitly allow access to Kubernetes API Server
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
ports:
- protocol: TCP
port: 443
# Explicitly allow access to OpenShift API Server
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-apiserver
ports:
- protocol: TCP
port: 443
# Explicitly allow access to Kubernetes API Server (OpenShift Namespace)
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-kube-apiserver
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 6443
273 changes: 273 additions & 0 deletions docs/NetworkPolicies/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
# NetworkPolicies for OADP (OpenShift API for Data Protection)

This directory contains NetworkPolicy configurations for securing OADP components in your Kubernetes cluster. NetworkPolicies provide a way to control network traffic flow between pods and other network endpoints at the application layer.

## What are NetworkPolicies?

NetworkPolicies are Kubernetes resources that define how groups of pods are allowed to communicate with each other and other network endpoints. They work at the IP address or port level (OSI layer 3 or 4) and provide a way to implement network segmentation and micro-segmentation within your cluster.

As described in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/), NetworkPolicies use labels to select pods and define rules that specify what traffic is allowed to and from those pods.

## Prerequisites

- Your cluster must be using a Container Network Interface (CNI) plugin that supports NetworkPolicies (such as Calico, Cilium, Weave Net, or others)
- NetworkPolicies are namespaced resources and only affect pods in the same namespace

## OADP NetworkPolicy Configuration

The `network_policy.yaml` file in this directory defines a NetworkPolicy specifically designed for OADP components. Here's what it does:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Correct the policy filename reference.

Line 18 refers to the policy as network_policy.yaml, but the actual filename is networkpolicy.yaml (no underscore). Update the reference:

-The `network_policy.yaml` file in this directory defines a NetworkPolicy specifically designed for OADP components. Here's what it does:
+The `networkpolicy.yaml` file in this directory defines a NetworkPolicy specifically designed for OADP components. Here's what it does:

Also applies to: 23-23

🤖 Prompt for AI Agents
In docs/NetworkPolicies/README.md around lines 18 and 23, the README incorrectly
references the policy file as "network_policy.yaml"; update both occurrences to
the actual filename "networkpolicy.yaml" (remove the underscore) so the README
matches the repository file name and any links or commands referencing it work
correctly.


### Policy Overview

```yaml
name: default-deny-labelled
```

This policy implements a **default-deny approach** for pods managed by the OADP operator, meaning that by default, all network traffic is blocked except for explicitly allowed connections.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this block the OADP CLI from functioning? Did we ever enable the pull-through logs download that @kaovilai had started? Do we need to allow this in some way?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can revise the default policy later if needed. The download server has not yet been implemented.


### Pod Selection

```yaml
podSelector:
matchLabels:
app.kubernetes.io/managed-by: "oadp-operator"
```

The policy applies to all pods that have the label `app.kubernetes.io/managed-by: "oadp-operator"`. This typically includes:
- Velero pods
- OADP operator pods
- Other OADP-related components

### Traffic Rules

#### Ingress Rules (Incoming Traffic)

```yaml
ingress:
- from:
- podSelector: {}
# Allow OpenShift Monitoring
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-monitoring
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-user-workload-monitoring
ports:
- protocol: TCP
port: 8085 # Velero Metrics
- protocol: TCP
port: 8443 # Controller Metrics
# Allow API Server Webhooks
- ports:
- protocol: TCP
port: 9443 # Webhook
```

**What this allows:**
- **Internal Communication**: Allows incoming traffic from **any pod within the same namespace**.
- **Monitoring**: Allows OpenShift Monitoring stack to scrape metrics from OADP components (ports 8085, 8443).
- **Webhooks**: Allows the Kubernetes API server to communicate with OADP validation/mutation webhooks (port 9443).

#### Egress Rules (Outgoing Traffic)

The policy defines multiple egress rules to ensure comprehensive connectivity:

**1. General Network Access**
```yaml
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 6443
```

**What this allows:**
- Outbound HTTPS traffic (port 443) to any IP address.
- Outbound traffic to Kubernetes API servers (port 6443).
- This covers cloud storage providers, external APIs, container registries, and external/host-networked API servers.

**2. DNS Resolution**
```yaml
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-dns
podSelector:
matchLabels:
dns.operator.openshift.io/daemonset-dns: default
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- protocol: UDP
port: 5353
- protocol: TCP
port: 5353
```

**What this allows:**
- DNS queries to the OpenShift DNS service (ports 53 and 5353).
- Uses specific selectors for the `openshift-dns` namespace and `dns-default` pods.

**3. Kubernetes API Access (Explicit)**
```yaml
# Allow access to Kubernetes API Server
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
ports:
- protocol: TCP
port: 443

# Allow access to OpenShift API Server
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-apiserver
ports:
- protocol: TCP
port: 443

# Allow access to Kubernetes API Server (OpenShift Namespace)
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-kube-apiserver
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 6443
```

**What this allows:**
- Explicitly allows traffic to the Kubernetes API server (in `default` and `openshift-kube-apiserver` namespaces) and OpenShift API server (in `openshift-apiserver` namespace).
- Ensures internal Service Network traffic is permitted even if broader rules don't apply to cluster services in some CNI configurations.
- Covers both port 443 (Service) and 6443 (Pod/Endpoint) for the API server.

## Why These Rules Matter for OADP

### Security Benefits

1. **Principle of Least Privilege**: Only allows the minimum network access required for OADP to function
2. **Attack Surface Reduction**: Limits potential network-based attacks on OADP components
3. **Compliance**: Helps meet security compliance requirements for network segmentation

### OADP-Specific Requirements

OADP components need specific network access to function properly:

- **Cloud Storage Access**: HTTPS (443) for communicating with cloud storage APIs
- **DNS Resolution**: Required to resolve cloud storage endpoint names
- **Inter-Component Communication**: OADP pods may need to communicate with each other within the namespace
- **Monitoring**: The OpenShift Monitoring stack needs to reach OADP metrics endpoints
- **Webhooks**: The Kubernetes API server needs to reach the OADP operator for CR validation

## Applying the NetworkPolicy

To apply this NetworkPolicy to your cluster:

```bash
kubectl apply -f network_policy.yaml -n <oadp-namespace>
```

Replace `<oadp-namespace>` with the namespace where OADP is installed (typically `openshift-adp`).

## Monitoring and Troubleshooting

### Verifying the Policy

Check if the NetworkPolicy is applied:
```bash
kubectl get networkpolicy -n <oadp-namespace>
kubectl describe networkpolicy default-deny-labelled -n <oadp-namespace>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Correct the NetworkPolicy name reference.

Line 160 references the policy as default-deny-labelled, but the actual policy name is oadp-default-deny-labelled. Update the reference:

-kubectl describe networkpolicy default-deny-labelled -n <oadp-namespace>
+kubectl describe networkpolicy oadp-default-deny-labelled -n <oadp-namespace>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
kubectl describe networkpolicy default-deny-labelled -n <oadp-namespace>
kubectl describe networkpolicy oadp-default-deny-labelled -n <oadp-namespace>
🤖 Prompt for AI Agents
In docs/NetworkPolicies/README.md around line 160, the kubectl command
references the wrong NetworkPolicy name; change `default-deny-labelled` to the
actual policy name `oadp-default-deny-labelled` so the command reads `kubectl
describe networkpolicy oadp-default-deny-labelled -n <oadp-namespace>`.

```

### Common Issues

1. **DNS Resolution Failures**: If OADP components can't resolve domain names, verify the DNS egress rule
2. **Cloud Storage Connection Issues**: Ensure the HTTPS egress rule allows traffic to your storage provider
3. **Inter-Pod Communication Problems**: Check that pods have the correct labels and the ingress rule is configured properly

### Debugging Network Connectivity

If you suspect NetworkPolicy issues:

1. Check pod labels:
```bash
kubectl get pods -n <oadp-namespace> --show-labels
```

2. Test connectivity from within a pod:
```bash
kubectl exec -it <pod-name> -n <oadp-namespace> -- nslookup <domain-name>
kubectl exec -it <pod-name> -n <oadp-namespace> -- curl -I https://<endpoint>
```

## Customizing the Policy

You may need to modify the NetworkPolicy based on your specific requirements:

### Adding Additional Egress Rules

If your OADP setup requires access to additional services, add more egress rules:

```yaml
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8 # Private network range
ports:
- protocol: TCP
port: 9000 # MinIO or other S3-compatible storage
```

### Restricting Cloud Access

To limit access to specific cloud provider IP ranges instead of allowing all internet traffic:

```yaml
egress:
- to:
- ipBlock:
cidr: 52.219.0.0/16 # AWS S3 IP range example
ports:
- protocol: TCP
port: 443
```

## Important Considerations

### Pod Lifecycle

As noted in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/), when a NetworkPolicy is first applied, there may be a brief period where pods are started without full network isolation. OADP pods should be resilient to temporary network connectivity issues during startup.

### CNI Plugin Compatibility

Ensure your CNI plugin fully supports NetworkPolicies. Some features (like `endPort` ranges) may not be supported by all plugins.

### Default Behavior

Remember that NetworkPolicies implement a "default deny" model. If no NetworkPolicy selects a pod, all traffic is allowed. Once a pod is selected by any NetworkPolicy, only traffic explicitly allowed by those policies will be permitted.

## Additional Resources

- [Kubernetes NetworkPolicy Documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
- [OADP Documentation](https://docs.openshift.com/container-platform/latest/backup_and_restore/application_backup_and_restore/oadp-features-plugins.html)
- [OpenShift Network Security](https://docs.openshift.com/container-platform/latest/networking/network_policy/about-network-policy.html)

## Contributing

When modifying NetworkPolicies for OADP:

1. Test thoroughly in a development environment
2. Verify that all OADP functionality continues to work
3. Document any changes and the reasoning behind them
4. Consider the security implications of any new rules