From 06b040f3384971bb1a91b66d58391fe8de7f9dc9 Mon Sep 17 00:00:00 2001 From: Alex Starosta Date: Mon, 2 Nov 2026 22:02:20 -0500 Subject: [PATCH 1/5] docs: fix typos and increase clarity --- cmd/bundle.go | 2 +- cmd/run.go | 2 +- docs/guides/getting-started.mdx | 4 ++-- docs/reference/config.mdx | 2 +- example/README.md | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/bundle.go b/cmd/bundle.go index 65600b68..0e928ffb 100644 --- a/cmd/bundle.go +++ b/cmd/bundle.go @@ -45,7 +45,7 @@ var sealCmd = &cobra.Command{ var openCmd = &cobra.Command{ Use: "open [central public key]", - Short: "Bundles provided bundle against the public key. Outputs the parsed configuration", + Short: "Decrypts and verifies a sealed bundle against the central public key. Outputs the parsed configuration", Run: func(cmd *cobra.Command, args []string) { if len(args) != 1 { _ = cmd.Usage() diff --git a/cmd/run.go b/cmd/run.go index 8f059151..732a76b8 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -40,7 +40,7 @@ func init() { runCmd.Flags().BoolVarP(&opts.DBG_debug, "dbg-perf", "", false, "Enables performance debugging server on port 6060") runCmd.Flags().BoolVarP(&opts.DBG_trace, "dbg-trace", "", false, "Enables trace to trace.out") runCmd.Flags().BoolVarP(&opts.DBG_trace_tc, "dbg-trace-tc", "", false, "Enables logging of packet routing") - runCmd.Flags().BoolVarP(&opts.DBG_log_json, "json", "j", false, "Enables structued json logging") + runCmd.Flags().BoolVarP(&opts.DBG_log_json, "json", "j", false, "Enables structured JSON logging") runCmd.Flags().StringP("config", "c", DefaultConfigPath, "Path to the config file") runCmd.Flags().StringP("node", "n", DefaultNodeConfigPath, "Path to the node config file") runCmd.Flags().StringP("log", "l", "", "Path to the log file (overrides config)") diff --git a/docs/guides/getting-started.mdx b/docs/guides/getting-started.mdx index 5cd70533..195aa43d 100644 --- a/docs/guides/getting-started.mdx +++ b/docs/guides/getting-started.mdx @@ -84,7 +84,7 @@ The Linux and macOS versions are well tested, but the Windows TUN interface has ``` -4. ### Validate your configuration +3. ### Validate your configuration Before launching, you can check that your config files are correct: @@ -92,7 +92,7 @@ The Linux and macOS versions are well tested, but the Windows TUN interface has nylon verify central.yaml --node node.yaml ``` -5. ### Launch nylon +4. ### Launch nylon Run nylon on both machines: diff --git a/docs/reference/config.mdx b/docs/reference/config.mdx index a4d40c30..8688115c 100644 --- a/docs/reference/config.mdx +++ b/docs/reference/config.mdx @@ -90,7 +90,7 @@ routers: addresses: [10.0.0.2, 10.1.0.2] # multiple addresses are fine endpoints: - "192.168.1.1:57175" - - "nylon.example.org" # port defaults to the node's configured port + - "nylon.example.org" # no port: uses the _nylon._udp.nylon.example.org SRV record if present, otherwise 57175 - id: eve pubkey: 2mXTTD+FYdtJm/v1vSHz8qimvCucjW9vY+nLYacXJFE= diff --git a/example/README.md b/example/README.md index 9c120ffc..077e84b9 100644 --- a/example/README.md +++ b/example/README.md @@ -25,7 +25,7 @@ You can modify the `sample-central.yaml` to define your network topology. Here a > - A router is an active nylon node that participates in routing, and can forward packets to other nodes. Routers should have at least one endpoint that is reachable by other nodes. > - A client is a vanilla WireGuard client that does not participate in routing, and must connect through a router. Clients should not have any endpoints. -You must declare a graph, which defines your network topology. Each edge in the graph represents a bidirectional link between two nodes. You may simply connect every node to every other node, but this is always not necessary. +You must declare a graph, which defines your network topology. Each edge in the graph represents a bidirectional link between two nodes. You may simply connect every node to every other node, but this is not always necessary. Now, on every node, copy the same `central.yaml` file. @@ -35,7 +35,7 @@ Notice nodes can have 0 or more accessible endpoints. Nylon will regularly try t ### Running the network -Before running Nylon, make sure to open UDP port `57175` (or whatever port you configured) so that Nylon can communicate. Without further to do, simply run `nylon run` (you may need CAP_NET_ADMIN or sudo). +Before running Nylon, make sure to open UDP port `57175` (or whatever port you configured) so that Nylon can communicate. Without further ado, simply run `nylon run` (you may need CAP_NET_ADMIN or sudo). After a while (5-10 seconds), you will notice that the network has converged! From 9f2ffae966167d8d6b33a9492c4c948c0b65664d Mon Sep 17 00:00:00 2001 From: Alex Starosta Date: Mon, 2 Nov 2026 22:02:21 -0500 Subject: [PATCH 2/5] docs: fix the example and wg-clients links in the README The README said the sample systemd and launchd files are under `examples`, but the directory is `example/`, so name it correctly and link it. The Windows note linked to /guides/wg-clients, a docs site route that 404s on GitHub, so use the absolute nylon.jq.ax URL like the README's other docs links. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1cdc3836..349c8d4b 100644 --- a/README.md +++ b/README.md @@ -33,14 +33,14 @@ Then head to the [docs](https://nylon.jq.ax) for setup instructions. > **[Read the full documentation at nylon.jq.ax](https://nylon.jq.ax)** > includes configuration reference, guides for connecting WireGuard clients, port forwarding, and comparisons with Tailscale/Nebula. -Sample systemd service and launchctl plist files can be found under the `examples` directory. +Sample systemd service and launchctl plist files can be found under the [`example`](example/) directory. > [!NOTE] > **Stability:** I daily-drive nylon on Linux and macOS. The routing protocol has an [extensive test suite](https://github.com/encodeous/nylon/blob/main/core/router_test.go) and integration tests with simulated network conditions. The config format may still change between releases. > > **Security:** Nylon does not modify WireGuard's cryptographic code. All nylon control traffic (route updates, probes) is sent inside the encrypted WireGuard tunnel. For security concerns, [contact me directly](https://jiaqi.ch/). > -> **Windows:** The Windows client has known issues. For now, I recommend connecting Windows machines as [passive WireGuard clients](/guides/wg-clients) via a Linux/macOS gateway. +> **Windows:** The Windows client has known issues. For now, I recommend connecting Windows machines as [passive WireGuard clients](https://nylon.jq.ax/guides/wg-clients) via a Linux/macOS gateway. > > Bugs and feature requests welcome via [GitHub issues](https://github.com/encodeous/nylon/issues). From e23426179354084b32940ce2786541c394c75819 Mon Sep 17 00:00:00 2001 From: Alex Starosta Date: Mon, 2 Nov 2026 22:02:21 -0500 Subject: [PATCH 3/5] docs: correct the setup steps in the example README The config distribution section said to put the bundle URL in the node config under `dist/url`, which node.yaml no longer accepts, and that nylon downloads the config before starting up. It also said `nylon seal` uses the public key, when it reads the private key from `central.key`. List the URL under `dist.repos` in central.yaml, say that every node still needs central.yaml before its first start, link the config distribution guide, and write `dist.key` as that guide does. The last tip said to run `nylon i`, which no longer exists. Point to `nylon status -i `, and say what --routes and --full add to its output. --- example/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/README.md b/example/README.md index 077e84b9..77383739 100644 --- a/example/README.md +++ b/example/README.md @@ -4,12 +4,12 @@ On every node, copy the `sample-node.yaml`, and fill in the relevant details. run `nylon key` to generate the keypair. The first key printed (stdout) is the private key, and the second key printed (stderr) is the public key. Fill the private key in the node config, and put the public key in the central config later. #### Distribution -(Optional) To setup key distribution, you can also generate a keypair. Save the private key into `central.key` (this will be used by `nylon seal`). You can put the public key into the central config under `dist/key`. +(Optional) To setup key distribution, you can also generate a keypair. Save the private key into `central.key` (this will be used by `nylon seal`). You can put the public key into the central config under `dist.key`. > [!IMPORTANT] > Do not share this **public** key with anyone outside the network, as it can be used to decrypt the central config. Leaking this public key will compromise the confidentiality of your network topology, but it will not compromise the security of the network itself. -If you run `nylon seal` on the central config, it will encrypt and sign the config using this public key. You may then distribute the sealed config to any http server, S3 bucket, etc (which supports GET), and put the URL in the node config under `dist/url`. Nylon will automatically download and verify the config before starting up. The config is versioned with a timestamp. +If you run `nylon seal` on the central config, it will encrypt and sign the config using `central.key`. You may then distribute the sealed config to any http server, S3 bucket, etc (which supports GET), and list its URL in the central config under `dist.repos`. Every node still needs a copy of `central.yaml` before its first start; Nylon then polls the repos, verifies new configs and applies them. The config is versioned with a timestamp. See the [config distribution guide](https://nylon.jq.ax/guides/config-distribution) for details. #### Central Config @@ -40,4 +40,4 @@ Before running Nylon, make sure to open UDP port `57175` (or whatever port you c After a while (5-10 seconds), you will notice that the network has converged! > [!TIP] -> You can check the status of the node by running `nylon i `. This will show you the current routing table, peers, and other useful information. \ No newline at end of file +> You can check the status of the node by running `nylon status -i ` (the interface defaults to `nylon`). This will show you the current peers, advertised prefixes, and other useful information. Add `--routes` to also show the forward and exit tables and neighbour route advertisements, or `--full` for full routing internals. \ No newline at end of file From 92288e1604f4d0ad36c2d0bd9e616af4f114d739 Mon Sep 17 00:00:00 2001 From: Alex Starosta Date: Mon, 2 Nov 2026 22:02:22 -0500 Subject: [PATCH 4/5] docs: clarify the sample http prefix check comments The comment on the sample's `type: http` prefix compared it to itself; it means the ping check above it. The url comment said only that the check expects a success response, but anything other than HTTP 200 is a failure. Unlike ping there is also no max_failures: any failed request stops advertising the prefix until the next successful one. --- example/sample-central.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/sample-central.yaml b/example/sample-central.yaml index 09d2cfeb..bb0e7e59 100644 --- a/example/sample-central.yaml +++ b/example/sample-central.yaml @@ -20,9 +20,9 @@ routers: max_failures: 3 bind_if: en10 # optional bind, if empty, we bind to all interfaces # metric: 0 # optional metric, if set, this will be used instead of RTT - - type: http # similar to the http prefix, but uses an HTTP GET request to determine prefix health. the duration of the GET request is used as the metric. + - type: http # similar to the ping prefix, but uses an HTTP GET request to determine prefix health. the duration of the GET request is used as the metric. prefix: 10.2.0.0/24 - url: http://example.com/healthz # will expect a success response + url: http://example.com/healthz # will expect an HTTP 200 response. unlike ping, there is no max_failures: any failed request stops advertising the prefix until the next successful one delay: 15s metric: 5 # optional static metric, overrides the GET duration - id: bob From f3e3755ca3cefa77fa87c79751ae72c35c4ade09 Mon Sep 17 00:00:00 2001 From: Alex Starosta Date: Mon, 2 Nov 2026 22:02:22 -0500 Subject: [PATCH 5/5] docs: say that run --json and nylon open write to stderr `nylon run --json` only changes the console log on stderr; the log file stays in text format. `nylon open` prints the parsed config to stderr too, and stdout stays empty. The help text said neither. --- cmd/bundle.go | 2 +- cmd/run.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/bundle.go b/cmd/bundle.go index 0e928ffb..592e57c6 100644 --- a/cmd/bundle.go +++ b/cmd/bundle.go @@ -45,7 +45,7 @@ var sealCmd = &cobra.Command{ var openCmd = &cobra.Command{ Use: "open [central public key]", - Short: "Decrypts and verifies a sealed bundle against the central public key. Outputs the parsed configuration", + Short: "Decrypts and verifies a sealed bundle against the central public key. Outputs the parsed configuration to stderr", Run: func(cmd *cobra.Command, args []string) { if len(args) != 1 { _ = cmd.Usage() diff --git a/cmd/run.go b/cmd/run.go index 732a76b8..e43a0073 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -40,7 +40,7 @@ func init() { runCmd.Flags().BoolVarP(&opts.DBG_debug, "dbg-perf", "", false, "Enables performance debugging server on port 6060") runCmd.Flags().BoolVarP(&opts.DBG_trace, "dbg-trace", "", false, "Enables trace to trace.out") runCmd.Flags().BoolVarP(&opts.DBG_trace_tc, "dbg-trace-tc", "", false, "Enables logging of packet routing") - runCmd.Flags().BoolVarP(&opts.DBG_log_json, "json", "j", false, "Enables structured JSON logging") + runCmd.Flags().BoolVarP(&opts.DBG_log_json, "json", "j", false, "Enables structured JSON logging to stderr") runCmd.Flags().StringP("config", "c", DefaultConfigPath, "Path to the config file") runCmd.Flags().StringP("node", "n", DefaultNodeConfigPath, "Path to the node config file") runCmd.Flags().StringP("log", "l", "", "Path to the log file (overrides config)")