diff options
author | Nathan Skrzypczak <nathan.skrzypczak@gmail.com> | 2021-08-19 11:38:06 +0200 |
---|---|---|
committer | Dave Wallace <dwallacelf@gmail.com> | 2021-10-13 23:22:32 +0000 |
commit | 9ad39c026c8a3c945a7003c4aa4f5cb1d4c80160 (patch) | |
tree | 3cca19635417e28ae381d67ae31c75df2925032d /docs/usecases/home_gateway.rst | |
parent | f47122e07e1ecd0151902a3cabe46c60a99bee8e (diff) |
docs: better docs, mv doxygen to sphinx
This patch refactors the VPP sphinx docs
in order to make it easier to consume
for external readers as well as VPP developers.
It also makes sphinx the single source
of documentation, which simplifies maintenance
and operation.
Most important updates are:
- reformat the existing documentation as rst
- split RELEASE.md and move it into separate rst files
- remove section 'events'
- remove section 'archive'
- remove section 'related projects'
- remove section 'feature by release'
- remove section 'Various links'
- make (Configuration reference, CLI docs,
developer docs) top level items in the list
- move 'Use Cases' as part of 'About VPP'
- move 'Troubleshooting' as part of 'Getting Started'
- move test framework docs into 'Developer Documentation'
- add a 'Contributing' section for gerrit,
docs and other contributer related infos
- deprecate doxygen and test-docs targets
- redirect the "make doxygen" target to "make docs"
Type: refactor
Change-Id: I552a5645d5b7964d547f99b1336e2ac24e7c209f
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
Diffstat (limited to 'docs/usecases/home_gateway.rst')
-rw-r--r-- | docs/usecases/home_gateway.rst | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/docs/usecases/home_gateway.rst b/docs/usecases/home_gateway.rst new file mode 100644 index 00000000000..90d25cf4a6c --- /dev/null +++ b/docs/usecases/home_gateway.rst @@ -0,0 +1,520 @@ +VPP as a Home Gateway +===================== + +Vpp running on a small system (with appropriate NICs) makes a fine home +gateway. The resulting system performs far in excess of requirements: a +debug image runs at a vector size of ~1.2 terminating a 150-mbit down / +10-mbit up cable modem connection. + +At a minimum, install sshd and the isc-dhcp-server. If you prefer, you +can use dnsmasq. + +System configuration files +-------------------------- + +/etc/vpp/startup.conf: + +.. code-block:: c + + 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 dpdk_plugin.so { enable } + plugin nat_plugin.so { enable } + ## if you plan to use the time-based MAC filter + plugin mactime_plugin.so { enable } + } + +/etc/dhcp/dhcpd.conf: + +.. code-block:: c + + 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; + } + +If you decide to enable the vpp dns name resolver, substitute +192.168.1.2 for 8.8.8.8 in the dhcp server configuration. + +/etc/default/isc-dhcp-server: + +.. code-block:: c + + # On which interfaces should the DHCP server (dhcpd) serve DHCP requests? + # Separate multiple interfaces with spaces, e.g. "eth0 eth1". + INTERFACESv4="lstack" + INTERFACESv6="" + +/etc/ssh/sshd_config: + +.. code-block:: c + + # What ports, IPs and protocols we listen for + Port <REDACTED-high-number-port> + # Change to no to disable tunnelled clear text passwords + PasswordAuthentication no + +For your own comfort and safety, do NOT allow password authentication +and do not answer ssh requests on port 22. Experience shows several hack +attempts per hour on port 22, but none (ever) on random high-number +ports. + +Systemd configuration +--------------------- + +In a typical home-gateway use-case, vpp owns the one-and-only WAN link +with a prayer of reaching the public internet. Simple things like +updating distro software requires use of the "lstack" interface created +above, and configuring a plausible upstream DNS name resolver. + +Configure /etc/systemd/resolved.conf as follows. + +/etc/systemd/resolved.conf: + +.. code-block:: c + + [Resolve] + DNS=8.8.8.8 + #FallbackDNS= + #Domains= + #LLMNR=no + #MulticastDNS=no + #DNSSEC=no + #Cache=yes + #DNSStubListener=yes + +Netplan configuration +--------------------- + +If you want to configure a static IP address on one of your home-gateway +Ethernet ports on Ubuntu 18.04, you'll need to configure netplan. +Netplan is relatively new. It and the network manager GUI and can be +cranky. In the configuration shown below, s/enp4s0/<your-interface>/... + +/etc/netplan-01-netcfg.yaml: + +.. code-block:: c + + # 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: + +.. code-block:: c + + [Match] + Name=enp4s0 + + [Link] + RequiredForOnline=no + + [Network] + ConfigureWithoutCarrier=true + Address=192.168.2.254/24 + +Note that we've picked an IP address for the home gateway which is on an +independent unrouteable subnet. This is handy for installing (and +possibly reverting) new vpp software. + +VPP Configuration Files +----------------------- + +Here we see a nice use-case for the vpp debug CLI macro expander: + +/setup.gate: + +.. code-block:: c + + 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 + + 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_NAT44 comment + define FEATURE_CNAT uncomment + define FEATURE_DNS comment + define FEATURE_IP6 comment + define FEATURE_MACTIME uncomment + + exec /setup.tmpl + +/setup.tmpl: + +.. code-block:: c + + 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_NAT44) { nat44 enable users 50 user-sessions 750 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 22432 external $(TRUNK) 22432 tcp } + + $(FEATURE_CNAT) { cnat snat with $(TRUNK) } + $(FEATURE_CNAT) { set interface feature bvi0 ip4-cnat-snat arc ip4-unicast } + $(FEATURE_CNAT) { cnat translation add proto tcp real $(TRUNK) 22432 to -> 192.168.$(INSIDE_SUBNET).2 22432 } + $(FEATURE_CNAT) { $(FEATURE_DNS) { cnat translation add proto udp real $(TRUNK) 53053 to -> 192.168.$(INSIDE_SUBNET).1 53053 } } + + $(FEATURE_DNS) { $(FEATURE_NAT44) { 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 } + + comment { set ct6 inside $(TRUNK) } + comment { set ct6 outside $(TRUNK) } + + $(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 5 3 ra-lifetime 180 } + comment { ip6 nd bvi0 prefix 0::0/0 ra-lifetime 100000 } + + + $(FEATURE_MACTIME) { bin mactime_add_del_range name cisco-vpn mac a8:b4:56:e1:b8:3e allow-static } + $(FEATURE_MACTIME) { bin mactime_add_del_range name old-mac mac <redacted> allow-static } + $(FEATURE_MACTIME) { bin mactime_add_del_range name roku mac <redacted> 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) } + +Installing new vpp software +--------------------------- + +If you're **sure** that a given set of vpp Debian packages will install +and work properly, you can install them while logged into the gateway +via the lstack / nat path. This procedure is a bit like standing on a +rug and yanking it. If all goes well, a perfect back-flip occurs. If +not, you may wish that you'd configured a static IP address on a +reserved Ethernet interface as described above. + +Installing a new vpp image via ssh to 192.168.1.2: + +.. code-block:: c + + # nohup dpkg -i *.deb >/dev/null 2>&1 & + +Within a few seconds, the inbound ssh connection SHOULD begin to respond +again. If it does not, you'll have to debug the issue(s). + +Reasonably Robust Remote Software Installation +---------------------------------------------- + +Here are a couple of scripts which yield a reasonably robust software +installation scheme. + +Build-host script +~~~~~~~~~~~~~~~~~ + +.. code-block:: c + + #!/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 +~~~~~~~~~~~~~ + +.. code-block:: c + + #!/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 + +Note that the target script **requires** that the user id which invokes +it will manage to “sudo dpkg …” without further authentication. If +you’re uncomfortable with the security implications of that requirement, +you’ll need to solve the problem a different way. Strongly suggest +configuring sshd as described above to minimize risk. + +Testing new software +-------------------- + +If you frequently test new home gateway software, it may be handy to set +up a test gateway behind your production gateway. This testing +methodology reduces complaints from family members, to name one benefit. + +Change the inside network (dhcp) subnet from 192.168.1.0/24 to +192.168.3.0/24, change the (dhcp) advertised router to 192.168.3.1, +reconfigure the vpp tap interface addresses onto the 192.168.3.0/24 +subnet, and you should be all set. + +This scenario nats traffic twice: first, from the 192.168.3.0/24 network +onto the 192.168.1.0/24 network. Next, from the 192.168.1.0/24 network +onto the public internet. + +Patches +------- + +You'll want this addition to src/vpp/vnet/main.c to add the "service +restart isc-dhcp-server” and "service restart vpp" commands: + +.. code-block:: c + + #include <sys/types.h> + #include <sys/wait.h> + + static int + mysystem (char *cmd) + { + int rv = 0; + + if (fork()) + wait (&rv); + else + execl("/bin/sh", "sh", "-c", cmd); + + if (rv != 0) + clib_unix_warning ("('%s') child process returned %d", cmd, rv); + return rv; + } + + static clib_error_t * + restart_isc_dhcp_server_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) + { + int rv; + + /* Wait a while... */ + vlib_process_suspend (vm, 2.0); + + rv = mysystem("/usr/sbin/service isc-dhcp-server restart"); + + vlib_cli_output (vm, "Restarted the isc-dhcp-server, status %d...", rv); + return 0; + } + + VLIB_CLI_COMMAND (restart_isc_dhcp_server_command, static) = + { + .path = "service restart isc-dhcp-server", + .short_help = "restarts the isc-dhcp-server", + .function = restart_isc_dhcp_server_command_fn, + }; + + static clib_error_t * + restart_dora_tunnels_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) + { + int rv; + + /* Wait three seconds... */ + vlib_process_suspend (vm, 3.0); + + rv = mysystem ("/usr/sbin/service dora restart"); + + vlib_cli_output (vm, "Restarted the dora tunnel service, status %d...", rv); + return 0; + } + + VLIB_CLI_COMMAND (restart_dora_tunnels_command, static) = + { + .path = "service restart dora", + .short_help = "restarts the dora tunnel service", + .function = restart_dora_tunnels_command_fn, + }; + + static clib_error_t * + restart_vpp_service_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) + { + (void) mysystem ("/usr/sbin/service vpp restart"); + return 0; + } + + VLIB_CLI_COMMAND (restart_vpp_service_command, static) = + { + .path = "service restart vpp", + .short_help = "restarts the vpp service, be careful what you wish for", + .function = restart_vpp_service_command_fn, + }; + +Using the time-based mac filter plugin +-------------------------------------- + +If you need to restrict network access for certain devices to specific +daily time ranges, configure the "mactime" plugin. Add it to the list of +enabled plugins in /etc/vpp/startup.conf, then enable the feature on the +NAT "inside" interfaces: + +.. code-block:: c + + bin mactime_enable_disable GigabitEthernet0/14/0 + bin mactime_enable_disable GigabitEthernet0/14/1 + ... + +Create the required src-mac-address rule database. There are 4 rule +entry types: + +- 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 + +Here are some examples: + +.. code-block:: c + + 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 |