{"id":26166035,"url":"https://github.com/linkdata/wgnet","last_synced_at":"2026-05-16T13:08:35.885Z","repository":{"id":281647572,"uuid":"945937983","full_name":"linkdata/wgnet","owner":"linkdata","description":"WireGuard ContextDialer","archived":false,"fork":false,"pushed_at":"2026-02-20T10:41:31.000Z","size":95,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-20T12:40:32.368Z","etag":null,"topics":["go","golang","wireguard"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linkdata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-10T11:08:50.000Z","updated_at":"2026-02-20T10:40:47.000Z","dependencies_parsed_at":"2025-12-09T12:10:42.846Z","dependency_job_id":null,"html_url":"https://github.com/linkdata/wgnet","commit_stats":null,"previous_names":["linkdata/wgnet"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/linkdata/wgnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Fwgnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Fwgnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Fwgnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Fwgnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linkdata","download_url":"https://codeload.github.com/linkdata/wgnet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Fwgnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33104011,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","wireguard"],"created_at":"2025-03-11T16:28:24.948Z","updated_at":"2026-05-16T13:08:35.880Z","avatar_url":"https://github.com/linkdata.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![build](https://github.com/linkdata/wgnet/actions/workflows/build.yml/badge.svg)](https://github.com/linkdata/wgnet/actions/workflows/build.yml)\n[![coverage](https://github.com/linkdata/wgnet/blob/coverage/main/badge.svg)](https://html-preview.github.io/?url=https://github.com/linkdata/wgnet/blob/coverage/main/report.html)\n[![goreport](https://goreportcard.com/badge/github.com/linkdata/wgnet)](https://goreportcard.com/report/github.com/linkdata/wgnet)\n[![Docs](https://godoc.org/github.com/linkdata/wgnet?status.svg)](https://godoc.org/github.com/linkdata/wgnet)\n\n# wgnet\n\nWireGuard ContextDialer for Go.\n\n`wgnet.New` requires a non-nil `*wgnet.Config`. Calling `Open` on an instance\ncreated with `nil` config will panic.\n\n`wgnet.Parse` requires valid input. The reader must be non-nil and contain a\nvalid WireGuard INI configuration. If `opts` is nil, `Parse` uses\n`wgnet.DefaultOptions`, which must be non-nil.\n\n`[Peer] Endpoint` must be an IP literal with port (for example `203.0.113.10:51820`\nor `[2001:db8::1]:51820`). Hostnames are not resolved by `Parse`.\n\n`(*WgNet).Close` is intentionally asynchronous. It detaches the netstack\nimmediately and returns before the underlying WireGuard device is guaranteed\nto release OS resources (for example the UDP listen port). This means an\nimmediate `Open` on another instance using the same listen port can fail\ntransiently with `address already in use`.\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/linkdata/wgnet\"\n)\n\nvar ServerConfig = `[Interface]\nPrivateKey = GInruesHOogIjjFsKCorYEAENAfYfPL/yH8ObFgyFUs=\nListenPort = 51820\nAddress = 10.131.132.1/24\n\n[Peer]\nPublicKey = kTUQWHx4Y3ZYMZQPnRarzlx0qnen3plDoI0z7s45in4=\nAllowedIPs = 10.131.132.2/32\n`\n\nvar ClientConfig = `[Interface]\nPrivateKey = AEnvL9tVr+7JF0sMVjjzPjIxrrc/hoVJ5B82WWpVamI=\nAddress = 10.131.132.2/24\nDNS = 1.1.1.1\n\n[Peer]\nPublicKey = Wh3yY7/fE3fyHJ8TOwLJ//CIRbgrlVl4bLQ+npNBSRU=\nEndpoint = 127.0.0.1:51820\nAllowedIPs = 0.0.0.0/0, ::/0\n`\n\nfunc main() {\n\tvar err error\n\tvar srv, cli *wgnet.WgNet\n\tvar srvCfg, cliCfg *wgnet.Config\n\tif srvCfg, err = wgnet.Parse(strings.NewReader(ServerConfig), nil); err == nil {\n\t\tsrv = wgnet.New(srvCfg)\n\t\tif cliCfg, err = wgnet.Parse(strings.NewReader(ClientConfig), nil); err == nil {\n\t\t\tcli = wgnet.New(cliCfg)\n\t\t\tif err = srv.Open(); err == nil {\n\t\t\t\tdefer srv.Close()\n\t\t\t\tif err = cli.Open(); err == nil {\n\t\t\t\t\tdefer cli.Close()\n\t\t\t\t\tctx, cancel := context.WithTimeout(context.Background(), time.Minute)\n\t\t\t\t\tdefer cancel()\n\t\t\t\t\tvar latency time.Duration\n\t\t\t\t\tif latency, err = cli.Ping4(ctx, \"10.131.132.1\"); err == nil {\n\t\t\t\t\t\tfmt.Println(latency \u003e 0, latency \u003c time.Minute)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// Output:\n\t// true true\n}\n```\n\n## Setting up a Wireguard exit node on Debian/Ubuntu\n\n### Install software and generate keys for exit node\n\n```sh\napt install firewalld wireguard\nwg genkey | tee /etc/wireguard/wg_private.key | wg pubkey | tee /etc/wireguard/wg_public.key\n```\n\n### Create configuration file\n\n`nano /etc/wireguard/wg0.conf`\n\n```conf\n[Interface]\nAddress = 10.99.0.1/24\nSaveConfig = true\nListenPort = 51820\nPrivateKey = \u003cwg_private.key\u003e\n```\n\n### Configure firewall\n\n```sh\nfirewall-cmd --permanent --zone public --add-interface=\u003cexternal_if\u003e\nfirewall-cmd --permanent --zone public --add-masquerade\nfirewall-cmd --permanent --zone public --add-port=51820/udp\nfirewall-cmd --reload\n```\n\n### Start and set wireguard to start on boot\n\n```sh\nwg-quick up wg0\nsystemctl enable wg-quick@wg0\n```\n\n### Add the clients that will use the exit node\n\n```\nwg set wg0 peer \u003cpeer1_public_key\u003e allowed-ips 10.99.0.2\nwg set wg0 peer \u003cpeer2_public_key\u003e allowed-ips 10.99.0.3\n\nwg-quick save wg0\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinkdata%2Fwgnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinkdata%2Fwgnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinkdata%2Fwgnet/lists"}