多年的 iptables 脚本崩溃(-o 选项不再存在?)

多年的 iptables 脚本崩溃(-o 选项不再存在?)

我有一个脚本,可以通过我的 Wireguard VPN 转发端口。最近,我尝试使用它,结果返回:

Bad argument `wg0'
Try `iptables -h' or 'iptables --help' for more information.

这是我的脚本:

#!/usr/bin/env bash

# Usage: ./wireguard_port_forward.sh <client IP> <server IP> <port> <interface>
# Example: ./wireguard_port_forward.sh 10.0.0.2 10.0.0.1 8080 ens3
# Script must be run as root

CLIENT=$1
SERVER=$2
PORT=$3
INTERFACE=$4

iptables -A FORWARD -i $INTERFACE -o wg0 -p tcp --syn --dport $PORT -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i $INTERFACE -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wg0 -o $INTERFACE -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -i $INTERFACE -p tcp --dport "$PORT" -j DNAT --to-destination "$CLIENT"
iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport "$PORT" -d "$CLIENT" -j SNAT --to-source "$SERVER"
netfilter-persistent save

参数被删除了吗-o?我对 iptables 不太熟悉,也不想因为摆弄太多而弄乱我的防火墙规则。

答案1

您没有为脚本提供足够的参数。因此,$INTERFACE为空,您会收到Bad argument错误。像这样的脚本,尤其是以 root 身份运行时,应该在命令中使用输入之前验证输入并给出错误iptables。例如

#!/usr/bin/env bash

if [ "$#" -lt 4 ]; then
  echo "Usage: sudo $0 <client IP> <server IP> <port> <interface>"
  echo "Example: sudo $0 10.0.0.2 10.0.0.1 8080 ens3"
  exit 1
fi

if ! [ "$(id -u)" = 0 ]; then
  echo "Script must be run as root"
  exit 1
fi

CLIENT="$1"
SERVER="$2"
PORT="$3"
INTERFACE="$4"
WGIF="wg0"

function valid_ip()
{
  local ip="$1"
  local stat=1

  if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
    OIFS="$IFS"
    IFS='.'
    # shellcheck disable=SC2206
    ip=($ip)
    IFS="$OIFS"
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
      && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
      stat="$?"
  fi
  return "$stat"
}

errors=0

if ! valid_ip "$CLIENT" ; then
  echo "Invalid client IP: $CLIENT"
  ((errors=errors+1))
fi

if ! valid_ip "$SERVER" ; then
  echo "Invalid server IP: $SERVER"
  ((errors=errors+1))
fi

if ! [ "$PORT" -le 65535 ]; then
  echo "Invalid TCP port: $PORT"
  ((errors=errors+1))
fi

if ! [ "$PORT" -gt 0 ]; then
  echo "Invalid TCP port: $PORT"
  ((errors=errors+1))
fi

if ! ( ip -o link show | awk -F': ' '{print $2}' \
  | grep "$INTERFACE" > /dev/null ); then
  echo "Interface not found: $INTERFACE"
  ((errors=errors+1))
fi

if [ "$errors" -ge 1 ]; then
  exit 1
fi

set -e

iptables -A FORWARD -i "$INTERFACE" -o "$WGIF" -p tcp --syn \
  --dport "$PORT" -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i "$INTERFACE" -o "$WGIF" -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i "$WGIF" -o "$INTERFACE" -m conntrack \
  --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -i "$INTERFACE" -p tcp \
  --dport "$PORT" -j DNAT --to-destination "$CLIENT"
iptables -t nat -A POSTROUTING -o "$WGIF" -p tcp --dport "$PORT" \
  -d "$CLIENT" -j SNAT --to-source "$SERVER"
netfilter-persistent save

echo "Successfully forwarded port $PORT from $CLIENT" \
  "to $SERVER on interface $INTERFACE."

相关内容