CoreRAD is an extensible and observable IPv6 Neighbor Discovery Protocol router advertisement daemon. Apache 2.0 Licensed.

CoreRAD Test Go Reference Go Report Card

CoreRAD is an extensible and observable IPv6 Neighbor Discovery Protocol router advertisement daemon.

Apache 2.0 Licensed.

To get started with CoreRAD, check out corerad.net!

Overview

CoreRAD has reached v1.x.x and is considered stable and ready for production use on Linux routers. Users are welcome to join us on:

For more information, you can also check out:

CoreRAD is inspired by the CoreDNS and CoreDHCP projects.

Dashboard

A sample Grafana + Prometheus dashboard for CoreRAD can be found at corerad-grafana.json.

CoreRAD Grafana + Prometheus dashboard

Owner
Matt Layher
Software Engineer. Go, Rust, Linux, networking, and open source software. On and ever upward.
Matt Layher
Comments
  • Router Solicitation spam

    Router Solicitation spam

    Whenever I enable corerad on my network my wlan adapter starts seeing a lot of Router Solicitation spam. Around 1-2 dozen a second. I've tried changing reachable_time and retransmit_timer hoping that may fix it but no dice. As soon as I stop corerad the spam stops. Not really sure what I'm doing wrong. I've included an image of the types of packets I see in wireshark. Screenshot from 2022-08-04 00-38-00

  • docs: provide recommended systemd unit

    docs: provide recommended systemd unit

    We can basically steal and tidy the one I'm using with my NixOS package and module:

    [matt@routnerr-2:~]$ systemctl cat corerad
    # /nix/store/g67911s4ili2jpf99qcapv0c7ynwda6l-unit-corerad.service/corerad.service
    [Unit]
    After=network.target
    Description=CoreRAD IPv6 NDP RA daemon
    
    [Service]
    Environment="LOCALE_ARCHIVE=/nix/store/irbxdgqx84sj3aknpi3l38qw1gs4qgsc-glibc-locales-2.30/lib/locale/locale-archive"
    Environment="PATH=/nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin:/nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/bin:/nix/store/srmjkp5pq8c055j0lak2hn0ls0fis8yl-gnugrep-3.4/bin:/nix/>
    Environment="TZDIR=/nix/store/caalbaj31answcw6gjabf6xfsdaa8hk1-tzdata-2019c/share/zoneinfo"
    
    
    
    AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
    CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
    DynamicUser=true
    ExecStart=/nix/store/zvls0b2f3hpvkgj766sr3hk1zrighrj3-corerad-0.2.7/bin/corerad -c=/nix/store/4c34qf2rxlw3w346x8fw1qzdpfqqy55b-corerad.toml
    LimitNOFILE=1048576
    LimitNPROC=512
    NoNewPrivileges=true
    NotifyAccess=main
    Restart=on-failure
    Type=notify
    
  • internal/corerad: support for config reload without removing client default routes

    internal/corerad: support for config reload without removing client default routes

    At the moment, whenever CoreRAD shuts down, it sends a multicast RA with default lifetime 0 which causes clients to drop their default route. If an immediate restart is needed to reload config or similar, we should look into what it would take to perform an online config reload via SIGHUP.

    In addition, maybe we can differentiate the signals sent by systemctl restart vs systemctl stop to control the default route removal behavior.

  • failed to send scheduled router advertisement ... network is unreachable

    failed to send scheduled router advertisement ... network is unreachable

    corerad works for me but I see once in the logs:

    2020/01/02 10:34:01 ens18: failed to send scheduled router advertisement to ::: failed to send router advertisement to ::: write ip fe80::8883:72ff:fe56:a25b%ens18->::%ens18: sendmsg: network is unreachable
    

    ... even though ndp ndp rs works fine.

    So not sure what's with that single log entry. Why was it unreachable just once when it's been running fine for hours?

  • Prometheus documentation: default to listening on all addresses.

    Prometheus documentation: default to listening on all addresses.

    localhost:9430 picks one particular IP/interface, which can be quite confusing on systems with many interfaces or addresses. It likely makes most sense to default to listening on all addresses so this does not cause confusion.

    (And we expect users to have adequate firewalling to prevent access from WAN if relevant)


    Some additional background: I spent more time than I'm comfortable admitting, trying to debug why Prometheus running in Docker container could not reach corerad on the host. From Docker, the host is addressed as 172.x.x.x, an address that corerad does not bind to if one uses address = "localhost:9430".

    Thanks!

  • internal/corerad: rework Metrics type

    internal/corerad: rework Metrics type

    The current Metrics structure is difficult to test, and in order to generate reliable alerts in critical conditions, we need better test coverage on the generation of metrics under different failure scenarios.

    Consider making the Metrics type an interface to enable better testing without setting up an entire CoreRAD/HTTP/Prometheus scrape stack.

  • docs: initial commit

    docs: initial commit

    I haven't put much thought into what sorts of plugins should exist as of yet, but I certainly think it makes sense to support:

    • static option configuration via config file
    • dynamic request/response handling via HTTP/gRPC API

    I also wonder if it'd make sense to try to query upstream routers for certain configurations, but I want to be sure I don't do anything funny that'd totally violate the RFCs.

    /cc @miekg @hugelgupf @insomniacslk

  • RFC: internal/*: support for automatic routes from loopback

    RFC: internal/*: support for automatic routes from loopback

    Signed-off-by: Matt Layher [email protected]

    I've traveled a bit recently and noticed some ATT DHCPv6-PD setups are advertising:

    • prefix /64 for SLAAC
    • route information for the covering /60

    This makes sense in the event that multiple routers may be present on a network: the router "owns" the covering /60 and anything in that /60 should be sent to that router. An unreachable route for the /60 is set on router's lo and then longer /64 routes are added for each LAN.

    Consider a hypothetical /48 DHCPv6-PD setup may configure the following addresses and routes on cradveth0 (a LAN interface) and lo, the loopback:

    $ ip -6 a s dev cradveth0
    4: cradveth0@cradveth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        inet6 2001:db8::1/64 scope global 
           valid_lft forever preferred_lft forever
        inet6 fd38:4ad5:6ad6::1/64 scope global 
           valid_lft forever preferred_lft forever
        inet6 fe80::d02b:fdff:fe71:97c9/64 scope link 
           valid_lft forever preferred_lft forever
    
    $ ip -6 r s dev lo
    ::1 proto kernel metric 256 pref medium
    unreachable 2001:db8::/48 metric 1024 pref medium
    unreachable 2001:db8::/32 metric 1024 pref medium
    unreachable fd38:4ad5:6ad6::/48 metric 1024 pref medium
    

    For demonstration, I've also added an overlapping /32 for the delegated prefix and a ULA /48.

    Given the following configuration:

    # CoreRAD development (n/a) configuration file
    [[interfaces]]
    name = "cradveth0"
    advertise = true
      [[interfaces.prefix]]
      [[interfaces.route]]
    

    CoreRAD will start up as follows:

    $ sudo ./corerad 
    CoreRAD development (n/a) starting with configuration file "corerad.toml"
    cradveth0: "prefix": ::/64 [fd38:4ad5:6ad6::/64] [on-link, autonomous], preferred: 4h0m0s, valid: 24h0m0s
    cradveth0: "route": ::/0 [2001:db8::/32, fd38:4ad5:6ad6::/48], preference: Medium, lifetime: 24h0m0s
    cradveth0: "lla": source link-layer address: d2:2b:fd:71:97:c9
    cradveth0: initialized, advertising from fe80::d02b:fdff:fe71:97c9
    

    Producing the following router advertisement:

    $ ndp -i cradveth1 rs
    ndp> interface: cradveth1, link-layer address: 2e:81:cb:78:01:ad, IPv6 address: fe80::2c81:cbff:fe78:1ad
    ndp rs> router solicitation:
      - source link-layer address: 2e:81:cb:78:01:ad
    
    ndp rs> router advertisement from: fe80::d02b:fdff:fe71:97c9:
      - hop limit:        64
      - preference:       Medium
      - router lifetime:  30m0s
      - options:
        - prefix information: 2001:db8::/64, flags: [on-link, autonomous], valid: 24h0m0s, preferred: 4h0m0s
        - prefix information: fd38:4ad5:6ad6::/64, flags: [on-link, autonomous], valid: 24h0m0s, preferred: 4h0m0s
        - route information: 2001:db8::/32, preference: Medium, lifetime: 24h0m0s
        - route information: fd38:4ad5:6ad6::/48, preference: Medium, lifetime: 24h0m0s
        - source link-layer address: d2:2b:fd:71:97:c9
    

    This seems like a useful behavior to me, but there are some questions here:

    • What happens if a user is using multiple routing tables? Right now we only check for automatic routes from "main", table 254. Do we tell the user they're on their own?
    • Would it be useful to support ::/48 or similar instead of just ::/0, meaning "any route /48 or longer?". This would drop the covering /32.
    • Should we only support this behavior for routes with type unreachable/blackhole? Right now we ignore the type and assume any route configured on a loopback should be redistributed via NDP RA.

    Feedback very welcome! This is something I want to deploy on my own LAN but I am also afraid of implementing something that is subtly incorrect.

  • internal/plugin: implement RDNSS wildcard syntax

    internal/plugin: implement RDNSS wildcard syntax

    Signed-off-by: Matt Layher [email protected]

    Credit for this idea comes from https://github.com/radvd-project/radvd/issues/126. I've been configuring automatic DNS servers via my NixOS templating, but this will be even more convenient for cases where CoreRAD and a DNS server are bound to the same interface.

  • corerad: release v0.3.0 stable

    corerad: release v0.3.0 stable

    With all the work that's been done through the v0.1.x alpha and v0.2.x beta series, I think we are approaching a time where I can tag a v0.3.x "stable" series.

    My intent is to stabilize as much of CoreRAD as possible during v0.3.x as a possible predecessor to a v1.0.0 release:

    • configuration file format
    • default configuration settings
    • Prometheus metrics output
    • HTTP API interface

    Another big goal is to have a nice and polished website with docs about:

    • getting started
    • full configuration
    • systemd unit
    • internal architecture
    • future work

    I'll create a v0.3.0 project and start adding issues to that project.

  • internal/netstate: move back in from external repo and rework

    internal/netstate: move back in from external repo and rework

    github.com/mdlayher/netstate was factored out of this package a bit prematurely and could probably use more work. We should pull it back in and re-evaluate the situation on Linux and *BSD.

  • allow to specify source LLA's address

    allow to specify source LLA's address

    While this causes a breaking change in the way source_lla is configured, it could be an approach to allow for overriding the source link-layer address derived from the dialing interface.

    This PR is in response to #26

  • Investigate sending RAs on behalf of an actual router

    Investigate sending RAs on behalf of an actual router

    @skoef writes:

    I have a question that relates to this issue but is unrelated to WireGuard however: I'm currently running a RAD that I've built myself to send out router advertisements on behalf of my actual router. Basically the trick is to use the router's link local address in the router advertisement instead of the interface's which is sending the RA.

    This wouldn't be possible in the current implementation either since the hardwareaddr is taken from the interface from the dialcontext, but if CoreRAD would allow me to do this, I could replace my own implementation for CoreRAD right away: it has everything I need and then some.

    Would this be something that CoreRAD could offer, or is it perhaps against some principal ideas behind CoreRAD and/or hardcore violating RFCs (didn't check but can imagine). Otherwise I would gladly send in a PR for this feature!

    I'll need to think on this further and make sure it doesn't result in any weird behaviors to have a mismatch between the Ethernet source MAC and RA source MAC.

  • Ability to use on wireguard interfaces that have no MAC address

    Ability to use on wireguard interfaces that have no MAC address

    Very interesting project, I was trying to tinker with corerad for having IPv6 autoconfiguration / SLAAC to work over a wireguard tunnel. This does not seem to be possible at the moment?

    root@mia2:/etc/systemd/system# /usr/local/bin/corerad -c=/etc/corerad/corerad.toml
    CoreRAD v0.3.0-15-g8f828f7 (2021-03-05) starting with configuration file "/etc/corerad/corerad.toml"
    starting HTTP debug listener on "localhost:9430": prometheus: true, pprof: false
    eth0: initialized, monitoring from fe80::216:3eff:fec5:213d
    failed to run: failed to serve: failed to run task advertiser "noproxy": failed to reinitialize "noproxy" listener: interface "noproxy" has no MAC address
    root@mia2:/etc/systemd/system# wg show
    interface: noproxy
      public key: nope
      private key: (hidden)
      listening port: 88
    
    peer: somepeer
      preshared key: (hidden)
      endpoint: [2x]:56692
      allowed ips: 10.100.100.10/32, 2x:b00b::10/128
      latest handshake: 1 minute, 51 seconds ago
      transfer: 18.58 KiB received, 354.57 KiB sent
    
    

    I have a VPS with a public IPv6 /64 allocation that I am hoping to route via wireguard to my home. I have been successful at configuring wireguard peers with the public IPv6 segment and then on the VPS host using linux kernel 'net.ipv6.conf.all.proxy_ndp' and manual 'ip -6 neigh add proxy ' commands to allow RAs to be proxied.

    eth0 is VPS connection to the internet and where IPv6 /64 is assigned. 'noproxy' is the wireguard interface name that clients connect to.

    While this works great when I want to give a wireguard client only a single IPv6 I was trying to explore if I could allow more of the available IPv6 public pool to work over wireguard as well. For example, Windows 10 has by default IPv6 privacy extensions enabled and its common to see a win10 client have 4-6 IPv6s autoconfigured on the network. I was experimenting in ways to make it work over wireguard - I think I am halfway there but I think I am limited by linux's ndp proxy capabilities - and I rather not have to deal with cumbersome manual adding of proxy entries to the IPv6 neighbors table if I could have corerad or similar service handle this for me.

    Hope this makes sense? Again, just experimenting to see what other alternatives could work and truly enable SLAAC via wireguard. corerad seems promising but it crashed after I tried to run it - as it seems to have a depency on a mac address.

  • internal/corerad: *BSD autoconf and forwarding configuration

    internal/corerad: *BSD autoconf and forwarding configuration

    After fixing a small compilation failure, it looks like CoreRAD works just fine on FreeBSD.

    $ sudo tcpdump icmp6 -vvv
    tcpdump: listening on vtnet0, link-type EN10MB (Ethernet), capture size 262144 bytes
    15:21:50.906990 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 160) fe80::a026:8aff:fe33:4e1 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 160
            hop limit 64, Flags [none], pref medium, router lifetime 1800s, reachable time 0s, retrans time 0s
              prefix info option (3), length 32 (4): 2604:a880:cad:d0::/64, Flags [onlink, auto], valid time 86400s, pref. time 14400s
                0x0000:  40c0 0001 5180 0000 3840 0000 0000 2604
                0x0010:  a880 0cad 00d0 0000 0000 0000 0000
              prefix info option (3), length 32 (4): 2001:db8::/64, Flags [onlink, auto], valid time 86400s, pref. time 14400s
                0x0000:  40c0 0001 5180 0000 3840 0000 0000 2001
                0x0010:  0db8 0000 0000 0000 0000 0000 0000
              rdnss option (25), length 40 (5):  lifetime 1200s, addr: 2001:db8::1 addr: 2001:db8::2
                0x0000:  0000 0000 04b0 2001 0db8 0000 0000 0000
                0x0010:  0000 0000 0001 2001 0db8 0000 0000 0000
                0x0020:  0000 0000 0002
              dnssl option (31), length 32 (4):  lifetime 1200s, domain(s): foo.example.com.
                0x0000:  0000 0000 04b0 0366 6f6f 0765 7861 6d70
                0x0010:  6c65 0363 6f6d 0000 0000 0000 0000
              source link-address option (1), length 8 (1): a2:26:8a:33:04:e1
                0x0000:  a226 8a33 04e1
    

    We should add support for tuning *BSD kernel configuration as well.

SOCKS Protocol Version 5 Library in Go. Full TCP/UDP and IPv4/IPv6 support

socks5 中文 SOCKS Protocol Version 5 Library. Full TCP/UDP and IPv4/IPv6 support. Goals: KISS, less is more, small API, code is like the original protoc

Jan 8, 2023
Package arp implements the ARP protocol, as described in RFC 826. MIT Licensed.

arp Package arp implements the ARP protocol, as described in RFC 826. MIT Licensed. Portions of this code are taken from the Go standard library. The

Dec 20, 2022
Quickly find all IPv6 and IPv4 hosts in a LAN.

invaentory Quickly find all IPv6 and IPv4 hosts in a LAN. Overview ?? This project is a work-in-progress! Instructions will be added as soon as it is

May 17, 2022
The Dual-Stack Dynamic DNS client, the world's first dynamic DNS client built for IPv6.

dsddns DsDDNS is the Dual-Stack Dynamic DNS client. A dynamic DNS client keeps your DNS records in sync with the IP addresses associated with your hom

Sep 27, 2022
Sep 23, 2022
Package ethernet implements marshaling and unmarshaling of IEEE 802.3 Ethernet II frames and IEEE 802.1Q VLAN tags. MIT Licensed.

ethernet Package ethernet implements marshaling and unmarshaling of IEEE 802.3 Ethernet II frames and IEEE 802.1Q VLAN tags. MIT Licensed. For more in

Dec 29, 2022
Package raw enables reading and writing data at the device driver level for a network interface. MIT Licensed.

raw Package raw enables reading and writing data at the device driver level for a network interface. MIT Licensed. For more information about using ra

Dec 28, 2022
Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and deadline support. MIT Licensed.

socket Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and d

Dec 14, 2022
Package dhcp6 implements a DHCPv6 server, as described in RFC 3315. MIT Licensed.

dhcp6 Package dhcp6 implements a DHCPv6 server, as described in IETF RFC 3315. MIT Licensed. At this time, the API is not stable, and may change over

Sep 27, 2022
wire protocol for multiplexing connections or streams into a single connection, based on a subset of the SSH Connection Protocol

qmux qmux is a wire protocol for multiplexing connections or streams into a single connection. It is based on the SSH Connection Protocol, which is th

Dec 26, 2022
A simple tool to convert socket5 proxy protocol to http proxy protocol

Socket5 to HTTP 这是一个超简单的 Socket5 代理转换成 HTTP 代理的小工具。 如何安装? Golang 用户 # Required Go 1.17+ go install github.com/mritd/s2h@master Docker 用户 docker pull m

Jan 2, 2023
Message relay written in golang for PostgreSQL and Apache Kafka

Message Relay Message relay written in golang for PostgreSQL and Apache Kafka Requirements Docker and Docker Compose Local installation and using dock

Dec 19, 2021
This project provides fully automated one-click experience to create Cloud and Kubernetes environment to run Data Analytics workload like Apache Spark.
This project provides fully automated one-click experience to create Cloud and Kubernetes environment to run Data Analytics workload like Apache Spark.

Introduction This project provides a fully automated one-click tool to create Data Analytics platform in Cloud and Kubernetes environment: Single scri

Nov 25, 2022
Use Consul to do service discovery, use gRPC +kafka to do message produce and consume. Use redis to store result.
Use  Consul to do service discovery, use gRPC +kafka to do message produce and consume. Use redis to store result.

目录 gRPC/consul/kafka简介 gRPC+kafka的Demo gRPC+kafka整体示意图 限流器 基于redis计数器生成唯一ID kafka生产消费 kafka生产消费示意图 本文kafka生产消费过程 基于pprof的性能分析Demo 使用pprof统计CPU/HEAP数据的

Jul 9, 2022
Subfinder is a subdomain discovery tool that discovers valid subdomains for websites. Designed as a passive framework to be useful for bug bounties and safe for penetration testing.
Subfinder is a subdomain discovery tool that discovers valid subdomains for websites. Designed as a passive framework to be useful for bug bounties and safe for penetration testing.

Fast passive subdomain enumeration tool. Features • Install • Usage • API Setup • License • Join Discord Subfinder is a subdomain discovery tool that

Jan 4, 2023
Service registration and discovery, support etcd, zookeeper, consul, etc.

discox 支持类型 zookeeper etcd consul 示例 zookeeper server package main import ( "fmt" "github.com/goeasya/discox" "os" ) func main() { cfg := discox

Aug 31, 2022
Aidos Kuneen (v2 network) daemon program that is controlled through the command line and remotely via RPC calls

adk-daemon: aidosd.v2 aidosd (v2) is a deamon which acts as bitcoind for adk. This version has been built specifically for network mesh version 2+ For

Dec 1, 2021
A service registry and service discovery implemention for kitex based on etcd

kitex etcd Introduction kitexetcd is an implemention of service registry and service discovery for kitex based on etcd. Installation go get -u github.

Feb 18, 2022
Jun 20, 2022