# How to get natd to start before ipfw?



## tingo (Jan 30, 2012)

Hello,
I am using ipfw + natd for my firewall. For the longest time, there has been one obstacle that I have done a manual workaround for:
When the firewall is booted, the rule for natd isn't working, I get an error message instead. Relevant output (transcribed, as it doesn't get logged anywhere I could find):

```
01000 allow ipv6-icmp from any to any ip6 icmp6types 2,135,136
ipfw: getsockopt(IP_FW_ADD): Invalid argument
01100 deny ip from 10.1.0.0/16 to any via xl0
```
and here is the corresponding ipfw commands from my firewall script:

```
${fwcmd} add pass ipv6-icmp from any to any icmp6types 2,135,136
${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface}
iif="rl0"
inet="10.1.0.0"
imask="255.255.0.0"
iip="10.1.10.1"

# --- rules ---
# no spoofing, please
${fwcmd} add deny all from ${inet}:${imask} to any in via ${oif}
```
From the console output, I can see that natd is started after ipfw is loaded:

```
Firewall rules loaded.
Firewall logging enabled.
Starting natd.
```
The point is that if I manually run my firewall script after the firewall has been booted, everything works.

Is this because natd is started after ipfw, or am I missing something?
I am currently using FreeBSD 8.1-stable:

```
root@kg-omni1# uname -a
FreeBSD kg-omni1.kg4.no 8.1-STABLE FreeBSD 8.1-STABLE #0: Sun Oct 17 12:35:38 CEST 2010
     root@kg-i82.kg4.no:/usr/obj/usr/src/sys/GENERIC  i386
```
but this problem has existed as far back as I can remember. I had to rework my firewall today (new isp), that's the reason why I remembered it.


----------



## phoenix (Jan 30, 2012)

How are you starting IPFW and NATD?  Via /etc/rc.conf?  Via a manual script?  Are you pre-loading the natd kernel module, or relying on IFPW to load it manually?

And, as an aside, why aren't you using the build-in NAT functionality of IPFW, instead of using divert sockets and external NATD?


----------



## tingo (Jan 30, 2012)

Yes, I'm starting ipfw and natd via /etc/rc.conf (sorry for not telling in my first posting). Relevant lines:

```
# --- natd ---
natd_interface="xl0"
natd_flags="-f /etc/natd.conf"
natd_enable="YES"
# --- firewall ---
firewall_enable="YES"
firewall_logging="YES"
firewall_script="/etc/fw/fw.get"
```
No, I'm not pre-loading any modules (nothing in /boot/loader.conf in fact).

Why am I using ipfw + natd instead of the built-in nat functionality of ipfw? Mostly because of old habits; this is what I know of, and what I am comfortable with. I've looked at the description in ipfw(8) of nat and the few examples I could find, to me it seems like the built-in nat is more complex to set up and use.
I might be wrong; I do not "live and breath" firewalls, I'm just dabbling in it when I have to.


----------



## phoenix (Jan 30, 2012)

Ah, yes.  You hit the one "niggle" with using rc.conf to manage IPFW and NATD.  There's a bug in the RC scripts that sometimes loads the modules in the wrong order, which is what you are hitting.

If you edit /etc/rc.d/ipfw and add *natd* to the end of the *REQUIRE* line, you should get the required functionality.


----------



## tingo (Jan 30, 2012)

phoenix said:
			
		

> Ah, yes.  You hit the one "niggle" with using rc.conf to manage IPFW and NATD.  There's a bug in the RC scripts that sometimes loads the modules in the wrong order, which is what you are hitting.
> 
> If you edit /etc/rc.d/ipfw and add *natd* to the end of the *REQUIRE* line, you should get the required functionality.



I just tried that, and rcorder confirms that I did it right:

```
root@kg-omni1# rcorder /etc/rc.d/ipfw /etc/rc.d/natd
/etc/rc.d/natd
rcorder: requirement `ppp' in file `/etc/rc.d/ipfw' has no providers.
/etc/rc.d/ipfw
root@kg-omni1#
```
But - it does not work.


----------



## phoenix (Jan 30, 2012)

Hrm, bizarre.

That's all the tips I've got, since we don't use the rc.d scripts for our firewalls, doing everything via custom scripts that manually start/stop natd processes.  Perhaps take it up on the -ipfw of -stable mailing lsits?


----------



## Khabarik (Jan 31, 2012)

Just fought same problem, it was driving me nuts... Found only two solutions - 
1. Add */etc/rc.d/ipfw restart* to /etc/rc.local
2. Add ipdivert to /etc/rc.d/ipfw required_modules


----------



## tingo (Feb 1, 2012)

This is interesting - thanks!


----------

