# WireGuard VPN networking for unprivileged network namespaces
wireguard4netns is directly inspired by the awesome work of the authors of
[slirp4netns](https://github.com/rootless-containers/slirp4netns). Instead of
providing generic user-mode networking for unprivileged network namespaces
through libslirp, wireguard4netns brings network access to the containers
through [wireguard-go](https://git.zx2c4.com/wireguard-go/about/), a userspace
WireGuard VPN tunnel implementation.
## Motivation
We were building a framework for developing Edge-Native applications (the
[Sinfonia](https://github.com/cmusatyalab/sinfonia/) project) and for this we
split applications into two primary components, a frontend that runs on the
user's device and a backend consisting of one or more services are deployed on
a nearby Kubernetes cluster (`cloudlet`). We leverage WireGuard tunnels
between the two to avoid having to expose deployed services to the world, the
frontend's network environment is as if it was part of the same deployment
inside the same Kubernetes cluster and namespace as the backend. This hides
most of the unnecessary network details from the application's frontend and
provides other advantages such as privacy and network mobility.
The main disadvantage was that root privileges are needed to create, configure
and attach the in-kernel WireGuard interface to a network namespace. This
required either sudo access by the user, or an administrator installed setuid
root binary helper. However slirp4netns showed the path to an alternative
approach, create a tuntap interface inside the unprivileged network namespace
and pass the control socket back to the default namespace where (in our case) a
userspace WireGuard implementation is started. All frontend traffic is then
sent through the tunnel to a VPN endpoint on the nearby cloudlet which passes
it along to the deployed namespace of the application's backend.
## Building from source
The only executable that is needed is `patch`. The build will try to download a
copy of golang and use that to build a custom `wireguard-go` binary.
Make sure you have an initialized and updated wireguard-go git-submodule.
```sh
git clone ... wireguard4netns
cd wireguard4netns/
git submodule update --init
poetry build
```
The `wireguard-go` binary is then placed at `src/wireguard4netns/wireguard-go`.
As long as that binary is present in that location, the build will avoid
rebuilding the wireguard-go code.
We use a custom built version of wireguard-go because starting with an existing
tunnel socket fd is really just an artifact of how the unmodified wireguard-go
process sets up the tuntap device and uapi socket in the foreground and then
daemonizes itself, passing along the already open file descriptors. With our
approach the tuntap device ends up being created in a different network
namespace and wireguard-go was unable to query or set the MTU.
Our modifications simply change the code to not fail when MTU operations are
not working and is in `wireguard-go.patch`.
We also needed to make sure the UAPI socket is placed in a user-writable
location instead of `/var/run/wireguard`. This `socketDirectory` path is
customized through a custom linker flag that we set in `build.py` at the time
we build the binary.
## Licenses
wireguard4netns is MIT licensed
Copyright (c) 2022-2023 Carnegie Mellon University
SPDX-License-Identifier: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
wireguard-go is MIT licensed
Copyright (C) 2017-2022 WireGuard LLC. All Rights Reserved.
License: MIT
see wireguard-go/LICENSE and wireguard-go/README.md
"WireGuard" is a registered trademark of Jason A. Donenfeld.
Raw data
{
"_id": null,
"home_page": "https://github.com/cmusatyalab/wireguard4netns",
"name": "wireguard4netns",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.7",
"maintainer_email": null,
"keywords": null,
"author": "Carnegie Mellon University",
"author_email": "satya+group@cs.cmu.edu",
"download_url": "https://files.pythonhosted.org/packages/d1/25/63b70f5b31385aa89158c7791d8fd5e260311479b09d54cdf50646675664/wireguard4netns-0.1.6.tar.gz",
"platform": null,
"description": "# WireGuard VPN networking for unprivileged network namespaces\n\nwireguard4netns is directly inspired by the awesome work of the authors of\n[slirp4netns](https://github.com/rootless-containers/slirp4netns). Instead of\nproviding generic user-mode networking for unprivileged network namespaces\nthrough libslirp, wireguard4netns brings network access to the containers\nthrough [wireguard-go](https://git.zx2c4.com/wireguard-go/about/), a userspace\nWireGuard VPN tunnel implementation.\n\n\n## Motivation\n\nWe were building a framework for developing Edge-Native applications (the\n[Sinfonia](https://github.com/cmusatyalab/sinfonia/) project) and for this we\nsplit applications into two primary components, a frontend that runs on the\nuser's device and a backend consisting of one or more services are deployed on\na nearby Kubernetes cluster (`cloudlet`). We leverage WireGuard tunnels\nbetween the two to avoid having to expose deployed services to the world, the\nfrontend's network environment is as if it was part of the same deployment\ninside the same Kubernetes cluster and namespace as the backend. This hides\nmost of the unnecessary network details from the application's frontend and\nprovides other advantages such as privacy and network mobility.\n\nThe main disadvantage was that root privileges are needed to create, configure\nand attach the in-kernel WireGuard interface to a network namespace. This\nrequired either sudo access by the user, or an administrator installed setuid\nroot binary helper. However slirp4netns showed the path to an alternative\napproach, create a tuntap interface inside the unprivileged network namespace\nand pass the control socket back to the default namespace where (in our case) a\nuserspace WireGuard implementation is started. All frontend traffic is then\nsent through the tunnel to a VPN endpoint on the nearby cloudlet which passes\nit along to the deployed namespace of the application's backend.\n\n\n## Building from source\n\nThe only executable that is needed is `patch`. The build will try to download a\ncopy of golang and use that to build a custom `wireguard-go` binary.\n\nMake sure you have an initialized and updated wireguard-go git-submodule.\n\n```sh\n git clone ... wireguard4netns\n cd wireguard4netns/\n git submodule update --init\n poetry build\n```\n\nThe `wireguard-go` binary is then placed at `src/wireguard4netns/wireguard-go`.\nAs long as that binary is present in that location, the build will avoid\nrebuilding the wireguard-go code.\n\nWe use a custom built version of wireguard-go because starting with an existing\ntunnel socket fd is really just an artifact of how the unmodified wireguard-go\nprocess sets up the tuntap device and uapi socket in the foreground and then\ndaemonizes itself, passing along the already open file descriptors. With our\napproach the tuntap device ends up being created in a different network\nnamespace and wireguard-go was unable to query or set the MTU.\n\nOur modifications simply change the code to not fail when MTU operations are\nnot working and is in `wireguard-go.patch`.\n\nWe also needed to make sure the UAPI socket is placed in a user-writable\nlocation instead of `/var/run/wireguard`. This `socketDirectory` path is\ncustomized through a custom linker flag that we set in `build.py` at the time\nwe build the binary.\n\n\n## Licenses\n\nwireguard4netns is MIT licensed\n\n Copyright (c) 2022-2023 Carnegie Mellon University\n SPDX-License-Identifier: MIT\n\n Permission is hereby granted, free of charge, to any person obtaining a copy of\n this software and associated documentation files (the \"Software\"), to deal in\n the Software without restriction, including without limitation the rights to\n use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n of the Software, and to permit persons to whom the Software is furnished to do\n so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\nwireguard-go is MIT licensed\n\n Copyright (C) 2017-2022 WireGuard LLC. All Rights Reserved.\n License: MIT\n\n see wireguard-go/LICENSE and wireguard-go/README.md\n\n\"WireGuard\" is a registered trademark of Jason A. Donenfeld.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "WireGuard VPN networking for unprivileged network namespaces",
"version": "0.1.6",
"project_urls": {
"Homepage": "https://github.com/cmusatyalab/wireguard4netns",
"Repository": "https://github.com/cmusatyalab/wireguard4netns"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "87136d6826e58b6aaa15b58da4c808999b02716b8a34e216d443b69b71819670",
"md5": "c0b61afcca22ebf3fc761547e43939fc",
"sha256": "6a594d1321ed83ce435fe365bf626beec6833070dc9bf2d61b0a7dd58f82de4c"
},
"downloads": -1,
"filename": "wireguard4netns-0.1.6-cp310-cp310-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "c0b61afcca22ebf3fc761547e43939fc",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": "<4.0,>=3.7",
"size": 1090753,
"upload_time": "2024-07-23T20:41:52",
"upload_time_iso_8601": "2024-07-23T20:41:52.388997Z",
"url": "https://files.pythonhosted.org/packages/87/13/6d6826e58b6aaa15b58da4c808999b02716b8a34e216d443b69b71819670/wireguard4netns-0.1.6-cp310-cp310-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "4e0e71e50d5e374751e1fd255b5a0709b3ed97150c3779d93f0217f3a9f3cb6b",
"md5": "2e08a9141027f1c577a62a61df1b307d",
"sha256": "92722c3704714e6e72b61ae625eadadda6125d35bd750072a0628a42c58326d2"
},
"downloads": -1,
"filename": "wireguard4netns-0.1.6-cp311-cp311-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "2e08a9141027f1c577a62a61df1b307d",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": "<4.0,>=3.7",
"size": 1090754,
"upload_time": "2024-07-23T20:41:54",
"upload_time_iso_8601": "2024-07-23T20:41:54.154499Z",
"url": "https://files.pythonhosted.org/packages/4e/0e/71e50d5e374751e1fd255b5a0709b3ed97150c3779d93f0217f3a9f3cb6b/wireguard4netns-0.1.6-cp311-cp311-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d0122450563d25c6411b466f6186a3186f6126f087fa708f172c00b60c16acff",
"md5": "8eca4f76d41f2742f30eab52f5c7a32a",
"sha256": "aeffe525a1bce7a9e536530a33718051d315d07e98fed3337a32d7c5c809deb6"
},
"downloads": -1,
"filename": "wireguard4netns-0.1.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "8eca4f76d41f2742f30eab52f5c7a32a",
"packagetype": "bdist_wheel",
"python_version": "cp37",
"requires_python": "<4.0,>=3.7",
"size": 1090755,
"upload_time": "2024-07-23T20:41:56",
"upload_time_iso_8601": "2024-07-23T20:41:56.682065Z",
"url": "https://files.pythonhosted.org/packages/d0/12/2450563d25c6411b466f6186a3186f6126f087fa708f172c00b60c16acff/wireguard4netns-0.1.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "9f59488ebeef29592909dc25179dfc187cf697e8f398a77b46c3d4b974d2a435",
"md5": "77c378320686e993728bac8af489b4e2",
"sha256": "f07182a7537405dc39e0452b45dd4445073aba3d42441355a35334e6d8160703"
},
"downloads": -1,
"filename": "wireguard4netns-0.1.6-cp38-cp38-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "77c378320686e993728bac8af489b4e2",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": "<4.0,>=3.7",
"size": 1090754,
"upload_time": "2024-07-23T20:41:58",
"upload_time_iso_8601": "2024-07-23T20:41:58.312572Z",
"url": "https://files.pythonhosted.org/packages/9f/59/488ebeef29592909dc25179dfc187cf697e8f398a77b46c3d4b974d2a435/wireguard4netns-0.1.6-cp38-cp38-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f3203ea7ade8041064be7e4040a4759c148770037e56e5728218cede8faa25c2",
"md5": "c83b326b3f643d40e63eaac998d3f6fb",
"sha256": "b5fc83792f59b5021f9f1935d51318df51a333ada18194d0e8a57995b5734f8f"
},
"downloads": -1,
"filename": "wireguard4netns-0.1.6-cp39-cp39-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "c83b326b3f643d40e63eaac998d3f6fb",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": "<4.0,>=3.7",
"size": 1090757,
"upload_time": "2024-07-23T20:41:59",
"upload_time_iso_8601": "2024-07-23T20:41:59.540823Z",
"url": "https://files.pythonhosted.org/packages/f3/20/3ea7ade8041064be7e4040a4759c148770037e56e5728218cede8faa25c2/wireguard4netns-0.1.6-cp39-cp39-manylinux_2_17_x86_64.manylinux_2_5_x86_64.manylinux1_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d12563b70f5b31385aa89158c7791d8fd5e260311479b09d54cdf50646675664",
"md5": "442bfb205eb517e9e8a8fa3a1e7d8410",
"sha256": "7f977eae0bc78d94f7b8454bba88601e4e0e40ffcdb85d2900e77be60343ce4a"
},
"downloads": -1,
"filename": "wireguard4netns-0.1.6.tar.gz",
"has_sig": false,
"md5_digest": "442bfb205eb517e9e8a8fa3a1e7d8410",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.7",
"size": 117854,
"upload_time": "2024-07-23T20:42:00",
"upload_time_iso_8601": "2024-07-23T20:42:00.720322Z",
"url": "https://files.pythonhosted.org/packages/d1/25/63b70f5b31385aa89158c7791d8fd5e260311479b09d54cdf50646675664/wireguard4netns-0.1.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-07-23 20:42:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cmusatyalab",
"github_project": "wireguard4netns",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "wireguard4netns"
}