How to simulate different NAT behaviours - networking

I am working on Holepunching using UDP and UDT. For the final testing I need to test the application on different NAT types (Symmetric,full cone,restricted cone, port restricted NATs).
Is there any method I can simulate these? What I expect here is some kind of virtual-Box setup. Can I use PC as a router so that I can configure according to my needs?
In general how do we test applications for different network conditions?

Just in case someone else is looking to do this, this website explains how to set up the different NAT environments using IPTables.
Update
It has been a few years since I did this, given that the link was placed behind a login, and the rewind was also placed behind a login, I went through my notes from back than and found the following. Please note these are untested.
Full Cone NAT;
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source "public IP"
iptables -t nat -A PREROUTING -i eth1 -j DNAT --to-destination "private IP"
Restricted Cone NAT;
iptables -t nat -A POSTROUTING -o eth1 -p udp -j SNAT --to-source "public IP"
iptables -t nat -A PREROUTING -i eth1 -p udp -j DNAT --to-destination "private IP"
iptables -A INPUT -i eth1 -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth1 -p udp -m state --state NEW -j DROP
Port Restricted Cone NAT;
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source "public IP"
Symmetric NAT;
echo "1" >/proc/sys/net/ipv4/ip_forward
iptables --flush
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE --random
iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT

I think you already answered your own question, use VirtualBox (or VMware, Xen, etc..).
I've done this very thing successfully by setting up mini-lans of VM's. If you're looking for software to act as your router inside a VM, I'd start off at http://www.pfsense.org/ and see if that meets your needs. It's a FreeBSD distribution tailored for being an easy to install router/firewall with a nice web management UI and all of that.
If pfsense doesn't fit your needs, there are plenty of other linux/bsd distributions out there that are tailored for this kind of stuff and that you can install in a VM: http://en.wikipedia.org/wiki/List_of_router_or_firewall_distributions for a good list :) (I've heard good things about OpenWRT and ClearOS as well.)

Related

IPv6 forwarding on wireguard

I've been trying to set up a Wireguard VPN on my Dedibox at Scaleway for the past few days now, with limited success. First of all, IPv4 is working, so at least I am not hopelessly lost. Currently my peers are using private IPv4 addresses to talk to the server, which then nats them onto it's own public IP using iptables. Works great. Now I want to set up IPv6 too, but not using nat. I want to forward public IPv6 addresses assigned on my peers using ip6tables and use those to go over the internet, rather than using the Masquerade option like with IPv4.
I have so far had limited success in that field. I set up a little test environment in GNS3 and without Wireguard it's definitely possible to route IPv6 addresses using ip6tables (just to find out what rules to make, I am kind of new to iptables). Now I tried to do the same thing on my wireguard equipped server, but to no avail. My PostUp and PostDown are currently as follows (censoring out my IPv6 addresses):
PostUp:
iptables -A FORWARD -o wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -o enp0s20 -j MASQUERADE
ip6tables -t filter -I INPUT 1 -s 2001:db8:abcd:100::/56 -j ACCEPT
ip6tables -t filter -I INPUT 2 -s 2001:db8:abcd:101::/64 -j ACCEPT
ip6tables -t filter -I FORWARD 1 -o wg0 -j ACCEPT
ip6tables -t filter -I FORWARD 2 -i wg0 -j ACCEPT
PostDown:
iptables -D FORWARD -o wg0 -j ACCEPT
iptables -t nat -D POSTROUTING -o enp0s20 -j MASQUERADE
ip6tables -t filter -D INPUT -s 2001:db8:abcd:100::/56 -j ACCEPT
ip6tables -t filter -D INPUT -s 2001:db8:abcd:101::/64 -j ACCEPT
ip6tables -t filter -D FORWARD -o wg0 -j ACCEPT
ip6tables -t filter -D FORWARD -i wg0 -j ACCEPT
The public IPv6 range assigned to my main interface (enp0s20) is 2001:db8:abcd:100::/56, while I want to use 2001:db8:abcd:101::/64 for my Wireguard peers.
Another curious thing is that for some reason it appears as though I can ping between peers on this network, but that might be a fluke here, not exactly sure. I currently have both my workstation and smartphone on this network, and pinging between my workstation and smartphone works fine using the following command on Windows:
ping -6 -S 2001:db8:abcd:101::2 2001:db8:abcd:101::3
Where my workstation ends in 2 and my smartphone ends in 3.
I am at a total loss, anyone who could help me with this?

How to access internal from external?

I have two network interfaces on a node. One is internal network and the other is external network. Internal network is 192.168.50.0/255.255.255.0(internal network).
And external network is 192.168.0.0/255.255.255.0. Kubernetes consists of 192.168.50.0/255.255.255.0. I want to approach internal network from another local nodes without using internal network interface. How can I solve this problem?
Without subnet masks , I do not understand how they are different networks.
But , in any case , you need to enable routing packets from one interface to another. I assume you are on Linux node , there you may enable ip-forwarding.
echo 1 >> /proc/sys/net/ipv4/ip_forward
Then set up some rules in iptables to perform the natting and forwarding:
Example rules:
# Always accept loopback traffic
iptables -A INPUT -i lo -j ACCEPT
# We allow traffic from the LAN side
iptables -A INPUT -i eth0 -j ACCEPT
######################################################################
#
# ROUTING
#
######################################################################
# eth0 is LAN
# eth1 is WAN
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Masquerade.
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
# fowarding
iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
# Allow outgoing connections from the LAN side.
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
https://serverfault.com/questions/453254/routing-between-two-networks-on-linux

Restrict Docker exposed port from only specific IP adresses

How to restrict a container's port exposed by Docker from only a list of IPs? Only this list of IP would be able to access this port.
I tried that:
iptables -I DOCKER -p tcp --dport PORT_X -j REJECT --reject-with icmp-port-unreachable
iptables -I DOCKER -p tcp --dport PORT_X --source EXTERNAL_IP_1 --destination HOST_IP_1 -j ACCEPT
iptables -I DOCKER -p tcp --dport PORT_X --source EXTERNAL_IP_2 --destination HOST_IP_1 -j ACCEPT
iptables -I DOCKER -p tcp --dport PORT_X --source EXTERNAL_IP_3 --destination HOST_IP_1 -j ACCEPT
I had the same problem. I solved it with this rules :
iptables -I DOCKER-USER -i <your_interface_name> -j DROP
iptables -I DOCKER-USER -i <your_interface_name> -s <your_first_ip> -j ACCEPT
iptables -I DOCKER-USER -i <your_interface_name> -s <your_second_ip> -j ACCEPT
Care, DOCKER-USER is a chain which will not be deleted when service docker restart
You should be able to add your port flag, but i'm not an expert and it is not my needs.
Your policy is whitelist, it's better to create a user custom chain handle this alone.
For example, I have a redis container, I want it only serve for specific IPs:
$ docker run -d -p 6379:6379 redis:2.8
After started redis container, the iptables looks like this:
$ iptables -t filter -nL
Chain DOCKER (1 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 172.17.0.2 tcp dpt:6379
Create our custom chain:
$ iptables -N CUSTOM_REDIS
$ iptables -A CUSTOM_REDIS -p tcp --dport 6379 --source 172.31.101.37 --destination 172.17.0.2 -j ACCEPT
$ iptables -A CUSTOM_REDIS -p tcp --dport 6379 --source 172.31.101.38 --destination 172.17.0.2 -j ACCEPT
$ iptables -A CUSTOM_REDIS -p tcp --dport 6379 --source 0.0.0.0/0 --destination 172.17.0.2 -j DROP
Replace the original rule with custom chain:
$ iptables -R DOCKER 1 -p tcp --source 0.0.0.0/0 --destination 172.17.0.2 --dport 6379 -j CUSTOM_REDIS
Now my redis can only access by ip: 172.31.101.37 and 172.31.101.38.
Note:
172.17.0.2 is the ip of redis container
From the docker guide here:
Docker’s forward rules permit all external source IPs by default. To allow only a specific IP or network to access the containers, insert a negated rule at the top of the DOCKER filter chain. For example, to restrict external access such that only source IP 8.8.8.8 can access the containers, the following rule could be added:
$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP
In your case since you want to allow multiple IP addresses I think something like this should work:
iptables -I DOCKER -s EXTERNAL_IP_1 -p tcp --dport PORT_X -j ACCEPT
iptables -I DOCKER -s EXTERNAL_IP_2 -p tcp --dport PORT_X -j ACCEPT
iptables -I DOCKER -s EXTERNAL_IP_3 -p tcp --dport PORT_X -j ACCEPT
iptables -I DOCKER -p tcp --dport PORT_X -j REJECT --reject-with icmp-port-unreachable
You may also want to prevent access from docker directly, using the specific IP you want to listen, like -p 1.2.3.4:6379:6379/tcp syntax, that way the container will listen only on that IP and interface.
If you use that IP as private IPs, you can avoid completely the iptables because you restricted access only from local/private network.
You can use ufw from inside docker container
sudo ufw [--dry-run] [delete] [insert NUM] allow|deny|reject|limit [in|out on INTERFACE] [log|log-all] [proto protocol] [from ADDRESS [port PORT]][to ADDRESS [port PORT]]

Direct port 5060 for eth1

I have two network interface, eth0 is the internal network necessary for the connection of PCs with the softphone and eth1 to link to internet. I'm using iptables on CentOS 6.5 to direct all the outputs of the Freepbx (Asterisk) to eth1, but I don't have success.
The rule
iptables -A PREROUTING -i eth1 -t mangle -p tcp --dport 5060 -j MARK --set-mark 1
Take a ook at sip.conf. In the [general] section, there is a bindaddress or udpbindaddress. Set it to 0.0.0.0 to make sure asterisk listens on all interfaces. You can check it by:
netstat -lnap | grep 5060
udp 0 0 0.0.0.0:5060 0.0.0.0:* 30822/asterisk
Then restrict access to unnecessary interfaces using iptables, like (note the order):
iptables -A INPUT -i eth1 -p udp --dport 5060 -j ACCEPT
iptables -A INPUT -p udp --dport 5060 -j DROP
iptables -A OUTPUT -o eth1 -p udp --sport 5060 -j ACCEPT
iptables -A OUTPUT -p udp --sport 5060 -j DROP
If public ip on same server, you need use INPUT table and ACCEPT destination.
If it on other host, you have use DNAT.

Iptables to modify source ip. Nothing in POSTROUTING chain log

Here is a little picture
Asterisk eth1 10.254.254.2/28------------- Many Good Guys
eth1:1 192.168.83.5/32----------- 192.168.59.3 Bad Guy Peer
I have an Asterisk which is connected with several peers. Some of them are connected through
eth1 and one the badest through alias eth1:1.
Then my asterisk send invite to peers it goes with the eth1 source. So for the bad guy I need to change my source ip to 192.168.83.5 As far as I know it can be done with iptables.
So I tried the rule
iptables -t nat -A POSTROUTING -s 10.254.254.2 -d 192.168.59.3 -j SNAT
--to 192.168.83.5
nothing happens.
When I log I can see send packets in INPUT and OUTPUT chains with :
iptables -t filter -A OUTPUT -o eth1 -s 10.254.254.2 -d 192.168.59.3
-j LOG --log-level 7 --log-prefix "OUTPUT"
iptables -t filter -A INPUT-i eth1 -s 192.168.59.3 -d 192.168.83.5 -j
LOG --log-level 7 --log-prefix "OUTPUT"
but I don’t see any in POSTROUTING chain with:
iptables -t nat -A POSTROUTING -s 10.254.254.2 -d 192.168.59.3 -j LOG
--log-level 7 --log-prefix "POSTROUTING"
That is I have nothing to SNAT(((
At the same time the traffic from other peers is visible in POSTROUTING log. What can it be?
Any thoughts, wishes, kicks would be very appreciated!
The solution has been found!!
I didn' t find a way to make my iptables work. But know i know how to do it without iptables at all.
So generally speaking my task was to modify|mask|replace my source ip of eth1 with eth1:1 ip.
By the way i use CentOS 5.8
And there is a command:
ip route add
which gives you ability to point scr address unlike the route command.
so
ip route add 192.168.59.3/32 via 10.254.254.1 dev eth1 src
192.168.83.5
is doing just what i need.
Thank you for attention!
That will not work. Reason is simple, asterisk will set in packet source addres=address of eth1.
You can start enother asterisk same host(with other config dir). I am sorry, i not know other simple variants.

Resources