1. Cài đặt firehol
Xem hướng dẫn tại: https://firehol.org/installing/redhat/
Tiến hành download 2 file rpm là firehol-3.1.6-1.el7.noarch.rpm và iprange-1.0.4-1.el7.x86_64.rpm
Cài đặt:
yum --nogpgcheck localinstall iprange-1.0.4-1.el7.x86_64.rpm
yum --nogpgcheck localinstall firehol-3.1.6-1.el7.noarch.rpm

Bạn cũng có thể sử dụng script để cài đặt và upgrade firehol một cách tự động.
2. Cài đặt ulogd để chuyên ghi log cho Firehol
Tải lux-release về và cài đặt:
wget http://repo.iotti.biz/CentOS/7/noarch/lux-release-7-1.noarch.rpm
rpm -Uvh lux-release-7-1.noarch.rpm
hoặc yum install lux-release --enablerepo=epel
yum install ulogd
Trong file firehog.conf khai báo sử dụng mod NFLOG như sau:
FIREHOL_LOG_MOD=”NFLOG”
Trong file cấu hình ulogd, đảm bảo plugin NFLOG được bật và bỏ comment dòng sau:
plugin=”/usr/lib64/ulogd/ulogd_inppkt_NFLOG.so”
# this is a stack for logging packet send by system via LOGEMU
stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
Bật ulogd
systemctl start ulogd
systemctl enable ulogd
Ulogd sẽ log các dropped connection từ Firehol vào file /var/log/ulogd/ulogd_syslogemu.log
3. Cấu hình iprange
Nếu bạn gặp lỗi “WARNING 16@/etc/firehol/firehol.conf: blacklist4:: iprange command is not installed - ipsets will not be optimal.”, hãy thực hiện:
Tìm đường dẫn của iprange
which iprange
/bin/iprange
Thêm đường dẫn này vào /usr/libexec/firehol/3.1.6/install.config
IPRANGE_CMD=”/bin/iprange”
3. Chạy firehol
systemctl start firehol
systemctl enable firehol
4. Sử dụng IPSET firehol_level1 để blacklist các subnet “xấu”.
ipset firehol_level1 do Firehol xây dựng từ các nguồn khác. Bạn tải ipset này về
cd /etc/firehol/ipsets
wget https://iplists.firehol.org/files/firehol_level1.netset
Sau này ta sẽ update ipset này tự động thông qua tool update-ipsets như sau:
update-ipsets enable firehol_level1
update-ipsets
Cấu hình cronjob để tự động update sau mỗi 9 phút.
crontab -e
*/9 * * * * root update-ipsets >/dev/null 2>&1
5. Cấu hình cơ bản Firehol

Chỉ cho phép truy cập từ internet vào các dịch vụ mà zimbra cung cấp. Chỉ cho phép server kết nối ra ngoài internet trên các cổng chỉ định như smpt. Để bảo mật hơn, chặn tất cả các kết nối ra ngoài ngoại trừ các kế nối đến domain liên quan.

vi /etc/firehol/firehol.conf
# Zimbra Firewall
version 5

FIREHOL_LOG_MOD=”NFLOG”
lan=”1.2.3.0/27″
zimbra_service=”http https submission pop3 pop3s imap imaps”

# allow_domain ‘domainname.com another.domain.com’ ‘client http accept dst’
function allow_domain() {
domains=”$1″
firehol_line=”$2″
for domain in ${domains}; do
while read ip; do
if echo “${ip}” | grep -Eq ‘^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}’; then
$firehol_line “$ip”
fi
done < <(dig “${domain}” +short +tries=1 +time=3)
done
}

# Use firehol_level1 blacklist
ipv4 ipset create firehol_level1 hash:net
ipv4 ipset addfile firehol_level1 /etc/firehol/ipsets/firehol_level1.netset
blacklist4 input inface not lo src ipset:firehol_level1 except src “$lan”

# Allow countries
ipv4 ipset create countries hash:net
country_list=”vn us”
ipset_src_dst_options=
for country in $country_list; do
# url=”http://www.ipdeny.com/ipblocks/data/aggregated/${country}-aggregated.zone” #site down?
url=”http://ipverse.net/ipblocks/data/countries/${country}.zone”
country_ips=$(curl -s $url)
if [[ $? != 0 ]]; then
echo “Error downloading country IP list from $url”
server countrylist deny # force firehol to error out
fi
# Make sure that the entry is an IP, or error out
while read ip; do
if [[ “$ip” =~ ^#.* ]]; then
continue
fi
if ! [[ “$ip” =~ ^[0-9].*\/.* ]]; then
echo “Country zone had a line with no network address: $ip”
server countrylist deny # force firehol to error out
else
ipv4 ipset add countries “$ip”
fi
done <<< “$country_ips”
done

# Redirect 8822 to ssh port 22
redirect to 22 inface ens160 proto tcp dport 8822

interface ens160 internet
# Incoming:
server ssh accept
server ping accept
server “smtp smtps” accept
server “$zimbra_service” accept src ipset:countries
server custom ZimbraAdminport tcp/7071 default accept
server all accept src “$lan”

# Outgoing:
client all accept user “root”
client all accept dst “$lan”
client ping accept
client dns accept
client smtp accept
#client “http https” accept
client ntp accept user “chrony”
client custom pyzor “tcp/24441 udp/24441” any accept
client custom razor “tcp/2703 tcp/7” any accept
client custom dcc “udp/6277” any accept

# Zimbra site
allow_domain “license.zimbra.com” ‘client https accept dst’
allow_domain “files.zimbra.com” ‘client https accept dst’
allow_domain “www.zimbra.com” ‘client https accept dst’
allow_domain “zimbra.com” ‘client https accept dst’

# rspamd site
allow_domain “rspamd.com” ‘client https accept dst’
allow_domain “rspamd.com” ‘client http accept dst’
allow_domain “maps.rspamd.com” ‘client https accept dst’
allow_domain “maps.rspamd.com” ‘client http accept dst’
# zextras site
allow_domain “zextras.com” ‘client https accept dst’
allow_domain “updates.zextras.com” ‘client https accept dst’
allow_domain “update.zextras.com” ‘client https accept dst’
allow_domain “download.zextras.com” ‘client https accept dst’

# ClamAV
allow_domain “db.us.clamav.net database.clamav.net” ‘client http accept dst’
allow_domain “db.us.clamav.net database.clamav.net” ‘client https accept dst’

# SpamAssassin
allow_domain “spamassassin.apache.org” ‘client http accept dst’
allow_domain “spamassassin.apache.org” ‘client https accept dst’
allow_domain “yerp.org” ‘client http accept dst’
allow_domain “yerp.org” ‘client https accept dst’
sa_mirror_list=$(dig txt mirrors.updates.spamassassin.org +short +tries=1 +time=3 | tr -d ‘”‘)
sought_mirror_list=$(dig txt mirrors.sought.rules.yerp.org +short +tries=1 +time=3 | tr -d ‘”‘)
while read line; do
if echo $line | grep -vq ‘^#\|^$’; then
sa_mirror=$(echo $line | sed -e ‘s/.*:\/\/\([^\/]*\).*/\1/g’)
allow_domain “$sa_mirror” ‘client http accept dst’
allow_domain “$sa_mirror” ‘client https accept dst’
fi
done < <(curl -s “$sa_mirror_list” “$sought_mirror_list”)

Chạy thử firehol với quyền root
firehol try
Nhấn enter để đồng ý.
Nhập commit trong 30 giây để xác nhận. Nếu không, firehol sẽ sử dụng lại cấu hình cũ.
Sau khi chỉnh sửa nội dung firehol.conf, bạn áp cấu hình mới bằng lệnh:
firehol stop
firehol start
hoặc firehol restart