125

Is there any reason why I would want to have

iptables -A INPUT -j REJECT

instead of

iptables -A INPUT -j DROP
Mike B
  • 12,354

7 Answers7

121

As a general rule, use REJECT when you want the other end to know the port is unreachable' use DROP for connections to hosts you don't want people to see.

Usually, all rules for connections inside your LAN should use REJECT. For the Internet, with the exception of Ident on certain servers, connections from the Internet are usually DROPPED.

Using DROP makes the connection appear to be to an unoccupied IP address. Scanners may choose not to continue scanning addresses which appear unoccupied. Given that NAT can be used to redirect a connection on the firewall, the existence of a well known service does not necessarily indicate the existence of a server on an address.

Ident should be passed or rejected on any address providing SMTP service. However, use of Ident look-ups by SMTP serves has fallen out of use. There are chat protocols which also rely on a working Ident service.

EDIT: When using DROP rules:

  • UDP packets will be dropped and the behavior will be the same as connecting to an unfirewalled port with no service.
  • TCP packets will be dropped and no response will sent, rather than an ACK/RST response, which an unfirewalled port with no service will respond with. Some routers will respond with and ACK/RST on behalf of servers which are down.

When using REJECT rules an ICMP packet is sent indicating the port is unavailable.

BillThor
  • 28,379
  • 9
    This is not true. Even when the rule says "DROP" the system will still reply to the incoming packet with a TCP SYN/ACK as if it was open. To truly drop a packet, the system needs to reply with a TCP RST/ACK - for which there is no firewall rule.

    As such, the best firewalling setup is one where only selected ports are forwarded.

    Your DROP rule will advertise your firewall and port-scanners will know that you are firewalling something and keep hammering you in the hopes of catching your firewall down.

    – Dagelf Jan 03 '14 at 06:02
  • @Dagelf See my edit. The RST/ACK does not indicate to scanners that you are firewalling anything. While some hackers may continue to probe after this response, that should be based on knowing your services not the firewall response. It definitely dropped the number and length of scans I experience. – BillThor Jan 04 '14 at 13:43
  • 4
    My point is, it is detectable from outside whether you are firewalling something or not because of the mere fact that your TCP stack behaves different when you DROP than to when you don't have a service running in the first place! – Dagelf Feb 25 '14 at 15:49
  • @Dagelf I have seen all three responses in cases where a server was not available. None of the responses necessarily indicate a server is at the address. DROP is the response which is least helpful to a scanner. – BillThor Feb 26 '14 at 01:30
  • 3
    Doesn't alter the fact that there are botnets capitalizing on the difference and monitoring your ports as a consequence. – Dagelf Feb 27 '14 at 14:08
  • 1
    whatever you do, be consistent. if the attacker picks an unused port number and tries to connect, he should get the same response as if he has picked one you are purposefully blocking. giving a different response tells him that there's something there. eg it he can use purtnumber that gives a different response to determine which database server you are using he can tailor SQL injection to that server... – user313114 Feb 15 '17 at 02:32
  • 15
    @Dagelf where are you getting the information that DROP sends a response? That's big news and runs counter to everything I've observed and been told. Do you have a link to the documentation that describes this behaviour? – Score_Under Jan 11 '18 at 10:01
  • 1
    Indeed. I was playing with raw sockets when I discovered this, there was no github and my backups are in a drawer somewhere... I'm afraid you'll have to start at linux/net/core/dev.c and net/netfilter/core.c :-( – Dagelf Mar 13 '18 at 22:17
  • 16
    @Dagelf, you're partially correct, but made quite a mess of things. DROP will NOT reply anything! A closed port will return with RST/ACK, an open port will ACK or SYN/ACK. Now a REJECT rule will default to "reject-with icmp-port-unreachable" (replying with an icmp packet), and is thereby different from a closed port response and a DROPped (timeout) response both. If you don't like that, use a rule like -j REJECT --reject-with tcp-reset.
    Also see http://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject
    – nyov Feb 01 '20 at 19:36
  • @nyov When I tested this on whatever the prevailing Debian kernel version was in 2018, DROP replied with RST/ACK. Do you have any info on when this started happening, and when it stopped again? – Dagelf Feb 06 '20 at 12:51
  • 1
    @Dagelf, hmm sorry, but I'm not aware of such behavior or when it might have occured. I can't say there isn't a case where this might be true; but the only reason that comes to my mind for seeing this, would be another network device/firewall responding on behalf of the host. Or some obscure iptables setup possibly. – nyov Feb 07 '20 at 00:45
  • DROP just silently ignores ("drops") packets, obviously, not replying anything, as if there was nothing to receive and process a packet. It was intended to be like this, it was always like this, and any other behaviour might be only due to some bug in the kernel (and would be considered a major security vulnerability, by the way). @Dagelf's test was presumably wrong or mistakenly interpreted, or he really had a broken kernel, which is, considering the extent of the problem and the importance of this particular code path, very unlikely. – Nikita Kipriyanov Jul 21 '25 at 07:57
35

The difference is that the REJECT target sends a reject response to the source, while the DROP target sends nothing.

This can be useful e.g. for the ident service. If you use REJECT then the clients doesn't need to wait for timeout.

More about this: http://www.linuxtopia.org/Linux_Firewall_iptables/x4550.html

Zizzencs
  • 947
  • 1
    DROP will cause packet to timeout but it cannot hide existence of server. Try nmap -sS targethost sometime. It will be able to tell the difference between true closed and filtered ports based on SYN behavior. – Mikko Rantalainen Dec 14 '21 at 13:30
12

I see lots of conflicting answers here and given this is the first article in Google with the right keywords; here is the correct explanation.
It's simple:

DROP does nothing at all with the packet. It does not get forwarded to a host, it does not get answered. The manpage of IPtables says it drops the packet on the floor, i.e. it does nothing with the packet.

REJECT differs to DROP that it does send a packet back, but the answer is as if a server is located on the IP, but does not have the port in a listening state. IPtables will sent a RST/ACK in case of TCP or with UDP an ICMP destination port unreachable.

  • 5
    +1 from me, but the answers don't really disagree. They all agree, as far as I can see, except for Dagelf - who is wrong. – MadHatter Jan 11 '16 at 12:45
  • 2
    Okay, here's a little trick for you then: do an "nmap localhost". Now pick any port that's not "open"... and add a rule that "does nothing", eg: "iptables -I INPUT -p tcp --dport 888 -j DROP". Now "nmap localhost" again. What do you see? ... – Dagelf Mar 13 '18 at 21:55
  • Host is up, PORT 801/tcp STATE filtered – a55 Dec 27 '20 at 01:47
  • 1
    @Dagelf I tested it and you are 100% correct. Don't mind the others. – WGRM Feb 16 '23 at 15:37
  • 1
    @Dagelf THANK YOU VERY MUCH. Im currently compiling a set of firewall rules with nftables and the rule ip protocol tcp reject with tcp reset gives the result all ports cloed. The scan is finished immediately, also. Have more useful tips? – WGRM Feb 16 '23 at 15:40
  • @WGRM Note that filtered literally means no response within timeout. – woodenadmin Mar 22 '25 at 01:18
  • @marbens You literally don't seem to get the point of this whole discussion. But this answer is for others to read. I don't plan to respond any further. – WGRM Mar 23 '25 at 03:05
  • 1
    @WGRM While I agree that the comment Dagelf's comment is correct, his/her answer disproves itself, unlike what you said in another comment.

    You said in your other comment: "This is the correct answer. Do your homework, follow his example. Its 100% correct."

    It probably would've been more appropriate to reply to that one instead.

    His answer said: "Even when the rule says 'DROP' the system still replies to an incoming SYN with a TCP RST/ACK"

    And then he pointed to nmap which said "filtered", which usually means no-response. You can confirm this with --reason option to nmap.

    – woodenadmin Mar 23 '25 at 18:09
10

Usually, you want to ignore probes from attackers to certain ports, by which I mean you do not want to send back 'connection refused'. 'Connection refused' means: 'there is a server here', and possibly gives away more information, whereas dropping a packet doesn't give away clues about software versions, possible vulnerabilities or even the fact that a server is listening at you IP.

The above is one of the main reasons to use DROP instead of REJECT.

wzzrd
  • 10,639
  • 12
    Without iptables rules, a closed port defaults to REJECT. If you DROP every port it's a fine alternative (your host appears down) but if you DROP only specific ports you're actually giving them more information than REJECT. If someone uses a blanket probe like nmap, specific ports that drop packets will appear as "filtered", which means they know you have a service there that you're hiding. – Raptor007 Aug 18 '16 at 04:52
6

If you're trying to hide your machine's existence entirely, -j DROP is appropriate. For example, you might use this to implement a blacklist.

If you're trying to hide the fact that a port is open, you should mimic the behavior that would occur if the port was not open:

  • TCP: -p tcp -j REJECT --reject-with tcp-reset
  • UDP: -p udp -j REJECT --reject-with icmp-port-unreachable

If a port scanner sees that a few ports are dropping packets while most are rejecting them, it can assume the dropped packets are on ports that are open but hidden.

Raptor007
  • 161
  • What if you open a few ports (i.e. 22, 25, 53, 80, 443) and then DROP everything else? Now whether I have MySQL, PostgreSQL, SQLite, or Cassandra running... the scanner cannot tell, right? – Alexis Wilke Nov 13 '16 at 00:33
  • @AlexisWilke In that case, the only additional information you're giving the port scanner is that you have some sort of firewall in place with a default DROP policy. – Raptor007 Nov 14 '16 at 21:14
2

Despite of lots of correct answers, just my two cents:

Here is a short PoC FW.IDS-DROP-vs-REJECT of me to the subject as regards the rules for ban-system (firewall, IDS, etc).

Shortly:

  • DROP can be used for recidive intruders, if banning all ports (so looks like the server is down on the intruder side)
  • REJECT --reject-with tcp-reset is the best choice for multi-port banning, because it seems to behave as a real closed port
  • if some ports are answering (intruder knows that the host is alive), DROP and REJECT (without tcp-reset) will give the intruder a "signal" that something blocking is there (so that could stimulate him to continue the "attack" in hope to provide required data at some point)
sebres
  • 1,337
-9

Yes, using DROP is pointless. Use REJECT.

A connection is initiated with a SYN packet.

If a service is running, the SYN is met with SYN/ACK.

If a port is unused, or with REJECT, the SYN is met with RST.

If there is a DROP rule, the SYN is ignored, and that stands out.

Truly dropping a packet is no good at hiding services, it just shows that you have something to hide because the DROP does not "blend in" - ie. it does not respond as an unused port would, with RST/ACK; your DROP rule will just advertise your firewall and port-scanners will know that you are firewalling something and might keep hammering you in the hopes of catching your firewall down.

This is how nmap can report "filtered" instead of "closed" for example:

$ nmap localhost

Starting Nmap 6.40 ( http://nmap.org ) at 2018-03-14 00:21 SAST Nmap scan report for localhost (127.0.0.1) Host is up (0.0000060s latency). Not shown: 986 closed ports PORT STATE SERVICE 21/tcp open ftp 53/tcp open domain 80/tcp open http

Nmap done: 1 IP address (1 host up) scanned in 1.60 seconds

$ iptables -I INPUT -p tcp --dport 1111 -j DROP $ nmap localhost

Starting Nmap 6.40 ( http://nmap.org ) at 2018-03-14 00:21 SAST Nmap scan report for localhost (127.0.0.1) Host is up (0.0000060s latency). Not shown: 986 closed ports PORT STATE SERVICE 21/tcp open ftp 53/tcp open domain 80/tcp open http 1111/tcp filtered lmsocialserver

Nmap done: 1 IP address (1 host up) scanned in 1.60 seconds

$ iptables -D INPUT 1

Thus, if you have a dedicated device between your devices and only selectively forwards ports, that device will also respond with RST to all the ports that are not forwarded.

If you really want to mess with the basic scanners, you can TARPIT tcp connections, which sets the TCP Window to 0 so that no data can get transferred after the connection is opened, ignoring requests to close the connection, meaning the scanner has to wait for the connection timeout to occur, if it wants to be sure. But it's trivial for an attacker to detect this and make his timeout very short on their side.

All things considered, you're probably best off just using REJECT.

Nowadays the bigger threat is malware coming in through legitimate ports though, which is why application firewalls that double check the contents of the connection, have become a thing.

Generally REJECT is best for web servers, as whatever service is trying to access it (probably more often than not, you) will quickly get a response and users or other services won't be kept waiting wondering if there's a network outage.

UPDATE: Thank you to everyone trying to correct my stubbornness, you should've pointed out what lead to the behavior I saw, and that I must have swopped DROP and REJECT in my test results, where I mistakenly attributed RST/ACK to DROP instead of REJECT, I wasn't very thorough.

Dagelf
  • 645
  • 3
    @Dagelf Your article does say "DROP (aka DENY, BLACKHOLE) Prohibit a packet from passing. Send no response." – JeanT Jul 24 '15 at 11:32
  • To clarify here: this was not opinion. This was based on packet tracing through an external router. The only missing info here is the kernel versions, and whether the functionality changed at some point, and why. – Dagelf Feb 06 '20 at 12:47
  • 1
    This is the correct answer. Do your homework, follow his example. Its 100% correct. – WGRM Feb 16 '23 at 15:50
  • I've got where @Dagelf is mistaken. It works exactly the opposite way. When you send a packet do a port where there is no service but no firewall, an OS replies with a ICMP port unreach. When there is a firewall that DROPs on that port, OS doesn't send anything, even ICMP, because the packet is dropped by the filter before being analyzed for mapping to a service. By that, nmap could distinguish DROP and "no firewall, but no service" situations. I am not sure about the OS no-service default behavior with ICMP, but DROP's behavior was always like this since iptables inclusion in 2.4 – Nikita Kipriyanov Jul 21 '25 at 08:10
  • This answer is almost correct. By default REJECT does not send back a TCP RST, it sends back an ICMP port unreachable message, which only blends in for UDP ports, not TCP ports (try nmap -sS --reason). You can set it to use TCP RST (for TCP only of course) with --reject-with tcp-reset. – woodenadmin Dec 03 '25 at 20:43