From cf88bb30fde5bc8a8f29d7feaaf317eb3fc3111d Mon Sep 17 00:00:00 2001 From: joe Date: Thu, 22 Jan 2026 11:45:51 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E7=84=A1=E3=81=97=E3=81=A7=E3=83=AA=E3=82=B9=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ipfn1.0 | 148 ++++++++++++++++++++++++-------------------------------- 1 file changed, 62 insertions(+), 86 deletions(-) diff --git a/ipfn1.0 b/ipfn1.0 index feb7c81..1edd03d 100755 --- a/ipfn1.0 +++ b/ipfn1.0 @@ -1,8 +1,8 @@ #!/bin/bash # Name: ipfn -# Version: 1.0.6 +# Version: 1.0.7 # Date: 2026-01-22 -# Description: Supports -dHANDLE / -dfHANDLE (no space) and asterisk highlighting. +# Description: Default to list, auto-test on add, skip test with -f, and port collision warning. # sudo権限チェック if [ "$(id -u)" -ne 0 ]; then @@ -10,9 +10,9 @@ if [ "$(id -u)" -ne 0 ]; then fi TABLE_NAME="ipf_wrapper" -QUIET=false PROTO="tcp" -FORCE_DELETE=false +FORCE_FLAG=false +SKIP_TEST=false # --- 初期化 --- init_nft() { @@ -23,7 +23,7 @@ init_nft() { nft add chain inet ${TABLE_NAME} forward { type filter hook forward priority 0 \; policy accept \; } 2>/dev/null } -# --- ルール表示 (アスタリスク & ハイライト対応) --- +# --- ルール表示 (アスタリスク強調) --- list_rules() { local highlight_uuid=$1 init_nft @@ -37,32 +37,23 @@ list_rules() { target=$(echo "$line" | grep -oE '[0-9.]*:[0-9]+' | head -n 1) lport=$(echo "$line" | grep -o 'dport [0-9]*' | awk '{print $2}') full_uuid=$(echo "$line" | grep -o 'ipf-id:[a-z0-9-]*' | cut -d':' -f2) - short_uuid="${full_uuid:0:8}" - + if [[ -n "$highlight_uuid" && "$full_uuid" == "$highlight_uuid" ]]; then - # 新規ルールは HANDLE の前に * を付け、シアン太字で表示 - printf "\e[1;36m*%-9s %-6s %-20s %-20s %-10s\e[0m\n" "$handle" "$proto" ":$lport" "$target" "$short_uuid" + printf "\e[1;36m*%-9s %-6s %-20s %-20s %-10s\e[0m\n" "$handle" "$proto" ":$lport" "$target" "${full_uuid:0:8}" else - printf "%-10s %-6s %-20s %-20s %-10s\n" "$handle" "$proto" ":$lport" "$target" "$short_uuid" + printf "%-10s %-6s %-20s %-20s %-10s\n" "$handle" "$proto" ":$lport" "$target" "${full_uuid:0:8}" fi done } # --- 疎通確認 --- -test_rule() { - local handle=$1 - init_nft - local rule_line=$(nft -a list chain inet ${TABLE_NAME} prerouting | grep "handle $handle") - if [[ -z "$rule_line" ]]; then - echo "Error: Rule handle $handle not found." - exit 1 - fi - local lp=$(echo "$rule_line" | grep -o 'dport [0-9]*' | awk '{print $2}') - echo "Testing connectivity to local port :$lp..." - if nc -z -v -w 3 127.0.0.1 "$lp" 2>&1; then - echo -e "\e[32mSuccess: Port is responding.\e[0m" +test_rule_by_port() { + local lp=$1 + echo -n "Testing connectivity to :$lp... " + if nc -z -v -w 2 127.0.0.1 "$lp" 2>&1 | grep -E "succeeded|connected|open" >/dev/null; then + echo -e "\e[32mOK\e[0m" else - echo -e "\e[31mFailed: Port is NOT responding.\e[0m" + echo -e "\e[31mFAILED\e[0m" fi } @@ -74,6 +65,11 @@ add_rule() { local target_ip=$(echo "$port_ip_port" | cut -d':' -f2) local target_port=$(echo "$port_ip_port" | cut -d':' -f3) + # 重複チェック (警告のみ) + if nft list chain inet ${TABLE_NAME} prerouting | grep -q "dport $local_port"; then + echo -e "\e[33mWarning: Port :$local_port is already in use by another rule.\e[0m" + fi + local raw_uuid=$(cat /proc/sys/kernel/random/uuid) local uuid="ipf-id:$raw_uuid" local comment="comment \"$uuid\"" @@ -90,6 +86,12 @@ add_rule() { echo "ipfn: Rule added." echo "" list_rules "$raw_uuid" + + # 自動テスト + if [[ "$SKIP_TEST" == false ]]; then + echo "" + test_rule_by_port "$local_port" + fi } # --- ルール削除 --- @@ -97,90 +99,64 @@ delete_rule() { init_nft local handle=$1 local rule_info=$(nft -a list chain inet ${TABLE_NAME} prerouting | grep "handle $handle") - if [[ -z "$rule_info" ]]; then - echo "Error: Rule handle $handle not found." - exit 1 - fi + [[ -z "$rule_info" ]] && { echo "Error: Handle $handle not found."; exit 1; } local uuid=$(echo "$rule_info" | grep -o 'ipf-id:[a-z0-9-]*' | head -n 1) - local lport=$(echo "$rule_info" | grep -o 'dport [0-9]*' | awk '{print $2}') - local target=$(echo "$rule_info" | grep -oE '[0-9.]*:[0-9]+' | head -n 1) + local lp=$(echo "$rule_info" | grep -o 'dport [0-9]*' | awk '{print $2}') + local tg=$(echo "$rule_info" | grep -oE '[0-9.]*:[0-9]+' | head -n 1) - local do_delete=false - if [[ "$FORCE_DELETE" == true ]]; then - do_delete=true - else - echo "About to delete rule group:" - echo " Handle: $handle" - echo " Local: :$lport" - echo " Target: $target" + if [[ "$FORCE_FLAG" == false ]]; then + echo "Delete Handle $handle (:$lp -> $tg)?" echo -n "Are you sure? (y/N): " read -r confirm - [[ "$confirm" =~ ^[yY]$ ]] && do_delete=true + [[ ! "$confirm" =~ ^[yY]$ ]] && { echo "Aborted."; exit 0; } fi - if [[ "$do_delete" == true ]]; then - for chain in prerouting output forward postrouting; do - nft -a list chain inet ${TABLE_NAME} "$chain" | grep "$uuid" | grep -o 'handle [0-9]*' | awk '{print $2}' | while read -r h; do - nft delete rule inet ${TABLE_NAME} "$chain" handle "$h" - done + for chain in prerouting output forward postrouting; do + nft -a list chain inet ${TABLE_NAME} "$chain" | grep "$uuid" | grep -o 'handle [0-9]*' | awk '{print $2}' | while read -r h; do + nft delete rule inet ${TABLE_NAME} "$chain" handle "$h" done - echo "ipfn: Rule group deleted." - echo "" - list_rules - else - echo "Aborted." - fi + done + echo "ipfn: Deleted."; echo ""; list_rules } -# --- メイン処理 --- +# --- メインパース --- +# 先にフラグをスキャン +for arg in "$@"; do + [[ "$arg" == "-f" ]] && FORCE_FLAG=true && SKIP_TEST=true +done + +if [[ $# -eq 0 ]]; then + list_rules + exit 0 +fi + while [[ $# -gt 0 ]]; do case "$1" in -L|-l) list_rules; exit 0 ;; - - # 強制削除 (-df または -df17) - -df*) - FORCE_DELETE=true - handle="${1#-df}" - if [[ -z "$handle" ]]; then handle="$2"; shift; fi - delete_rule "$handle" - exit 0 ;; - - # 通常削除 (-d または -d17) - -d*) - handle="${1#-d}" - if [[ -z "$handle" ]]; then handle="$2"; shift; fi - delete_rule "$handle" - exit 0 ;; - - # テスト (-t または -t17) + -df*|-d*) + [[ "$1" == -df* ]] && FORCE_FLAG=true + h="${1#-df}"; h="${h#-d}" + [[ -z "$h" ]] && { h="$2"; shift; } + delete_rule "$h"; exit 0 ;; -t*) - handle="${1#-t}" - if [[ -z "$handle" ]]; then handle="$2"; shift; fi - test_rule "$handle" - exit 0 ;; - - -p) PROTO="$2"; shift 2 ;; - -q) QUIET=true; shift ;; - -f) - # 削除フラグとして機能させるための先読み - FORCE_DELETE=true + h="${1#-t}" + [[ -z "$h" ]] && { h="$2"; shift; } + # ハンドルからポートを引いてテスト + lp=$(nft -a list chain inet ${TABLE_NAME} prerouting | grep "handle $h" | grep -o 'dport [0-9]*' | awk '{print $2}') + test_rule_by_port "$lp"; exit 0 ;; + -f) # 単体実行時はカーネル設定 if [[ $# -eq 1 ]]; then - sysctl -w net.ipv4.ip_forward=1 - sysctl -w net.ipv4.conf.all.route_localnet=1 + sysctl -w net.ipv4.ip_forward=1 >/dev/null + sysctl -w net.ipv4.conf.all.route_localnet=1 >/dev/null echo "Kernel parameters updated." exit 0 - fi - ;; - -v) nft list table inet ${TABLE_NAME}; exit 0 ;; + fi ;; *) if [[ "$1" =~ ^[0-9]+: ]]; then add_rule "$1" exit 0 - fi - ;; + fi ;; esac shift done - -echo "Usage: ipfn [PORT:IP:PORT | -L | -d(HANDLE) | -df(HANDLE) | -t(HANDLE) | -f]"