I would like to create my own iptables rules from scratch instead of using the YaST > Firewall custom rules.
If I create my own firewall script with those rules and disable the built-in firewall service of openSUSE - where should I put this script in order the system to run it at proper time during boot? I would like to do it in a clean way so that if I change my mind later I can still go back to the built-in firewall.
P.S. My main idea is to drop all packets and to allow only what I really need. Does that imply any worse security than the default firewall scheme?
Just from looking at my firewall on Leap, the default seems to do this out of the box and looks pretty secure for most users to me. If you do iptables -L -v -n you should see rules like so (pay attention to bolded):
Explanation (No spoiler tags?):
Note how iptables has a default policy for INPUT set to drop, this means that any packet that does not match one of the rules will be dropped. In addition, there is a DROP for all packets at the end of the INPUT chain. Note that the LOG above the DROP in the INPUT chain ensures that all these packets get logged so we can always check if there is some communication made that we did not approve of.
Then the OUTPUT chain is set to ACCEPT all traffic. This is done because the computer will likely need to act as a client various services like HTTP, SSH and so on. The reason its set to accept is to allow use of the high non reserved ports since they are assigned randomly and its not really possible to predict what service will use what port.
Lastly there is input_ext chain which is actually referenced in the INPUT chain. Since its referenced before the LOG and DROP, iptables will check this chain to see if the packet matches any of the rules here. Notice in this chain there are 3 LOG rules which are used to track what type of traffic is being sent to us if it didnt match the rules above (TCP, ICMP or UDP). After the packets are logged they are dropped.
IMO these rules are pretty good, it could be hardened further if you are dedicated but I think you should be able to do that with the SuSE firewall, unless you really really want to write all the rules yourself
#!/bin/bash
ipt=`which iptables`
$ipt -F
$ipt -t nat -F
$ipt -P INPUT DROP
$ipt -P FORWARD DROP
$ipt -A INPUT -i lo -j ACCEPT
$ipt -A INPUT -s 127.0.0.1/8 -i ! lo -j LOG
$ipt -A INPUT -s 127.0.0.1/8 -i ! lo -j DROP
# and then allow only what I really need
I am not sure I want all the logging which SuSEfirewall2 does by default. Why would I fill my journal with that info? I suppose cleaner approach would be: if some program doesn’t work, use tcpdump to see what it needs and add it to the custom script as a rule.
Then the OUTPUT chain is set to ACCEPT all traffic. This is done because the computer will likely need to act as a client various services like HTTP, SSH and so on. The reason its set to accept is to allow use of the high non reserved ports since they are assigned randomly and its not really possible to predict what service will use what port.
I certainly don’t want anything happening randomly. No program should communicate without being explicitly allowed. Imagine this machine used as as a router and there are Windows machines in the LAN. Some of the machines might get infected by something at any time and start sending and receiving info randomly (not that Windows is not a spyware by itself but that’s another story). You get the point.
I also don’t want to forward all ports for all protocols to all the world.
Also - why would I want all the icmp related accepts which SuSEfirewall2 offers by default? I don’t want even to be pinged (except from a few known hosts).
I hope that makes clear why I am looking for a solution with full control over all this.
Ah you didn’t mention you wanted to use this as a router
There is a configuration file for susefirewall located at /etc/sysconfig/SuSEfirewall2 (https://en.opensuse.org/SuSEfirewall2) which may help you out with some of what you want. Perhaps the best way to set it would be with a systemd service for your custom rules? You could just tell it when to start and it should work… but I havent tried this before so maybe someone else can help with that
-rw-r--r-- 1 root root 423 Jun 27 12:44 SuSEfirewall2.service
-rw-r--r-- 1 root root 240 Jun 27 12:44 SuSEfirewall2_init.service
Is it appropriate to use one of them (which one if yes?) as a template and put my own firewall script in the ExecStart? Then I will simply enable my service and disable the SuSEfirewall2 one. Would that be a clean solution?
Without digging into why your script may not work (if you want help with this, start with providing a link to whatever you’re using to guide your efforts),
You should know that SUSE FW is only one iptables management app.
It’s pretty well known that SUSE FW is a fairly simple tool which only supports most common User scenarios.
Searching the OSS,
zypper se firewall
Returns a couple tools “Firewall Builder” and “Firewall Configuration” which might be of interest (I haven’t used either).
Searching the OSS, it looks like there is an alternative to to SUSE FW called xfw.
You may want to try uninstalling SUSE FW and installing ufw
zypper rm SuSEfirewall2 yast2-firewall && zypper in xfw
You can also download iptables firewall config and managers from non-openSUSE sources, just be sure to uninstall SuSEfirewall2 first.
I don’t want to install other firewalls. I can write my own iptables lines. My script will work - it has worked for years on an older router and on a different distro, so the script itself is ok. It is similar to this one but not identical.
I understand that the SuSEfirewall2 service needs to be disabled. I know how to do that in YaST. The only question is how to make my script run on boot, i.e. register it as a service with proper parameters.
Recommend you copy the SUSE FW systemd Unit file as follows. Note that the original location is the standard location for system Unit files which you should <never> alter and the new location is where any custom User Unit files files reside. If a Unit file in the User location is the same name as the original default in /usr/lib/* then the custom Unit file will over-ride.
So, for instance you should look at what the default SuSEfirewall2 scripts currently say. It’s almost certain that they will contain code to both instantiate (or stop) iptables as well as contain configurations.
Since it appears that you’re replacing the existing SuSEfirewall2 scripts completely, you need to make sure you replace all the necessary functionality, which means that if your existing script only modifies you’d need to insert all the other functionality.
I’d recommend you use the existing SuSEfirewall2 scripts as templates for whatever you wish to do, modifying with your existing script.
Of course, this all supposes that your existing script can’t just modify iptables the way SUSE FW sets up which would be a lot less work.
What info would that be? The script is just lines of iptables rules (as shown in a previous post).
The SuSEfirewall2 scripts are too complicated because they need to read info from what one puts in YaST etc. So I am not going to adopt such complexity, it is not necessary. Actually that is exactly what I am trying to avoid - some complicated script aimed at better desktop usability doing the thinking for me (and logging and so on).
Network.service brings network interfaces up. I assume your script needs that. My changes also ensure your firewall script is executed after network.service exits and only if the latter doesn’t fail.
Besides that, “Before=basic.service” should not be necessary.