diff --git a/examples/config.yml b/examples/config.yml index f8930af..db5d0e3 100644 --- a/examples/config.yml +++ b/examples/config.yml @@ -204,21 +204,24 @@ tun: tx_queue: 500 # Default MTU for every packet, safe setting is (and the default) 1300 for internet based traffic mtu: 1300 + # Route based MTU overrides, you have known vpn ip paths that can support larger MTUs you can increase/decrease them here routes: #- mtu: 8800 # route: 10.0.0.0/16 + # Unsafe routes allows you to route traffic over nebula to non-nebula nodes # Unsafe routes should be avoided unless you have hosts/services that cannot run nebula # NOTE: The nebula certificate of the "via" node *MUST* have the "route" defined as a subnet in its certificate - # `mtu` will default to tun mtu if this option is not specified - # `metric` will default to 0 if this option is not specified + # `mtu`: will default to tun mtu if this option is not specified + # `metric`: will default to 0 if this option is not specified + # `install`: will default to true, controls whether this route is installed in the systems routing table. unsafe_routes: #- route: 172.16.1.0/24 # via: 192.168.100.99 # mtu: 1300 # metric: 100 - + # install: true # TODO # Configure logging level diff --git a/overlay/route.go b/overlay/route.go index e8626bb..41c7a9c 100644 --- a/overlay/route.go +++ b/overlay/route.go @@ -14,10 +14,11 @@ import ( ) type Route struct { - MTU int - Metric int - Cidr *net.IPNet - Via *iputil.VpnIp + MTU int + Metric int + Cidr *net.IPNet + Via *iputil.VpnIp + Install bool } func makeRouteTree(l *logrus.Logger, routes []Route, allowMTU bool) (*cidr.Tree4, error) { @@ -81,7 +82,8 @@ func parseRoutes(c *config.C, network *net.IPNet) ([]Route, error) { } r := Route{ - MTU: mtu, + Install: true, + MTU: mtu, } _, r.Cidr, err = net.ParseCIDR(fmt.Sprintf("%v", rRoute)) @@ -182,10 +184,20 @@ func parseUnsafeRoutes(c *config.C, network *net.IPNet) ([]Route, error) { viaVpnIp := iputil.Ip2VpnIp(nVia) + install := true + rInstall, ok := m["install"] + if ok { + install, err = strconv.ParseBool(fmt.Sprintf("%v", rInstall)) + if err != nil { + return nil, fmt.Errorf("entry %v.install in tun.unsafe_routes is not a boolean: %v", i+1, err) + } + } + r := Route{ - Via: &viaVpnIp, - MTU: mtu, - Metric: metric, + Via: &viaVpnIp, + MTU: mtu, + Metric: metric, + Install: install, } _, r.Cidr, err = net.ParseCIDR(fmt.Sprintf("%v", rRoute)) diff --git a/overlay/route_test.go b/overlay/route_test.go index 1d4286d..f83b5c1 100644 --- a/overlay/route_test.go +++ b/overlay/route_test.go @@ -92,6 +92,8 @@ func Test_parseRoutes(t *testing.T) { tested := 0 for _, r := range routes { + assert.True(t, r.Install) + if r.MTU == 8000 { assert.Equal(t, "10.0.0.1/32", r.Cidr.String()) tested++ @@ -205,35 +207,45 @@ func Test_parseUnsafeRoutes(t *testing.T) { assert.Nil(t, routes) assert.EqualError(t, err, "entry 1.mtu in tun.unsafe_routes is below 500: 499") + // bad install + c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "9000", "route": "1.0.0.0/29", "install": "nope"}}} + routes, err = parseUnsafeRoutes(c, n) + assert.Nil(t, routes) + assert.EqualError(t, err, "entry 1.install in tun.unsafe_routes is not a boolean: strconv.ParseBool: parsing \"nope\": invalid syntax") + // happy case c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{ - map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "9000", "route": "1.0.0.0/29"}, - map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "8000", "route": "1.0.0.1/32"}, + map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "9000", "route": "1.0.0.0/29", "install": "t"}, + map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "8000", "route": "1.0.0.1/32", "install": 0}, + map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "1500", "metric": 1234, "route": "1.0.0.2/32", "install": 1}, map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "1500", "metric": 1234, "route": "1.0.0.2/32"}, }} routes, err = parseUnsafeRoutes(c, n) assert.Nil(t, err) - assert.Len(t, routes, 3) + assert.Len(t, routes, 4) tested := 0 for _, r := range routes { if r.MTU == 8000 { assert.Equal(t, "1.0.0.1/32", r.Cidr.String()) + assert.False(t, r.Install) tested++ } else if r.MTU == 9000 { assert.Equal(t, 9000, r.MTU) assert.Equal(t, "1.0.0.0/29", r.Cidr.String()) + assert.True(t, r.Install) tested++ } else { assert.Equal(t, 1500, r.MTU) assert.Equal(t, 1234, r.Metric) assert.Equal(t, "1.0.0.2/32", r.Cidr.String()) + assert.True(t, r.Install) tested++ } } - if tested != 3 { - t.Fatal("Did not see both unsafe_routes") + if tested != 4 { + t.Fatal("Did not see all unsafe_routes") } } diff --git a/overlay/tun_darwin.go b/overlay/tun_darwin.go index d7b4884..6320570 100644 --- a/overlay/tun_darwin.go +++ b/overlay/tun_darwin.go @@ -287,7 +287,7 @@ func (t *tun) Activate() error { // Unsafe path routes for _, r := range t.Routes { - if r.Via == nil { + if r.Via == nil || !r.Install { // We don't allow route MTUs so only install routes with a via continue } diff --git a/overlay/tun_freebsd.go b/overlay/tun_freebsd.go index 0a3f722..1054228 100644 --- a/overlay/tun_freebsd.go +++ b/overlay/tun_freebsd.go @@ -86,7 +86,7 @@ func (t *tun) Activate() error { } // Unsafe path routes for _, r := range t.Routes { - if r.Via == nil { + if r.Via == nil || !r.Install { // We don't allow route MTUs so only install routes with a via continue } diff --git a/overlay/tun_linux.go b/overlay/tun_linux.go index 1406438..932b585 100644 --- a/overlay/tun_linux.go +++ b/overlay/tun_linux.go @@ -279,6 +279,10 @@ func (t tun) Activate() error { // Path routes for _, r := range t.Routes { + if !r.Install { + continue + } + nr := netlink.Route{ LinkIndex: link.Attrs().Index, Dst: r.Cidr, diff --git a/overlay/tun_water_windows.go b/overlay/tun_water_windows.go index 8e2e571..b1c28d6 100644 --- a/overlay/tun_water_windows.go +++ b/overlay/tun_water_windows.go @@ -80,7 +80,7 @@ func (t *waterTun) Activate() error { } for _, r := range t.Routes { - if r.Via == nil { + if r.Via == nil || !r.Install { // We don't allow route MTUs so only install routes with a via continue } diff --git a/overlay/tun_wintun_windows.go b/overlay/tun_wintun_windows.go index 0538849..9146c88 100644 --- a/overlay/tun_wintun_windows.go +++ b/overlay/tun_wintun_windows.go @@ -92,7 +92,7 @@ func (t *winTun) Activate() error { routes := make([]*winipcfg.RouteData, 0, len(t.Routes)+1) for _, r := range t.Routes { - if r.Via == nil { + if r.Via == nil || !r.Install { // We don't allow route MTUs so only install routes with a via continue }