• Proxmox VE 网络配置 NAT共享IP 端口映射iptables、brook


    PVE网络配置官方文档:跳转

    配置桥接网卡,使Proxmox VE(PVE)可以同时创建NAT虚拟机和独立IP虚拟机,同时可以使用脚本映射NAT虚拟机的端口到外网。

    1、开启ipv4、ipv6转发

    vim /etc/sysctl.conf
    
    • 1

    文件最后加入如下配置

    net.ipv4.ip_forward=1
    net.ipv4.conf.all.rp_filter=1
    net.ipv4.icmp_echo_ignore_broadcasts=1
    net.ipv4.conf.default.forwarding=1
    net.ipv4.conf.default.proxy_arp = 0
    net.ipv4.conf.default.send_redirects = 1
    net.ipv4.conf.all.send_redirects = 0
    net.ipv6.conf.eno1.autoconf=0
    net.ipv6.conf.eno1.accept_ra=2
    net.ipv6.conf.default.forwarding=1
    net.ipv6.conf.all.forwarding=1
    net.ipv6.conf.default.proxy_ndp=1
    net.ipv6.conf.all.proxy_ndp=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、 配置Proxmox VE网卡文件信息

    vim /etc/network/interfaces
    
    • 1

    新增一个vmbr172网桥,并设置流量转发

    auto lo
    iface lo inet loopback
    
    iface enp40 inet manual
    
    auto vmbr0
    iface vmbr0 inet static
            address 192.168.0.103/24
            gateway 192.168.0.1
            bridge-ports enp40
            bridge-stp off
            bridge-fd 0
    
    #物理网卡配置一般不做改动,系统模板都是配置好的。
    #为虚拟机新建一个虚拟网桥
    #内网地址,虚拟机的网关
    auto vmbr172          
    iface vmbr172 inet static
            address  172.16.1.1
            netmask  255.255.255.0
            bridge-ports none
            bridge-stp off
            bridge-fd 0
            post-up echo 1 > /proc/sys/net/ipv4/ip_forward
            post-up echo 1 > /proc/sys/net/ipv4/conf/eno1/proxy_arp
            #转发IPv4流量到虚拟机,使虚拟机与外网联通。
            post-up iptables -t nat -A POSTROUTING -s '172.16.1.0/16' -o vmbr0 -j MASQUERADE
            post-down iptables -t nat -D POSTROUTING -s '172.16.1.0/16' -o vmbr0 -j MASQUERADE
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    重启

    sudo service networking restart
    
    • 1

    3、 搭建DHCP服务器

    此处使用的是ubuntu做dhcp服务器
    参考地址

    4、 内外网端口映射转发

    #新增
    iptables -t nat -A PREROUTING -p tcp -m tcp --dport 10022 -j DNAT --to-destination 10.10.10.100:22
    #删除 (即把新增映射的-A改成-D)
    iptables -t nat -D PREROUTING -p tcp -m tcp --dport 10022 -j DNAT --to-destination 10.10.10.100:22
    #查看NAT规则,并显示行号
    iptables -t nat --list --line-number
    #删除指定行号的iptables规则
    iptables -t nat -D POSTROUTING 10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    IPv4是经过内网转发的,所以现在只可以访问外网,而外网却无法访问虚拟机。所以我们需要配置端口转发,将外部的访问转发到虚拟机。一般的做法是通过iptables进行转发。

    4.1 使用ufw

    LInux原始的防火墙工具iptables由于过于繁琐,所以ubuntu系统默认提供了一个基于iptable之上的防火墙工具ufw。而UFW支持图形界面操作,只需在命令行运行ufw命令即能看到一系列的操作
    UFW 全称为Uncomplicated Firewall,是Ubuntu 系统上默认的防火墙组件, 为了轻量化配置iptables 而开发的一款工具。 UFW 提供一个非常友好的界面用于创建基于IPV4,IPV6的防火墙规则。
      Linux 2.4内核以后提供了一个非常优秀的防火墙工具:netfilter/iptables,他免费且功能强大,可以对流入、流出的信息进行细化控制,它可以 实现防火墙、NAT(网络地址翻译)和数据包的分割等功能。netfilter工作在内核内部,而iptables则是让用户定义规则集的表结构。
    但是iptables的规则稍微有些“复杂”,因此ubuntu提供了ufw这个设定工具,以简化iptables的某些设定,其后台仍然是 iptables。ufw 即uncomplicated firewall的简称,
    参考地址

    4.2 使用iptables

    端口映射可以使用iptables来完整,已经有大佬写了方便的脚本;
    脚本名称 iptables.sh

    #! /bin/bash
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
    export PATH
    #ConfFile
    iptablesconf='/root/iptables.config.sh'
    function rootness(){
        if [[ $EUID -ne 0 ]]; then
           echo "脚本需要以ROOT权限运行!"
           exit 1
        fi
    }
    function conf_list(){
        cat $iptablesconf
    }
    function conf_add(){
        if [ ! -f $iptablesconf ];then
            echo "找不到配置文件!"
            exit 1
        fi
        echo "请输入虚拟机的内网IP"
        read -p "(Default: Exit):" confvmip
        [ -z "$confvmip" ] && exit 1
        echo
        echo "虚拟机内网IP = $confvmip"
        echo
        while true
        do
        echo "请输入虚拟机的端口:"
        read -p "(默认端口: 22):" confvmport
        [ -z "$confvmport" ] && confvmport="22"
        expr $confvmport + 0 &>/dev/null
        if [ $? -eq 0 ]; then
            if [ $confvmport -ge 1 ] && [ $confvmport -le 65535 ]; then
                echo
                echo "虚拟机端口 = $confvmport"
                echo
                break
            else
                echo "输入错误,端口范围应为1-65535!"
            fi
        else
            echo "输入错误,端口范围应为1-65535!"
        fi
        done
        echo
        while true
        do
        echo "请输入宿主机的端口"
        read -p "(默认端口: 8899):" natconfport
        [ -z "$natconfport" ] && natconfport="8899"
        expr $natconfport + 0 &>/dev/null
        if [ $? -eq 0 ]; then
            if [ $natconfport -ge 1 ] && [ $natconfport -le 65535 ]; then
                echo
                echo "宿主机端口 = $natconfport"
                echo
                break
            else
                echo "输入错误,端口范围应为1-65535!"
            fi
        else
            echo "输入错误,端口范围应为1-65535!"
        fi
        done
        echo "请输入转发协议:"
        read -p "(tcp 或者 udp ,回车默认操作: 退出):" conftype
        [ -z "$conftype" ] && exit 1
        echo
        echo "协议类型 = $conftype"
        echo
        iptablesshell="iptables -t nat -A PREROUTING -i vmbr0 -p $conftype --dport $natconfport -j DNAT --to-destination $confvmip:$confvmport"
        if [ `grep -c "$iptablesshell" $iptablesconf` != '0' ]; then
            echo "配置已经存在"
            exit 1
        fi
        get_char(){
            SAVEDSTTY=`stty -g`
            stty -echo
            stty cbreak
            dd if=/dev/tty bs=1 count=1 2> /dev/null
            stty -raw
            stty echo
            stty $SAVEDSTTY
        }
        echo
        echo "回车继续,Ctrl+C退出脚本"
        char=`get_char`
        echo $iptablesshell >> $iptablesconf
        runreturn=`$iptablesshell`
        echo $runreturn
        echo '配置添加成功'
    }
    function add_confs(){
        rootness
        conf_add
    }
    function del_conf(){
        echo
        while true
        do
        echo "请输入宿主机的端口"
        read -p "(默认操作: 退出):" confserverport
        [ -z "$confserverport" ] && exit 1
        expr $confserverport + 0 &>/dev/null
        if [ $? -eq 0 ]; then
            if [ $confserverport -ge 1 ] && [ $confserverport -le 65535 ]; then
                echo
                echo "宿主机端口 = $confserverport"
                echo
                break
            else
                echo "输入错误,端口范围应为1-65535!"
            fi
        else
            echo "输入错误,端口范围应为1-65535!"
        fi
        done
        echo
        iptablesshelldel=`cat $iptablesconf | grep "dport $confserverport"`
        if [ ! -n "$iptablesshelldel" ]; then
             echo "配置文件中没有该宿主机的端口"
             exit 1
        fi
        iptablesshelldelshell=`echo ${iptablesshelldel//-A/-D}`
        runreturn=`$iptablesshelldelshell`
        echo $runreturn
        sed -i "/$iptablesshelldel/d" $iptablesconf
        echo '配置删除成功'
    }
    function del_confs(){
        printf "你确定要删除配置吗?操作是不可逆的(y/n) "
        printf "\n"
        read -p "(默认: n):" answer
        if [ -z $answer ]; then
            answer="n"
        fi
        if [ "$answer" = "y" ]; then
            rootness
            del_conf
        else
            echo "配置删除操作取消"
        fi
    }
    action=$1
    case "$action" in
    add)
        add_confs
        ;;
    list)
        conf_list
        ;;
    del)
        del_confs
        ;;
    *)
        echo "参数错误! [${action} ]"
        echo "用法: `basename $0` {add|list|del}"
        ;;
    esac
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159

    脚本配置文件
    名称 iptables.config.sh

    #!/usr/bin/env bash
    
    • 1

    上传iptables.sh和iptables.config.sh 脚本到宿主机root目录,或者直接在root目录下创建
    赋予iptables.config.sh可执行权限
    xxx自行更改,为配置文件的路径

    chmod +x /xxx/iptables.config.sh
    
    • 1

    在 iptables.sh目录下执行一下命令根据提示进行添加或删除端口映射

     #添加端口映射
    bash iptables.sh add 
    #删除端口映射
    bash iptables.sh del  
    
    • 1
    • 2
    • 3
    • 4

    4.3 使用brook 进行统一控制

    这样,访问服务器10022端口就会自动转发到虚拟机10.10.10.100的22端口上,实现了外网通过ssh登陆虚拟机的目的。但是,这样做有一个问题,ProxmoxVE自带防火墙,iptables开放22端口,相当于在防火墙上面开了一个洞,而且这个洞不受防火墙的控制,如果需要做安全防护,你还需要单独配置iptables,不是很方便。于是想到一个折中办法,用brook做端口转发,同时利用ProxmoxVE的防火墙进行统一控制。
    获取brook,项目地址

    #version 版本
    wget -O /root/brook https://github.com/txthinking/brook/releases/download/{version}/brook/brook_linux_xxx
    
    wget -O /root/brook https://github.com/txthinking/brook/releases/download/v20221212/brook_linux_amd64
    
    • 1
    • 2
    • 3
    • 4

    将brook移动到你想要放的地方
    赋予执行权限
    brook路径 需要自行修改

    chmod +x /brook路径/brook
    
    • 1

    启动端口转发 from 宿主机端口。to 虚拟机的ip+端口

    #前台运行退出终端及结束转发
    nohup /root/brook relay --from :10022 --to 10.10.10.100:22
    #设置为后台运行
    nohup /root/brook relay --from :10022 --to 10.10.10.100:22 > output 2>&1 &
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    利用命令ps -ef|grep brook来查看转发是否生效,同时在ProxmoxVE防火墙中开放或者关闭10022端口来控制外网对虚拟机的访问。
    KVM虚拟机的配置是类似的,创建时选择桥接vmbr0,不论安装的是Linux系统还是windows系统,都需要手动输入IPv4和IPv地址,同时在主机配置IPv6信息和添加端口转发。

    若想实现开机自动启动端口映射,可以将上边命令写成shell脚本,并加入系统守护进程,写成service服务。

    brook开机自动执行端口转发命令

    创建brookforward.sh

    vim /root/brookforward.sh
    
    • 1

    写入以下命令

    #! /bin/sh
    nohup /root/brook relay --from :10022 --to 10.10.10.100:22 > output 2>&1
    
    • 1
    • 2

    赋予brookforward.sh执行权限

    chmod +x brookforward.sh
    
    • 1

    !!! 注意若要使用systemD 将brookforward.sh实现开机自启动,以及服务自启。在.sh文件中nohup命令不能在最后加上&,让nohup命令保持后台运行,加上了该brookforward.service将会启动失败。
    创建 SystemD service 配文件

    vim /etc/systemd/system/brookforward.service
    
    • 1

    写入以下信息

    # /etc/systemd/system/brookforward.service
    [Unit]
    Description=brookforward
    After=syslog.target
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/root/brookforward.sh
    Restart=always
    RestartSec=5
    
    [Install]
    WantedBy=multi-user.target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Reload SystemD 以加载新的配置文件:

    systemctl daemon-reload
    
    • 1

    启动 brookforward 服务并设置开机自启:

    systemctl enable --now brookforward
    
    • 1

    查看运行状态:

    systemctl status brookforward
    
    • 1

    在这里插入图片描述

    实现开机自启还可以将上边的brookforward.sh文件写入/etc/rc.local中,进行开机启动,但是不能实现服务自动重启。
    实现开机自启和服务自动重启还可以借助supervisor,​ Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。supervisor还提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程。有需要可以自行研究,参考

    以下操作因为没有开启ipv6,没有实操,仅供给有需要的参考

    这样,一个同时开启了NAT和IPv6的虚拟机就创建好了,但是,还有个问题,IPv6的配置和端口转发是会随着主机重启而失效,我们需要在主机上启动开机自启服务,保证每次开机的时候,虚拟机器都能正常工作。
    需要在PVE中开启开机自启服务,创建/etc/rc.local。

    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    # Make sure that the script will "exit 0" on success or any other
    # value on error.
    #
    # In order to enable or disable this script just change the execution
    # bits.
    #
    # By default this script does nothing.
     
    exit 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    赋予执行权限

    chmod +x /etc/rc.local
    
    • 1

    启动服务

    systemctl start rc-local
    
    • 1

    这样,我们只需要将需要执行的命令写在/etc/rc.local的exit 0前面,就可以在开机后自动执行。

    参考

    Proxmox VE同时配置NAT共享IP和独立IP虚拟机

    PVE服务器网络配置

    单IP服务器利用ProxmoxVE建立IPv4-NAT和IPv6虚拟机

    brook安装使用参考

  • 相关阅读:
    python中return和print的区别
    [vue] event.currentTarget和 event.target的区别
    Java项目实战《苍穹外卖》 二、项目搭建
    HI3519DV500快速启动
    054协同过滤算法的电影推荐系统
    Java知识点(知识点)
    双十一某宝、某东活动脚本
    使用 Neuron 接入 Modbus TCP 及 Modbus RTU 协议设备
    供应链金融融资模式
    Python数据攻略-递归方式实现json多层级数据展平
  • 原文地址:https://blog.csdn.net/god_sword_/article/details/128052598