diff --git a/ipfn1.0 b/ipfn1.0 index f58f9dd..29c2f45 100755 --- a/ipfn1.0 +++ b/ipfn1.0 @@ -1,8 +1,8 @@ #!/bin/bash # Name: ipfn -# Version: 1.0.4 +# Version: 1.0.5 # Date: 2026-01-22 -# Description: Automatic list display after addition with highlighting. +# Description: Added asterisk highlight for new handles and forced delete (-df). # sudo権限チェック if [ "$(id -u)" -ne 0 ]; then @@ -12,16 +12,7 @@ fi TABLE_NAME="ipf_wrapper" QUIET=false PROTO="tcp" - -# --- コンテナ検出 --- -is_container() { - if command -v systemd-detect-virt &> /dev/null; then - if systemd-detect-virt --quiet | grep -qE "container|vm"; then - return 0 - fi - fi - return 1 -} +FORCE_DELETE=false # --- 初期化 --- init_nft() { @@ -32,14 +23,13 @@ init_nft() { nft add chain inet ${TABLE_NAME} forward { type filter hook forward priority 0 \; policy accept \; } 2>/dev/null } -# --- ルール表示 (強調表示対応) --- -# 引数 $1 に UUID を渡すと、その行を強調する +# --- ルール表示 (アスタリスク強調対応) --- list_rules() { local highlight_uuid=$1 init_nft echo "Forwarding Rules (ipfn):" - printf "%-8s %-6s %-20s %-20s %-10s\n" "HANDLE" "PROTO" "LOCAL" "TARGET" "UUID" - echo "---------------------------------------------------------------------------------" + printf "%-10s %-6s %-20s %-20s %-10s\n" "HANDLE" "PROTO" "LOCAL" "TARGET" "UUID" + echo "-----------------------------------------------------------------------------------" nft -a list chain inet ${TABLE_NAME} prerouting | grep "dnat" | while read -r line; do handle=$(echo "$line" | grep -o 'handle [0-9]*' | awk '{print $2}') @@ -49,33 +39,15 @@ list_rules() { 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 - # シアンの太字で表示 - printf "\e[1;36m%-8s %-6s %-20s %-20s %-10s\e[0m\n" "$handle" "$proto" ":$lport" "$target" "$short_uuid" + # 新規ルールは HANDLE の前に * を付け、シアン太字で表示 + printf "\e[1;36m*%-9s %-6s %-20s %-20s %-10s\e[0m\n" "$handle" "$proto" ":$lport" "$target" "$short_uuid" else - printf "%-8s %-6s %-20s %-20s %-10s\n" "$handle" "$proto" ":$lport" "$target" "$short_uuid" + printf "%-10s %-6s %-20s %-20s %-10s\n" "$handle" "$proto" ":$lport" "$target" "$short_uuid" fi done } -# --- 疎通確認 --- -test_rule() { - local handle=$1 - 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 lport=$(echo "$rule_line" | grep -o 'dport [0-9]*' | awk '{print $2}') - echo "Testing connectivity to local port :$lport (via nc -z)..." - if nc -z -v -w 3 127.0.0.1 "$lport" 2>&1; then - echo -e "\e[32mSuccess: Port :$lport is responding.\e[0m" - else - echo -e "\e[31mFailed: Port :$lport is NOT responding.\e[0m" - fi -} - # --- ルール追加 --- add_rule() { init_nft @@ -98,13 +70,13 @@ add_rule() { nft add rule inet ${TABLE_NAME} postrouting $family daddr "$target_ip" "$PROTO" dport "$target_port" masquerade "$comment" if [[ $QUIET == false ]]; then - echo "ipfn: Rule added successfully." + echo "ipfn: Rule added." echo "" - list_rules "$raw_uuid" # 追加したルールのUUIDを渡して強調表示 + list_rules "$raw_uuid" fi } -# --- ルール削除 --- +# --- ルール削除 (強制削除フラグ対応) --- delete_rule() { init_nft local handle=$1 @@ -118,20 +90,26 @@ delete_rule() { 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) - echo "About to delete the following rule group:" - echo " Handle: $handle" - echo " Local: :$lport" - echo " Target: $target" - echo -n "Are you sure? (y/N): " - read -r confirm + 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" + echo -n "Are you sure? (y/N): " + read -r confirm + [[ "$confirm" =~ ^[yY]$ ]] && do_delete=true + fi - if [[ "$confirm" =~ ^[yY]$ ]]; then + 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 done - echo "ipfn: Rule group deleted." + echo "ipfn: Rule handle $handle deleted." echo "" list_rules else @@ -140,28 +118,54 @@ delete_rule() { } # --- メイン処理 --- +# 引数の前処理 (強制削除フラグの検出) +TEMP_ARGS=() +while [[ $# -gt 0 ]]; do + case "$1" in + -df) FORCE_DELETE=true; TEMP_ARGS+=("-d") ;; + -f) # 削除コンテキストでのみ強制フラグとして動作 + FORCE_DELETE=true ;; + *) TEMP_ARGS+=("$1") ;; + esac + shift +done +set -- "${TEMP_ARGS[@]}" + while [[ $# -gt 0 ]]; do case "$1" in -L|-l) list_rules; exit 0 ;; -d) [[ -z "$2" ]] && { echo "Error: Handle required."; exit 1; } delete_rule "$2"; exit 0 ;; - -t) test_rule "$2"; exit 0 ;; + -t) # 疎通確認ロジック (ver 1.0.4と同様) + local handle=$2 + local rule_line=$(nft -a list chain inet ${TABLE_NAME} prerouting | grep "handle $handle") + if [[ -z "$rule_line" ]]; then echo "Error: Handle $handle not found."; exit 1; fi + local lp=$(echo "$rule_line" | grep -o 'dport [0-9]*' | awk '{print $2}') + echo "Testing :$lp..." + nc -z -v -w 3 127.0.0.1 "$lp" 2>&1 | grep -E "succeeded|connected" && echo -e "\e[32mSuccess\e[0m" || echo -e "\e[31mFailed\e[0m" + exit 0 ;; -p) PROTO="$2"; shift 2 ;; -q) QUIET=true; shift ;; - -f) - sysctl -w net.ipv4.ip_forward=1 - sysctl -w net.ipv4.conf.all.route_localnet=1 - sysctl -w net.ipv4.conf.default.route_localnet=1 - echo "Enabled: IP forward and Localnet routing." - exit 0 ;; + -f_sys) # 内部用: 以前の -f (sysctl) は -f_sys またはメインループ外で処理 + 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 ;; -v) nft list table inet ${TABLE_NAME}; exit 0 ;; - -*) echo "Unknown option: $1"; exit 1 ;; *) break ;; esac + shift done +# 初期設定 (-f 単体で実行された場合などの互換性維持) +if [[ "$FORCE_DELETE" == true && $# -eq 0 ]]; then + # -f 単体ならカーネル設定を行う + sysctl -w net.ipv4.ip_forward=1 + sysctl -w net.ipv4.conf.all.route_localnet=1 + exit 0 +fi + if [[ -n "$1" ]]; then add_rule "$1" else - echo "Usage: ipfn [PORT:IP:PORT | -L | -d HANDLE | -t HANDLE]" + echo "Usage: ipfn [PORT:IP:PORT | -L | -d HANDLE | -df HANDLE | -t HANDLE]" fi