projectcalico / calico

Cloud native networking and network security
https://docs.tigera.io/calico/latest/about/
Apache License 2.0
5.85k stars 1.31k forks source link

Full cone NAT #9008

Closed NinoSkopac closed 1 month ago

NinoSkopac commented 1 month ago

I did wanna post this in your slack, but one isn't able to join Calico slack without a @tigera.io email, which I don't have.

As the title says, I must have full cone nat in pods in a certain namespace.

I've never worked with Calico before, so I'll definitely get on it and start figuring it out, but any help is highly appreciated.

By default, pods have symmetric nat, at least in eks.

I've tested NAT on EC2 (without k8s):

% pystun3
NAT Type: Full Cone

Different story inside pods:

% kubectl run natdisco --rm -i --tty --image=yarmak/natdisco --restart=Never
NAT Type: Symmetric

Nino

caseydavenport commented 1 month ago

You can join the Calico Users slack with any email. Here's a link: https://slack.projectcalico.org/

caseydavenport commented 1 month ago

Could you share some more detail about your use-case?

NinoSkopac commented 1 month ago

Sure, and thank you for your response.

My use case is a k8s pod which requires port forwarding on 50000-50100/udp.

It requires full or restricted cone nat. Definitely not symmetric.

Have a great day!

Nino

caseydavenport commented 1 month ago

To make sure I understand, I'd like to talk about this in terms of connectivity requirements rather than generic classes of NAT, as that's typically how Kubernetes thinks about this.

Sounds like you need the ability to map UDP ports 50000-50100 on an external IP such that the traffic is DNAT'd to a particular pod IP (i.e., "restricted cone NAT")

Sounds like it would be nice-to-have (but not required) that egress traffic from the pod is SNAT's to the same external IP address (i.e., "full cone NAT")

For the former (ingress only) there are a variety of solutions that can provide stable addressing such as LoadBalancer / NodePort services, although as far as I know they do not currently support port ranges which means you would need to specify all 100 ports individually, which is a bit tedious.

NinoSkopac commented 1 month ago

@caseydavenport Yup, I think you nailed it.

Let me try to simplify it, let me show you a PoC I'm trying to get working using pystun3 as a NAT type detection utility: https://hub.docker.com/r/skopac/pystun3)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pystun3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pystun3
  template:
    metadata:
      labels:
        app: pystun3
    spec:
      containers:
        - name: pystun3
          image: skopac/pystun3:latest
          imagePullPolicy: IfNotPresent

What I tried already:

  1. --network=host
  2. run pod on instance which is in a public subnet
  3. NodePort

How would you get this to output anything but symmetric nat in eks?

NinoSkopac commented 1 month ago

@caseydavenport

just wrapping my head around what you said

i dont need both ingress and egress, right?

This is how I'm imagining the connection is supposed to work (but it's suffering due to NAT):

  1. Pod sends its ip:port to server
  2. Later, server calls back the pod using the same ip:port mapping

So, only egress should be used, because the 2. part must come in the same way part 1. went out?

If that makes sense

NinoSkopac commented 1 month ago

More things I tried: