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
| package main
import ( "context" "encoding/json" "fmt" "io" "net" "net/http" "net/url" "os" "time"
"github.com/sigcn/pg/disco" "github.com/sigcn/pg/langs" "github.com/sigcn/pg/p2p" "github.com/sigcn/pg/peermap/network" "github.com/sigcn/pg/vpn" "github.com/sigcn/pg/vpn/nic" "github.com/sigcn/pg/vpn/nic/gvisor" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" )
var ( server = "wss://openpg.in/pg" secretFile = "psns.json" _, ip4, _ = net.ParseCIDR("100.99.0.27/24") )
func prepareSecret() error { fetchSecret := func() error { join, err := network.JoinOIDC("", server) if err != nil { return err } fmt.Println("Open the following link to authenticate") fmt.Println(join.AuthURL()) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) secret, err := join.Wait(ctx) cancel() if err != nil { panic(err) } f, err := os.Create(secretFile) if err != nil { return err } json.NewEncoder(f).Encode(secret) return nil }
f, err := os.Open(secretFile) if err != nil { return fetchSecret() } var secret disco.NetworkSecret if err := json.NewDecoder(f).Decode(&secret); err != nil { return err } if time.Now().After(secret.Expire) { return fetchSecret() } return nil }
func startVPN(ctx context.Context) *gvisor.GvisorCard { s := stack.New(stack.Options{ NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol}, })
vnic := nic.VirtualNIC{NIC: &gvisor.GvisorCard{Stack: s, Config: nic.Config{IPv4: ip4.String()}}} packetConn := langs.Must(p2p.ListenPacket( &disco.Server{Secret: &disco.FileSecretStore{StoreFilePath: secretFile}, URL: server}, p2p.ListenPeerUp(func(pi disco.PeerID, v url.Values) { vnic.AddPeer(nic.Peer{Addr: pi, IPv4: v.Get("alias1"), IPv6: v.Get("alias2"), Meta: v}) }), p2p.ListenPeerSecure(), p2p.PeerAlias1(ip4.IP.String()), ))
go vpn.New(vpn.Config{MTU: 1371}).Run(ctx, &vnic, packetConn) return vnic.NIC.(*gvisor.GvisorCard) }
func main() {
if err := prepareSecret(); err != nil { panic(err) }
ctx, cancel := context.WithCancel(context.Background()) defer cancel() gvisorCard := startVPN(ctx)
cli := http.Client{ Transport: &http.Transport{DialContext: gvisorCard.DialContext}, Timeout: 15 * time.Second, }
r := langs.Must(cli.Get("http://100.99.0.2")) defer r.Body.Close() io.Copy(os.Stdout, r.Body) }
|