0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

f23: ubuntu + 海外アクセス抑止 + 自動更新(2) ufw 更新版

Last updated at Posted at 2025-11-02

.

2025/11/04 以下追記

 [ 03. 海外からの接続ブロック設定 ]
 ・更新エラー時復旧用の iptables バックアップ処理の追加

 [ 06. ルール適用エラーが発生した場合 ]
 ・更新エラー時の説明と復旧方法を追記

2025/11/02 以下訂正

 [ 02. 事前設定 ]

 誤:
 以下を実施し、after.init を実行可能状態にしておきます

 # chmod +x /etc/ufw/after.init
 # chmod +x /etc/ufw/after.init.drop_except_jp

(ファイル (after.init.drop_except_jp) 作成されていない状態で、chmod を行っている)

 正:
 以下を実施し、after.init と after.init.drop_except_jp を 実行可能状態にしておきます

 # chmod +x /etc/ufw/after.init

 # touch /etc/ufw/after.init.drop_except_jp
 # chmod +x /etc/ufw/after.init.drop_except_jp

 新規環境構築時は、after.init.drop_except_jp が存在してないため、
 初回は、事前設定として最初に touch で手動作成するように修正いたしました
 また、after.init.drop_except_jp の chmod は、
 drop_except_jp.sh 内でも実行しますが、そのまま初回時も実行とします
 失礼いたしました


以前の記事
f16: xserver vps + ubuntu + 海外アクセス抑止 + 自動更新
https://qiita.com/cxfgp/items/ff18545adb3c1dc1bec2
の派生メモです

前回は ufw も使用しますが、
基本的には、iptables ダイレクト更新版でしたが、
少しわかりにくい部分があり、
ubuntu (debian系) なので、
シンプルな ufw 制御版に切り替えました

実施することは基本同じです
・ubuntu + ufw にて海外からのアクセス抑止設定を行います
・それらの定期自動更新の設定を行います


[ 00. メニュー ]

01. キッチン
02. 事前設定
03. 海外からの接続ブロック設定
04. ufw 再起動・設定更新
05. 自動更新 設定
06. ルール適用エラーが発生した場合
07. デザート
08. 参考


[ 01. キッチン ]

 ・Xserver VPS / 2GB プラン
  -> Ubuntu 22.04 (64bit)


[ 02. 事前設定 ]

vi などで、/etc/ufw/after.init の start) に以下追記します
/etc/ufw/after.init.drop_except_jp

/etc/ufw/after.init
start)
    # typically required
    /etc/ufw/after.init.drop_except_jp
    ;;

以下を実施し、after.init と after.init.drop_except_jp を 実行可能状態にしておきます

# chmod +x /etc/ufw/after.init

# touch /etc/ufw/after.init.drop_except_jp
# chmod +x /etc/ufw/after.init.drop_except_jp

[ 03. 海外からの接続ブロック設定 ]

以下の実行で、
after.init (正確には after.init.drop_except_jp) に、
許可するポートや IP、例外などのルール設定を書き込みます

正確にいうと、海外(国外)抑止 (ブラックリスト) というよりも、
国内・例外許可 (ホワイトリスト) です

※日付や時間の表示形式は各環境により
違う場合がありますのでご注意ください

drop_except_jp.sh

#!/bin/bash

# set script dir / log / init / cidr
s_dir=$(cd $(dirname $0) && pwd)
logs1=${s_dir}/logs/log-1.log
AFTER_INIT=/etc/ufw/after.init.drop_except_jp

cid1=${s_dir}/cidr.txt.gz
cid2=${s_dir}/cidr.txt
cid2tmp=${cid2}.tmp

#----------------------------------------
# バックアップ ( iptables backup )
#----------------------------------------
iptables-save > /home/userA/iptables-backup.$(date +%F)

#----------------------------------------
# 古い CIDR ファイル削除
#----------------------------------------

for fe2 in "$cid1" "$cid2"; do
    if [ -f "$fe2" ]; then
        rm -rf "$fe2"
        sleep 1s; dates1=$(date +"%Y/%m/%d %T")
        echo "$dates1 : delete OK: $fe2" >> "$logs1"
    else
        sleep 1s; dates1=$(date +"%Y/%m/%d %T")
        echo "$dates1 : delete NG: not found $fe2" >> "$logs1"
    fi
done

#----------------------------------------
# 新しい CIDR ファイル取得
#----------------------------------------

wget -q -N http://nami.jp/ipv4bycc/cidr.txt.gz -O "$cid1"
wget_status=$?
if [ $wget_status -eq 0 ] && [ -f "$cid1" ]; then
    sleep 2s; dates2=$(date +"%Y/%m/%d %T")
    echo "$dates2 : dl: OK: cidr.txt.gz" >> "$logs1"
else
    sleep 2s; dates2=$(date +"%Y/%m/%d %T")
    echo "$dates2 : dl: NG: wget failed ($wget_status)" >> "$logs1"
    exit 1
fi

#----------------------------------------
# cidr.txt.gz を解凍
#----------------------------------------

if gunzip -f -c "$cid1" > "$cid2tmp"; then
    mv "$cid2tmp" "$cid2"
    sleep 2s; dates3=$(date +"%Y/%m/%d %T")
    echo "$dates3 : OK: to gunzip cidr.txt.gz" >> "$logs1"
else
    rm -rf "$cid2tmp"
    sleep 2s; dates3=$(date +"%Y/%m/%d %T")
    echo "$dates3 : NG: failed to gunzip cidr.txt.gz" >> "$logs1"
    exit 1
fi


#----------------------------------------
# after.init にルール適用
#----------------------------------------

if [ -f "$cid2" ]; then

    # after.init ファイル出力(ufw 用)
    {
        echo "#!/bin/sh"
        echo "# drp_excep $(date +"%Y/%m/%d %T")"
        echo ""

        # 許可ポート設定
        echo "ufw allow 80/tcp"
        echo "ufw allow 443/tcp"
        echo ""

        # 例外許可IP設定
        FIXED_IPS=(
            # (例 google 一部)
            "35.190.247.0/24" "35.191.0.0/16" "64.233.160.0/19" "66.102.0.0/20"
        )

        for ip2 in "${FIXED_IPS[@]}"; do
            echo "ufw allow from $ip2"
        done

        # 国内許可IP設定
        sed -n 's/^JP\t//p' "$cid2" | while read address; do
            echo "ufw allow from $address"
        done

    } > "$AFTER_INIT"

    chmod +x "$AFTER_INIT"

    dates4=$(date +"%Y/%m/%d %T")
    echo "$dates4 : OK: ufw after.init file updated" >> "$logs1"

else

    dates4=$(date +"%Y/%m/%d %T")
    echo "$dates4 : NG: not found cidr.txt or not a file" >> "$logs1"
    exit 1

fi


[ 04. ufw 再起動・設定更新 ]

[ 03. 海外からの接続ブロック設定 ] にて
after.init (after.init.drop_except_jp)
に設定したルールを有効にするために、以下を実施します

やっていることは、
ufw の再起動 ( systemctl restart ufw ) だけ です
自動実行を想定しているため、付随で起動状況チェックしてます

( 後述しておりますが、after.init のルール適用に
30分くらいかかるため、プロンプトでの手動実行では
systemctl restart ufw 実行後に処理が返ってこないまま固まります

cron 実行では、およそ、30分後に、以下がログに書き込まれました

2025/10/30 03:46:40 : end ufw re-start

ので、テストを行う場合は、適用ルールを数件に絞るか、
cron で行ったほうがよさそうです )

restart_ufw.sh

#!/bin/sh

# set script dir / log
s_dir=$(cd $(dirname $0) && pwd)
logs2=${s_dir}/logs/log-2.log
logs3=${s_dir}/logs/log-3.log

#----------------------------------------
# ufw 再起動
#----------------------------------------

dates1=`date +"%Y/%m/%d %T"`
echo "$dates1 : str ufw re-start" >> $logs2

systemctl restart ufw

sleep 20s; dates2=`date +"%Y/%m/%d %T"`
echo "$dates2 : end ufw re-start" >> $logs2

#----------------------------------------
# ufw 起動状況確認
#----------------------------------------

# out ufw status to check log
systemctl status ufw -l> $logs3

sleep 2s; dates3=`date +"%Y/%m/%d %T"`

# set date(ymd) for checking ufw status is active or not
dates4=`date +"%Y-%m-%d"`

if grep -q "active (exited)" $logs3; then

   comp4=`grep "Active:" $logs3 | { IFS= read -r lines && trimmed_lines=$(echo "$lines" | awk '{$1=$1};1'); echo "$trimmed_lines"; }`

   echo "$dates3 : $comp4" >> $logs2

   get_date=$(echo "$comp4" | awk '{print $6}')
   # print $6 -> 2025-10-31 (以下 6項目目に記載の日付)
   # Active: active (exited) since Fri 2025-10-31 03:36:16 JST; 9h ago

   if [ "$get_date" = "$dates4" ]; then
     echo "$dates3 : OK: ufw status: active (exited) + $get_date" >> $logs2
   else
     echo "$dates3 : NG: ufw status: active (exited) + date NOT-FOUND: $dates4" >> $logs2
     exit 1
   fi

else

  grep "Active:" $logs3 | { IFS= read -r lines && trimmed_lines=$(echo "$lines" | awk '{$1=$1};1'); echo "$dates3 : NG: NOT-FOUND active: $trimmed_lines"; } >> $logs2
  exit 1

fi


[ 05. 自動更新 設定 ]

実行後、after.init に設定した項目は以下で確認できます

# ufw status

cron の自動設定を行います

cron 例 ( root側 )
月、木 03:00am -> drop_except_jp.sh
月、木 03:30am -> restart_ufw.sh

[ 設定 ]

# crontab -u root -e
00 3 * * 1,4 bash /home/userA/drop_except_jp.sh
30 3 * * 1,4 sh /home/userA/restart_ufw.sh

※ drop_except_jp.sh は、bash に切り替えましたので、
bash /home/userA/drop_except_jp.sh です
※ restart_ufw.sh は、変わらず
sh /home/userA/drop_except_jp.sh です

[ 確認 ]

# crontab -l

( よくいわれます、crontab -r の削除オプションにはご注意ください )

ちなみに、

# systemctl is-enabled ufw

の値が enabled になっている場合、OSリブート後にも、
ufw の起動と、after.init の読み込み
が処理されますのでご注意ください


[ 06. ルール適用エラーが発生した場合 ]

drop_except_jp.sh の実行により、
after.init.drop_except_jp にルールが書き込まれ、

・restart_ufw.sh の実行
・systemctl restart ufw の直接実行
・OS 再起動時 (uwf enabled の場合)

いずれかの実行により、適用ルールが ufw を通して、
iptables に更新されるのですが、
まれに適用時エラーになることがあります

その際、ルールが空で更新された、ないしは、
ポート許可設定が更新されなかった場合は、
web アクセスも、ssh 接続も不可になります

復旧方法の事例が以下となります

A. VPS などの web コンソール上から、
シリアル接続にて、コンソールにログイン

B. drop_except_jp.sh で取得した
iptables backup のバックアップファイル
を用いてリストアを実施

( リストア例 )
cd で、バックアップファイル階層まで移動後、
NG になる以前のファイルを指定し、以下を実行します

# iptables-restore < iptables-backup.2025-10-30

C. リストア実施後、いずれかの実行
・restart_ufw.sh の実行
・systemctl restart ufw の直接実行
・OS 再起動時 (uwf enabled の場合)

これで NG になるまえのルールに戻りますので、
ssh 接続可能になったか等の確認を行います

(後述しますが、環境により、ルール適用に時間がかかりますので、
焦って即確認などをおこなわずに、通常適用完了時同等の完了まで
待ってから接続確認等を行います)


[ 07. デザート ]

今回確認しました CIDR の JP IP 件数
および、ルール適用状況は、以下の通りです

==========================================
2025/09/12 cidr.txt / JP IP -> 3154 件

==========================================
ufw 再起動後のルール適用時間

( ufw restart )
2025/10/30 03:20:01 : str ufw re-start (開始)
2025/10/30 03:46:40 : end ufw re-start (終了)

==========================================

今回の環境では、ざっくり、3000件 30分 (100件/分) でした
(ufw 再起動および、OS 再起動時に、バックグラウンドで30分処理)

環境にもよりますが、
ルールが膨大になることによる処理負荷の増大
および、
ufw ( iptables ) のルール数制限等にはご注意ください


[ 08. 参考にさせていただいた記事 ]

(こちらの記事は iptables 更新版です)


.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?