IPFW nice or ugly?

nice or ugly?

  • nice

  • ugly

  • undecided


Results are only viewable after voting.
ipfw.png
 
I'd go with undecided.
For me personally, the part above Flows is too busy with left and right and dropdowns.

But that's the problem with "GUI"-anything. can't please everyone.

If it produces a correct and working ruleset, that's the only thing that matters.
 
I'd go with undecided too. I can only tell how effective an interface is if I'm trying to figure out why something doesn't work. If I have to click on a lot of stuff to get the information I need then it's not a good interface.
 
Thank You all, so far! :)
If it produces a correct and working ruleset, that's the only thing that matters.
Yes, that was the beginning of it. Usually people start ipfw by writing a few rules for what should be allowed or denied. That may then work for a while, but it quite certainly fails when you want to use
  1. jails
  2. NAT
  3. stateful rules
together. This was occasionally asked here and elsewhere, because at that point the example configs in the distribution are no longer helpful either. But I have not seen solid recommendations of good practices to generally handle such cases. (The conclusion rather seems that ipfw is too complicated and you should use pf instead - for whatever it hurts.)

So at first I came up with my own dirty hack to solve the issue. And when that became unmanageable after some time, I started to think about a general solution that could be put into an algorithm.
And so I wrote that algorithm, and it works, and produces reliable results as far as I can see. At that stage the configuration data was put into some simple html, without layout or styling - because I had the same opinion: I just need the working rulesets; the design is of no regard.

Now, finally I put some attempt into making the look a bit more inspiring - but UI design appears to be a neverending story in itself. eternal_noob: vision impaired, thank you, yes, this could also be considered in an UI. Ah, and BTW, nobody yet mentioned the need to support&translate at least to Spanish, French, Russian, Burmese and Japanese... :cool:

It is very nice. Where can I get it?
Well, I started to write the GUI in order to motivate myself to then re-write the algorithm (because I don't think that is still intellegible, and it gets difficult to maintain).
So, to be honest: this new GUI does not have an algorithm attached yet.
The old algorithm does still run with the (really ugly) just-html inputfields, and that is currently here, and it can create a ruleset. So this one could be used, for now. Getting it is again a slightly different matter: it is a Ruby-on-Rails application (because that appeared to be the most simple and straightforward way of handling the configuration data). So getting it would imply you have a means to run Rails applications. Also, it is maintained in Svn, and while I recently built a means to publish Git repos, I do not yet have such a means for Svn.
So, it is all still a bit work-in-progress...
 
  • Thanks
Reactions: a6h
PMc I want to make clear I was not downplaying or denigrating your effort, in fact I find it fascinating that you've done it. I'm a command line guy from way back, GUIs annoy me (part of why I have issues with Windows), so I've always been more comfortable with drawing on a piece of paper, then using vi to edit a text file. My pictures of data flow also help create test cases.

But: I understand and agree with making something easier for "the average person". It expands market share, and helps a lot of folks actually understand.

So, you've done good stuff here, making it available for comments is also a good thing and can only make it better.
 
PMc I want to make clear I was not downplaying or denigrating your effort, in fact I find it fascinating that you've done it. I'm a command line guy from way back, GUIs annoy me (part of why I have issues with Windows), so I've always been more comfortable with drawing on a piece of paper, then using vi to edit a text file. My pictures of data flow also help create test cases.
Don't worry, no problem. I also have my ideas where I do not want a gui (and have similar issues with windows). But then, if something appears as some hundreds of lines of basic-style spaghetti code, and otoh could as well be displayed as a simple hierarchy of normalized tables, then I prefer the second.
But: I understand and agree with making something easier for "the average person". It expands market share, and helps a lot of folks actually understand.
*smile* Actually I am doing this primarily for *me*. My original vi-edited ruleset was not manageable anymore, and rather risky to reload. These ones now are costructed so that they can be dynamically reloaded without breaking stateful connections - you can reload the rules within a stateful ssh session, even without stdout/stderr redirection, and it normally does not break.

Also, statefulness is done in subroutines, and I wouldn't want to write those manually:
Code:
03615 call 65509 ip from any to any
65509 count tag 65534 tcp from 203.0.113.27 to not 203.0.113.27,192.168.95.0/24 443 setup keep-state :f13rd
65510 return ip from any to any
03625 allow untag 65534 ip from any to any tagged 65534
(The idea here is that normally one must do the same action on a keep-state and on subsequent check-state. I don't want this; I probably want an allow on the keep-state, and then maybe a blacklistd on the check-state, or whatever.)

Currently I'm going to refactor the "History" button. I explained it here (but didn't receive much help). I think I now have a workiing means to grab an arbitrary chunk from a set of normalized tables and then roll it back to an arbitrary historical point in time. It is an interesting operation and it probably has more use-cases than only this one...
 
  • Like
Reactions: mer
Gui's are a nice tool when you have hundreds or thousands of rules.
I can't grep(1) a GUI ;) Yes, some firewall GUIs have a search, but it's just not the same. Things get even worse when everything is abstracted behind "objects" instead of plain IPs or networks. Especially if there's no proper naming convention (or nobody bothers to use it) and you end up with multiple, differently named, objects all referring to the same thing.
 
  • Like
Reactions: mer
I can't grep(1) a GUI ;) Yes, some firewall GUIs have a search, but it's just not the same. Things get even worse when everything is abstracted behind "objects" instead of plain IPs or networks.
I see. That's about as these people who insist in coding raw hex instead of using an assembler - because in the assembler code are these strange abstract symbol names, and you can't just search for the opcodes and hex offsets...
 
That's about as these people who insist in coding raw hex instead of using an assembler - because in the assembler code are these strange abstract symbol names, and you can't just search for the opcodes and hex offsets...
Not really. It's about people not using a consistent naming convention. Especially when you have multiple people administrating the same firewall(s). Then you get "SomeObject", "SomeServer" and "IdontknowwhatImdoing" objects all referring to the same 192.168.12.34 IP address for example. Spread over multiple lines casually thrown in on a massive rules list. And you're tasked to find out why application X or Y isn't working to that server.

With assembler there's only one LDA instruction (with a few different address modes), that translates to the same hex code, every time, all the time. Even if you use a different assembler/dissembler.
 
Not really. It's about people not using a consistent naming convention. Especially when you have multiple people administrating the same firewall(s). Then you get "SomeObject", "SomeServer" and "IdontknowwhatImdoing" objects all referring to the same 192.168.12.34 IP address for example. Spread over multiple lines casually thrown in on a massive rules list. And you're tasked to find out why application X or Y isn't working to that server.
Hm, that's nice, that's an issue. But that's an organizational issue...
Or, maybe, the "IdontknowwhatImdoing" division wouldn't dare to touch it at all if there weren't a gui? ;)
 
Hi folks,

a little update on this:
Currently I'm going to refactor the "History" button. I explained it here (but didn't receive much help). I think I now have a workiing means to grab an arbitrary chunk from a set of normalized tables and then roll it back to an arbitrary historical point in time. It is an interesting operation and it probably has more use-cases than only this one...

The history works now:
restore.jpg


Here is how I am doing it.

And rulesets are produced: this is the one from above:

Code:
/sbin/ipfw add 1055 set 16 reass proto all in
/sbin/ipfw add 1065 set 16 count untag 65534 proto all
/sbin/ipfw add 1075 set 16 skipto 1475 proto all out
/sbin/ipfw add 1085 set 16 skipto 1435 proto all not recv igb0
/sbin/ipfw add 1095 set 16 call 1125 proto all
/sbin/ipfw add 1105 set 16 skipto 1375 untag 65534 proto all tagged 65534
/sbin/ipfw add 1115 set 16 skipto 1145 proto all
/sbin/ipfw add 1125 set 16 check-state :f6r
/sbin/ipfw add 1135 set 16 return proto all
/sbin/ipfw add 1145 set 16 call 65504 proto all setup
/sbin/ipfw add 1155 set 16 skipto 1375 untag 65534 proto all tagged 65534 setup
/sbin/ipfw add 1165 set 16 call 1195 proto all
/sbin/ipfw add 1175 set 16 skipto 1375 untag 65534 proto all tagged 65534
/sbin/ipfw add 1185 set 16 skipto 1215 proto all
/sbin/ipfw add 1195 set 16 check-state :f4r
/sbin/ipfw add 1205 set 16 return proto all
/sbin/ipfw add 1215 set 16 skipto 1375 proto icmp icmptypes 0,3,8,11,12 and not src-ip 198.51.100.237 and not src-ip 203.0.113.27 '{' dst-ip 10.1.0.130 or dst-ip 127.0.0.1 or dst-ip 192.168.95.1 or dst-ip 201.0.113.27 '}'
/sbin/ipfw add 1225 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 1235 set 16 call 1265 proto all
/sbin/ipfw add 1245 set 16 allow untag 65534 proto all tagged 65534
/sbin/ipfw add 1255 set 16 skipto 1285 proto all
/sbin/ipfw add 1265 set 16 check-state :f6
/sbin/ipfw add 1275 set 16 return proto all
/sbin/ipfw add 1285 set 16 call 65524 proto all setup
/sbin/ipfw add 1295 set 16 allow untag 65534 proto all tagged 65534 setup
/sbin/ipfw add 1305 set 16 call 1335 proto all
/sbin/ipfw add 1315 set 16 allow untag 65534 proto all tagged 65534
/sbin/ipfw add 1325 set 16 skipto 1355 proto all
/sbin/ipfw add 1335 set 16 check-state :f4
/sbin/ipfw add 1345 set 16 return proto all
/sbin/ipfw add 1355 set 16 allow proto icmp icmptypes 0,3,8,11,12 and not src-ip 198.51.100.237 and not src-ip 203.0.113.27 '{' dst-ip 10.1.0.130 or dst-ip 127.0.0.1 or dst-ip 192.168.95.1 or dst-ip 201.0.113.27 '}'
/sbin/ipfw add 1365 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 1375 set 16 unreach filter-prohib log proto all dst-ip 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,0.0.0.0/8,169.254.0.0/16,192.0.0.0/24,192.0.2.0/24,198.51.100.0/24,203.0.113.0/24,192.88.99.0/24,198.18.0.0/15,204.152.64.0/23,224.0.0.0/3,255.255.255.255/32
/sbin/ipfw add 1385 set 16 call 10 proto all
/sbin/ipfw add 1395 set 16 divert 8677 proto all
/sbin/ipfw add 1405 set 16 divert natd proto all
/sbin/ipfw add 1415 set 16 unreach filter-prohib log proto all src-ip 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,0.0.0.0/8,169.254.0.0/16,192.0.0.0/24,192.0.2.0/24,198.51.100.0/24,203.0.113.0/24,192.88.99.0/24,198.18.0.0/15,204.152.64.0/23,224.0.0.0/3,255.255.255.255/32
/sbin/ipfw add 1425 set 16 skipto 1235 proto all
/sbin/ipfw add 1435 set 16 skipto 1465 proto all not recv lo0
/sbin/ipfw add 1445 set 16 allow proto all '{' src-ip 10.1.0.130 or src-ip 127.0.0.1 or src-ip 192.168.95.1 or src-ip 201.0.113.27 '}' dst-ip6 ::1
/sbin/ipfw add 1455 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 1465 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 1475 set 16 skipto 1765 proto all not xmit igb0
/sbin/ipfw add 1485 set 16 call 65414 proto all
/sbin/ipfw add 1495 set 16 skipto 1705 untag 65534 proto all tagged 65534
/sbin/ipfw add 1505 set 16 call 1535 proto all
/sbin/ipfw add 1515 set 16 skipto 1705 untag 65534 proto all tagged 65534
/sbin/ipfw add 1525 set 16 skipto 1555 proto all
/sbin/ipfw add 1535 set 16 check-state :f5
/sbin/ipfw add 1545 set 16 return proto all
/sbin/ipfw add 1555 set 16 call 65454 proto all setup
/sbin/ipfw add 1565 set 16 skipto 1705 untag 65534 proto all tagged 65534 setup
/sbin/ipfw add 1575 set 16 skipto 1705 proto icmp icmptypes 0,3,8,11,12 '{' src-ip 10.1.0.130 or src-ip 127.0.0.1 or src-ip 192.168.95.1 or src-ip 201.0.113.27 '}' and not dst-ip 198.51.100.237 and not dst-ip 203.0.113.27
/sbin/ipfw add 1585 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 1595 set 16 call 65434 proto all
/sbin/ipfw add 1605 set 16 allow untag 65534 proto all tagged 65534
/sbin/ipfw add 1615 set 16 call 1645 proto all
/sbin/ipfw add 1625 set 16 allow untag 65534 proto all tagged 65534
/sbin/ipfw add 1635 set 16 skipto 1665 proto all
/sbin/ipfw add 1645 set 16 check-state :f5o
/sbin/ipfw add 1655 set 16 return proto all
/sbin/ipfw add 1665 set 16 call 65474 proto all setup
/sbin/ipfw add 1675 set 16 allow untag 65534 proto all tagged 65534 setup
/sbin/ipfw add 1685 set 16 allow proto icmp icmptypes 0,3,8,11,12 '{' src-ip 10.1.0.130 or src-ip 127.0.0.1 or src-ip 192.168.95.1 or src-ip 201.0.113.27 '}' and not dst-ip 198.51.100.237 and not dst-ip 203.0.113.27
/sbin/ipfw add 1695 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 1705 set 16 unreach filter-prohib log proto all src-ip 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,0.0.0.0/8,169.254.0.0/16,192.0.0.0/24,192.0.2.0/24,198.51.100.0/24,203.0.113.0/24,192.88.99.0/24,198.18.0.0/15,204.152.64.0/23,224.0.0.0/3,255.255.255.255/32
/sbin/ipfw add 1715 set 16 call 10 proto all
/sbin/ipfw add 1725 set 16 divert 8677 proto all
/sbin/ipfw add 1735 set 16 divert natd proto all
/sbin/ipfw add 1745 set 16 unreach filter-prohib log proto all dst-ip 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,0.0.0.0/8,169.254.0.0/16,192.0.0.0/24,192.0.2.0/24,198.51.100.0/24,203.0.113.0/24,192.88.99.0/24,198.18.0.0/15,204.152.64.0/23,224.0.0.0/3,255.255.255.255/32
/sbin/ipfw add 1755 set 16 skipto 1595 proto all
/sbin/ipfw add 1765 set 16 skipto 1795 proto all not xmit lo0
/sbin/ipfw add 1775 set 16 allow proto all '{' src-ip 10.1.0.130 or src-ip 127.0.0.1 or src-ip 192.168.95.1 or src-ip 201.0.113.27 '}' dst-ip6 ::1
/sbin/ipfw add 1785 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 1795 set 16 unreach filter-prohib log proto all
/sbin/ipfw add 65404 set 16 return proto all
/sbin/ipfw add 65414 set 16 count tag 65534 proto udp dst-port domain,ntp src-ip 102.113.0.27 and not dst-ip 198.51.100.237 and not dst-ip 203.0.113.27 keep-state :f6
/sbin/ipfw add 65424 set 16 return proto all
/sbin/ipfw add 65434 set 16 count tag 65534 proto udp dst-port domain,ntp src-ip 102.113.0.27 and not dst-ip 198.51.100.237 and not dst-ip 203.0.113.27 keep-state :f6r
/sbin/ipfw add 65444 set 16 return proto all
/sbin/ipfw add 65454 set 16 count tag 65534 proto tcp dst-port http,https src-ip 102.113.0.27 and not dst-ip 198.51.100.237 and not dst-ip 203.0.113.27 setup keep-state :f4
/sbin/ipfw add 65464 set 16 return proto all setup
/sbin/ipfw add 65474 set 16 count tag 65534 proto tcp dst-port http,https src-ip 102.113.0.27 and not dst-ip 198.51.100.237 and not dst-ip 203.0.113.27 setup keep-state :f4r
/sbin/ipfw add 65484 set 16 return proto all setup
/sbin/ipfw add 65494 set 16 return proto all
/sbin/ipfw add 65504 set 16 count tag 65534 proto tcp dst-port 9,22,9102,9103 and not src-ip 198.51.100.237 and not src-ip 203.0.113.27 dst-ip 102.113.0.27 setup keep-state :f5o
/sbin/ipfw add 65514 set 16 return proto all setup
/sbin/ipfw add 65524 set 16 count tag 65534 proto tcp dst-port 9,22,9102,9103 and not src-ip 198.51.100.237 and not src-ip 203.0.113.27 dst-ip 102.113.0.27 setup keep-state :f5
/sbin/ipfw add 65534 set 16 return proto all setup
/sbin/ipfw add 9 set 16 skipto 1046 proto all
 
Last edited:
  • Thanks
Reactions: a6h
Gui's are a nice tool when you have hundreds or thousands of rules.
For a home setup with less then 100 rules a text file fits.
Yes, but then the FreeBSD builtin configs would in most cases also fit.
When I started, I had a machine with three jails: webserver, appserver and crapserver.
And the webserver had a public IP. So filtering was not only needed from the outbound link, but also from this jail to the rest of the system. And vnet jails didn't exist yet, it did all work on the lo interface. Filtering traffic between (trad.) jail and host is possible - but it is not easy, specifically for stateful rules.
I have seen many msgs where people did struggle when combining jails and NAT and stateful rules (and I have seen almost no correct solutions). There aren't many now anymore, probably because now we can use vnet jails and guests. So maybe this here comes too late; but that is how it started.

And when I make a mistake, I fix it. Once. From then on, the machine should care for it automatically.
The text file approach may work, but then all the things that we write in textfile, as program code, are normally run through a test suite before being used. Because we tend to introduce mistakes. Syntactical ones (most of these are easily discovered) and also logical ones that may not be immediately obvious.
 
Back
Top