With ipchains you can ACCEPT, REJECT or DENY a packet. What ACCEPT does is self-explainatory, but nearly everybody asks what the difference between REJECT and DENY is and which one is better. And how does nmap see the ports?
Below is my attempt at explaining the differences. The example transactions were captured with tcpdump.
means that for every packet received an ICMP port unreachable packet is sent to the source address. Of course this tells the remote host that your system is up and running and that you are running a firewall.For the identd service (port 113) read the identd section further down.
Example: Port 23 is set to REJECT:
08:29:33.908826 reddwarf.xix.com.2876 > megahard.xix.com.23: S
611071769:611071769(0) win 32120
<mss 1460,sackOK,timestamp 8136624[|tcp]> (DF) [tos 0x10]
08:29:33.908826 megahard.xix.com > reddwarf.xix.com:
icmp: megahard.xix.com tcp port 23 unreachable [tos 0xd0]
The response to the syn-packet (S) is an ICMP port “unreachable”;.
means the packet is discarded, dropped to the floor, assigned to oblivion. No reply packet of any kind is sent. (In the new iptables for Linux 2.4, this is now called DROP, which is clearer than DENY).If you set a rule which matches a particular source address and a rule-target of DENY, then your computer may as well be turned off as far as that source address is concerned. However, if you DENY some port ranges, say ports below 1024, and allow others, then it is also obvious that you are running a firewall.
For the identd service (port 113) read the identd section further down.
Example: Port 24 is set to DENY:
08:29:36.138037 reddwarf.xix.com.2877 > megahard.xix.com.24: S
621695306:621695306(0) win 32120
<mss 1460,sackOK,timestamp 8136847[|tcp]> (DF) [tos 0x10]
There is no response to the syn-packet (S) and reddwarf keeps trying a few more times.
ACCEPT (or no firewall)
There are two cases here. Either there is a service listening on that port or not.Example: Port 12345 with no service listening:
08:43:11.386320 reddwarf.xix.com.1302 > megahard.xix.com.12345: S
1961263534:1961263534(0) win 32120
<mss 1460,sackOK,timestamp 7858375[|tcp]> (DF) [tos 0x10]
08:43:11.386320 megahard.xix.com.12345 > reddwarf.xix.com.1302: R
0:0(0) ack 1961263535 win 0 [tos 0x10]
The response to the syn-packet (S) is a connection reset (R). This is clearly different from what you get from an ipchains firewall.
Example: Port 22 with sshd listening:
08:41:27.840998 reddwarf.xix.com.2878 > megahard.xix.com.22: S
1377668429:1377668429(0) win 32120
<mss 1460,sackOK,timestamp 8208017[|tcp]> (DF)
08:41:27.840998 megahard.xix.com.22 > reddwarf.xix.com.2878: S
1362603816:1362603816(0) ack 1377668430 win 32120
<mss 1460,sackOK,timestamp 62682656[|tcp]> (DF)
08:41:27.840998 reddwarf.xix.com.2878 > megahard.xix.com.22: .
ack 1 win 32120 <nop,nop,timestamp 8208017 62682656> (DF)
A successfully established TCP connection. The hosts have exchanged and acknowleged their respective syn-packets (S).
How does nmap see these ports?
As before, port 21 is not used (it has nothing listening on it).
Port 22 is open with ssh listening.
Ports 23 and 24 have these ipchains rules:
megahard:# ipchains -I input -i eth0 -p tcp --dport 23 -j REJECT
megahard:# ipchains -I input -i eth0 -p tcp --dport 24 -j DENYreddwarf:# nmap -sT -p 21-24 megahard
Starting nmap V. 2.12 by Fyodor (firstname.lastname@example.org, www.insecure.org/nmap/)
Interesting ports on megahard (192.168.1.1):
Port State Protocol Service
22 open tcp ssh
23 filtered tcp telnet
24 filtered tcp priv-mail
Nmap run completed -- 1 IP address (1 host up) scanned in 1 second
nmap has no trouble recognising both firewalled ports as filtered!
Presumably, it classes the DENYed port as filtered because there was a response from other ports at the same IP address.
Which one is better?
REJECT is appropriate for UDP packets you don’t want to accept, it causes an ICMP port unreachable reply. The correct response to unwanted TCP packets is a reset, unfortunately ipchains is not capable of sending a TCP reset. Sending port unreachable ICMP messages in response to a TCP packet (as REJECT does) is useless and is disregarded by many protocol stacks. A viable option is to use DENY, which sends no reply. Alternatively you can use a package such as return-rst in conjunction with ipchains to produce the correct response.
I believe in making it unpleasant for people who have no business connecting to my system, so those rules use DENY. I have also observed that once I changed most of my ipchains rules from REJECT to DENY, the number of connection attempts has dropped to a fraction of what it used to be.
More recently (December 2000), I have changed back to REJECT for UDP and I use return-rst for TCP. For other protocols I use DENY. Within a few days, the number of firewall hits has increased by at least a factor of two! I’ll keep watching this for a while.
identd / authd:
Some servers will attempt to establish your identity before proceeding with your connection. If you don’t run an identd or authd, a TCP reset is normally returned and everything is fine.If you firewall port 113 with REJECT or DENY, you are likely to experience inconvenient delays. My recommendation is therefore to leave that port open and to make sure you don’t run a server there. Or if you do run an identd, make sure you picked an up-to-date one with a good reputation.
Revealing the existence of a firewall?
I have heard the argument that DENY gives away the presence of a firewall and REJECT does not. The above examples prove this argument to be nonsense. It is possible to make your system look like it has not got a firewall, at least on first inspection. Use REJECT for all UDP, and for TCP, implement a means of sending reset packets, for example with return-rst. Other protocols should be DENYed.