aboutsummaryrefslogtreecommitdiff
path: root/posts
diff options
context:
space:
mode:
authorflu0r1ne <flu0r1ne@flu0r1ne.net>2023-08-28 21:33:44 -0500
committerflu0r1ne <flu0r1ne@flu0r1ne.net>2023-08-28 21:33:44 -0500
commitf0c03a9b8e15387c4defd0a0e3e0298324406fae (patch)
tree564011d0265666953b17258954ff68614ff6566a /posts
parent2f0439621cff059e414d67f6ce43a7a6c4de13bc (diff)
downloadhomepage-f0c03a9b8e15387c4defd0a0e3e0298324406fae.tar.xz
homepage-f0c03a9b8e15387c4defd0a0e3e0298324406fae.zip
Add wg2nd
Diffstat (limited to 'posts')
-rw-r--r--posts/announcing-wg2nd/main.md75
-rw-r--r--posts/announcing-wg2nd/meta.json4
-rw-r--r--posts/packaging-nebula-for-debian/main.md88
-rw-r--r--posts/packaging-nebula-for-debian/meta.json2
4 files changed, 124 insertions, 45 deletions
diff --git a/posts/announcing-wg2nd/main.md b/posts/announcing-wg2nd/main.md
new file mode 100644
index 0000000..fc51748
--- /dev/null
+++ b/posts/announcing-wg2nd/main.md
@@ -0,0 +1,75 @@
+# Announcing wg2nd: Migrate WireGuard Configurations to networkd
+
+Today, I am excited to release `wg2nd`, a tool specifically engineered to convert WireGuard configurations
+from the `wg-quick(8)` format to `systemd-networkd` compatible configurations.
+
+- [wg2nd](https://www.git.flu0r1ne.net/wg2nd) - Source Code
+- [wg2nd-web](/wg2nd) - Web Port (contains some limitations)
+
+## Purpose
+
+`wg2nd` serves as a bridge to translate `wg-quick` configurations into `networkd` configurations without
+requiring additional setup. `networkd` is a feature-complete network manager, allowing users greater
+control over WireGuard tunnels. This tool also addresses potential reliability issues that may arise
+when `networkd` interferes with tunnels it doesn't manage. Moreover, `wg2nd` can batch-convert `wg-quick`
+configurations to `networkd`.
+
+## Goals of the Project
+
+1. **Compatibility**: `wg2nd` supports all `wg-quick` configurations except those that involve
+ `PreUp`, `PostUp`, `PreDown`, and `PostDown` scripts, which are omitted.
+
+2. **Security**: Private and symmetric keys are stored in keyfiles with restricted access permissions.
+ `wg2nd` leverages the same formally-verified Curve25519 implementation employed in WireGuard.
+ All operations involving private keys are executed in constant-time. Additionally, the web port operates
+ entirely on the client-side. It does not transmit or store any sensitive data.
+
+3. **Reproducibility**: `wg2nd` generates configurations deterministically with respect to
+ the input WireGuard configuration. When updates are made to the WireGuard source configurations,
+ only the corresponding elements in the output will be altered. This ensures that configurations
+ from a VPN provider can be batch-converted without generating unnecessary files or inducing unexpected
+ behavioral changes.
+
+ Keyfiles for both private and symmetric keys are named according to the public key of the relevant
+ interface or peer. These keyfiles are encoded in base32 rather than base64 to avoid issues with the
+ Unix path separator present in base64 encoding. The public key corresponding to a keyfile can be
+ obtained using the following command:
+
+ ```bash
+ echo $KEY | sed -E 's/\.(priv|sym)key//' | base32 -d | base64
+ ```
+
+ This approach effectively ensures that if two interfaces share the same private key, a single shared
+ keyfile will be generated. The `fwmark` field employs a SipHash of the interface name, enabling the
+ generation of identical network and netdev files across separate program invocations, while minimizing
+ the risk of `fwmark` collisions.
+
+### Compatibility and Limitations
+
+`wg2nd` is designed for high compatibility but comes with some caveats:
+
+1. **Dynamic Firewall Installation**: Unlike `wg-quick`, which installs a firewall by default when a default route
+ is specified, `wg2nd` does not. However, an equivalent firewall can be generated if desired.
+
+2. **Pre/Post Interface Setup Scripts**: `wg2nd` does not handle `PreUp`, `PostUp`, `PreDown`, and `PostDown`
+ script snippets, which `wg-quick` does recognize.
+
+3. **FwMark and Table Handling**: `wg2nd` uses a deterministic method for generating `fwmark` based on the interface
+ name. This contrasts with `wg-quick`, which dynamically checks availability. This deterministic approach is
+ necessary because a static value must be chosen for configuration. However, this could result in a birthday
+ collision if a large number of interfaces are ported. (Such a scenario becomes only _remotely probable_ after porting
+ around 500 interfaces.)
+
+### Web Port
+
+The web port has been developed by converting the `C` / `C++` implementation into WebAssembly (WASM). It offers an
+entirely browser-based experience, converting your WireGuard configurations into a series of Bash commands to configure
+the interface. This allows you to experiment within your browser.
+
+The code is dual-licensed under the GPL-2.0 and MIT licenses. Feel free to send me patches via email or submit pull
+requests through GitHub.
+
+For further details, including installation instructions, please consult the project
+[README](https://www.git.flu0r1ne.net/wg2nd/tree/README.md?h=main).
+
+Happy networking!
diff --git a/posts/announcing-wg2nd/meta.json b/posts/announcing-wg2nd/meta.json
new file mode 100644
index 0000000..536a53f
--- /dev/null
+++ b/posts/announcing-wg2nd/meta.json
@@ -0,0 +1,4 @@
+{
+ "name": "Announcing wg2nd: Migrate WireGuard Configurations to networkd",
+ "lastUpdated": "2023-08-27"
+}
diff --git a/posts/packaging-nebula-for-debian/main.md b/posts/packaging-nebula-for-debian/main.md
index f4b1651..daf8ad6 100644
--- a/posts/packaging-nebula-for-debian/main.md
+++ b/posts/packaging-nebula-for-debian/main.md
@@ -22,25 +22,25 @@ For the sake of simplicity, I'm going to assume that you're setting up a network
If this is not the case, please consult the [upstream instructions](https://github.com/slackhq/nebula#user-content-getting-started-quickly) which will guide you through the processing of installing the binaries directly.
#### 1. Install Nebula through Aptitude
-
+
You'll need to install Nebula on both endpoints.
-
+
```bash
sudo apt install nebula
```
-
+
#### 2. Creating a certificate authority
-
+
The certificate authority is to "root of trust" for a Nebula network. Compromising the certificate authority's key file would compromise the integrity and security of the entire network. The upstream instructions recommend that you store the key file in a location with strong encryption [^1].
-
+
You can generate a `ca.key` and `ca.cert` file with the following command:
```bash
nebula-cert ca -name "Myorganization, Inc"
```
-
+
You will copy the `ca.crt` file to all the hosts. The `ca.key` file should remain secret.
-
-#### 4. Nebula host keys and certificates generated from that certificate authority
+
+#### 3. Nebula host keys and certificates generated from that certificate authority
With your `ca.key` file in hand, generate keys for each node.
@@ -73,60 +73,60 @@ rm ca.crt lighthouse.{key,crt}
```
#### 5. Configure your network
-
+
The upstream recommends that you start from an example configuration file:
-
+
```
cp /usr/share/doc/nebula/examples/config.yml /etc/nebula/my_network.yml
```
-
-* On your lighthouse, you'll want to change the `cert` and `key` sections to the paths `/etc/nebula/lighthouse.crt` and `/etc/nebula/ligthouse.key`. Change `am_lighthoue: true`. Remove the lighthouse ip from the `hosts` section under `lighthouse`.
-
-* On the host, change the `cert` and `key` sections to the paths `/etc/nebula/laptop.crt` and `/etc/nebula/laptop.key`. Ensure the lighthouse is added to the `static_host_map` and the `hosts` section.
-
+
+- On your lighthouse, you'll want to change the `cert` and `key` sections to the paths `/etc/nebula/lighthouse.crt` and `/etc/nebula/ligthouse.key`. Change `am_lighthoue: true`. Remove the lighthouse ip from the `hosts` section under `lighthouse`.
+
+- On the host, change the `cert` and `key` sections to the paths `/etc/nebula/laptop.crt` and `/etc/nebula/laptop.key`. Ensure the lighthouse is added to the `static_host_map` and the `hosts` section.
+
Once you're done, you can test whether your configuration is valid with `nebula-service -test -config /etc/nebula/my_network.yml`.
-
+
#### 6. Bringing up the tunnel
-
+
To start the tunnel, you can use the templated `systemd` service packaged alongside Nebula [^3][^4].
```bash
sudo systemctl start nebula@my_network
```
-
+
There is also a means by which a Nebula lighthouse can be run by a unprivileged user but further configuration is required [^5].
-
+
Once both ends of the tunnel have been started, you should be able to ping the lighthouse from the laptop node and vice versa.
```bash
ping 192.168.100.1
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=5.67 ms
```
-
+
#### 7. Additional Configuration
-
+
Nebula has built-in default deny firewall. The default configuration file allows network traffic `outbound`. (That is, any node is permitted to initiate a connection.) In order for a node to provide services, the port mapping needs to be added to the `inbound` section. For instance, to permit ssh to the lighthouse:
-
+
```yaml
inbound:
- port: 22
proto: tcp
host: lighthouse
```
-
+
Now, an ssh connection should be able to be initiated via Nebula's internal ip:
```bash
ssh 192.168.100.1
```
-
+
Once you're happy with the setup, you can automatically start Nebula when the laptop / server boots:
-
+
```bash
sudo systemctl enable nebula@my_network
```
-
+
For more information on usage and configuration, you may want to take a look at `nebula.yml(5)`, `nebula(1)`, and `nebula-cert(1)`.
-
+
Enjoy.
```
* . . * * . . * . * . . * .
@@ -136,42 +136,42 @@ Enjoy.
. . * . * . * . * * . .
* . * . * . * . * . * . . *
```
-
+
### Installation Footnotes
-
+
[^1] If you're in need of a technology to provide strong encryption, [LUKS](https://guardianproject.info/archive/luks/) is a popular choice on Linux. [Veracrypt](https://www.veracrypt.fr) is a venerable cross-platform encryption application. Some password managers, like KeePassXC, also allow you to attach files.
-
+
[^2] Effectively, this means all nodes will receive an ip in the form "192.168.y.x". The y part is a value in the range [0, 255] and is specific to the network. (Thus, all nodes should have the same "y" value.) "x" should be a unique ip for each node and be in the range [0, 244].
-
+
[^3] The launcher I wrote will detect the `my_network.yml` and `my_network.yaml` files. Do not specify the extension when launching the service. The launcher has no way to discriminate between `my_network.yml` and `my_network.yaml` extension so pick a distinct name for each network.
-
+
[^4] If Nebula is misconfigured, the service will fail without warning. You can check the status of the unit with `systemctl status nebula@my_network`. Nebula can also be started within the terminal using `nebula -conifg /etc/nebula/my_network.yml`.
-
+
[^5] The systemd unit that is packaged with Nebula runs the interface as root. This is what I expect most users will want. If the lighthouse doesn't need to be connected to the network, you can `sudo systemd edit nebula@.serivce` and simply change the `User` section to the user you wish to use to launch Nebula. The user will also need read access to the configuration file, key, and cert files.
-
+
Packaging Notes
---------------
-
+
I am going to create a brief summary of the changes made while packaging. I suspect other distros might benefit from some of the work done to package Debian [^6].
-
+
The Debian package differs from the packaging done on [Arch](https://archlinux.org/packages/community/x86_64/nebula/). There's also a package created for [NixOS](https://github.com/NixOS/nixpkgs/blob/8284fc30c84ea47e63209d1a892aca1dfcd6bdf3/nixos/tests/nebula.nix) but Nix is its own beast.
-
+
### Templating the Unit File
-
+
If we were to use the unit file provided by the upstream project, it would fail without warning until the user fully setup the service because (1) the path of to Nebula configuration was hard coded as `/etc/nebula/config.yml` and (2) the user needed to change the configuration file in order for Nebula to function.
-
+
To make the relationship between the user configuration and the `systemd` unit clear, the `systemd` unit was templated. This also means that there is a clear and simple way to connect one machine to multiple Nebula networks. To accomplish this and support both `.yml` and `.yaml` extension, the systemd file executes a shell script under `/usr/lib/nebula/bin/nebula-systemd-launcher` passing the "instance variable" as the first argument. This script then identifies the proper configuration and launches Nebula with this configuration. The script was installed user `/usr/lib` so that it would not autocomplete in the user's shell.
-
+
### Doc and examples
-
+
- Man pages were generated from the nebula help flag to create `nebula(1)` and `nebula-cert(1)`.
- `nebula.yml(5)` man page was created to describe the configuration process. It was derived from the comments in the example configuration.
- The `config.yml` example configuration was installed under `/usr/share/doc/nebula/examples/` so users could copy it into `/etc/nebula` if they wished to use it as a starting point.
-
+
### Patching for Go 1.13
-
+
Debian packages all go dependencies to maintain tight control over the versions used while building go binaries. It also packages `go` itself. Currently, `go 1.16` is not in the debian repos [^7]. The following patch was applied since `net.ErrClosed` is not available in older versions of go.
-
+
```go
--- nebula.orig/sshd/server.go
+++ nebula/sshd/server.go
diff --git a/posts/packaging-nebula-for-debian/meta.json b/posts/packaging-nebula-for-debian/meta.json
index 1f8f362..49ec10e 100644
--- a/posts/packaging-nebula-for-debian/meta.json
+++ b/posts/packaging-nebula-for-debian/meta.json
@@ -1,4 +1,4 @@
{
"name": "Packaging Nebula for Debian",
"lastUpdated": "2021-07-19"
-} \ No newline at end of file
+}