1

I'm trying to configure Iptables of a server in order to permit SSH incoming connections only from a certain network.

by the way this is the rule chain :

# Drop anything we aren't explicitly allowing. All outbound traffic is okay
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type echo-reply -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
# Accept Pings
-A RH-Firewall-1-INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Log anything on eth0 claiming it's from a local or non-routable network
# If you're using one of these local networks, remove it from the list below
-A INPUT -i eth0 -s 10.0.0.0/8 -j LOG --log-prefix "IP DROP SPOOF A: "
-A INPUT -i eth0 -s 172.16.0.0/12 -j LOG --log-prefix "IP DROP SPOOF B: "
-A INPUT -i eth0 -s 192.168.0.0/16 -j LOG --log-prefix "IP DROP SPOOF C: "
-A INPUT -i eth0 -s 224.0.0.0/4 -j LOG --log-prefix "IP DROP MULTICAST D: "
-A INPUT -i eth0 -s 240.0.0.0/5 -j LOG --log-prefix "IP DROP SPOOF E: "
-A INPUT -i eth0 -d 127.0.0.0/8 -j LOG --log-prefix "IP DROP LOOPBACK: "
# Accept any established connections
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Accept ssh traffic. Restrict this to known ips if possible.
-A INPUT -p tcp -s 88.253.5.38 --dport 22 -j ACCEPT
# Opening port 80 and port 443 in order to allow http and https requests
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
#Log and drop everything else
-A RH-Firewall-1-INPUT -j LOG
-A RH-Firewall-1-INPUT -j DROP
COMMIT

Saving those rules using following commands seems to apply them correctly:

/etc/init.d/iptables restart && service iptables save

# iptables -nvL
Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
25332   17M RH-Firewall-1-INPUT  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 LOG        all  --  eth0   *       10.0.0.0/8           0.0.0.0/0           LOG flags 0 level 4 prefix `IP DROP SPOOF A: ' 
    0     0 LOG        all  --  eth0   *       172.16.0.0/12        0.0.0.0/0           LOG flags 0 level 4 prefix `IP DROP SPOOF B: ' 
    0     0 LOG        all  --  eth0   *       192.168.0.0/16       0.0.0.0/0           LOG flags 0 level 4 prefix `IP DROP SPOOF C: ' 
    0     0 LOG        all  --  eth0   *       224.0.0.0/4          0.0.0.0/0           LOG flags 0 level 4 prefix `IP DROP MULTICAST D: ' 
    0     0 LOG        all  --  eth0   *       240.0.0.0/5          0.0.0.0/0           LOG flags 0 level 4 prefix `IP DROP SPOOF E: ' 
    0     0 LOG        all  --  eth0   *       0.0.0.0/0            127.0.0.0/8         LOG flags 0 level 4 prefix `IP DROP LOOPBACK: ' 
    0     0 ACCEPT     tcp  --  *      *       88.253.5.38          0.0.0.0/0           tcp dpt:22 

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RH-Firewall-1-INPUT  all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 25163 packets, 17M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain RH-Firewall-1-INPUT (2 references)
 pkts bytes target     prot opt in     out     source               destination         
24175   17M ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           icmp type 0 
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           icmp type 3 
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           icmp type 11 
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           icmp type 8 
 1052  121K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
   94  6016 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:443 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:80 
   11   440 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           LOG flags 0 level 4 
   11   440 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0 

The critical part where i'm having difficulties is :

-A INPUT -p tcp -s 88.253.5.38 --dport 22 -j ACCEPT

What i'm trying to achieve is to allow connection only from this LAN where i'm at, for this I have checked from here the external ip of my router(it is statical ip) , and it returned lets say 88.253.5.38

My main doubt is, am I doing the right thing by using the external IP of my router? or should I use the internal ip of my machine, or the range of internal ip addresses?

Or maybee the whole chain have some conflict that don't permit the configuration i'm trying to do?

Thanks for any push, im really stuck

2

Am I doing the right thing by using the external IP of my router? or should I use the internal ip of my machine, or the range of internal ip addresses?

TL;DR: if your server is "across the Internet" from your own machine, you use the router's address in your iptables rules.

Longer answer:

The firewall rules work from the perspective of the device being firewalled. Ideally every device in the world would have its own IP address. But they don't, and we have this ugly hackery called NAT. In the simplistic case this is a device or piece of software that takes a range of IP addresses such as 192.168.1.* and maps them to a single IP address. The 192.168.* addresses are guaranteed to be unroutable, so they can never be found on the real Internet. Each person's network is hidden behind a NAT device, so that each network is presented as a single unique IP address. Therefore many people can use the same range of addresses 192.168.* on their internal networks as no-one else gets to see them directly.

So, back to the question.

If your server is "outside" your NATed network then it will only see the single public address. So that is what must go in the iptables rules.

On the other hand, if your server is connected to your own network without a NAT device between them, then the actual internal addresses must be used.

This is a highly simplified version of the ugly reality of IPv4 Internet addressing, but it should get you started.


Now to answer your specific issue, which is why your iptables rules don't work as expected. Start with the INPUT chain and follow it sequentially. The very first line calls the chain RH-Firewall-1-INPUT. As you follow that through you'll see a pair of rules that ACCEPT traffic on ports 80 and 443. And then there's a DROP rule for everything else. At the end of that chain we return to INPUT and finally reach your ACCEPT for port 22. But all traffic is already being dropped by this point so the rule is irrelevant.

A solution here is to move your ACCEPT rule for port 22 into the RH-Firewall-1-INPUT chain, immediately after the rules for ports 80 and 443, but before the catch-all DROP.

The proper solution, I suspect, is to learn to use firewalld, but I don't know if that was available in CentOS 6.x or whether it first arrived only in CentOS 7.

  • Exactly, sorry I was unclear, the server is located remotely from the (only) Network I 'm trying to allow SSH connection from. Your explaination is very usefull to me, thank you. The problem is that using the external ip of the router over here, and putting it on the rule, seems to not work, since it don't let me connect anymore. There is not Other firewall between us – lese Jun 3 '15 at 8:27
  • There is a way to check, from the server, what IP really tries to ssh connect? It is a centOS 6.5 – lese Jun 3 '15 at 8:30
  • @lese the saved state list you posted in your question looks quite reasonable. You are reloading it each time you make a change, aren't you..? – roaima Jun 3 '15 at 9:38
  • yes, I do reload it, the exact process I execute is : · modify by hand /etc/sysconfig/iptables ·/etc/init.d/iptables restart ·/etc/init.d/iptables save – lese Jun 3 '15 at 9:45
  • I know it seems a strange procedure, but some months ago I researched around, and I tried in many ways, at it looked like it was the only to work when you modify the iptables file by hand (text editor) – lese Jun 3 '15 at 9:47
2

So what your rule is saying is:

  1. Append the INPUT chain
  2. For packets that use TCP and are destined for port 22
  3. That come from this source address
  4. We will accept them.

There are two ways you can do this, and your question seems a little vague (to me at least), so I'll answer all three scenarios:

Scenario 1


You want anyone from a given public IP address to access this box.

Your rule is currently written like that. If I am sitting at my house and my public IP is 88.253.5.38 then I can access your box at work or somewhere else through SSH.*

*Possibly not correct, but we'll ignore that for simplicity. For example, if you have this box behind another firewall then you'll need forwarding.

Scenario 2


You want someone from their office (or internal network) to access this box.

You rule would need to change only slightly. Only the IP would change.

So, I'm on a 10.0.0.0/8 network and my workstation has a static IP of 10.0.0.127 then you'd change your rule to:

-A INPUT -p tcp -s 10.0.0.127 --dport 22 -j ACCEPT

This means that Bob, whose workstation has an IP of 10.0.0.128 will not be able to access this machine through ssh.

Scenario 3


You want anyone from your office to access (or internal network) to access this box.

Your rule would change the most, but still not that much.

Once again, I'm on a 10.0.0.0/8 network and I want anyone who has an IP in the range of 10.0.0.1-10.0.0.254 to access this box. Well, I know that is a /24 network, so:

-A INPUT -p tcp -s 10.0.0.0/24 --dport 22 -j ACCEPT

This means Charlie who has an IP of 10.0.0.1.127 can't access this box through SSH.

Hopefully that clears things up for you!

  • Thank you for your reply, and sorry I was unclear, the exact Scenario for me is the 1, I want permit SSH connection for any request coming from the given IP. By your replies it seems my rule chain is correct for what i'm trying to do, but it doesn't work, i get locked out(not really I have an alternative way to connect), and also requests coming from 88.253.5.38 external&statical IP are refused. Is important to remind that between this network and the server, there are not other firewalls in the middle – lese Jun 3 '15 at 9:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.