Fast, multithreaded, modular and extensible DHCP server written in Go

Overview

coredhcp

Build Status codecov Go Report Card

Fast, multithreaded, modular and extensible DHCP server written in Go

This is still a work-in-progress

Example configuration

In CoreDHCP almost everything is implemented as a plugin. The order of plugins in the configuration matters: every request is evaluated calling each plugin in order, until one breaks the evaluation and responds to, or drops, the request.

The following configuration runs a DHCPv6-only server, listening on all the interfaces, using a custom server ID and DNS, and reading the leases from a text file.

server6:
    # this server will listen on all the available interfaces, on the default
    # DHCPv6 server port, and will join the default multicast groups. For more
    # control, see the `listen` directive in cmds/coredhcp/config.yml.example .
    plugins:
        - server_id: LL 00:de:ad:be:ef:00
        - file: "leases.txt"
        - dns: 8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844

For more complex examples, like how to listen on specific interfaces and configure other plugins, see config.yml.example.

Build and run

An example server is located under cmds/coredhcp/, so enter that directory first. To build a server with a custom set of plugins, see the "Server with custom plugins" section below.

Once you have a working configuration in config.yml (see config.yml.example), you can build and run the server:

$ cd cmds/coredhcp
$ go build
$ sudo ./coredhcp
INFO[2019-01-05T22:28:07Z] Registering plugin "file"
INFO[2019-01-05T22:28:07Z] Registering plugin "server_id"
INFO[2019-01-05T22:28:07Z] Loading configuration
INFO[2019-01-05T22:28:07Z] Found plugin: `server_id` with 2 args, `[LL 00:de:ad:be:ef:00]`
INFO[2019-01-05T22:28:07Z] Found plugin: `file` with 1 args, `[leases.txt]`
INFO[2019-01-05T22:28:07Z] Loading plugins...
INFO[2019-01-05T22:28:07Z] Loading plugin `server_id`
INFO[2019-01-05T22:28:07Z] plugins/server_id: loading `server_id` plugin
INFO[2019-01-05T22:28:07Z] plugins/server_id: using ll 00:de:ad:be:ef:00
INFO[2019-01-05T22:28:07Z] Loading plugin `file`
INFO[2019-01-05T22:28:07Z] plugins/file: reading leases from leases.txt
INFO[2019-01-05T22:28:07Z] plugins/file: loaded 1 leases from leases.txt
INFO[2019-01-05T22:28:07Z] Starting DHCPv6 listener on [::]:547
INFO[2019-01-05T22:28:07Z] Waiting
2019/01/05 22:28:07 Server listening on [::]:547
2019/01/05 22:28:07 Ready to handle requests
...

Then try it with the local test client, that is located under cmds/client/:

$ cd cmds/client
$ go build
$ sudo ./client
INFO[2019-01-05T22:29:21Z] &{ReadTimeout:3s WriteTimeout:3s LocalAddr:[::1]:546 RemoteAddr:[::1]:547}
INFO[2019-01-05T22:29:21Z] DHCPv6Message
  messageType=SOLICIT
  transactionid=0x6d30ff
  options=[
    OptClientId{cid=DUID{type=DUID-LLT hwtype=Ethernet hwaddr=00:11:22:33:44:55}}
    OptRequestedOption{options=[DNS Recursive Name Server, Domain Search List]}
    OptElapsedTime{elapsedtime=0}
    OptIANA{IAID=[250 206 176 12], t1=3600, t2=5400, options=[]}
  ]
...

Plugins

CoreDHCP is heavily based on plugins: even the core functionalities are implemented as plugins. Therefore, knowing how to write one is the key to add new features to CoreDHCP.

Core plugins can be found under the plugins directory. Additional plugins can also be found in the coredhcp/plugins repository.

Server with custom plugins

To build a server with a custom set of plugins you can use the coredhcp-generator tool. Head there for documentation on how to use it.

How to write a plugin

The best way to learn is to read the comments and source code of the example plugin, which guides you through the implementation of a simple plugin that prints a packet every time it is received by the server.

Authors

Comments
  • website has broken links to config.yml.example

    website has broken links to config.yml.example

    https://coredhcp.io/README.md

    <p>For more complex examples, like how to listen on specific interfaces and configure other plugins, see <a href="cmds/coredhcp/config.yml.example">config.yml.example</a>.</p>
    
    <p>Once you have a working configuration in <code>config.yml</code> (see <a href="cmds/coredhcp/config.yml.example">config.yml.example</a>), you can build and run the server:</p>
    

    Both links are broken. Github repo README has a working link to https://github.com/coredhcp/coredhcp/blob/master/cmds/coredhcp/config.yml.example

    opened by tv42 16
  • Proposed redis plugin

    Proposed redis plugin

    This is a proposed plugin to get static lease information from redis for review. Currently only supports IPv4 as I don't have much v6 equipment to test with.

    opened by kworm83 13
  • Build fail

    Build fail

    Hi there,

    Thanks for providing coredhcp.

    I am facing a build issue while building master:

     ~/code/g/src/coredhcp/cmds/coredhcp
    % go build -v
    net
    github.com/insomniacslk/dhcp/dhcpv4
    # github.com/insomniacslk/dhcp/dhcpv4
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/dhcpv4.go:267:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/dhcpv4.go:457:17: undefined: uio.Lexer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/dhcpv4.go:468:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/option_archtype.go:23:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/option_archtype.go:45:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/option_broadcast_address.go:19:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/option_ip_address_lease_time.go:18:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/option_ip_address_lease_time.go:30:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/option_ips.go:15:9: undefined: uio.NewBigEndianBuffer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/options.go:233:29: undefined: uio.Lexer
    /home/firefly/go/pkg/mod/github.com/insomniacslk/[email protected]/dhcpv4/option_ips.go:15:9: too many errors
    
    opened by borats 13
  • IPv4 server plugin

    IPv4 server plugin

    An example of the IPv4 server made in the CoreDHCP library. The example uses custom creation of UDP connection, so it can bind the connection to an interface and communicate to a client without an IP address successfully.

    opened by borna-blazevic 12
  • refresh records when leases file is updated

    refresh records when leases file is updated

    The leases in my environment are fetched over HTTP from an API and are updated periodically. Since I don't want to restart CoreDHCP every time the leases change, this PR should make the file plugin automatically update the lease database when the file was changed. It does so in a best-effort: if it can't update the database it will show a warning but nothing will break.

    opened by skoef 10
  • Unified config and plugin loading for v6 and v4

    Unified config and plugin loading for v6 and v4

    Unified configuration and plugin loading for DHCPv6 and DHCPv4. There is some code duplication in the plugin loading that I will remove in a subsequent commit.

    enhancement 
    opened by insomniacslk 9
  • Integration tests

    Integration tests

    Based on @natolumin's initial work at https://github.com/Natolumin/coredhcp/commit/c37fbceece39be191719225e856f65ae8f4b31e1

    Signed-off-by: Andrea Barberio [email protected]

    opened by insomniacslk 7
  • Prefix Delegation

    Prefix Delegation

    This implements a first pass for an IPv6 Prefix Delegation plugin, and happens to create some scaffolding for other fun things at the same time.

    There is again a lot of stuff in here (sorry) so I'll try my best to provide explanations. Please ask if anything is unclear, I'll update the comments and/or readmes.

    First 4 commits are just tidying up the go.mod,go version,tests, and updating dependencies

    Allocators

    The first bit of scaffolding is an interface and a plugin for address allocation. Currently this is geared towards ipv6 and prefixes, but should be usable as-is for ipv4 and single addresses (and obviously single ipv6 addresses as well). The interface for now is extremely simple, it has alloc and free, with alloc taking an optional hint of what the client desires. This allows implementing different strategies to allocate ips, eg sequentially or at random.

    The base package for allocators also provides helpers (in ipcalc.go) to help with managing ipv6 addresses as 128-bit integers, since net.IP itself doesn't have a fixed size and can't be used to index a map. I expect these operations will be basically needed by all the allocators we'll implement, so I put them in the package with the interface declaration

    Finally, there is one trivial allocator implemented, which always allocates blocks of the same size. it basically has the logic for an allocator of single addresses, except then you left-shift the addresses to get a prefix instead. Not very interesting, but useful for debugging/prototyping.

    Prefix delegation

    The prefix delegation plugin does 2 things with each request (which I think should be mirrored in the other plugins that have to allocate, like range), it tries to reconcile the request with its existing leases, to renew and extend them, and if that fails it allocates new leases and assigns them to the client.

    Part of the complexity of the plugin is caused by the fact that it has to implement lease storage (again, which we also do in range) and retrieval, which I think is something we'll have to move in another plugin category like allocators later.

    The logic for reconciling requests with existing leases and extending them isn't great, this is something I want to improve asap, but it was starting to be a lot for a single PR. The current one works and mostly does what you expect in "normal" cases.

    opened by Natolumin 7
  • Revert

    Revert "Relay reply"

    Reverts coredhcp/coredhcp#67

    Copying the relevant portion of the RFC from https://github.com/coredhcp/coredhcp/pull/67#issuecomment-557078623:

    Relay agents implementing this specification may be configured instead to 1) use a source port number other than 547 when relaying messages toward servers and 2) receive responses toward clients on that same port.

    Lower down:

    Additionally, the IPv6 server MUST check and use the UDP source port from the UDP packet of the Relay-forward message in replying to the relay agent.

    opened by Natolumin 7
  • Allow listening on multiple addresses

    Allow listening on multiple addresses

    This implements the changes discussed in #52

    There is an additional remaining issue mentioned in https://github.com/coredhcp/coredhcp/issues/52#issuecomment-532621844 where, when listening on a socket that is not bound to an interface, reply packets, especially broadcast or link-local, may be sent on the wrong interface.

    I believe this is fixable as mentioned in the issue, so this is a draft until we decide on a solution (or decide this is fine for the moment and to commit this)

    Individual commit messages have more information

    opened by Natolumin 7
  • support booting over HTTP(S) or FTP for DHCPv4

    support booting over HTTP(S) or FTP for DHCPv4

    In my environment where I boot using iPXE, the bootfile and further instructions are server over HTTP but the NBP plugin for CoreDHCP always assumes TFTP for DHCPv4. This MR changes that:

    • when the argument passed to the NBP plugin is prefixed with http/https/ftp as parsed by url.Parse, it doesn't split the host/path into TFTPServerOption and BootfileOption, but passes the entire URL into BootfileOption
    • for any other arguments the behaviour is identical as before
    opened by skoef 6
  • plugins: each plugin instance now has its own state

    plugins: each plugin instance now has its own state

    Now each plugin setup has its own state

    If we use coreDHCP as a library and run multiple servers, we can't separate plugin variables for each server. This PR fix this problem.

    Signed-off-by: Dmitrii Aleksandrov [email protected]

    opened by Insei 0
  • Lint version updates

    Lint version updates

    A general version bump for actions, including our lints and the base setup/checkout actions, and build with newer go versions too (while keeping the minimum supported version at 1.14 for now)

    opened by Natolumin 1
  • Allow two new features in IPv4 leases.txt: 1) Match on RFC3993 Subscriber-ID, 2) supply optional netmask,gateway alongside each IPv4

    Allow two new features in IPv4 leases.txt: 1) Match on RFC3993 Subscriber-ID, 2) supply optional netmask,gateway alongside each IPv4

    This is some work I did for a client who wanted coredhcp to do just a little bit more on their network. I hope the 2 commits are self-explanatory and well-tested enough.

    I guess adding much more to the 'file' plugin might start to get messy, and need a proper parser, but right now it still seemed like overkill.

    opened by matthewbloch 1
  • Cannot build on Windows

    Cannot build on Windows

    While installing this using PowerShell on Windows:

    # go install 'github.com/coredhcp/coredhcp/cmds/[email protected]'
    go build github.com/u-root/u-root/pkg/rand: build constraints exclude all Go files in C:\Users\rgl\go\pkg\mod\github.com\u-root\[email protected]+incompatible\pkg\rand
    
    # $LASTEXITCODE
    1
    

    This was supposed to be fixed in:

    • https://github.com/coredhcp/coredhcp/issues/63
    • https://github.com/insomniacslk/dhcp/issues/339

    But it seems this repository is still not picking the corrected dhcp library version.

    opened by rgl 0
Lightweight network boot/install server (DHCP, TFTP, HTTP)

netbootd netbootd is a lightweight network boot server, designed for maximum flexibility and with "batteries included" approach in mind, serving as a

Daniel Speichert 164 Sep 22, 2022
DHCP backed by Tink server

dhcp DHCP is a dhcp server backed by Tink server. All IP addresses are served as DHCP reservations. There are no leases. Definitions DHCP Reservation:

Jacob Weinstock 0 Mar 23, 2022
Multithreaded Airline Check-In Simulator

Multithreaded Airline Check-In Simulator This is a task scheduler which includes a single queue and 5 clerks. The queue will be sorted based on priori

null 0 Mar 15, 2022
Amateras - DHCP Starvation attack exploitation tool

Amateras Amateras - DHCP Starvation attack exploitation tool DHCP starvation attack is a malicious digital attack that targets DHCP servers. During a

Yasser Janah 2 Jul 1, 2022
A modular is an opinionated, easy-to-use P2P network stack for decentralized applications written in Go.

xlibp2p xlibp2p is an opinionated, easy-to-use P2P network stack for decentralized applications written in Go. xlibp2p is made to be minimal, robust,

XFS Network 63 Jul 10, 2022
Event driven modular status-bar for dwm; written in Go & uses Unix sockets for signaling.

dwmstat A simple event-driven modular status-bar for dwm. It is written in Go & uses Unix sockets for signaling. The status bar is conceptualized as a

Navaz Alani 1 Dec 25, 2021
Go network programming framework, supports multiplexing, synchronous and asynchronous IO mode, modular design, and provides flexible custom interfaces

Go network programming framework, supports multiplexing, synchronous and asynchronous IO mode, modular design, and provides flexible custom interfaces。The key is the transport layer, application layer protocol has nothing to do

rick.wu 10 Jun 27, 2022
CoreRAD is an extensible and observable IPv6 Neighbor Discovery Protocol router advertisement daemon. Apache 2.0 Licensed.

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

Matt Layher 122 Sep 20, 2022
Extensible network application framework inspired by netty

GO-NETTY 中文介绍 Introduction go-netty is heavily inspired by netty Feature Extensible transport support, default support TCP, UDP, QUIC, KCP, Websocket

The Go-Netty Project 330 Sep 25, 2022
llb - It's a very simple but quick backend for proxy servers. Can be useful for fast redirection to predefined domain with zero memory allocation and fast response.

llb What the f--k it is? It's a very simple but quick backend for proxy servers. You can setup redirect to your main domain or just show HTTP/1.1 404

Kirill Danshin 12 Jan 23, 2022
server-to-server sync application, written in go/golang.

svcpy: server to server copy a basic server-to-server copy application. on a single binary, it can be a server or a client. example usage: on the serv

Mert Akengin 0 Nov 4, 2021
Pape-server - A small server written in golang to serve a random wallpaper.

pape-server I like to inject custom CSS themes into a lot of websites and electron apps, however browsers don't let websites access local disk through

null 0 Dec 31, 2021
Server - Dupman server written in Go

server dupman server written in Go Requirements Go (>=1.17) Installation Usage C

dupman 9 Feb 22, 2022
`kawipiko` -- blazingly fast static HTTP server -- focused on low latency and high concurrency, by leveraging Go, `fasthttp` and the CDB embedded database

kawipiko -- blazingly fast static HTTP server kawipiko is a lightweight static HTTP server written in Go; focused on serving static content as fast an

Volution 310 Sep 20, 2022
A modern, fast and scalable websocket framework with elegant API written in Go

About neffos Neffos is a cross-platform real-time framework with expressive, elegant API written in Go. Neffos takes the pain out of development by ea

Gerasimos (Makis) Maropoulos 400 Sep 18, 2022
sonarbyte is a simple and fast subdomain scanner written in go to extract subdomain from Rapid7's DNS Database using omnisint's api.

sonarbyte Description Sonarbyte is a simple and fast subdomain scanner written in go to extract subdomains from Rapid7's DNS Database using omnisint's

Chan Nyein Wai 22 Jul 27, 2022
Go-random-chat - Fast and scalable real-time random chat written in go

Go Random Chat Fast and scalable real-time random chat written in go. Features:

Hao-Ming, Hsu 9 Aug 30, 2022
A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.

frp README | 中文文档 What is frp? frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. As of now, it s

null 60.2k Sep 21, 2022
Privacy important, fast, recursive dns resolver server with dnssec support

?? Privacy important, fast, recursive dns resolver server with dnssec support Installation go get github.com/semihalev/sdns Pre-build Binaries Downloa

Yasar Alev 716 Sep 22, 2022