First answer was related to FreeBSD. The issues are the same but the parameters are different on Ubuntu:
Stock Ubuntu goes a long way. When you start to tune these parameters you might introduce more problems than you fix. From the lack of information you give my advice would be not to touch these parameters until you understand the networking parts a little better. And if you really have problems with some of these parameters you will usually get entries in your kernel log.
300 servers behind a NAT with only 600 rules is not huges numbers. If they are just a bunch of servers with little inbound and outbound traffic this should be a walk in the park. If any of the servers are doing heavy inbound or outbound traffic then things can turn sour pretty quickly.
The first problem to solve is how much is "lots". The numbers you have shown so far are not scary. And you should really confirm that you have big numbers before you start tweaking your network stack with sysctl. Be very very carefull with this.
To see if you have a large number of concurrent connections through the box you can do a:
wc -l /proc/net/tcp
Or to get even more statistics you can do netstat -s
(Linux) or netstat -m
(FreeBSD). This will tell you the currently used numbers. With that information in hand you can decide if you need to tune or not.
The most common problem with busy NATs is net.ipv4.netfilter.ip_conntrack_max
which governs how many connections you track. You can see how many entries are in the tracking table with:
sysctl net.netfilter.nf_conntrack_count
Check the current maximum you have set:
sysctl net.ipv4.netfilter.ip_conntrack_max
AFAIK default is 65536. You can increase this number as needed as long as you have memory for it.
davidgo mentions 64K ports. You can check the number of configured ephemeral ports using:
sysctl net.ipv4.ip_local_port_range
Maybe you need to increase the number of ports here.
It is interesting to know how quickly you discard closing sockets. This can leave hanging sockets and on a busy server you like to free them up more quickly:
sysctl net.ipv4.tcp_fin_timeout
You can free up ports quicker by decreasing thie value to 25 of maybe 10 seconds.
This as usually the ones to tune - but there are other relevant as well:
sysctl -a | grep conntrack | grep timeout
You can set all parameters using the sysctl
command or edit /etc/sysctl.conf
You results may differ but to give you an idea the numbers below have been set on a reasonably busy server:
net.ipv4.netfilter.ip_conntrack_max = 196608
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 86400
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768 61000