Firewall - Restrict 443 from a single IP only - How to?


#1

I need to restrict web access (443) to my FreePBX server via a single IP address only. what is the simplest (read recommended) way to do this?

Should I just setup an IPTables rule at CLI or is there another recommended approach?

Thanks


#2

If you are using the Distro, apparently it’s not currently feasible to easily add any reliably persistent custom rules of that granularity in the gooey. But

https://wiki.freepbx.org/display/FPG/Firewall+Custom+Rules


#3

Thanks @dicko
I implemented the rules but no luck

[root@ast ~]# cat /etc/firewall-4.rules
-I INPUT \! --src x.x.x.x -p tcp --dport 443 -j DROP  # if web access NOT from VPN x.x.x.x drop it
[root@ast ~]#

File permissions set

[root@ast etc]# ll firewall-4.rules
-rw-rw-rw- 1 root root 60 Mar 20 06:21 firewall-4.rules

Custom firewall Rules enabled

image

Is there anything I’m missing?


#4

iptables -L

Does not showing the rule implemented


#5

as it says ‘not writable by anyone else’ than root (chmod 0600)


#6

Done.
Disabled & reEnabled Firewall
I’m still able to access 443 (FreePBX GUI) without connecting to VPN.

ll /tmp/fire*
ls: cannot access /tmp/fire*: No such file or directory

#7

ls -l /etc/fire*


#8

I’m logged in as user “root”

I have done chmod 600 /etc/firewall-4.rules multiple times and within a few minutes, it automatically changes back to 666, not sure why or how.

NOTE: the chmod command shown on https://wiki.freepbx.org/display/FPG/Firewall+Custom+Rules is 644 and not 600 while my server seems to love to keep it at 666. Totally clueless :frowning:

ls -l /etc/fire*
-rw-rw-rw- 1 root root   60 Mar 20 07:12 /etc/firewall-4.rules
-rw-rw-rw- 1 root root    0 Jul 29  2020 /etc/firewall-6.rules

/etc/firewalld:
total 28
-rw-r--r-- 1 root root 2006 Oct 30  2018 firewalld.conf
drwxr-x--- 2 root root 4096 Oct 30  2018 helpers
drwxr-x--- 2 root root 4096 Oct 30  2018 icmptypes
drwxr-x--- 2 root root 4096 Oct 30  2018 ipsets
-rw-r--r-- 1 root root  271 Oct 30  2018 lockdown-whitelist.xml
drwxr-x--- 2 root root 4096 Oct 30  2018 services
drwxr-x--- 2 root root 4096 Jul 28  2020 zones

#9
  1. Should my firewall rule start with -A or -I
    I have tried both but not entirely sure of the right switch

  2. After saving the rule in /etc/firewall-4.rules, I disable-enable the custom firewall rules button. Is this required or do I need to do anything to activate the rules?

  3. I believe when I disable/enable the custom firewall rules button, the file permission changes from 600 to 666


#10

A appends, I inserts presumably you need to insertit , but I can’thelp you with the firewall module, I don’t use it


#11

What do you suggest is a good way to implement the rule I need – allow 443 from x.x.x.x IP only and DROP all other source traffic?


#12

I will have to leave that for someone else with knowledge of the module


(Defcomllc) #13

I mean I don’t solely use FreePBX firewall…I have a hardware firewall (Untangle)… I port forward 443 to my internal FreePBX Server LAN static ip…and set source address to the IP I am connecting from…then in FreePBX… I add that same source IP to Firewall and mark as Trusted Zone…AND in Intrusion Detection I white list that same source IP… works great


(Henning Reich) #14

The easiest solution would be a simple clean iptables-rule as you already tried.

This is how it should work:

# become root 
sudo -i
# disable and stop firewall-cmd, not sure if its installed. its basic on centos7....
systemctl disable --now firewalld
# install things
yum install iptables iptables-save
# enable and start things
systemctl enable --now iptables
# add your rule 
iptables -I INPUT \! --src x.x.x.x -p tcp --dport 443 -j DROP  # if web access NOT from VPN x.x.x.x drop it
# show your current settings
iptables-save
# save it
service iptables save
# or overwrite it manually and restart iptables/reboot
# iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

#15

Trouble with that is it would be your only rule, which is probably not a good thing, if ‘inserted’ as a first rule in INPUT after all the other rules are in place and make it stay, would work, but the official way seems o be a problem here


#16

Maybe I’ve missed something.

Why not just use the GUI?
image

Directly editing /etc/firewall-4.rules probably should have worked. Best guess is the comments mucked things up.


(Henning Reich) #17

Its not a configured firewall. Ist just “no-firewall” with one exception (block 443 if ip is not matching), as thats the thread creater wanted.
If he use more rules or a fully configured iptables-firewall, he should re-think the rule order and the rules.
Maybe he can post a bit more about what the “realy” want and what the setup is.


#18

I don’t see anything in the thread implying that is the case.

@vaibhav shows a screenshot with advanced rules enabled, which means the firewall must already be enabled, and @vaibhav also states “Disabled & reEnabled Firewall.”

If the Firewall is enabled, then the advanced rules options should work as advertised. They do here.


#19

Apparently, in his case “They don’t there”

iptables -L

Does not showing the rule implemented


#20

He was only trying editing /etc/firewall-4.rules directly, and then with comments. Don’t fight against the system - use the GUI and remove the comments.

Comments confirmed as an issue, firewall.log excerpt(line without comment works, line with comment fails):

1616377705: Custom rule: /sbin/iptables -I INPUT ! --src 99.98.97.96 -p tcp --dport 443 -j DROP
1616377705: Custom rule: /sbin/iptables -I INPUT ! --src 99.98.97.95 -p tcp --dport 443 -j DROP \# this is a commentw
Bad argument `#'
Try `iptables -h' or 'iptables --help' for more information.

Comments are allowed in the file, but the processing is sophomoric. They must be on a separate line and the “#” must be the first character. Anything else and the entire line is wrapped in an escapeshellcmd() and passed to iptables (hence the “\#” in the above log)…

foreach ($cmds as $id => $cmd) {
        if (empty($cmd) || strpos($cmd, "#") === 0 || strpos($cmd, ";") === 0) {
                $lineno = $id + 1;
                fwLog("Skipping line $lineno in file $f ('$cmd')");
                continue;
        }
        $safecmd = escapeshellcmd($cmd);
        fwLog("Custom rule: $ipt $safecmd");
        exec("$ipt $safecmd");
}