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 return an ACK/RST which is the same response that an open port with no service on it 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.
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.
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.
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.
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)
Even when the rule says "DROP" the system still replies to an incoming SYN with a TCP RST/ACK - which is the default behavior for ports with no services running. (tcpdump et al doesn't log this.)
If a service is running, the SYN is met with TCP SYN/ACK.
Because the DROP does not respond as per normal with a TCP SYN/ACK, but with a RST/ACK instead, your DROP rule will 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 now 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
As such, the only "invisible" firewalling setup is one where a dedicated device sits between your devices and only selectively forwards ports.
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.
All things considered, you're probably best off just using REJECT - or putting a dedicated port forwarding device between your server and the internet.
Or just running services on your internet-facing machines that do not require firewalling.
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.
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 return an ACK/RST which is the same response that an open port with no service on it 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.
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
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.
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.
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:
-p tcp -j REJECT --reject-with tcp-reset
-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.
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 portDROP
andREJECT
(withouttcp-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)Yes, using DROP is pointless. Use REJECT.
Even when the rule says "DROP" the system still replies to an incoming SYN with a TCP RST/ACK - which is the default behavior for ports with no services running. (tcpdump et al doesn't log this.)
If a service is running, the SYN is met with TCP SYN/ACK.
Because the DROP does not respond as per normal with a TCP SYN/ACK, but with a RST/ACK instead, your DROP rule will 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 now nmap can report "filtered" instead of "closed" for example:
As such, the only "invisible" firewalling setup is one where a dedicated device sits between your devices and only selectively forwards ports.
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.
All things considered, you're probably best off just using REJECT - or putting a dedicated port forwarding device between your server and the internet.
Or just running services on your internet-facing machines that do not require firewalling.
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.