思科VPP系列砖题:如何使用vpp构建家庭网关

2023-09-07 14:22:53 浏览数 (1)

本文章主要是用来描述如何使用vpp来搭建家庭网关。

首先vpp软件简介

VPP 平台是一个可扩展的框架,可提供开箱即用的生产质量交换机 / 路由器功能。它是思科矢量数据包处理(Vector Packet Processing,VPP)技术的开源版本:一种高性能的数据包处理堆栈,可以在商用 CPU 上运行。

FD.io 矢量数据包处理器使用矢量数据包处理算法。这个开源的 Linux Foundation 项目是 FD.io 项目的一部分。FD.io VPP 是一个 2 到 4 层网络堆栈。它运行在 Linux 用户空间,并能运行在多个商用 CPU 平台上。FD.io VPP 使用 DPDK 设备驱动程序和库来实现许多第 1 层的功能。


搭建家庭网关需要使用到的服务类型:ssh、DHCP、DNS等基础网络功能;

系统配置文件

文件名称:startup.conf

代码语言:javascript复制
unix {
  nodaemon
  log /var/log/vpp/vpp.log
  full-coredump
  cli-listen /run/vpp/cli.sock
  startup-config /setup.gate
  poll-sleep-usec 100
  gid vpp
}
api-segment {
  gid vpp
}
dpdk {
     dev 0000:03:00.0
     dev 0000:14:00.0
     etc.
 }

 plugins {
   ## Disable all plugins, selectively enable specific plugins
       ## YMMV, you may wish to enable other plugins (acl, etc.)
   plugin default { disable }
   plugin dhcp_plugin.so { enable }
   plugin dns_plugin.so { enable }
   plugin dpdk_plugin.so { enable }
   plugin nat_plugin.so { enable }
   plugin ping_plugin.so { enable }
       ## if you plan to use the time-based MAC filter
   plugin mactime_plugin.so { enable }
   plugin vmxnet3_plugin.so { enable }
 }

2、 DHCP 配置文件

文件名:dhcpd.conf

注意:

如果您决定启用vpp-dns名称解析程序,请在dhcp服务器配置中将8.8.8.8替换为192.168.1.2。

代码语言:javascript复制
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.10 192.168.1.99;
  option routers 192.168.1.1;
  option domain-name-servers 8.8.8.8;
}

3、SSH配置文件

文件:/etc/ssh/sshd_config:

代码语言:javascript复制
# What ports, IPs and protocols we listen for
Port <REDACTED-high-number-port>
# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

注意:

为了您自己的舒适和安全,不要允许密码验证,也不要回答端口22上的ssh请求。经验显示,在端口22上每小时有几次黑客攻击尝试,但在随机的高数量端口上没有。

4、Systemd configuration

在一个典型的家庭网关用例中,vpp拥有唯一一个广域网链接,并能接入公共互联网。像更新发行版软件这样简单的事情需要使用上面创建的“lstack”接口,并配置一个合理的上游DNS名称解析程序。

按照如下配置来配置/etc/systemd/resolved.conf

代码语言:javascript复制
[Resolve]
DNS=8.8.8.8
#FallbackDNS=
#Domains=
#LLMNR=no
#MulticastDNS=no
#DNSSEC=no
#Cache=yes
#DNSStubListener=yes

Netplan configuration

该部分提供一个在ubuntu18.04上通过netplan来配置静态IP的一个参考,在现实使用中,需要根据实际情况调整。

/etc/netplan-01-netcfg.yaml:

代码语言:javascript复制
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    enp4s0:
      dhcp4: no
      addresses: [192.168.2.254/24]
      gateway4: 192.168.2.100
      nameservers:
        search: [my.local]
        addresses: [8.8.8.8]

/etc/systemd/network-10.enp4s0.network:

代码语言:javascript复制
[Match]
Name=enp4s0

[Link]
RequiredForOnline=no

[Network]
ConfigureWithoutCarrier=true
Address=192.168.2.254/24

请注意,我们为家庭网关选择了一个IP地址,该地址位于一个独立的不可路由子网上。这对于安装(并可能恢复)新的vpp软件非常方便。

VPP配置文件

代码语言:javascript复制
define HOSTNAME vpp1
define TRUNK GigabitEthernet3/0/0

comment { Specific MAC address yields a constant IP address }
define TRUNK_MACADDR 48:f8:b3:00:01:01
define BVI_MACADDR 48:f8:b3:01:01:02

comment { inside subnet 192.168.<inside_subnet>.0/24 }
define INSIDE_SUBNET 1

# Adjust as needed to match PCI addresses of inside network ports
define INSIDE_PORT1 GigabitEthernet6/0/0
define INSIDE_PORT2 GigabitEthernet6/0/1
define INSIDE_PORT3 GigabitEthernet8/0/0
define INSIDE_PORT4 GigabitEthernet8/0/1

comment { feature selections }
define FEATURE_ADL uncomment
define FEATURE_NAT44 uncomment
define FEATURE_CNAT comment
define FEATURE_DNS comment
define FEATURE_IP6 comment
define FEATURE_IKE_RESPONDER comment
define FEATURE_MACTIME uncomment
define FEATURE_OVPN uncomment
define FEATURE_MODEM_ROUTE uncomment

exec /setup.tmpl

/setup.tmpl:

代码语言:javascript复制
show macro

set int mac address $(TRUNK) $(TRUNK_MACADDR)
set dhcp client intfc $(TRUNK) hostname $(HOSTNAME)
set int state $(TRUNK) up

bvi create instance 0
set int mac address bvi0 $(BVI_MACADDR)
set int l2 bridge bvi0 1 bvi
set int ip address bvi0 192.168.$(INSIDE_SUBNET).1/24
set int state bvi0 up

set int l2 bridge $(INSIDE_PORT1) 1
set int state $(INSIDE_PORT1) up
set int l2 bridge $(INSIDE_PORT2) 1
set int state $(INSIDE_PORT2) up
set int l2 bridge $(INSIDE_PORT3) 1
set int state $(INSIDE_PORT3) up
set int l2 bridge $(INSIDE_PORT4) 1
set int state $(INSIDE_PORT4) up

comment { dhcp server and host-stack access }
create tap host-if-name lstack host-ip4-addr 192.168.$(INSIDE_SUBNET).2/24 host-ip4-gw 192.168.$(INSIDE_SUBNET).1
set int l2 bridge tap0 1
set int state tap0 up

service restart isc-dhcp-server

$(FEATURE_ADL) { bin adl_interface_enable_disable $(TRUNK) }
$(FEATURE_ADL) { ip table 1 }
$(FEATURE_ADL) { ip route add table 1 0.0.0.0/0 via local }

$(FEATURE_NAT44) { nat44 forwarding enable }
$(FEATURE_NAT44) { nat44 plugin enable sessions 63000 }
$(FEATURE_NAT44) { nat44 add interface address $(TRUNK) }
$(FEATURE_NAT44) { set interface nat44 in bvi0 out $(TRUNK) }

$(FEATURE_NAT44) { nat44 add static mapping local 192.168.$(INSIDE_SUBNET).2 22342 external $(TRUNK) 22342 tcp }
$(FEATURE_NAT44) { $(FEATURE_IKE_RESPONDER) { nat44 add identity mapping external $(TRUNK) udp 500 } }
$(FEATURE_NAT44) { $(FEATURE_IKE_RESPONDER) { nat44 add identity mapping external $(TRUNK) udp 4500 } }
$(FEATURE_NAT44) { $(FEATURE_DNS) { nat44 add static mapping local 192.168.$(INSIDE_SUBNET).2 53053 external $(TRUNK) 53053 udp } }
$(FEATURE_NAT44) { $(FEATURE_OVPN) { nat44 add static mapping local 192.168.$(INSIDE_SUBNET).2 37979 external $(TRUNK) 37979 udp } }
$(FEATURE_NAT44) { $(FEATURE_OVPN) { set interface feature bvi0 skipnat arc ip4-unicast } }
$(FEATURE_NAT44) { $(FEATURE_OVPN) { ip route add 192.168.10.0/24 via 192.168.$(INSIDE_SUBNET).2 } }

$(FEATURE_CNAT) { set cnat snat-policy none }
$(FEATURE_CNAT) { set cnat snat-policy addr $(TRUNK) }
$(FEATURE_CNAT) { set interface feature bvi0 cnat-snat-ip4 arc ip4-unicast }
$(FEATURE_CNAT) { cnat translation add proto tcp real $(TRUNK) 22342 to -> 192.168.$(INSIDE_SUBNET).2 22342 }
$(FEATURE_CNAT) { $(FEATURE_DNS) { cnat translation add proto udp real $(TRUNK) 53053 to -> 192.168.$(INSIDE_SUBNET).1 53053 } }
$(FEATURE_CNAT) { $(FEATURE_OVPN) { cnat translation add proto udp real $(TRUNK) 37979 to -> 192.168.$(INSIDE_SUBNET).2 37979 } }
$(FEATURE_CNAT) { $(FEATURE_OVPN) { set interface feature bvi0 skipnat arc ip4-unicast } }
$(FEATURE_CNAT) { $(FEATURE_OVPN) { ip route add 192.168.10.0/24 via 192.168.$(INSIDE_SUBNET).2 } }


$(FEATURE_DNS) { nat44 add identity mapping external $(TRUNK) udp 53053 }
$(FEATURE_DNS) { bin dns_name_server_add_del 8.8.8.8 }
$(FEATURE_DNS) { bin dns_enable_disable }

$(FEATURE_IP6) { set int ip6 table $(TRUNK) 0 }
$(FEATURE_IP6) { ip6 nd address autoconfig $(TRUNK) default-route }
$(FEATURE_IP6) { dhcp6 client $(TRUNK) }
$(FEATURE_IP6) { dhcp6 pd client $(TRUNK) prefix group hgw }
$(FEATURE_IP6) { set ip6 address bvi0 prefix group hgw ::1/64 }
$(FEATURE_IP6) { ip6 nd address autoconfig bvi0 default-route }
comment { iPhones seem to need lots of RA messages... }
$(FEATURE_IP6) { ip6 nd bvi0 ra-managed-config-flag ra-other-config-flag ra-interval 30 20 ra-lifetime 180 }
comment { ip6 nd bvi0 prefix 0::0/0  ra-lifetime 100000 }

comment { responder profile }
$(FEATURE_IKE_RESPONDER) { ikev2 profile add swan }
$(FEATURE_IKE_RESPONDER) { ikev2 profile set swan auth rsa-sig cert-file /home/dbarach/certs/swancert.pem }
$(FEATURE_IKE_RESPONDER) { set ikev2 local key /home/dbarach/certs/dorakey.pem }
$(FEATURE_IKE_RESPONDER) { ikev2 profile set swan id remote fqdn swan.barachs.net }
$(FEATURE_IKE_RESPONDER) { ikev2 profile set swan id local fqdn broiler2.barachs.net }
$(FEATURE_IKE_RESPONDER) { ikev2 profile set swan traffic-selector remote ip-range 192.168.1.0 - 192.168.1.255 port-range 0 - 65535 protocol 0 }
$(FEATURE_IKE_RESPONDER) { ikev2 profile set swan traffic-selector local ip-range 192.168.$(INSIDE_SUBNET).0 - 192.168.$(INSIDE_SUBNET).255 port-range 0 - 65535 protocol 0 }
$(FEATURE_IKE_RESPONDER) { create ipip tunnel src 73.120.164.15 dst 162.255.170.167 }
$(FEATURE_IKE_RESPONDER) { ikev2 profile set swan tunnel ipip0 }

$(FEATURE_IKE_RESPONDER) { set int mtu packet 1390 ipip0 }
$(FEATURE_IKE_RESPONDER) { set int unnum ipip0 use $(TRUNK) }

comment { if using the mactime plugin, configure it }
$(FEATURE_MACTIME) { bin mactime_add_del_range name roku mac 00:00:01:de:ad:be allow-static }
$(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT1) }
$(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT2) }
$(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT3) }
$(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT4) }

$(FEATURE_MODEM_ROUTE) { ip route add 192.168.100.1/32 via $(TRUNK) }

安装新的vpp应用软件

代码语言:javascript复制
# nohup dpkg -i *.deb >/dev/null 2>&1 &

Build-host script

代码语言:javascript复制
#!/bin/bash

buildroot=/scratch/vpp-workspace/build-root
if [ $1x = "testx" ] ; then
    subdir="test"
    ipaddr="192.168.2.48"
elif [ $1x = "foox" ] ; then
    subdir="foo"
    ipaddr="foo.some.net"
elif [ $1x = "barx" ] ; then
    subdir="bar"
    ipaddr="bar.some.net"
else
    subdir="test"
    ipaddr="192.168.2.48"
fi

echo Save current software...
ssh -p 22432 $ipaddr "rm -rf /gate_debians.prev"
ssh -p 22432 $ipaddr "mv /gate_debians /gate_debians.prev"
ssh -p 22432 $ipaddr "mkdir /gate_debians"
echo Copy new software to the gateway...
scp -P 22432 $buildroot/*.deb $ipaddr:/gate_debians
echo Install new software...
ssh -p 22432 $ipaddr "nohup /usr/local/bin/vpp-swupdate > /dev/null 2>&1 &"

for i in 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
do
    echo Wait for $i seconds...
    sleep 1
done

echo Try to access the device...

ssh -p 22432 -o ConnectTimeout=10 $ipaddr "tail -20 /var/log/syslog | grep Ping"
if [ $? == 0 ] ; then
    echo Access test OK...
else
    echo Access failed, wait for configuration restoration...
    for i in 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
    do
        echo Wait for $i seconds...
        sleep 1
    done
    echo Retry access test
    ssh -p 22432 -o ConnectTimeout=10 $ipaddr "tail -20 /var/log/syslog | grep Ping"
    if [ $? == 0 ] ; then
        echo Access test OK, check syslog on the device
        exit 1
    else
        echo Access test still fails, manual intervention required.
        exit 2
    fi
fi

exit 0

Target script

代码语言:javascript复制
#!/bin/bash

logger "About to update vpp software..."
cd /gate_debians
service vpp stop
sudo dpkg -i *.deb >/dev/null 2>&1 &
sleep 20
logger "Ping connectivity test..."
for i in 1 2 3 4 5 6 7 8 9 10
do
    ping -4 -c 1 yahoo.com
    if [ $? == 0 ] ; then
        logger "Ping test OK..."
        exit 0
    fi
done

logger "Ping test NOT OK, restore old software..."
rm -rf /gate_debians
mv /gate_debians.prev /gate_debians
cd /gate_debians
nohup sudo dpkg -i *.deb >/dev/null 2>&1 &
sleep 20
logger "Repeat connectivity test..."
for i in 1 2 3 4 5 6 7 8 9 10
do
    ping -4 -c 1 yahoo.com
    if [ $? == 0 ] ; then
        logger "Ping test OK after restoring old software..."
        exit 0
    fi
done

logger "Ping test FAIL after restoring software, manual intervention required"
exit 2

启动定时访问功能

如果您需要将某些设备的网络访问限制在特定的每日时间范围内,请配置“mactime”插件。将其添加到/etc/vpp/startup.conf中已启用插件的列表中,然后在NAT“内部”接口上启用该功能:

代码语言:javascript复制
bin mactime_enable_disable GigabitEthernet0/14/0
bin mactime_enable_disable GigabitEthernet0/14/1
...
代码语言:javascript复制

创建所需的src-mac地址规则数据库。有4种规则类型:

  • allow-static - pass traffic from this mac address
  • drop-static - drop traffic from this mac address
  • allow-range - pass traffic from this mac address at specific times
  • drop-range - drop traffic from this mac address at specific times

举例:

代码语言:javascript复制
bin mactime_add_del_range name alarm-system mac 00:de:ad:be:ef:00 allow-static
bin mactime_add_del_range name unwelcome mac 00:de:ad:be:ef:01 drop-static
bin mactime_add_del_range name not-during-business-hours mac <mac> drop-range Mon - Fri 7:59 - 18:01
bin mactime_add_del_range name monday-busines-hours mac <mac> allow-range Mon 7:59 - 18:01

0 人点赞