Saving You 15 Minutes - NAT, Oracle Cloud Infrastructure and Oracle Enterprise Linux 6

I wanted to show you a couple of quick commands that will save you a bit of time when you’re configuring access to the outside world from a private instance in Oracle Cloud. For me this was an opportunity to quickly capture a couple of items down into a blog; I had this working a while ago and when I came back to it a seemingly couldn’t get it to work again! Always the way.

The key thing here is that we are building this configuration in Oracle Cloud Infrastructure and therefore this adds a couple of different challenges; firstly, network level firewalls between the VMs which are configured in your security lists; secondly all OEL images in OCI have IP tables configured by default. The latter configuration means that you ideally want to be amending those rules rather than removing them to get it working.

I have two VMs; one on a public subnet 172.10.1.0/24 and one on a private subnet 172.10.2.0/24. I have enabled all outbound traffic on both and enabled inbound traffic on the public VM from the private VM, i.e. to use the public VM as a NAT gateway.

The test I’m going to use for the NAT is being able to ping oracle.com. There are lots of other tests you could do but I want to get this quickly written and out into the blogsphere so people can then use this as a basis for more elaborate configurations.


Firstly let’s look at the IPTABLES configuration of my public VM.

[root@pb-pub-vm1 log]# service iptables status
Table: filter

Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)

num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)

num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 BareMetalInstanceServices all -- 0.0.0.0/0 169.254.0.0/16

Chain BareMetalInstanceServices (1 references)


The first thing I do is enable NAT using the iptables command as follows:

[root@pb-pub-vm1 log]# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
[root@pb-pub-vm1 log]# service iptables status
Table: nat
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination

Chain INPUT (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
1 MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0

[root@pb-pub-vm1 log]# service iptables status
Table: filter

Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)

num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)

num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 BareMetalInstanceServices all -- 0.0.0.0/0 169.254.0.0/16

Chain BareMetalInstanceServices (1 references)


Now if I try and PING oracle.com what happens???

[opc@pb-pri-vm1 ~]$ ping oracle.com
PING oracle.com (137.254.120.50) 56(84) bytes of data.

--- oracle.com ping statistics ---
16 packets transmitted, 0 received, 100% packet loss, time 15625ms

Not much. There are different Chains in IP tables which control the flow of traffic for different things. The ones from our output above are INPUT, OUTPUT and FORWARD. As we are using the Linux box as a gateway we need to look more closely at the FORWARD chain.

Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

So the one and only rule with the FORWARD chain is reject ALL. Therefore it doesn’t really matter what happens any use of FORWARDING will get rejected. Now the easy thing to do would be to remove that rule and if we do everything works perfectly. But that’s probably not a good idea. Let’s add a new rule. This IPTABLES command inserts a new rule at position 1 and allows all protocols to be forwarded. Remember rules are evaluated in sequence.

iptables -I FORWARD 1 -p all -j ACCEPT
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

[opc@pb-pri-vm1 ~]$ ping oracle.com
PING oracle.com (137.254.120.50) 56(84) bytes of data.
64 bytes from vp-ocoma-cms-adc.oracle.com (137.254.120.50): icmp_seq=1 ttl=248 time=50.0 ms
64 bytes from vp-ocoma-cms-adc.oracle.com (137.254.120.50): icmp_seq=2 ttl=248 time=50.0 ms

That’s all well and good but although we haven’t removed the old rule we have pretty much made it redundant with our rule. Let’s remove that rule we just created.

iptables -D FORWARD 1

Instead let’s use a new rule which specifies the source of our specific private VMs subnet (you could use a specific IP alternatively).

iptables -I FORWARD 1 -p all -s 172.10.2.0/24 -j ACCEPT

Now even now I’ve added that in place I still can’t ping oracle.com

[opc@pb-pri-vm1 ~]$ ping oracle.com
PING oracle.com (137.254.120.50) 56(84) bytes of data.
--- oracle.com ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3214ms

There is obviously something wrong; now what we can do is start to enable logging on the IPTABLES and see messages in /var/log/messages to see where the issues lie.

iptables -I FORWARD 1 -j LOG
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 LOG all -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4
2 ACCEPT all -- 172.10.2.0/24 0.0.0.0/0
3 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Now when we ping from our private VM we can see messages in the /var/log/messages file.

localhost kernel: [630378.391477] IN=eth0 OUT=eth0
MAC=00:00:17:01:89:53:00:00:17:1a:8e:c9:08:00 SRC=172.10.2.2 DST=137.254.120.50 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=25761 DF PROTO=ICMP TYPE=8 CODE=0 ID=48436 SEQ=5 localhost kernel: [630378.447970] IN=eth0 OUT=eth0
MAC=00:00:17:01:89:53:00:00:17:1a:8e:c9:08:00 SRC=137.254.120.50 DST=172.10.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=248 ID=13191 DF PROTO=ICMP TYPE=0 CODE=0 ID=48436 SEQ=5

It was interesting and when I was working through this as you enable and disable different rules in the IPTABLES you can see the different messages and how ‘far’ the ping worked. What you can deduce ultimately from these log records is that the IPTABLES is enabling the OUTBOUND traffic to be forwarded but the INBOUND traffic is still being blocked. So I added a new rule.

Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 LOG all -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4
2 ACCEPT all -- 172.10.2.0/24 0.0.0.0/0
3 ACCEPT all -- 0.0.0.0/0 172.10.2.0/24
4 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Hey presto..

[opc@pb-pri-vm1 ~]$ ping oracle.com
PING oracle.com (137.254.120.50) 56(84) bytes of data.
64 bytes from vp-ocoma-cms-adc.oracle.com (137.254.120.50): icmp_seq=1 ttl=248 time=63.4 ms
64 bytes from vp-ocoma-cms-adc.oracle.com (137.254.120.50): icmp_seq=2 ttl=248 time=63.1 ms

Other things to note is you need to enable IP forwarding at the kernel level and don’t forget to remove the log entries.

What’s your cloud strategy?

Now’s the time to start your journey and get your business in the cloud! Learn more about how we can help your business with a FREE cloud readiness assessment today.

Download the data sheet or contact us now to find out more

Subscribe to our mailing list

Sign up to receive all the latest news from Data Intensity

What Our Customers Say