Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This is my /etc/sysconfig/iptables:

It has two ports open 80 apache and 22 for ssh.

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

For port 22 ( SSH ) I want to ensure no-one can connect to this port except for a specific ip address.

example ip:

0.0.0.0

Please disregard any oversight/concerns regarding what if my ip changes and I can not SSH to my server any more.

share|improve this question
6  
there isn't an IP like this 0.0.0.0.0 –  Networker Jul 22 '14 at 15:37
    
@Networker, it is an example only so within given examples/answers one can easily understand. –  user78337 Jul 22 '14 at 15:56
    
I'm not against the example, What I was trying to say is there is no ip with 5 fields, you could say: 0.0.0.0 as an example –  Networker Jul 22 '14 at 15:58
    
@Networker, i see thanks. but to be honest it was simply prettier looking than "IP_GOES_HERE" text that was all. –  user78337 Jul 22 '14 at 16:00
    
trying to figure out why there wasn't a clear answer like this one : stackoverflow.com/questions/7423309 ( i edit my iptables file directly i do not play with it via command line ) ALSO... mine is all "A"s not "I"s –  user78337 Jul 22 '14 at 16:24

3 Answers 3

if I get the question in a right way, you want your server to be reachable only from specific IP address on port 22, you can update Iptables for this:

iptables -I INPUT -p tcp -s YourIP --dport 22 -j ACCEPT

In that case, you are opening ssh port only to YourIP, if you need to open DNS for your internal network:

iptables -I INPUT -p udp -s YourIP --dport 53 -j ACCEPT

Once you have them added and opened for those IPs, you need to close the door for the rest of IPs

iptables -I INPUT -p tcp -s 0.0.0.0/0 --dport 22 -j DROP
iptables -I INPUT -p udp -s 0.0.0.0/0 --dport 53 -j DROP

or as joel said you can add one rule:

iptables -I INPUT -p tcp ! -s <permittedIP> -j DROP

or you can just set the default policy on the firewall with

iptables -P INPUT DROP

or you can use -A option: Link

iptables -A INPUT -p tcp --dport 22-s YourIP -j ACCEPT
iptables -A INPUT -p tcp --dport 22-j DROP
share|improve this answer
2  
It's also worth noting that iptables supports inversion with the bang operator in case you want to do a targeted DROP. Example: iptables -I INPUT -p tcp ! -s <permittedIP> -j DROP –  Bratchley Jul 22 '14 at 15:45
1  
Also, unconditional DROP's aren't really needed you can just set the default policy on the firewall with iptables -P INPUT DROP and let it go at that. You probably also want to do them as an append if do them this way otherwise all traffic will get caught by the DROP and never reach your ACCEPT rule. –  Bratchley Jul 22 '14 at 15:48

Though I recommend using SSH keys, I will give you an explanation.

You don't have to use IPtables for what you're trying to achieve, there are multiple ways. This is the IPtables way:

iptables -I INPUT -s [YOUR_HOME_IP] -p tcp -m tcp --dport [SSH_PORT] -j ACCEPT

[YOUR_HOME_IP] = Your home IP (pretty straightforward)

[SSH_PORT] = The port that you run SSH on (by default 22)

iptables -I INPUT -p tcp -m tcp --dport [SSH_PORT] -j REJECT

This makes sure no-one except your IP can log in to SSH.

There's another way, which is by adding something to the sshd_config.

Add the following:

AllowUsers root@[YOUR_HOME_IP]
PermitRootLogin without-password

This allows you to log in to SSH as the root user from your IP without asking for a password.

Please keep in mind that a cronjob with

iptables -X
iptables -F

may be smart so you don't get locked out of your server with SSH (the cronjob will reset IPtables so you will get access again). If you still have access, you can remove the cronjob and set up your IPtables again.

share|improve this answer
    
The cronjob would just remove the firewalling though. Why set iptables up in the first place? Some form of out of band access is the usual method around. knockd is another. –  Matt Jul 22 '14 at 16:18
    
@mtm Yes, when you're locked out the cronjob will reset your IPtables setup so you will be able to access SSH again. The reasons why people use IPtables are different, my opinion is that it is an effective, simple and flexible firewall. –  William D. Edwards Jul 22 '14 at 16:26
    
How does the cronjob know you are locked out? Sorry wasn't questioning your use of iptables, I meant why setup iptables if you are going to run a cronjob that removes them. –  Matt Jul 22 '14 at 16:28
2  
oic. you mean run the flush once at setup time, not regularly scheduled. at does that. –  Matt Jul 22 '14 at 17:24
1  
Whitelisting only your IP and then allowing a root login without a password seems like a terrible idea. –  Alex W May 8 at 4:01

Other answers are using iptables -I in their examples, which often isn't what you should use.

iptables will execute the first rule which matches, so the order of rules is very important. -I is the "insert" command, and should be used with an index parameter to specify where in the list a given rule belongs. -A is the "append" command, which will add the rule to the end of the list.

In some distrobutions (perhaps all) using -I without an index parameter will add the rule to index one, making it the first rule checked. In this scenario if the last command you run is iptables -I INPUT -s tcp 0.0.0.0/0 -j DROP then iptables will drop all traffic, regardless of whether or not you have any ACCEPT rules later in the chain.

Here's a sample of setting up a rule which only allows SSH from a single IP:

Starting without rules:

#> iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Add a new "allow SSH from 1.2.3.4" rule:

#>iptables -A INPUT -p tcp -s 1.2.3.4 --dport 22 -j ACCEPT

Block SSH from all other IPs:

#>iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 22 -j DROP

Now your INPUT chain will look like:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  1.2.3.4              0.0.0.0/0            tcp dpt:22
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22

Later, if you need to whitelist a second IP you can use the -I parameter to place it before the blacklist rule.

#>iptables -I INPUT 2 -p tcp -s 4.3.2.1 --dport 22 -j ACCEPT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  1.2.3.4              0.0.0.0/0            tcp dpt:22
ACCEPT     tcp  --  4.3.2.1              0.0.0.0/0            tcp dpt:22
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22

Notice that using -I INPUT 2 added the new rule as rule number 2 and bumped the DROP rule to number 3.

share|improve this answer

protected by Community Jul 22 '14 at 16:34

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?