Scenario / Questions

Problem: iptables resets to default settings after server reboot.

I’m trying to set rule like this:

iptables -I INPUT -p tcp --dport 3000 -j ACCEPT

after that I do:

service iptables save

and it writes back something like this

iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

and after this I just ran (this was done once):

chkconfig iptables on (I have read that this has to be done in order to restore settings after reboot)

After that I reboot and run this command:

systemctl list-unit-files | grep iptables

and I see that iptables.service is enabled, however, the rule (to open port 3000) does not work anymore.

How do I persist these settings?

Find below all possible solutions or suggestions for the above questions..

Suggestion: 1

CentOS 7 is using FirewallD now!

Example:

firewall-cmd --zone=public --add-port=3000/tcp --permanent

reload rules:

firewall-cmd --reload

Suggestion: 2

Disable firewalld by the following command:

systemctl disable firewalld

Then install iptables-service by following command:

yum install iptables-services

Then enable iptables as services:

systemctl enable iptables

Now you can save your iptable rules by following command:

service iptables save

Suggestion: 3

On CentOS 7 Minimal you may need to install the iptables-services package (thanks to @RichieACC for the suggestion):

sudo yum install -y iptables-services

And then enable the service using systemd:

sudo systemctl enable iptables.service

And run the initscript to save your firewall rules:

sudo /usr/libexec/iptables/iptables.init save

Suggestion: 4

Maybe a script like this would have been helpful to anyone?

Beware that you will loose anything currently configured because it removes firewalld and flushes any current rules in the INPUT table:

yum remove firewalld && yum install iptables-services

iptables --flush INPUT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT            # Any packages related to an existing connection are OK
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT   # ssh is OK
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT   # Port 3000 for IPv4 is OK
iptables -A INPUT -j REJECT # any other traffic is not welcome - this should be the last line
service iptables save       # Save IPv4 IPTABLES rules van memory naar disk
systemctl enable iptables   # To make sure the IPv4 rules are reloaded at system startup

I guess you want the same in case your system might be reached (now or anytime later) by IPv6 traffic:

ip6tables --flush INPUT
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT            # Any packages related to an existing connection are OK
ip6tables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT   # ssh is OK
ip6tables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT   # Port 3000 for IPv6 is OK
ip6tables -A INPUT -j REJECT # any other traffic is not welcome - this should be the last line
service ip6tables save       # Save IPv6 IPTABLES rules van memory naar disk
systemctl enable ip6tables   # To make sure the IPv6 rules are reloaded at system startup

Suggestion: 5

You can modify directly the /etc/sysconfig/iptables file.
Reload the iptables service to reload the rules from that file.
Yet, as you were told already, firewalld is the new default firewall system for Centos, and this is a good chance to learn how to use it, don’t you think?

Suggestion: 6
iptables-save

will save the current configuration without the need to install any other libraries or services.