13

I currently have my OUTPUT chain set to DROP. I'd like to change it to REJECT, so that I have a clue that it's my firewall stopping me from getting somewhere rather than a problem with whatever service I'm attempting to access (immediate reject instead of timing out). However, iptables doesn't seem to care for this. If I manually edit my saved rules file and try to restore it, I get iptables-restore v1.4.15: Can't set policy 'REJECT' on 'OUTPUT' line 22: Bad policy name and it refuses to load the rules. If I attempt to set this manually (iptables -P OUTPUT REJECT), I get iptables: Bad policy name. Run 'dmesg' for more information. but there's no output in dmesg.

I've confirmed the appropriate rule is compiled into the kernel and I've rebooted to ensure it's loaded:

# CONFIG_IP_NF_MATCH_TTL is not set
CONFIG_IP_NF_FILTER=y
***
CONFIG_IP_NF_TARGET_REJECT=y
***
CONFIG_IP_NF_TARGET_LOG=y
CONFIG_IP_NF_TARGET_ULOG=y

(Asterisks added to highlight applicable rule)

Everything I can find states that REJECT is a valid policy/target (in general), but I can't find anything that says it's not valid for the INPUT, FORWARD, or OUTPUT chains. My Google-fu isn't helping. I'm on Gentoo, if that makes any difference. Anyone here have any insight?

1
  • Can you show the iptables rule(s) in question?
    – bahamat
    Commented Aug 21, 2012 at 21:37

3 Answers 3

17

REJECT is a target extension, while a chain policy must be a target. The man page says that (although it's not really clear), but some of what it says is flat wrong.

The policy can only be ACCEPT or DROP on built-in chains. If you want the effect of rejecting all the packets that don't match the previous rules, just make sure the last rule matches everything and adds a rule with a REJECT target extension. In other words, after adding all relevant rules, do iptables -t filter -A OUTPUT -j REJECT.

See the "what are the possible chain policies" thread on the netfilter list for more details.

2
  • That makes sense, and a generic REJECT at the end should work. Out of curiosity, is the target extension definition somewhere fairly obvious and I just missed it, or is that one of the poorly documented bits?
    – ND Geek
    Commented Aug 22, 2012 at 3:03
  • 1
    Reading the whole man page, it's clear that REJECT is a target extension, but the man page is very long so "TL;DR" tends to apply. It also implies that DROP, ACCEPT and QUEUE are valid policy targets; from the current code, QUEUE isn't!
    – StarNamer
    Commented Aug 22, 2012 at 13:31
4

I couldn't find it documented, but a reference here indicates that the only allowed policies are ACCEPTor DROP. This is confirmed by looking at the source of libiptc (which is responsible for manipulating the rules) around line 2429, where the code has

2429         if (strcmp(policy, LABEL_ACCEPT) == 0)
2430                 c->verdict = -NF_ACCEPT - 1;
2431         else if (strcmp(policy, LABEL_DROP) == 0)
2432                 c->verdict = -NF_DROP - 1;
2433         else {
2434                 errno = EINVAL;
2435                 return 0;
2436         }

The original thread suggests the best thing to do is add REJECT at the end of the chain which should be iptables -A OUTPUT -j REJECT.

Note that the code just before this is:

2423         if (!iptcc_is_builtin(c)) {
2424                 DEBUGP("cannot set policy of userdefinedchain `%s'\n", chain);
2425                 errno = ENOENT;
2426                 return 0;
2427         }
2428 

So you can't set the policy on a User Defined chain at all.

2
  • That command in the thread is incorrect; -p is for matching on a protocol; he meant -A like my answer says. Commented Aug 21, 2012 at 21:55
  • That's pretty interesting. The curiosity in me wonders if there's a reason behind it, or if that's just how things are, possibly for simplicity's sake (simpler code means fewer possible spots for vulnerabilities after all). If I were even a moderate developer I might be tempted to hack it in locally, but since I'm not, and given it's a piece of security, I'm not gonna touch it.
    – ND Geek
    Commented Aug 22, 2012 at 3:09
2

REJECT on OUTPUT makes no sense; a REJECT will return an ICMP packet which would need to traverse a network.

Add a new -j LOG as your last rule (therefore before the DROP policy) to see what gets that far in the OUTPUT chain.

2
  • 1
    Couldn't the REJECT ICMP packet return on the lo interface? I agree that a LOG is useful for troubleshooting, but what I was really hoping for is a way to remind me that "Oh, yeah...that's probably being blocked by my DROP iptables default" instead of troubleshoots for 5 minutes asks co-worker to access XYZ server realizes it's probably local, which is my most common approach, since my typical workday rarely hits things I haven't opened a hole for already. Of course maybe I need to keep that in mind better, but a flat REJECT is more obvious.
    – ND Geek
    Commented Aug 22, 2012 at 2:55
  • I don't think you would want the ethX interface to generate traffic on the lo interface for many reasons. They are very independent; you can easily make chains apply to one and not the other. Commented Aug 22, 2012 at 9:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .