编辑
2024-07-20
记录
0
请注意,本文编写于 508 天前,最后修改于 119 天前,其中某些信息可能已经过时。
bash
apt-get install arp-scan
bash
#!/bin/bash #export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin LOGFILE="port_forwarding.log" NETWORK_INTERFACE="vmbr1" echo "[$(date)] 开始执行端口转发脚本" >> "$LOGFILE" # 获取所有运行中的虚拟机的ID和MAC地址 VM_INFO=$(/usr/sbin/qm list | awk '/running/{print $1, $2}') echo "[$(date)] 获取到的虚拟机信息: $VM_INFO" >> "$LOGFILE" # 获取虚拟机MAC地址的函数 function get_vm_mac { local vm_id=$1 mac=$(/usr/sbin/qm config $vm_id | grep -i "net0" | awk -F ',' '{print $1}' | awk -F '=' '{print $2}') echo $mac } # 获取虚拟机IP地址的函数 function get_vm_ip { local vm_mac=$1 ip=$(sudo arp-scan --interface=$NETWORK_INTERFACE --localnet | grep -i "$vm_mac" | awk '{print $1}') echo $ip } # 设置端口转发函数 function setup_port_forwarding { local host_port=$1 local vm_ip=$2 local vm_port=$3 # 检查是否已存在转发规则 if ! iptables -t nat -L PREROUTING -n | grep -q "$vm_ip:$vm_port"; then iptables -t nat -A PREROUTING -p tcp --dport "$host_port" -j DNAT --to-destination "$vm_ip:$vm_port" iptables -t nat -A POSTROUTING -p tcp -d "$vm_ip" --dport "$vm_port" -j MASQUERADE echo "[$(date)] 添加转发规则:宿主机端口 $host_port -> $vm_ip:$vm_port" >> "$LOGFILE" else echo "[$(date)] 转发规则已存在:宿主机端口 $host_port -> $vm_ip:$vm_port" >> "$LOGFILE" fi } # 配置端口转发规则 while read -r VM_ID VM_NAME; do echo "[$(date)] 处理虚拟机ID: $VM_ID, 名称: $VM_NAME" >> "$LOGFILE" VM_MAC=$(get_vm_mac $VM_ID) echo "[$(date)] 获取到的虚拟机MAC地址: $VM_MAC" >> "$LOGFILE" VM_IP=$(get_vm_ip $VM_MAC) echo "[$(date)] 获取到的虚拟机IP地址: $VM_IP" >> "$LOGFILE" if [[ $VM_IP =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then IP_SUFFIX=$(echo $VM_IP | awk -F '.' '{print $4}') # 设置22端口的转发规则 setup_port_forwarding $((22000 + IP_SUFFIX)) $VM_IP 22 # 设置80端口的转发规则 setup_port_forwarding $((18000 + IP_SUFFIX)) $VM_IP 80 # 设置30-40端口的转发规则 for PORT in {30..40}; do setup_port_forwarding $((PORT * 1000 + IP_SUFFIX)) $VM_IP $((PORT * 1000 + IP_SUFFIX)) done else echo "[$(date)] 无效的IP地址: $VM_IP" >> "$LOGFILE" fi done <<< "$VM_INFO" # 保存iptables规则 /sbin/iptables-save > /etc/iptables/rules.v4 echo "[$(date)] 端口转发规则设置完成。" >> "$LOGFILE"

将上述脚本保存在/home/ip 文件夹,并命名为ip.sh 添加计划任务: nano /etc/crontab

*/5 * * * * root cd /home/ip/ && ./ip.sh >> /home/ip/cron.log 2>&1

启动cron服务:

bash
sudo systemctl start cron sudo systemctl enable cron

检查cron服务状态:

js
sudo systemctl status cron

2024-07-31 更新。适应kvm 和CT

bash
#!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin LOGFILE="port_forwarding.log" NETWORK_INTERFACE="vmbr1" log() { echo "[$(date)] $1" >> "$LOGFILE" } log "开始执行端口转发脚本" # 获取所有运行中的KVM虚拟机的ID和名称 VM_INFO=$(/usr/sbin/qm list | awk '/running/{print $1, $2}') log "获取到的KVM虚拟机信息: $VM_INFO" # 获取所有运行中的LXC容器的ID和名称 CT_INFO=$(/usr/sbin/pct list | awk '/running/{print $1, $2}') log "获取到的容器信息: $CT_INFO" # 获取KVM虚拟机MAC地址的函数 get_vm_mac() { local vm_id=$1 /usr/sbin/qm config "$vm_id" | grep -i "net0:" | awk -F ',' '{print $1}' | awk -F '=' '{print $2}' } # 获取LXC容器MAC地址的函数 get_ct_mac() { local ct_id=$1 /usr/sbin/pct config "$ct_id" | grep -i "net0" | awk -F ',|=' '{for(i=1;i<=NF;i++) if ($i ~ /hwaddr/) print $(i+1)}' } # 获取IP地址的函数 get_ip() { local mac=$1 sudo arp-scan --interface="$NETWORK_INTERFACE" --localnet | grep -i "$mac" | awk '{print $1}' } # 设置端口转发函数 setup_port_forwarding() { local host_port=$1 local ip=$2 local port=$3 # 检查是否已存在转发规则 if ! iptables -t nat -L PREROUTING -n | grep -q "$ip:$port"; then iptables -t nat -A PREROUTING -p tcp --dport "$host_port" -j DNAT --to-destination "$ip:$port" iptables -t nat -A POSTROUTING -p tcp -d "$ip" --dport "$port" -j MASQUERADE log "添加转发规则:宿主机端口 $host_port -> $ip:$port" else log "转发规则已存在:宿主机端口 $host_port -> $ip:$port" fi } # 处理KVM虚拟机 if [ -n "$VM_INFO" ]; then while read -r VM_ID VM_NAME; do log "处理KVM虚拟机ID: $VM_ID, 名称: $VM_NAME" if [ -z "$VM_ID" ]; then log "无法获取KVM虚拟机ID $VM_ID 的MAC地址" continue fi VM_MAC=$(get_vm_mac "$VM_ID") if [ -z "$VM_MAC" ]; then log "无法获取KVM虚拟机ID $VM_ID 的MAC地址" continue fi log "获取到的KVM虚拟机MAC地址: $VM_MAC" VM_IP=$(get_ip "$VM_MAC") if [ -z "$VM_IP" ]; then log "无法获取KVM虚拟机MAC $VM_MAC 的IP地址" continue fi log "获取到的KVM虚拟机IP地址: $VM_IP" if [[ $VM_IP =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then IP_SUFFIX=$(echo "$VM_IP" | awk -F '.' '{print $4}') # 设置22端口的转发规则 setup_port_forwarding $((22000 + IP_SUFFIX)) "$VM_IP" 22 # 设置80端口的转发规则 setup_port_forwarding $((18000 + IP_SUFFIX)) "$VM_IP" 80 # 设置30-40端口的转发规则 for PORT in {30..40}; do setup_port_forwarding $((PORT * 1000 + IP_SUFFIX)) "$VM_IP" $((PORT * 1000 + IP_SUFFIX)) done else log "无效的IP地址: $VM_IP" fi done <<< "$VM_INFO" else log "没有运行中的KVM虚拟机" fi # 处理LXC容器 if [ -n "$CT_INFO" ]; then while read -r CT_ID CT_NAME; do log "处理容器ID: $CT_ID, 名称: $CT_NAME" if [ -z "$CT_ID" ]; then log "无法获取容器ID $CT_ID 的MAC地址" continue fi CT_MAC=$(get_ct_mac "$CT_ID") if [ -z "$CT_MAC" ]; then log "无法获取容器ID $CT_ID 的MAC地址" continue fi log "获取到的容器MAC地址: $CT_MAC" CT_IP=$(get_ip "$CT_MAC") if [ -z "$CT_IP" ]; then log "无法获取容器MAC $CT_MAC 的IP地址" continue fi log "获取到的容器IP地址: $CT_IP" if [[ $CT_IP =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then IP_SUFFIX=$(echo "$CT_IP" | awk -F '.' '{print $4}') # 设置22端口的转发规则 setup_port_forwarding $((22000 + IP_SUFFIX)) "$CT_IP" 22 # 设置80端口的转发规则 setup_port_forwarding $((18000 + IP_SUFFIX)) "$CT_IP" 80 # 设置30-40端口的转发规则 for PORT in {30..40}; do setup_port_forwarding $((PORT * 1000 + IP_SUFFIX)) "$CT_IP" $((PORT * 1000 + IP_SUFFIX)) done else log "无效的IP地址: $CT_IP" fi done <<< "$CT_INFO" else log "没有运行中的LXC容器" fi # 保存iptables规则 /sbin/iptables-save > /etc/iptables/rules.v4 log "端口转发规则设置完成。"
bash
#!/bin/bash set -euo pipefail LOGFILE="clean_port_forwarding.log" log() { echo "[$(date '+%F %T')] $1" | tee -a "$LOGFILE"; } log "开始清理端口转发规则..." is_ip_online() { local ip=$1 ping -c 2 -W 1 "$ip" >/dev/null 2>&1 } delete_rule() { local host_port=$1 ip=$2 port=$3 log "删除转发规则: 宿主机端口 $host_port -> $ip:$port" iptables -t nat -D PREROUTING -p tcp --dport "$host_port" -j DNAT --to-destination "$ip:$port" || log "删除PREROUTING失败" iptables -t nat -D POSTROUTING -p tcp -d "$ip" --dport "$port" -j MASQUERADE || log "删除POSTROUTING失败" } iptables -t nat -S PREROUTING | while read -r line; do if [[ "$line" =~ ^-A\ PREROUTING.*-p\ tcp.*--dport\ ([0-9]+).*--to-destination\ ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):([0-9]+) ]]; then host_port="${BASH_REMATCH[1]}" ip="${BASH_REMATCH[2]}" port="${BASH_REMATCH[3]}" if ! is_ip_online "$ip"; then delete_rule "$host_port" "$ip" "$port" else log "目标IP $ip 在线,保留规则: 宿主机端口 $host_port -> $ip:$port" fi fi done log "端口转发规则清理完成。"

本文作者:cheng

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!