[go: up one dir, main page]
More Web Proxy on the site http://driver.im/

ファイアウォール構築(firewalld)

最終更新日: 2023.01.13

■概要

Linuxサーバー上にファイアウォールを構築する。
ここでは、Linuxのパケットフィルタリング機能であるfirewalldを使用して、Web等外部に公開するサービス以外のポートへのアクセスをブロックするようにする。

※通常はルーター側にもファイアウォール機能があるため、Linuxサーバー上でファイアウォールを構築後にポートを開放する場合は、ルーター側とLinuxサーバー側の2箇所でポート開放を行う必要があることに注意

【想定するネットワーク環境】




■firewalld設定

(1)firewalld設定
[root@centos ~]# vi firewall.sh ← ファイアウォール設定スクリプト作成
#!/bin/bash

#---------------------------------------#
# 設定開始                              #
#---------------------------------------#

# 内部ネットワークアドレス定義
LOCALNET=192.168.1.0/24

#---------------------------------------#
# 設定終了                              #
#---------------------------------------#

#
# ファイアウォール設定初期化
#
systemctl stop firewalld
rm -f /etc/firewalld/zones/*
rm -f /etc/firewalld/ipsets/*
systemctl start firewalld
firewall-cmd --reload >/dev/null

#
# 内部からのアクセスを許可
#
firewall-cmd --add-rich-rule="rule family="ipv4" source address="10.0.0.0/8" accept" --permanent >/dev/null
firewall-cmd --add-rich-rule="rule family="ipv4" source address="172.16.0.0/12" accept" --permanent >/dev/null
firewall-cmd --add-rich-rule="rule family="ipv4" source address="192.168.0.0/16" accept" --permanent >/dev/null
firewall-cmd --add-rich-rule="rule family="ipv4" source address="${LOCALNET}" accept" --permanent >/dev/null

#
# SYN Cookiesを有効にする
# ※TCP SYN Flood攻撃対策
#
sysctl -w net.ipv4.tcp_syncookies=1 > /dev/null
sed -i '/net.ipv4.tcp_syncookies/d' /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies=1" >> /etc/sysctl.conf

#
# ブロードキャストアドレス宛pingには応答しない
# ※Smurf攻撃対策
#
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 > /dev/null
sed -i '/net.ipv4.icmp_echo_ignore_broadcasts/d' /etc/sysctl.conf
echo "net.ipv4.icmp_echo_ignore_broadcasts=1" >> /etc/sysctl.conf

#
# ICMP Redirectパケットは拒否
#
sed -i '/net.ipv4.conf.*.accept_redirects/d' /etc/sysctl.conf
for dev in `ls /proc/sys/net/ipv4/conf/`
do
    sysctl -w net.ipv4.conf.$dev.accept_redirects=0 > /dev/null
    echo "net.ipv4.conf.$dev.accept_redirects=0" >> /etc/sysctl.conf
done

#
# Source Routedパケットは拒否
#
sed -i '/net.ipv4.conf.*.accept_source_route/d' /etc/sysctl.conf
for dev in `ls /proc/sys/net/ipv4/conf/`
do
    sysctl -w net.ipv4.conf.$dev.accept_source_route=0 > /dev/null
    echo "net.ipv4.conf.$dev.accept_source_route=0" >> /etc/sysctl.conf
done

#
# IPアドレスリスト取得
#
IP_LIST=/tmp/cidr.txt
CHK_IP_LIST=/tmp/IPLIST
if [ ! -f ${IP_LIST} ]; then
    wget -q http://nami.jp/ipv4bycc/cidr.txt.gz
    gunzip -c cidr.txt.gz > ${IP_LIST}
    rm -f cidr.txt.gz
fi
rm -f ${CHK_IP_LIST}


#
# ゾーン(日本国内)作成
#

# domestic(日本国内)ゾーン作成
firewall-cmd --new-zone=domestic --permanent >/dev/null

# domestic(日本国内)IPセット作成
firewall-cmd --new-ipset=domestic --type=hash:net --permanent >/dev/null

# 日本国内のIPアドレスリスト作成
domestic_ipset=`mktemp`
for addr in `cat ${IP_LIST} | grep ^JP | awk '{print $2}'`
do
    echo ${addr} >> ${domestic_ipset}
done

# 日本国内のIPアドレスリストをdomestic(日本国内)IPセットに登録
firewall-cmd --ipset=domestic --add-entries-from-file=${domestic_ipset} --permanent >/dev/null
rm -f ${domestic_ipset}

# domestic(日本国内)IPセットをdomestic(日本国内)ゾーンに登録
firewall-cmd --zone=domestic --add-source=ipset:domestic --permanent >/dev/null

# IPアドレス更新チェック用に退避
grep ^JP ${IP_LIST} >> $CHK_IP_LIST

# 以降,日本国内からのみアクセスを許可したい場合はdomesticゾーンにサービスを追加する

# 全国警察施設への攻撃元上位5カ国(日本・アメリカを除く)からのアクセスを破棄
# 直近1週間の状況 https://www.npa.go.jp/bureau/cyber/koho/observation.html
# 国コード一覧 https://ja.wikipedia.org/wiki/ISO_3166-1#%E7%95%A5%E5%8F%B7%E4%B8%80%E8%A6%A7
DROP_COUNTRY_LIST=(BG HK RO CN GB)

# drop_country(アクセス禁止国)IPセット作成
firewall-cmd --new-ipset=drop_country --type=hash:net --permanent >/dev/null

# アクセス禁止国のIPアドレスリスト作成
drop_ipset=`mktemp`
for country in "${DROP_COUNTRY_LIST[@]}"
do
    for addr in `cat ${IP_LIST} | grep ^${country} | awk '{print $2}'`
    do
        echo ${addr} >> ${drop_ipset}
    done
    grep ^${country} ${IP_LIST} >> ${CHK_IP_LIST}
done

# アクセス禁止国のIPアドレスリストをdrop_country(アクセス禁止国)IPセットに登録
firewall-cmd --ipset=drop_country --add-entries-from-file=${drop_ipset} --permanent >/dev/null
rm -f ${drop_ipset}

# drop_country(アクセス禁止国)IPセットをdropゾーンに登録
firewall-cmd --zone=drop --add-source=ipset:drop_country --permanent >/dev/null

#----------------------------------------------------------#
# 各種サービスを公開する場合の設定(ここから)               #
#----------------------------------------------------------#

# 外部からのSSH(TCP22番ポート)へのアクセスを日本国内からのみ許可
# ※SSHサーバーを公開する場合のみ
firewall-cmd --remove-service=ssh --zone=public --permanent >/dev/null
firewall-cmd --add-service=ssh --zone=domestic --permanent >/dev/null

# 外部からのDNS(TCP/UDP53番ポート)へのアクセスを許可
# ※外部向けDNSサーバーを運用する場合のみ
firewall-cmd --add-service=dns --zone=domestic --permanent >/dev/null
firewall-cmd --add-service=dns --zone=public --permanent >/dev/null

# 外部からのHTTP(TCP80番ポート)へのアクセスを許可
# ※Webサーバーを公開する場合のみ
firewall-cmd --add-service=http --zone=domestic --permanent >/dev/null
firewall-cmd --add-service=http --zone=public --permanent >/dev/null

# 外部からのHTTPS(TCP443番ポート)へのアクセスを許可
# ※Webサーバーを公開する場合のみ
firewall-cmd --add-service=https --zone=domestic --permanent >/dev/null
firewall-cmd --add-service=https --zone=public --permanent >/dev/null

# 外部からのSMTP(TCP25番ポート)へのアクセスを許可
# ※SMTPサーバーを公開する場合のみ
firewall-cmd --add-service=smtp --zone=domestic --permanent >/dev/null
firewall-cmd --add-service=smtp --zone=public --permanent >/dev/null

# 外部からのSUBMISSION(TCP587番ポート)へのアクセスを日本国内からのみ許可
# ※SMTPサーバーを公開する場合のみ
# ※SMTPSサーバー(TCP465番ポート)を公開する場合は不要
firewall-cmd --add-service=smtp-submission --zone=domestic --permanent >/dev/null

# 外部からのSMTPS(TCP465番ポート)へのアクセスを日本国内からのみ許可
# ※SMTPSサーバーを公開する場合のみ 2>&1
firewall-cmd --add-service=smtps --zone=domestic --permanent >/dev/null

# 外部からのPOP3(TCP110番ポート)へのアクセスを日本国内からのみ許可
# ※POP3サーバーを公開する場合のみ
firewall-cmd --add-service=pop3 --zone=domestic --permanent >/dev/null

# 外部からのPOP3S(TCP995番ポート)へのアクセスを日本国内からのみ許可
# ※POP3Sサーバーを公開する場合のみ
firewall-cmd --add-service=pop3s --zone=domestic --permanent >/dev/null

# 外部からのIMAP(TCP143番ポート)へのアクセスを日本国内からのみ許可
# ※IMAPサーバーを公開する場合のみ
firewall-cmd --add-service=imap --zone=domestic --permanent >/dev/null

# 外部からのIMAPS(TCP993番ポート)へのアクセスを日本国内からのみ許可
# ※IMAPSサーバーを公開する場合のみ
firewall-cmd --add-service=imaps --zone=domestic --permanent >/dev/null

# 外部からのL2TP over IPsec(UDP500番ポート、UDP4500番ポート)へのアクセスを日本国内からのみ許可
# ※SoftEther VPN Serverを公開する場合のみ
firewall-cmd --add-service=ipsec --zone=domestic --permanent >/dev/null

# 外部からのUsermin(TCP20000番ポート)へのアクセスを日本国内からのみ許可
# ※Userminサーバーを公開する場合のみ
firewall-cmd --add-port=20000/tcp --zone=domestic --permanent >/dev/null

# 外部からのJpsonic(TCP8080番ポート)へのアクセスを日本国内からのみ許可
# ※Jpsonicを公開する場合のみ
firewall-cmd --add-port=8080/tcp --zone=domestic --permanent >/dev/null

# 外部からのMattermost server Callsプラグイン(UDP8443番ポート)へのアクセスを許可
# ※Mattermost serverを公開する場合のみ
firewall-cmd --add-port=8443/udp --zone=domestic --permanent >/dev/null
firewall-cmd --add-port=8443/udp --zone=public --permanent >/dev/null

#----------------------------------------------------------#
# 各種サービスを公開する場合の設定(ここまで)               #
#----------------------------------------------------------#

# 拒否IPアドレスからのアクセスはログを記録せずに破棄
# ※拒否IPアドレスは/root/deny_ipに1行ごとに記述しておくこと
# (/root/deny_ipがなければなにもしない)
if [ -s /root/deny_ip ]; then
    for ip in `cat /root/deny_ip`
    do
        firewall-cmd --zone=drop --permanent --add-source=${ip} --permanent >/dev/null
    done
fi


# ファイアウォール設定反映
firewall-cmd --reload >/dev/null



(2)IPアドレスリスト更新チェック
IPアドレスリストは頻繁に更新されるので、毎日自動でIPアドレスリストの更新有無をチェックし、更新がある場合はファイアウォール設定スクリプトを再起動するようにする。
[root@centos ~]# vi /etc/cron.daily/iplist_check.sh ← IPアドレスリストチェックスクリプト作成
#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# 新旧IPLIST差分チェック件数(0を指定するとチェックしない)
# ※新旧IPLIST差分がSABUN_CHKで指定した件数を越える場合はfirewall設定スクリプトを実行しない
# ※新旧IPLIST差分チェック理由はhttp://centossrv.com/bbshtml/webpatio/1592.shtmlを参照
SABUN_CHK=100
[ $# -ne 0 ] && SABUN_CHK=${1}

# IPアドレスリスト取得
IP_LIST=/tmp/cidr.txt
CHK_IP_LIST=/tmp/IPLIST
wget -q http://nami.jp/ipv4bycc/cidr.txt.gz
gunzip -c cidr.txt.gz > $IP_LIST
rm -f cidr.txt.gz

# チェック対象IPアドレスリスト最新化
rm -f IPLIST.new
for country in `awk '{print $1}' $CHK_IP_LIST |uniq`
do
    grep ^$country $IP_LIST >> IPLIST.new
done

# チェック対象IPアドレスリスト更新チェック
diff -q $CHK_IP_LIST IPLIST.new > /dev/null 2>&1
if [ $? -ne 0 ]; then
    if [ ${SABUN_CHK} -ne 0 ]; then
        if [ $(diff $CHK_IP_LIST IPLIST.new | egrep -c '<|>') -gt ${SABUN_CHK} ]; then
            (
             diff $CHK_IP_LIST IPLIST.new
             echo
             echo "firewall.sh not executed."
            ) | mail -s 'IPLIST UPDATE' root
            rm -f IPLIST.new
            exit
        fi
    fi
    /bin/mv IPLIST.new $CHK_IP_LIST
    sh /root/firewall.sh > /dev/null
else
    rm -f IPLIST.new
fi

[root@centos ~]# chmod +x /etc/cron.daily/iplist_check.sh ← IPアドレスリストチェックスクリプトに実行権限付加
※CRONより/root/firewall.sh not executed.という内容のメールが届いた場合の対処
なんらかの理由で、http://nami.jp/ipv4bycc/から取得した最新のIPアドレスリストと、前回取得したIPアドレスリストとの差分が100件を超えたため、firewall設定スクリプトを実行しなかったことを示す。
サーバーを長時間停止していた等、前回取得したIPアドレスリストとの差分が100件を超える理由が明確な場合には、「/etc/cron.daily/iplist_check.sh 0」と実行することにより強制的にfirewall設定スクリプトを実行する。


■firewalld起動

[root@centos ~]# bash firewall.sh ← ファイアウォール設定スクリプト実行

[root@centos ~]# systemctl enable firewalld ← firewall自動起動設定


■firewalld確認

[root@centos ~]# firewall-cmd --get-default-zone ← デフォルトゾーン確認
public

[root@centos ~]# firewall-cmd --get-active-zones ← アクティブゾーン確認
domestic
  sources: ipset:domestic
drop
  sources: ipset:drop_country
public
  interfaces: br0 ens3
  
[root@centos ~]# firewall-cmd --list-all --zone=domestic ← domesticゾーン情報確認
domestic (active)
  target: default ← 許可していないアクセスは拒否
  icmp-block-inversion: no
  interfaces:
  sources: ipset:domestic ← IPセット(日本国内)
  services: imap imaps ipsec pop3 pop3s smtp-submission smtps ssh ← サービス
  ports: 20000/tcp 4040/tcp ← ポート
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
日本国内からのみ指定サービス、ポートへのアクセスを許可する

[root@centos ~]# firewall-cmd --list-all --zone=drop ← dropゾーン情報確認
drop (active)
  target: DROP ← アクセスを破棄
  icmp-block-inversion: no
  interfaces:
  sources: ipset:drop_country ← IPセット(アクセス禁止国)
  services:
  ports:
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
アクセス禁止国からのアクセスを破棄する

[root@centos ~]# firewall-cmd --list-all --zone=public ← publicゾーン情報確認
public (active)
  target: default ← 許可していないアクセスは拒否
  icmp-block-inversion: no
  interfaces: br0 ens3
  sources:
  services: cockpit dhcpv6-client dns http https smtp ← サービス
指定サービスへのアクセスを許可する
  ports:
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="10.0.0.0/8" accept
        rule family="ipv4" source address="192.168.0.0/16" accept
        rule family="ipv4" source address="192.168.1.0/24" accept
        rule family="ipv4" source address="172.16.0.0/12" accept
指定ネットワークアドレスからのアクセスを許可する

[root@centos ~]# firewall-cmd --permanent --ipset=domestic --get-entries ← domesticIPセット確認
日本国内のIPアドレス一覧が出力される

[root@centos ~]# firewall-cmd --permanent --ipset=drop_country --get-entries ← drop_countryIPセット確認
指定したアクセス禁止国のIPアドレス一覧が出力される

Shields UP! - Internet Vulnerability Profilingで「Proceed」ボタン(2つあるがどちらでもよい)をクリック⇒「All Service Ports」ボタンをクリックして、外部からのアクセスを許可または拒否応答しているポートのみOPENまたはCLOSEDで、その他のポートはSTEALTHであることを確認


■関連コンテンツ




▲このページのトップへ戻る

プライバシーポリシー
centossrv.com