Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Policy Assistant] calculate all allowed connections in a cluster #221

Open
huntergregory opened this issue Apr 19, 2024 · 1 comment
Open

Comments

@huntergregory
Copy link
Contributor

huntergregory commented Apr 19, 2024

Parent issue: #150

Goal

For all the Deployments and DaemonSets in a cluster, calculate the set of allowed connections given a set of policies.

Current Functionality

Check whether traffic is allowed/denied for the specified source, destination, and port/protocol.

image

Proposed New Feature

Produce JSON of all allowed connections and the effective policy rules causing this.

Here is one idea for the format (let me put this in a PR):

{
    "Connections": [
        {
            "From": "10.0.0.0/28",
            "To": "ns-dev/daemonset/backend",
            "AllowedTraffic": {
                "TCPPorts": "all"
            },
            "EffectivePolicyRules": {
                "Ingress": {
                    "ANPPassed": [
                        {
                            "PolicyKey": "default/anp1",
                            "Priority": 1,
                            "RuleNumber": 9,
                            "Rule": "dev-pass-on-external-tcp",
                            "TCPPorts": "all"
                        }
                    ],
                    "ANPDenied": [
                        {
                            "PolicyKey": "default/anp1",
                            "Priority": 1,
                            "RuleNumber": 10,
                            "Rule": "deny-external",
                            "UDPPorts": "all",
                            "OtherPorts": "all"
                        }
                    ],
                    "NPv1Allowed": [
                        {
                            "PolicyKey": "ns-dev/allow-all",
                            "TCPPorts": "all"
                        }
                    ]
                }
            }
        },
        {
            "From": "ns-dev/deployment/frontend",
            "To": "ns-dev/daemonset/backend",
            "AllowedTraffic": {
                "TCPPorts": "80",
                "UDPPorts": "53,80"
            },
            "EffectivePolicyRules": {
                "Ingress": {
                    "ANPAllowed": [
                        {
                            "PolicyKey": "default/anp2",
                            "Priority": 2,
                            "RuleNumber": 1,
                            "Rule": "allow-all-udp",
                            "UDPPorts": "all"
                        }
                    ],
                    "ANPPassed": [
                        {
                            "PolicyKey": "default/anp1",
                            "Priority": 1,
                            "RuleNumber": 1,
                            "Rule": "pass-tcp-80",
                            "TCPPorts": "80"
                        },
                        {
                            "PolicyKey": "default/anp1",
                            "Priority": 1,
                            "RuleNumber": 2,
                            "Rule": "pass-rest-of-tcp",
                            "TCPPorts": "0-79,81-65535"
                        }
                    ],
                    "ANPDenied": [
                        {
                            "PolicyKey": "default/anp3",
                            "Priority": 3,
                            "RuleNumber": 1,
                            "Rule": "deny-everything-else",
                            "OtherPorts": "all"
                        }
                    ],
                    "NPv1Allowed": [
                        {
                            "PolicyKey": "ns-dev/deny-all"
                        },
                        {
                            "PolicyKey": "ns-dev/allow-tcp-80",
                            "TCPPorts": "80"
                        }
                    ]
                },
                "Egress": {
                    "BANPAllowed": [
                        {
                            "PolicyKey": "default/default",
                            "RuleNumber": 1,
                            "Rule": "allow-port-53-and-80",
                            "TCPPorts": "53,80",
                            "UDPPorts": "53,80",
                            "OtherPorts": "53,80",
                        }
                    ],
                    "BANPDenied": [
                        {
                            "PolicyKey": "default/default",
                            "RuleNumber": 2,
                            "Rule": "baseline-deny-udp",
                            "UDPPorts": "0-52,54-65535"
                        }
                    ]
                }
            }
        }
    ]
}

Implementation

 
There is a policy engine that calculates whether traffic is allowed/denied for a given set of:

  • protocol
  • destination port
  • source Pod info
  • destination Pod info

Can we brute force calculate all possible connections between each Deployment/DaemonSet in a cluster? There are only 65,000 ports, so this may be feasible?

Code

It's determined whether traffic is allowed here:

func (p *Policy) IsTrafficAllowed(traffic *Traffic) *AllowedResult {

if !m.Matches(subject, peer, traffic.ResolvedPort, traffic.ResolvedPortName, traffic.Protocol) {

Based on the port/protocol logic from the PeerMatcher interface:

Matches(subject, peer *TrafficPeer, portInt int, portName string, protocol v1.Protocol) bool

@huntergregory huntergregory changed the title [Policy Assistant] without specifying ports/protocols, determine all allowed L4 traffic between two Pods [Policy Assistant] calculate all allowed connections in a cluster Apr 19, 2024
@huntergregory
Copy link
Contributor Author

Some good discussion on this today.

Takeaways:

  • Iterate quickly. Improve scale etc. as needed
  • This issue is more about the data structure and code for calculating it. A follow-up goal will be to display the data structure in a useful/pretty way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant