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

iptables --random and --random-fully ignore /proc/sys/net/ipv4/ip_local_port_range #509

Closed
taylorb-syd opened this issue Jun 19, 2019 · 15 comments
Labels

Comments

@taylorb-syd
Copy link
Contributor

When selecting a port for the outgoing connection the kernel netfliter module will select the next port avaliable in the /proc/sys/net/ipv4/ip_local_port_range range by default. However, due to issues with port conflicts occuring as discussed in #246 the default behaviour has been changed to use the NF_NAT_RANGE_PROTO_RANDOM flag by way of the iptables --random option.

It turns out that the kernel is hard coded[1] when either the NF_NAT_RANGE_PROTO_RANDOM or NF_NAT_RANGE_PROTO_RANDOM_FULLY to select a random port in the non-privileged range, i.e. 1024 through 65535.

It has been determined that it is possible to create port range limited rules provided that the protocol is specified within the rule[2]. For example the following rule could be applied to limit the range to the traditional range as specified in RFC6056 of 49152 through 65535 for TCP traffic.

iptables -I AWS-SNAT-CHAIN-${LCN} -m addrtype ! --dst-type LOCAL -j SNAT -p tcp --to-source ${FSTIP}:49152-65535

Where:

  • ${LCN} represents the number of IPv4 VPC CIDRs in the VPC.
  • ${FSTIP} represents the first IP address of the first ENI of the instance.

Similarly rules could be created for other protocols such as UDP.

In response to this, we have updated the documentation in update #503 to make this clearer, but the purpose of this issue to determine if this is sufficient for the consumers of this plugin.

The question I wish to ask of the community is: Are you happy with his behaviour being documented or should we put development effort towards being able to control this range?

To me this seems like a very niche use case, and affected consumers should consider manually injecting the required rules into their chains as per the example above, but if enough consumers are affected we can put effort into this.

References:
[1] Line 478 of nf_nat_core.c
[2] Line 78 of libip6t_SNAT.c

@taylorb-syd taylorb-syd changed the title iptables --random and --random-fully ignore /proc/sys/net/ipv4/ip_local_port_range iptables --random and --random-fully ignore /proc/sys/net/ipv4/ip_local_port_range Jun 19, 2019
@nithu0115
Copy link
Contributor

From my observation, AL2 iptables version i.e., iptables v1.4.21 does not support --random-fully (AWS_VPC_K8S_CNI_RANDOMIZESNAT=prng environment variable), and is only compatible with iptables >=1.6.2.

@jaypipes
Copy link
Contributor

The root cause of this is old kernel/packages in the EKS AMI. We have created an issue in the EKS AMI repo for tracking.

awslabs/amazon-eks-ami#380

Closing this as duplicate (not related to AWS VPC plugin)

@taylorb-syd
Copy link
Contributor Author

taylorb-syd commented Dec 11, 2019

This is not a duplicate of #380.

I'm sorry nithu0115@ but I think you linked to the wrong issue when talking about this, did you mean pull request #246 where this change was introduced?

@jaypipes
Copy link
Contributor

Yup, we goofed, sorry @taylorb-syd! It is #516 and #662 that are related to the awslabs/amazon-eks-ami#380

@jaypipes jaypipes reopened this Dec 11, 2019
@madeddie
Copy link

madeddie commented Mar 5, 2020

What would be the canonical way to add these iptables rules? Where can we hook in to have these rules automagically created when the driver creates it's ruleset?

@taylorb-syd
Copy link
Contributor Author

What would be the canonical way to add these iptables rules? Where can we hook in to have these rules automagically created when the driver creates it's ruleset?

That's the point of this question, the agent currently provides no ability to do this. If this is functionality you would like to see (or similar functionality, i.e. the ability to provide custom rules) let us know and we can try and put some effort towards it.

Right now you need to write a script that checks for the existence of the AWS-SNAT-CHAIN-${LCN} and base external SNAT rule, and once it finds it, injects in the rule as specified in the first post.

May I understand your use case as to why you wish to restrict the port range?

@madeddie
Copy link

madeddie commented Mar 8, 2020

We have a cloud-wide ACL to protect ports between 1024 and 10240 from outside connections (possibly badly protected services) and so we need the NAT setup to choose ports between 10240 and 65535 instead of all the way down to 1024. I wouldn't mind injecting the rules manually, but in this case that would turn into something akin to cron in case the cni application messes with the rules for some reason. This'll become very brittle.
I'd rather use a way that is signalled by the cni process writing the rules somehow to always inject ours when needed.

@madeddie
Copy link

madeddie commented Mar 8, 2020

With cloud-wide I mean the subnet encompassing our k8s cluster but also some non-dockerized workloads on standard VMs

@taylorb-syd
Copy link
Contributor Author

We have a cloud-wide ACL to protect ports between 1024 and 10240 from outside connections (possibly badly protected services) and so we need the NAT setup to choose ports between 10240 and 65535 instead of all the way down to 1024. I wouldn't mind injecting the rules manually, but in this case that would turn into something akin to cron in case the cni application messes with the rules for some reason. This'll become very brittle.

That seems like a definite use case. I am currently working on designing a better iptables rules management engine for the CNI plug-in and this work will lead into the ability to inject custom rules and add other functionality like SNAT port ranges.

Unfortunately it might be a while. For this reason it is unlikely to be in the 1.6.0 RCs and instead likely to be introduced in the 1.7.0 RCs instead. I'll update you on my progress.

@github-actions
Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days

@github-actions github-actions bot added the stale Issue or PR is stale label Apr 13, 2022
@github-actions
Copy link

Issue closed due to inactivity.

@jayanthvn
Copy link
Contributor

/reopen

@jayanthvn jayanthvn reopened this Apr 27, 2022
@github-actions github-actions bot removed the stale Issue or PR is stale label Apr 28, 2022
@michelzanini
Copy link

I have come into this issue when trying to change a ACL to pass AWS CIS compliance.

AWS CIS 1.4.0 - Control 5.1:

5.1 Ensure no Network ACLs allow ingress from 0.0.0.0/0 to remote server administration ports (Automated)

The Network Access Control List (NACL) function provide stateless filtering of ingress and egress 
network traffic to AWS resources. 
It is recommended that no NACL allows unrestricted ingress access to remote server administration ports, 
such as SSH to port 22 and RDP to port 3389.

I need to be able to block port 3389 (RDP) to pass this CIS rule. But, because the ephemeral ports are on a range from 1024 to 65535 I can't do this without risking blocking a valid connection (when the ephemeral port end up being exactly 3389).

I figure that I could set AWS_VPC_K8S_CNI_RANDOMIZESNAT to none for this to work? But I don't what the implications of this would be. If there's any negative impact. Also, changing this env var for the CNI seems to be a problem when using Terraform since the AWS CNI is managed as a add-on and changing the env var alone is hard from Terraform, as the add-on content is not managed / owned by Terraform.

What else would I be able to do here?

Thanks.

@github-actions
Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days

@github-actions github-actions bot added the stale Issue or PR is stale label Sep 21, 2022
@github-actions
Copy link

github-actions bot commented Oct 6, 2022

Issue closed due to inactivity.

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

No branches or pull requests

7 participants