-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
112 lines (97 loc) · 3.07 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// SPDX-License-Identifier: MIT
package main
import (
"context"
"io"
"log/slog"
"net/http"
"os"
"strings"
"github.com/noisysockets/noisysockets"
latestconfig "github.com/noisysockets/noisysockets/config/v1alpha2"
"github.com/noisysockets/noisysockets/examples/util/router"
"github.com/noisysockets/noisysockets/types"
)
func main() {
logger := slog.Default()
// Generate keypair for the gateway peer.
routerPrivateKey, err := types.NewPrivateKey()
if err != nil {
logger.Error("Failed to generate gateway private key", slog.Any("error", err))
os.Exit(1)
}
// Get the public key for the gateway peer.
routerPublicKey := routerPrivateKey.Public()
// Generate keypair for our client peer.
clientPrivateKey, err := types.NewPrivateKey()
if err != nil {
logger.Error("Failed to generate client private key", slog.Any("error", err))
os.Exit(1)
}
// Usually this would be a VPN server running on a remote host. But for the
// sake of this example, we'll spin up a local container running WireGuard.
ctx := context.Background()
routerEndpoint, stopRouter, err := router.Start(ctx, routerPrivateKey, clientPrivateKey.Public())
if err != nil {
logger.Error("Failed to start wireguard router", slog.Any("error", err))
os.Exit(1)
}
defer stopRouter()
// Create a network for our "client" peer.
net, err := noisysockets.OpenNetwork(logger, &latestconfig.Config{
PrivateKey: clientPrivateKey.String(),
IPs: []string{
"100.64.0.2",
},
DNS: &latestconfig.DNSConfig{
Protocol: latestconfig.DNSProtocolTCP,
Servers: []string{"100.64.0.1"},
},
Routes: []latestconfig.RouteConfig{
{
// Route all IPv4 traffic through the gateway.
Destination: "0.0.0.0/0",
Via: "gateway",
},
},
Peers: []latestconfig.PeerConfig{
{
Name: "gateway",
PublicKey: routerPublicKey.String(),
Endpoint: routerEndpoint,
// Normally we wouldn't need to give the gateway peer any IPs, but
// since its doing dual duty as the DNS server, we need to give it
// a routable IP.
IPs: []string{"100.64.0.1"},
},
},
})
if err != nil {
logger.Error("Failed to create network", slog.Any("error", err))
os.Exit(1)
}
defer net.Close()
// Create a http client that will dial out through our network.
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.DialContext = net.DialContext
client := *http.DefaultClient
client.Transport = transport
// Make a request to a public address to verify that our network/gateway is working.
resp, err := client.Get("https://icanhazip.com")
if err != nil {
logger.Error("Failed to make request", slog.Any("error", err))
os.Exit(1)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
logger.Error("Request failed", slog.Any("status", resp.Status))
os.Exit(1)
}
// Print the response body (in this case the public ip of the gateway).
body, err := io.ReadAll(resp.Body)
if err != nil {
logger.Error("Failed to read response body", slog.Any("error", err))
os.Exit(1)
}
logger.Info("Public address", slog.String("ip", strings.TrimSpace(string(body))))
}