このスクリプトのver.2といったところです。

#!/bin/bash

# セット名の定義
SET_NAME="ufw-blocklist"
SAVE_FILE="/etc/ufw/ipsets.save"

# 1. root権限チェック
if [[ $EUID -ne 0 ]]; then
   echo "エラー: このスクリプトは sudo または root 権限で実行してください。"
   exit 1
fi

# 保存用関数 (変更があった場合のみ呼び出し)
confirm_and_save() {
    echo "------------------------------------------"
    read -p "変更をファイルに保存しますか? ($SAVE_FILE) (y/n): " confirm
    if [[ "$confirm" =~ ^[Yy]$ ]]; then
        ipset save "$SET_NAME" -f "$SAVE_FILE"
        echo "保存完了しました。"
    else
        echo "保存をスキップしました。"
    fi
}

# ipsetが存在しない場合に作成
if ! ipset list "$SET_NAME" > /dev/null 2>&1; then
    echo "情報: $SET_NAME が見つからないため新規作成します。"
    ipset create "$SET_NAME" hash:net
fi

while true; do
    echo "=========================================="
    echo " ipset 管理メニュー ($SET_NAME)"
    echo "=========================================="
    echo "1) ネットワーク帯/IP を追加 (例: 192.0.2.0/24 203.0.113.5)"
    echo "2) ネットワーク帯/IP を削除"
    echo "3) 現在のリストを表示 (list)"
    echo "q) 終了"
    echo "------------------------------------------"
    read -p "番号を選択してください: " choice

    case $choice in
        1)
            echo "【追加モード】追加したいNW帯を入力してください(空エンターでメニューに戻る)"
            echo "例: 203.0.113.0/24 198.51.100.0/24"
            changed=false
            while true; do
                read -p "追加対象: " targets
                [ -z "$targets" ] && break
                
                for target in $targets; do
                    if ipset add "$SET_NAME" "$target" 2>/dev/null; then
                        echo "  [成功] $target を追加しました。"
                        changed=true
                    else
                        echo "  [失敗] $target は既にあるか、形式が不正です。"
                    fi
                done
            done
            [ "$changed" = true ] && confirm_and_save
            ;;
        2)
            echo "【削除モード】削除したいNW帯を入力してください(空エンターでメニューに戻る)"
            changed=false
            while true; do
                read -p "削除対象: " targets
                [ -z "$targets" ] && break
                
                for target in $targets; do
                    if ipset del "$SET_NAME" "$target" 2>/dev/null; then
                        echo "  [成功] $target を削除しました。"
                        changed=true
                    else
                        echo "  [失敗] $target が見つからないか、形式が不正です。"
                    fi
                done
            done
            [ "$changed" = true ] && confirm_and_save
            ;;
        3)
            echo "--- 現在の登録内容 ---"
            ipset list "$SET_NAME" | grep -A 100 "Members:"
            ;;
        q)
            echo "終了します。"
            exit 0
            ;;
        *)
            echo "無効な選択です。"
            ;;
    esac
    echo ""
done

試作版との違いは

  1. 連続入力に対応。ASNが持つNWを連続で断つことができます。
  2. 既にブロックされているNW/IPアドレスをチェックする機能を追加。

まだ詰められる感じなのでもう少し続けます。