4 Vpp running on a small system (with appropriate NICs) makes a fine home
5 gateway. The resulting system performs far in excess of requirements: a
6 debug image runs at a vector size of ~1.2 terminating a 150-mbit down /
7 10-mbit up cable modem connection.
9 At a minimum, install sshd and the isc-dhcp-server. If you prefer, you
12 System configuration files
13 --------------------------
15 /etc/vpp/startup.conf:
21 log /var/log/vpp/vpp.log
23 cli-listen /run/vpp/cli.sock
24 startup-config /setup.gate
38 ## Disable all plugins, selectively enable specific plugins
39 ## YMMV, you may wish to enable other plugins (acl, etc.)
40 plugin default { disable }
41 plugin dhcp_plugin.so { enable }
42 plugin dns_plugin.so { enable }
43 plugin dpdk_plugin.so { enable }
44 plugin nat_plugin.so { enable }
45 plugin ping_plugin.so { enable }
46 ## if you plan to use the time-based MAC filter
47 plugin mactime_plugin.so { enable }
48 plugin vmxnet3_plugin.so { enable }
55 subnet 192.168.1.0 netmask 255.255.255.0 {
56 range 192.168.1.10 192.168.1.99;
57 option routers 192.168.1.1;
58 option domain-name-servers 8.8.8.8;
61 If you decide to enable the vpp dns name resolver, substitute
62 192.168.1.2 for 8.8.8.8 in the dhcp server configuration.
64 /etc/default/isc-dhcp-server:
68 # On which interfaces should the DHCP server (dhcpd) serve DHCP requests?
69 # Separate multiple interfaces with spaces, e.g. "eth0 eth1".
77 # What ports, IPs and protocols we listen for
78 Port <REDACTED-high-number-port>
79 # Change to no to disable tunnelled clear text passwords
80 PasswordAuthentication no
82 For your own comfort and safety, do NOT allow password authentication
83 and do not answer ssh requests on port 22. Experience shows several
84 hack attempts per hour on port 22, but none on random high-number
90 In a typical home-gateway use-case, vpp owns the one-and-only WAN link
91 with a prayer of reaching the public internet. Simple things like
92 updating distro software requires use of the "lstack" interface created
93 above, and configuring a plausible upstream DNS name resolver.
95 Configure /etc/systemd/resolved.conf as follows.
97 /etc/systemd/resolved.conf:
111 Netplan configuration
112 ---------------------
114 If you want to configure a static IP address on one of your home-gateway
115 Ethernet ports on Ubuntu 18.04, you'll need to configure netplan.
116 Netplan is relatively new. It and the network manager GUI and can be
117 cranky. In the configuration shown below, s/enp4s0/<your-interface>/...
119 /etc/netplan-01-netcfg.yaml:
123 # This file describes the network interfaces available on your system
124 # For more information, see netplan(5).
131 addresses: [192.168.2.254/24]
132 gateway4: 192.168.2.100
137 /etc/systemd/network-10.enp4s0.network:
148 ConfigureWithoutCarrier=true
149 Address=192.168.2.254/24
151 Note that we've picked an IP address for the home gateway which is on an
152 independent unrouteable subnet. This is handy for installing (and
153 possibly reverting) new vpp software.
155 VPP Configuration Files
156 -----------------------
158 Here we see a nice use-case for the vpp debug CLI macro expander:
165 define TRUNK GigabitEthernet3/0/0
167 comment { Specific MAC address yields a constant IP address }
168 define TRUNK_MACADDR 48:f8:b3:00:01:01
169 define BVI_MACADDR 48:f8:b3:01:01:02
171 comment { inside subnet 192.168.<inside_subnet>.0/24 }
172 define INSIDE_SUBNET 1
174 # Adjust as needed to match PCI addresses of inside network ports
175 define INSIDE_PORT1 GigabitEthernet6/0/0
176 define INSIDE_PORT2 GigabitEthernet6/0/1
177 define INSIDE_PORT3 GigabitEthernet8/0/0
178 define INSIDE_PORT4 GigabitEthernet8/0/1
180 comment { feature selections }
181 define FEATURE_ADL uncomment
182 define FEATURE_NAT44 uncomment
183 define FEATURE_CNAT comment
184 define FEATURE_DNS comment
185 define FEATURE_IP6 comment
186 define FEATURE_IKE_RESPONDER comment
187 define FEATURE_MACTIME uncomment
188 define FEATURE_OVPN uncomment
189 define FEATURE_MODEM_ROUTE uncomment
199 set int mac address $(TRUNK) $(TRUNK_MACADDR)
200 set dhcp client intfc $(TRUNK) hostname $(HOSTNAME)
201 set int state $(TRUNK) up
203 bvi create instance 0
204 set int mac address bvi0 $(BVI_MACADDR)
205 set int l2 bridge bvi0 1 bvi
206 set int ip address bvi0 192.168.$(INSIDE_SUBNET).1/24
207 set int state bvi0 up
209 set int l2 bridge $(INSIDE_PORT1) 1
210 set int state $(INSIDE_PORT1) up
211 set int l2 bridge $(INSIDE_PORT2) 1
212 set int state $(INSIDE_PORT2) up
213 set int l2 bridge $(INSIDE_PORT3) 1
214 set int state $(INSIDE_PORT3) up
215 set int l2 bridge $(INSIDE_PORT4) 1
216 set int state $(INSIDE_PORT4) up
218 comment { dhcp server and host-stack access }
219 create tap host-if-name lstack host-ip4-addr 192.168.$(INSIDE_SUBNET).2/24 host-ip4-gw 192.168.$(INSIDE_SUBNET).1
220 set int l2 bridge tap0 1
221 set int state tap0 up
223 service restart isc-dhcp-server
225 $(FEATURE_ADL) { bin adl_interface_enable_disable $(TRUNK) }
226 $(FEATURE_ADL) { ip table 1 }
227 $(FEATURE_ADL) { ip route add table 1 0.0.0.0/0 via local }
229 $(FEATURE_NAT44) { nat44 forwarding enable }
230 $(FEATURE_NAT44) { nat44 plugin enable sessions 63000 }
231 $(FEATURE_NAT44) { nat44 add interface address $(TRUNK) }
232 $(FEATURE_NAT44) { set interface nat44 in bvi0 out $(TRUNK) }
234 $(FEATURE_NAT44) { nat44 add static mapping local 192.168.$(INSIDE_SUBNET).2 22342 external $(TRUNK) 22342 tcp }
235 $(FEATURE_NAT44) { $(FEATURE_IKE_RESPONDER) { nat44 add identity mapping external $(TRUNK) udp 500 } }
236 $(FEATURE_NAT44) { $(FEATURE_IKE_RESPONDER) { nat44 add identity mapping external $(TRUNK) udp 4500 } }
237 $(FEATURE_NAT44) { $(FEATURE_DNS) { nat44 add static mapping local 192.168.$(INSIDE_SUBNET).2 53053 external $(TRUNK) 53053 udp } }
238 $(FEATURE_NAT44) { $(FEATURE_OVPN) { nat44 add static mapping local 192.168.$(INSIDE_SUBNET).2 37979 external $(TRUNK) 37979 udp } }
239 $(FEATURE_NAT44) { $(FEATURE_OVPN) { set interface feature bvi0 skipnat arc ip4-unicast } }
240 $(FEATURE_NAT44) { $(FEATURE_OVPN) { ip route add 192.168.10.0/24 via 192.168.$(INSIDE_SUBNET).2 } }
242 $(FEATURE_CNAT) { set cnat snat-policy none }
243 $(FEATURE_CNAT) { set cnat snat-policy addr $(TRUNK) }
244 $(FEATURE_CNAT) { set interface feature bvi0 cnat-snat-ip4 arc ip4-unicast }
245 $(FEATURE_CNAT) { cnat translation add proto tcp real $(TRUNK) 22342 to -> 192.168.$(INSIDE_SUBNET).2 22342 }
246 $(FEATURE_CNAT) { $(FEATURE_DNS) { cnat translation add proto udp real $(TRUNK) 53053 to -> 192.168.$(INSIDE_SUBNET).1 53053 } }
247 $(FEATURE_CNAT) { $(FEATURE_OVPN) { cnat translation add proto udp real $(TRUNK) 37979 to -> 192.168.$(INSIDE_SUBNET).2 37979 } }
248 $(FEATURE_CNAT) { $(FEATURE_OVPN) { set interface feature bvi0 skipnat arc ip4-unicast } }
249 $(FEATURE_CNAT) { $(FEATURE_OVPN) { ip route add 192.168.10.0/24 via 192.168.$(INSIDE_SUBNET).2 } }
252 $(FEATURE_DNS) { nat44 add identity mapping external $(TRUNK) udp 53053 }
253 $(FEATURE_DNS) { bin dns_name_server_add_del 8.8.8.8 }
254 $(FEATURE_DNS) { bin dns_enable_disable }
256 $(FEATURE_IP6) { set int ip6 table $(TRUNK) 0 }
257 $(FEATURE_IP6) { ip6 nd address autoconfig $(TRUNK) default-route }
258 $(FEATURE_IP6) { dhcp6 client $(TRUNK) }
259 $(FEATURE_IP6) { dhcp6 pd client $(TRUNK) prefix group hgw }
260 $(FEATURE_IP6) { set ip6 address bvi0 prefix group hgw ::1/64 }
261 $(FEATURE_IP6) { ip6 nd address autoconfig bvi0 default-route }
262 comment { iPhones seem to need lots of RA messages... }
263 $(FEATURE_IP6) { ip6 nd bvi0 ra-managed-config-flag ra-other-config-flag ra-interval 30 20 ra-lifetime 180 }
264 comment { ip6 nd bvi0 prefix 0::0/0 ra-lifetime 100000 }
266 comment { responder profile }
267 $(FEATURE_IKE_RESPONDER) { ikev2 profile add swan }
268 $(FEATURE_IKE_RESPONDER) { ikev2 profile set swan auth rsa-sig cert-file /home/dbarach/certs/swancert.pem }
269 $(FEATURE_IKE_RESPONDER) { set ikev2 local key /home/dbarach/certs/dorakey.pem }
270 $(FEATURE_IKE_RESPONDER) { ikev2 profile set swan id remote fqdn swan.barachs.net }
271 $(FEATURE_IKE_RESPONDER) { ikev2 profile set swan id local fqdn broiler2.barachs.net }
272 $(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 }
273 $(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 }
274 $(FEATURE_IKE_RESPONDER) { create ipip tunnel src 73.120.164.15 dst 162.255.170.167 }
275 $(FEATURE_IKE_RESPONDER) { ikev2 profile set swan tunnel ipip0 }
277 $(FEATURE_IKE_RESPONDER) { set int mtu packet 1390 ipip0 }
278 $(FEATURE_IKE_RESPONDER) { set int unnum ipip0 use $(TRUNK) }
280 comment { if using the mactime plugin, configure it }
281 $(FEATURE_MACTIME) { bin mactime_add_del_range name roku mac 00:00:01:de:ad:be allow-static }
282 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT1) }
283 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT2) }
284 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT3) }
285 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT4) }
287 $(FEATURE_MODEM_ROUTE) { ip route add 192.168.100.1/32 via $(TRUNK) }
289 Installing new vpp software
290 ---------------------------
292 If you're **sure** that a given set of vpp Debian packages will install
293 and work properly, you can install them while logged into the gateway
294 via the lstack / nat path. This procedure is a bit like standing on a
295 rug and yanking it. If all goes well, a perfect back-flip occurs. If
296 not, you may wish that you'd configured a static IP address on a
297 reserved Ethernet interface as described above.
299 Installing a new vpp image via ssh to 192.168.1.2:
303 # nohup dpkg -i *.deb >/dev/null 2>&1 &
305 Within a few seconds, the inbound ssh connection SHOULD begin to respond
306 again. If it does not, you'll have to debug the issue(s).
308 Reasonably Robust Remote Software Installation
309 ----------------------------------------------
311 Here are a couple of scripts which yield a reasonably robust software
321 buildroot=/scratch/vpp-workspace/build-root
322 if [ $1x = "testx" ] ; then
324 ipaddr="192.168.2.48"
325 elif [ $1x = "foox" ] ; then
327 ipaddr="foo.some.net"
328 elif [ $1x = "barx" ] ; then
330 ipaddr="bar.some.net"
333 ipaddr="192.168.2.48"
336 echo Save current software...
337 ssh -p 22432 $ipaddr "rm -rf /gate_debians.prev"
338 ssh -p 22432 $ipaddr "mv /gate_debians /gate_debians.prev"
339 ssh -p 22432 $ipaddr "mkdir /gate_debians"
340 echo Copy new software to the gateway...
341 scp -P 22432 $buildroot/*.deb $ipaddr:/gate_debians
342 echo Install new software...
343 ssh -p 22432 $ipaddr "nohup /usr/local/bin/vpp-swupdate > /dev/null 2>&1 &"
345 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
347 echo Wait for $i seconds...
351 echo Try to access the device...
353 ssh -p 22432 -o ConnectTimeout=10 $ipaddr "tail -20 /var/log/syslog | grep Ping"
354 if [ $? == 0 ] ; then
355 echo Access test OK...
357 echo Access failed, wait for configuration restoration...
358 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
360 echo Wait for $i seconds...
363 echo Retry access test
364 ssh -p 22432 -o ConnectTimeout=10 $ipaddr "tail -20 /var/log/syslog | grep Ping"
365 if [ $? == 0 ] ; then
366 echo Access test OK, check syslog on the device
369 echo Access test still fails, manual intervention required.
383 logger "About to update vpp software..."
386 sudo dpkg -i *.deb >/dev/null 2>&1 &
388 logger "Ping connectivity test..."
389 for i in 1 2 3 4 5 6 7 8 9 10
391 ping -4 -c 1 yahoo.com
392 if [ $? == 0 ] ; then
393 logger "Ping test OK..."
398 logger "Ping test NOT OK, restore old software..."
400 mv /gate_debians.prev /gate_debians
402 nohup sudo dpkg -i *.deb >/dev/null 2>&1 &
404 logger "Repeat connectivity test..."
405 for i in 1 2 3 4 5 6 7 8 9 10
407 ping -4 -c 1 yahoo.com
408 if [ $? == 0 ] ; then
409 logger "Ping test OK after restoring old software..."
414 logger "Ping test FAIL after restoring software, manual intervention required"
417 Note that the target script **requires** that the user id which invokes
418 it will manage to “sudo dpkg …” without further authentication. If
419 you’re uncomfortable with the security implications of that requirement,
420 you’ll need to solve the problem a different way. Strongly suggest
421 configuring sshd as described above to minimize risk.
426 If you frequently test new home gateway software, it may be handy to set
427 up a test gateway behind your production gateway. This testing
428 methodology reduces complaints from family members, to name one benefit.
430 Change the inside network (dhcp) subnet from 192.168.1.0/24 to
431 192.168.3.0/24, change the (dhcp) advertised router to 192.168.3.1,
432 reconfigure the vpp tap interface addresses onto the 192.168.3.0/24
433 subnet, and you should be all set.
435 This scenario nats traffic twice: first, from the 192.168.3.0/24 network
436 onto the 192.168.1.0/24 network. Next, from the 192.168.1.0/24 network
437 onto the public internet.
442 You'll want this addition to src/vpp/vnet/main.c to add the "service
443 restart isc-dhcp-server” and "service restart vpp" commands:
447 #include <sys/types.h>
448 #include <sys/wait.h>
458 execl("/bin/sh", "sh", "-c", cmd);
461 clib_unix_warning ("('%s') child process returned %d", cmd, rv);
465 static clib_error_t *
466 restart_isc_dhcp_server_command_fn (vlib_main_t * vm,
467 unformat_input_t * input,
468 vlib_cli_command_t * cmd)
472 /* Wait a while... */
473 vlib_process_suspend (vm, 2.0);
475 rv = mysystem("/usr/sbin/service isc-dhcp-server restart");
477 vlib_cli_output (vm, "Restarted the isc-dhcp-server, status %d...", rv);
481 VLIB_CLI_COMMAND (restart_isc_dhcp_server_command, static) =
483 .path = "service restart isc-dhcp-server",
484 .short_help = "restarts the isc-dhcp-server",
485 .function = restart_isc_dhcp_server_command_fn,
488 static clib_error_t *
489 restart_dora_tunnels_command_fn (vlib_main_t * vm,
490 unformat_input_t * input,
491 vlib_cli_command_t * cmd)
495 /* Wait three seconds... */
496 vlib_process_suspend (vm, 3.0);
498 rv = mysystem ("/usr/sbin/service dora restart");
500 vlib_cli_output (vm, "Restarted the dora tunnel service, status %d...", rv);
504 VLIB_CLI_COMMAND (restart_dora_tunnels_command, static) =
506 .path = "service restart dora",
507 .short_help = "restarts the dora tunnel service",
508 .function = restart_dora_tunnels_command_fn,
511 static clib_error_t *
512 restart_vpp_service_command_fn (vlib_main_t * vm,
513 unformat_input_t * input,
514 vlib_cli_command_t * cmd)
516 (void) mysystem ("/usr/sbin/service vpp restart");
520 VLIB_CLI_COMMAND (restart_vpp_service_command, static) =
522 .path = "service restart vpp",
523 .short_help = "restarts the vpp service, be careful what you wish for",
524 .function = restart_vpp_service_command_fn,
527 Using the time-based mac filter plugin
528 --------------------------------------
530 If you need to restrict network access for certain devices to specific
531 daily time ranges, configure the "mactime" plugin. Add it to the list of
532 enabled plugins in /etc/vpp/startup.conf, then enable the feature on the
533 NAT "inside" interfaces:
537 bin mactime_enable_disable GigabitEthernet0/14/0
538 bin mactime_enable_disable GigabitEthernet0/14/1
541 Create the required src-mac-address rule database. There are 4 rule
544 - allow-static - pass traffic from this mac address
545 - drop-static - drop traffic from this mac address
546 - allow-range - pass traffic from this mac address at specific times
547 - drop-range - drop traffic from this mac address at specific times
549 Here are some examples:
553 bin mactime_add_del_range name alarm-system mac 00:de:ad:be:ef:00 allow-static
554 bin mactime_add_del_range name unwelcome mac 00:de:ad:be:ef:01 drop-static
555 bin mactime_add_del_range name not-during-business-hours mac <mac> drop-range Mon - Fri 7:59 - 18:01
556 bin mactime_add_del_range name monday-busines-hours mac <mac> allow-range Mon 7:59 - 18:01