Git Product home page Git Product logo

router7's Introduction

router7

GitHub Actions CI GoDoc Go Report Card

router7 is a pure-Go implementation of a small home internet router. It comes with all the services required to make a fiber7 internet connection work (DHCPv4, DHCPv6, DNS, etc.).

Note that this project should be considered a (working!) tech demo. Feature requests will likely not be implemented, and see CONTRIBUTING.md for details about which contributions are welcome.

For more details, please see router7.org

router7's People

Contributors

codezombiech avatar dependabot[bot] avatar hugelgupf avatar insanitywholesale avatar insomniacslk avatar mdlayher avatar philhug avatar pmazzini avatar robryk avatar sseering avatar stapelberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

router7's Issues

native dyndns support

The https://github.com/libdns libraries¹ provide a uniform interface for updating DNS records across providers.

We could use these to implement dyndns: take the public IPv4 address of uplink0 and set it as an A record in the configured provider(s).

Personally, I use cloudflare for DNS, and have a little program which does these updates.

① Not entirely sure how ready they are. They come with a disclaimer.

dnsd incorrectly serves expired leases

E.g., when loading this lease file:

[{"num":18,"addr":"10.0.0.20","hardware_addr":"9c:b6:d0:ff:ee:b5","hostname":"xps","expiry":"2018-08-05T13:17:58.937396571+02:00"},
{"num":193,"addr":"10.0.0.195","hardware_addr":"a4:4c:c8:ff:ee:47","hostname":"xps","expiry":"2018-07-26T11:22:57.338044686+02:00"}]

dnsd incorrectly resolves xps.lan to 10.0.0.195 (expected: 10.0.0.20).

WireGuard support

Filing this for tracking the ongoing work.

Current status:

  • include WireGuard kernel patch in https://github.com/rtr7/kernel
  • use Linux ≥ 5.6
  • WireGuard netlink package
  • make netconfigd read a config file and create/configure WireGuard interfaces
  • netconfig: switch to wgctrl-go package

prometheus metrics: also include incoming/outgoing traffic

We currently only have metrics for forwarded bytes:

name: "filter_forward",
labels: prometheus.Labels{"family": "ipv4"},
obj: &nftables.CounterObj{
Table: &nftables.Table{Family: nftables.TableFamilyIPv4, Name: "filter"},
Name: "fwded",
},
},
{
name: "filter_forward",
labels: prometheus.Labels{"family": "ipv6"},
obj: &nftables.CounterObj{
Table: &nftables.Table{Family: nftables.TableFamilyIPv6, Name: "filter"},
Name: "fwded",
},
},

Notably, forwarded bytes does not include bytes that were sent by the router itself, e.g. by the webserver or rsync server running on the machine.

dns: listen on tcp/53 as well

See https://dnsflagday.net/2020/ for more details

I ran the test on https://dnsflagday.net/2020/#action-dns-resolver-operators but it unexpectedly passed.

Testing on the command line showed that router7’s dns forwarder currently only listens on udp/53:

% dig +tcp @10.0.0.1 zekjur.net.  
;; Connection to 10.0.0.1#53(10.0.0.1) for zekjur.net. failed: connection refused.

Should be an easy fix since https://godoc.org/github.com/miekg/dns#Server supports tcp listeners, so maybe we just need to adjust

dnsListeners.ListenAndServe(hosts, func(host string) multilisten.Listener {

Container Manager

It would be interesting to be able to run containers on the router as a way to manage services like reverse proxies, media servers, etc.

Perhaps integrate podman?

Nat66 or Natv6p

Is there a possibility to do Nat66 or something equal to give fix IPv6 to a Client?

apu2c4 fails to TFTP boot after it did not become healthy after an update

I have seen this a few times now, but finally have a serial log from when it happened.

The symptom is:

  1. The automated update writes a new version and triggers a kexec reboot
  2. The apu2c4 comes up, but fails to obtain a DHCP4 or DHCP6 lease, or even do DNS resolution using the IP address it had before the reboot. It seems like all network packets are dropped.
  3. The updater recognizes the apu2c4 is unhealthy and triggers a reboot after starting a TFTP server (to revert to the old revision).
  4. The apu2c4 prints the following, then hangs indefinitely:
Next server: 10.0.0.76
Filename: lpxelinux.0
tftp://10.0.0.76/lpxelinux.0... ok
lpxelinux.0 : 74379 bytes [PXE-NBP]

The updater’s log contains:

2019/04/25 07:09:47 client will use IP address 10.0.0.1 during recovery
2019/04/25 07:09:47 building github.com/rtr7/tools/cmd/rtr7-recovery-init
2019/04/25 07:09:48 serving TFTP, HTTP, DHCP (for PXE clients) on 10.0.0.76 (enp0s31f6)
2019/04/25 07:10:06 [dhcp] 00:0d:b9:xx:yy:zz DHCPDISCOVER → DHCPOFFER
2019/04/25 07:10:06 [dhcp] 00:0d:b9:xx:yy:zz DHCPREQUEST → DHCPACK
2019/04/25 07:10:22 [tftp] lpxelinux.0: success
2019/04/25 07:52:06 [dhcp] 00:0d:b9:xx:yy:zz DHCPDISCOVER → DHCPOFFER
2019/04/25 07:52:06 [dhcp] 00:0d:b9:xx:yy:zz DHCPREQUEST → DHCPACK

Given pcengines/coreboot#181, I wonder if the network interfaces sometimes don’t properly come up, perhaps because we are doing a kexec reboot.

I’ll check the network LED the next time it happens, and will try to disable kexec to see if that helps.

cannot boot from usb

I operate as follows:
first, Create an instance
go install github.com/gokrazy/tools/cmd/gok@main go install github.com/rtr7/tools/cmd/…@latest mkdir /tmp/recovery gok -i router7 new gok -i router7 edit
secend, Modify config.json to
{ "Hostname": "router7", "Packages": [ "github.com/gokrazy/fbstatus", "github.com/gokrazy/hello", "github.com/gokrazy/serial-busybox", "github.com/gokrazy/breakglass" "github.com/rtr7/router7/cmd/…" ], "SerialConsole": "ttyS0,115200", "GokrazyPackages": [ "github.com/gokrazy/gokrazy/cmd/ntp", "github.com/gokrazy/gokrazy/cmd/randomd" ], "KernelPackage": "github.com/rtr7/kernel", "FirmwarePackage": "github.com/rtr7/kernel", "EEPROM Package": "" }
Then, build an image:
GOARCH=amd64 gok -i router7 overwrite --full /dev/sdc
sdc is usb stick

Insert the usb into the pc, start the boot, but the following error occurs,
/dev/root: Can't open blockdev VFS: cannot open root device "sdc2" or unknown-block(0,0): error -6 please append a correct "root=" boot option; here are the avilable partitions: 0810 500107608 sdb driver: sd
full log click here
How to solve it, thank you

implement DHCPDECLINE by ensuring the device gets a different IP

Turns out that Apple’s DHCP client sends DHCPDECLINE requests when it’s unhappy about a lease (e.g. because it thinks the IP address is still in use by some other device).

We should implement that and ensure giving out a different address for subsequent requests. This will result in a better failure mode.

WireGuard use-case: route all traffic through a WireGuard tunnel

Raw WireGuard support was added in #14, this issue covers a specific use-case.

At a high level: when running an event, we might want to not use the uplink directly, but rather use the uplink to establish a WireGuard tunnel and then route all outgoing traffic through the WireGuard tunnel instead. Semantically, this means uplink0 should be a WireGuard tunnel, and the network interface that’s currently uplink0 should be transit0 and only allow WireGuard traffic.

Side note: this would also be beneficial for https://gokrazy.org/ when using unencrypted WiFi networks. Depending on how the implementation goes, we should probably file a separate issue over there to make the result work on gokrazy, too, not just router7.

dhcp4d: Panic on truncated packet

Found using go-fuzz

func TestTruncatedPacketMustNotPanic(t *testing.T) {
        handler, cleanup := testHandler(t)
        defer cleanup()

        var hardwareAddr = net.HardwareAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}

        p := request(net.IPv4zero, hardwareAddr)
        for i := 1; i < len(p)-1; i++ {
                truncated := dhcp4.Packet(p[0:i])
                handler.ServeDHCP(truncated, dhcp4.Discover, truncated.ParseOptions())
                // should not panic...
        }
}

I did not try to replicate this "on the wire", so it could be a false positive.

nftables: counters per source IP

We could implement a visualization of network activity (e.g. 254 colored squares to represent a /24 network) if we had per-source IP network traffic counters.

This would also make it easy to attribute unexpected large transfers to individual IPs.

netconfigd should zero counters after reading to prevent prometheus artifacts

We have a mismatch between how Prometheus’s counter metric type is supposed to be used and how netconfigd uses it: we directly expose nftables counter values from a prometheus.CounterFunc in:

promauto.NewCounterFunc(
prometheus.CounterOpts{
Subsystem: "nftables",
Name: metric.name + "_packets",
Help: "packet count",
ConstLabels: metric.labels,
},
func() float64 {
rules, err := c.GetRule(metric.table, metric.chain)
if err != nil ||
len(rules) != 1 ||
len(rules[0].Exprs) != 1 {
return 0
}
if ce, ok := rules[0].Exprs[0].(*expr.Counter); ok {
return float64(ce.Packets)
}
return 0
})

This is bad, because while we get correct handling of counter resets due to reboots/kernel crashes, we get artifacts when netconfigd restarts and prometheus registers a reset of the metric, where there should not be a reset.

Currently, when netconfigd restarts (e.g. due to issues such as https://twitter.com/zekjur/status/1021076738875568129), this manifests itself as ghost-spikes in the graph and incorrect sum values:
2018-07-22-190214_1779x1077_scrot

rtr7-recover etc. MIA?

I cannot find rtr7-recover anywhere, even a search of all of GitHub turns up nothing but the readme here https://github.com/search?q=rtr7-recover&type=Code. A Google search shows a cached result for https://github.com/rtr7/tools but that seems to have been deleted.

$ rg rtr7-recovery $GOPATH
/home/mike/go/src/github.com/rtr7/router7/README.md
137:  * an initrd archive containing the rtr7-recovery-init program and mke2fs

Am I just being daft, or are these tools hiding somewhere out of sight?

IGMP proxying setup for tv7

Out of curiosity, I figured I’d see what would be necessary to make tv7 work with router7.

Running a statically compiled igmpproxy 0.2.1 via breakglass with the following config:

phyint uplink0 upstream altnet 77.109.129.0/25
phyint lan0 downstream

…results in a working SRF1 stream:

% curl https://api.init7.net/tvchannels.xspf
% vlc udp://@239.77.0.77:5000

With regards to what we’d need to do:

  • listen to IGMP packets
  • when a client joins an IGMP group, make the router join it
  • install a multicast route (see linux/mroute.h for the API) to tell the kernel to forward multicast packets from uplink0 to lan0 for the specific IGMP group
  • looks like the mroute API needs to be added to x/sys/unix first

https://haefelfinger.ch/posts/2018/2018-10-31-fiber7-tv7-with-plex-media-server/ looks like it might contain some additional pointers.

This all seems feasible, but since I don’t consume TV, I don’t have a lot of motivation to get this done. Help welcome.

recover failed due to DHCP/MAC address conflict

On the serial console, the APU displayed:

net0: 00:53:00:00:0c:01 using i210-2 on 0000:01:00.0 (open)
  [Link:up, TX:0 TXE:0 RX:0 RXE:0]
Configuring (net0 00:53:00:00:0c:01).................. ok
net0: 10.0.0.1/255.255.255.0
Next server: 10.0.0.76
Filename: lpxelinux.0
tftp://10.0.0.76/lpxelinux.0... ok
lpxelinux.0 : 74379 bytes [PXE-NBP]

rtr7-recover displayed:

2018/11/28 07:09:43 client will use IP address 10.0.0.1 during recovery
2018/11/28 07:09:43 building github.com/rtr7/tools/cmd/rtr7-recovery-init
2018/11/28 07:09:45 serving TFTP, HTTP, DHCP (for PXE clients) on 10.0.0.76 (enp0s31f6)
2018/11/28 07:10:02 [dhcp] DHCPDISCOVER 00:53:00:00:0c:01
2018/11/28 07:10:02 [dhcp] DHCPREQUEST 00:53:00:00:0c:01
2018/11/28 07:10:03 [dhcp] DHCPDISCOVER 00:53:ff:ff:0c:ff
2018/11/28 07:10:03 [dhcp] DHCPREQUEST 00:53:ff:ff:0c:ff
2018/11/28 07:10:18 [tftp] lpxelinux.0: success
2018/11/28 07:10:54 [tftp] ldlinux.c32: read udp [::]:42924: i/o timeout

Note that two clients requested a DHCP lease and apparently got a reply (!). This resulted in a MAC address conflict, which broke network booting.

This behavior indicates our PXE-only / MAC-address filter is not working correctly: https://github.com/rtr7/tools/blob/912a4ba20a17a119a50d2a769a6a54106fcf6499/cmd/rtr7-recover/recover.go#L111

teelogger (writing to /dev/console) is a footgun

w, err := os.OpenFile("/dev/console", os.O_RDWR, 0600)

When the Linux console becomes unavailable (e.g. console on ttyUSB0, you un-plug the receiving end (!) of the serial console), writes to /dev/console block indefinitely, making the dhcp4d hang.

It’s better to keep functioning without logs than to not function anymore.

We should make the teelogger not block on writing to /dev/console.

Edit: information on blocking /dev/console (or stdout, stderr if talking about pid 1) is sparse on the internet. Will need to do some experiments. I think even with an efifb console, pressing scroll lock might make things lock up? Will test on a Raspberry Pi instead of my router :)

Support for Hairpinning

I noticed that I'm unable to connect to a server inside my local network using the router7 public IP and the forwarded port.

Example
Local machine: 192.168.0.100
Public IP: 12.34.56.78
Port forwarding rule: :22 -> 192.168.0.100:22

Result: connection refused

Connecting from outside of router7 works perfectly fine.

To ensure we can connect from the local network using the public IP, it would be nice if support for Hairpinning (see Hairpinning and Hairpin-NAT) could be added. This could be achieved by adding additional nftables rules.

(thanks for @stapelberg for helping me investigating this issue)

documentation of setup issues

hello!

I got this project building and running, thank you it is great.

My experience with the install script differed slightly, I'm using fedora && it's silverblue.

That said, some of this may be unrelated to that. I made a repo for the fixes I made:

https://github.com/developing-today/rtr7-install

I don't have time to change it here, and also I'm not sure if all of it is relevant to you.

If I get some more time I may look into a proper pr, but I wanted to get this to you in the meantime.

Status of other ISPs?

Hi.

It comes with all the services required to make a fiber7 internet connection work (DHCPv4, DHCPv6, DNS, etc.).

I'd like to ask whether router7 works with ISPs other than fiber7. The README is phrased in a way that makes it sound as though ISPs have different requirements.

Thanks.

Allow configuring bridge devices

Currently, we have 2 individual network interfaces uplink0 and lan0.

When running on hardware that has more than just 2 network interfaces, we should allow bundling the interfaces into a lan0 bridge, so that all ports are treated equal (except for uplink0 of course).

Bread crumb: https://goyalankit.com/blog/linux-bridge is a good introduction

netconfigd leaks sockets

From the serial console log:

2018/07/22 18:21:13 netconfig.go:625: cannot apply dhcp6 lease: open /perm/dhcp6/wire/lease.json: too many open files
2018/07/22 18:21:13 netconfig.go:637: notifying dyndns: open /proc: too many open files
2018/07/22 18:21:13 netconfig.go:637: notifying dnsd: open /proc: too many open files
2018/07/22 18:21:13 netconfig.go:637: notifying diagd: open /proc: too many open files
2018/07/22 18:21:13 netconfig.go:637: notifying backupd: open /proc: too many open files
2018/07/22 18:21:13 netconfig.go:637: notifying captured: open /proc: too many open files
2018/07/22 18:21:13 netconfig.go:645: cannot apply sysctl config: sysctl(net.ipv4.ip_forward=1): open /proc/sys/net/ipv4/ip_forward: too many open files
2018/07/22 18:21:13 netconfigd.go:159: firewall: open /perm/portforwardings.json: too many open files

netconfigd is restarted, which fixes the issue, but we should plug the leak. Sending SIGUSR1 seems to trigger leaking 1 file descriptor.

WireGuard use-case: connect external computers into home network

Raw WireGuard support was added in #14, this issue covers a specific use-case.

At a high level: when traveling, it should be possible to use WireGuard to connect to router7 and get access to machines on the lan0 interface.

Also, outgoing IPv4 and IPv6 traffic should be routed to the internet.

It should be possible to set up multiple such tunnels (e.g. one per computer that needs access).

neighbour: arp_cache: neighbor table overflow!

This is the first time I have encountered the problem, but it is puzzling.

From the serial log:

2019/06/05 06:08:35 dhcp4d.go:148: DHCPACK &{Num:25 Addr:10.0.0.27 HardwareAddr:(removed) Hostname:scan2drive Expiry:0001-01-01 00:00:00 +0000 UTC}
[843041.359054] neighbour: arp_cache: neighbor table overflow!
[843041.364702] neighbour: arp_cache: neighbor table overflow!

These messages keep repeating multiple times per second.

tcpdump shows no suspicious traffic on either uplink0 or lan0.

The neighbor table garbage collection settings are unchanged from the default:

# sysctl -a | grep neigh
[…]
net.ipv4.neigh.default.gc_interval = 30
net.ipv4.neigh.default.gc_stale_time = 60
net.ipv4.neigh.default.gc_thresh1 = 128
net.ipv4.neigh.default.gc_thresh2 = 512
net.ipv4.neigh.default.gc_thresh3 = 1024
[…]

The error message (arp_cache instead of ndisc_cache) leads me to believe that the problem is IPv4-related, though the IPv6 neighbor table only contains FAILED, INCOMPLETE and NOARP entries for lan0 (maybe a symptom caused by the IPv4 issue?).

Anyway, the IPv4 neighbor table only seems to contain one entry:

# ./ip -4 neigh show nud all
212.51.156.1 dev uplink0 lladdr 00:24:14:ef:72:ff REACHABLE

(In normal operation, it contains only one entry on uplink0, but a whole bunch of entries on lan0.)

I also checked /proc/net/stat/arp_cache:

entries  allocs destroys hash_grows  lookups hits  res_failed  rcv_probes_mcast rcv_probes_ucast  periodic_gc_runs forced_gc_runs unresolved_discards table_fulls
00000001  00001e12 000029f2 00000000  00338bff 001a39c2  000003e5  00000000 00000000  00000000 000015e8 00000000 00000b60
00000001  0000128d 00001860 00000000  00000000 00000000  000002a2  00000000 00000000  00000000 00000d85 00000000 00000b09
00000001  00002952 00002910 00000000  00000000 00000000  000003fe  00000000 00000000  0000d635 000017b0 00000000 00000b41
00000001  00005498 00004326 00000002  0012915b 000eef8d  000001b0  00000000 00000000  00000000 00004f53 00000071 00002e2a

I tried inserting a new entry into the neighbor table:

execve("./arp", ["./arp", "-s", "10.0.0.76", "(removed)"], 0x7ffd220b0438 /* 7 vars */) = 0
brk(NULL)                               = 0x21ce000
brk(0x21cf200)                          = 0x21cf200
arch_prctl(ARCH_SET_FS, 0x21ce8c0)      = 0
uname({sysname="Linux", nodename="router7", ...}) = 0
readlink("/proc/self/exe", "/perm/sh", 4096) = 8
brk(0x21f0200)                          = 0x21f0200
brk(0x21f1000)                          = 0x21f1000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
getuid()                                = 0
socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
ioctl(3, SIOCSARP, 0x7ffe5607713c)      = -1 ENOBUFS (No buffer space available)
write(2, "arp: SIOCSARP: No buffer space a"..., 41arp: SIOCSARP: No buffer space available
) = 41
exit_group(1)                           = ?
+++ exited with 1 +++

I also checked free memory:

             total         used         free       shared      buffers
Mem:       4020136       561812      3458324        38352       101844
-/+ buffers:             459968      3560168
Swap:            0            0            0

It’s a mystery to me how the neighbor table can be considered full with only one entry in it.

This is with Linux 5.1.1.

dhcp4d causes an IP address conflict

2018/12/14 23:10:13 dhcp4d.go:122: DHCPACK &{Num:1 Addr:10.0.0.3 HardwareAddr:00:e0:4c:68:fe:07 Hostname:xps Expiry:2018-12-15 01:10:13.724814008 +0100 CET m=+64928.993070360}
[…]
2018/12/14 23:16:54 dhcp4d.go:122: DHCPACK &{Num:1 Addr:10.0.0.3 HardwareAddr:80:e6:50:21:3a:36 Hostname:mbp Expiry:2018-12-15 01:16:54.061257234 +0100 CET m=+65329.329513710}

Unfortunately I don’t have a full capture because of issue #17

RADIUS server for authenticating 802.1x

The idea is to have people end up in a guest network (VLAN) of sorts until they authenticate using a certificate. This is a common setup in corporate environments.

Not sure if this is doable with reasonable effort.

It should probably go into a separate repository for the time being.

diagd: skip ICMP check for external targets

For network infrastructure (the default gateway), it makes sense to use ICMP (ping) for checking reachability.

For other targets (google.ch), ICMP does not necessarily work, while TCP connections should always work. We should remove the ICMP step in favor of just the TCP step.

reduce time for obtaining IPv6 router advertisment after rebooting

Currently, after an update, it sometimes takes up to a minute for the router to become healthy:

2018/10/24 08:35:53 unhealthy after 1m17.275630943s: unhealthy: ping6gw/<default-gateway>: i/o timeout
2018/10/24 08:35:54 became healthy after 1m18.332338502s

I think this is because we don’t solicit router advertisments, we just listen for them.

We could probably make dhcp6 send a router solicitation packet once it can successfully bind to the uplink0 interface.

staticcheck issues

Hey @stapelberg! Hello from my Twitch stream! :)

Just ran staticcheck and noticed some issues on the repo, and wanted to let you know!

$ staticcheck ./...
cmd/dhcp4d/dhcp4d.go:390:4: this value of b is never used (SA4006)
integration/radvd/radvd_test.go:81:2: the goroutine calls T.Fatal, which must be called in the same goroutine as the test (SA2002)
        integration/radvd/radvd_test.go:83:4: call to T.Fatal
internal/dhcp4/dhcp4.go:103:14: error strings should not be capitalized (ST1005)
internal/dhcp4d/dhcp4d_test.go:115:34: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:158:52: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:166:53: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:191:53: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:230:53: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:242:53: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:249:53: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:256:53: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:282:52: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:315:54: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:328:54: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:362:54: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:411:52: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp4d/dhcp4d_test.go:455:52: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/dhcp6/dhcp6.go:171:15: error strings should not be capitalized (ST1005)
internal/dns/dns.go:330:5: error var sentinelEmpty should have name of the form errFoo (ST1012)
internal/dns/dns_test.go:415:62: use net.IP.Equal to compare net.IPs, not bytes.Equal (SA1021)
internal/netconfig/netconfig.go:240:2: this value of err is never used (SA4006)
internal/radvd/radvd.go:266:14: icmp.DefaultMessageBody is deprecated: Use RawBody instead.  (SA1019)
internal/testing/dnsmasq/dnsmasq.go:112:2: the goroutine calls T.Fatalf, which must be called in the same goroutine as the test (SA2002)
        internal/testing/dnsmasq/dnsmasq.go:119:4: call to T.Fatalf

I will take a look and fix up a few of these at a time too!

optionally block incoming IPv6 connections except for explicitly allowed IPs

It might be prudent to only allow incoming IPv6 connections to IP addresses which are explicitly listed, and default to not allowing incoming connections to other IPs.

In terms of configuration, the feature will be enabled as soon as a non-empty array of allowed IP addresses is defined (blocking all incoming connections can be achieved by allowing an unused IP address).

These are the nftables commands I used for prototyping:

# nft add chain ip6 filter forward '{' type filter hook forward priority 0 \; '}'
# nft add chain ip6 filter block-incoming
# nft add rule ip6 filter forward jump block-incoming
# nft add rule ip6 filter block-incoming oifname "lan0" tcp flags syn ip6 daddr ::1 accept
# nft add rule ip6 filter block-incoming oifname "lan0" tcp flags syn reject

system clock weirdness

From my most recent boot:

2020/05/27 21:37:53 listeners.go:141: now listening on 127.0.0.1:80

The time being way off resulted in an update not succeeding:

2018/11/28 07:08:22 unhealthy after 39.59549534s: unhealthy: dhcp6: lease expired at 2018-11-28 07:28:03.860663142 +0100 CET

Note that the expiration timestamp is in the future.

Not sure what’s happening here. We’re setting the RTC in https://github.com/gokrazy/gokrazy/blob/2216841c80ef508f43b5b742ff423124f965f868/cmd/ntp/rtc.go

more recent DHCP leases should overwrite DNS entries from earlier DHCP leases

Currently, when connecting a computer via 2 links at the same time (wifi & ethernet), then severing a link (say, wifi), and reconnecting on the remaining link (ethernet), the hostname does not necessarily resolve to the ethernet IP address.

We should probably sort DHCP entries by expiration time descending, so that the newer lease gets the DNS entry.

captured stops upon interrupted system call

From the stdout:

2018/12/14 07:28:08 NextPacket: interrupted system call
2018/12/14 10:21:09 NextPacket: interrupted system call

When attaching wireshark, I see packets before 10:21 and after 23:13 (when I attached).

Failing build

I think the latest additions to gokrazy broke the build of router7.

I tried to reproduce the build failure in a docker container:

me@host: docker run --rm -t -i golang:1.14-buster bash
root@9d2557ae7b13:/go# go get -u github.com/gokrazy/tools/cmd/gokr-packer github.com/rtr7/tools/cmd/...
root@9d2557ae7b13:/go# go get -u -d github.com/rtr7/router7
root@9d2557ae7b13:/go# mkdir /tmp/recovery
root@9d2557ae7b13:/go# GOARCH=amd64 gokr-packer \
> -hostname=router7 \
> -overwrite_boot=/tmp/recovery/boot.img \
> -overwrite_mbr=/tmp/recovery/mbr.img \
> -overwrite_root=/tmp/recovery/root.img \
> -kernel_package=github.com/rtr7/kernel \
> -firmware_package=github.com/rtr7/kernel \
> -gokrazy_pkgs=github.com/gokrazy/gokrazy/cmd/ntp \
> -serial_console=ttyS0,115200n8 \
> github.com/rtr7/router7/cmd/...
2020/07/01 20:29:08 packer.go:353: building [github.com/rtr7/router7/cmd/...]
2020/07/01 20:29:08 gotool.go:77: getting incomplete packages [github.com/gokrazy/gokrazy/cmd/ntp github.com/rtr7/router7/cmd/backupd github.com/rtr7/router7/cmd/captured github.com/rtr7/router7/cmd/dhcp4 github.com/rtr7/router7/cmd/dhcp4d github.com/rtr7/router7/cmd/dhcp6 github.com/rtr7/router7/cmd/diagd github.com/rtr7/router7/cmd/dnsd github.com/rtr7/router7/cmd/dyndns github.com/rtr7/router7/cmd/netconfigd github.com/rtr7/router7/cmd/radvd github.com/gokrazy/gokrazy github.com/rtr7/kernel]
2020/07/01 20:31:48 write.go:149: writing boot file system
can't load package: package github.com/gokrazy/rpi-eeprom: cannot find package "github.com/gokrazy/rpi-eeprom" in any of:
	/usr/local/go/src/github.com/gokrazy/rpi-eeprom (from $GOROOT)
	/go/src/github.com/gokrazy/rpi-eeprom (from $GOPATH)
2020/07/01 20:31:48 packer.go:822: [go list -f {{ .Dir }} github.com/gokrazy/rpi-eeprom]: exit status 1

dhcp4 fails to acquire lease (race with netconfigd?)

Today, dhcp4 did not acquire a lease. Wireshark showed no DHCP packets going out, so most likely, dhcp4 was unable to send them out. Restarting the process fixed the issue.

My suspicion is that this is another race with netconfigd, where dhcp4 starts up while netconfigd is configuring the interfaces. The interface must have the correct name for dhcp4 to successfully start up (see logs below), and the MAC address is handled by commit 3dad1e9, so the only two remaining bits of configuration are whether there is a link, and which IP addresses are configured on the interface. Maybe some bit of our DHCP code relies on the address?

dhcp4:

2019/03/04 07:07:50 gokrazy: attempt 0, starting [/user/dhcp4]
2019/03/04 07:07:52 dhcp4.go:138: route ip+net: no such network interface
2019/03/04 07:07:52 gokrazy: exit status 1
2019/03/04 07:07:53 gokrazy: attempt 1, starting [/user/dhcp4]
2019/03/04 07:07:53 dhcp4.go:138: route ip+net: no such network interface
2019/03/04 07:07:53 gokrazy: exit status 1
2019/03/04 07:07:54 gokrazy: attempt 2, starting [/user/dhcp4]
2019/03/04 07:08:05 dhcp4.go:93: Temporary error: DHCP: timeout (server(s) unreachable) (waiting 10s)

dmesg:

07:07:54
[    7.383282] igb 0000:01:00.0 lan0: renamed from eth0
[    7.418912] IPv6: ADDRCONF(NETDEV_UP): lan0: link is not ready
[    7.426831] igb 0000:03:00.0 uplink0: renamed from eth2
[    7.475706] IPv6: ADDRCONF(NETDEV_UP): uplink0: link is not ready
[   10.186236] igb 0000:01:00.0 lan0: igb: lan0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[   10.299977] IPv6: ADDRCONF(NETDEV_CHANGE): lan0: link becomes ready
[   10.346282] igb 0000:03:00.0 uplink0: igb: uplink0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
[   10.357028] IPv6: ADDRCONF(NETDEV_CHANGE): uplink0: link becomes ready

netconfigd:

2019/03/04 07:07:54 netconfig.go:260: apply details {HardwareAddr:xx SpoofHardwareAddr:yy Name:lan0 Addr:10.0.0.1/24}
2019/03/04 07:07:54 netconfig.go:257: no config for interface eth1/zz
2019/03/04 07:07:54 netconfig.go:260: apply details {HardwareAddr:x2 SpoofHardwareAddr:y2 Name:uplink0 Addr:}

dhcp4: remove old IP address from interface when getting a new one

Currently, when the upstream DHCP4 server hands out a new IP address, we end up having two addresses on uplink0:

4: uplink0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
    inet 212.51.156.82/24 brd 212.51.156.255 scope global uplink0
       valid_lft forever preferred_lft forever
    inet 212.51.156.17/24 brd 212.51.156.255 scope global secondary uplink0
       valid_lft forever preferred_lft forever

We should ensure that any IP addresses that dhcp4 added to the interface will be removed when a different IP address is obtained. We don’t need to immediately remove addresses when we no longer have the lease (it might still work!), though.

This improvement was prompted by DHCP4 outage https://as13030.net/status/?ticket=OPS-32 ;)

rtr7-safe-update: should wait for unhealthy first

From the logs:

[…]
2019/03/04 09:21:13 446 bytes in 2.781371ms, i.e. 0.152924 MiB/s
2019/03/04 09:21:15 awaiting healthiness
2019/03/04 09:21:15 became healthy after 283ns

Obviously, this was checking healthiness just before the device rebooted. We should await unhealthiness, then healthiness again.

undefined: pcapgo.OpenEthernet

I'm running into issue while building:
src/github.com/rtr7/router7/cmd/captured/captured.go:48:18: undefined: pcapgo.OpenEthernet

I can't find OpenEthernet function in github.com/google/gopacket, there is only OpenLive, OpenOffline.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.