-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9d4b03a
Showing
12 changed files
with
955 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/sandbox | ||
/dist | ||
/bin | ||
/cert |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
export ROOT=$(realpath $(dir $(firstword $(MAKEFILE_LIST)))) | ||
export BIN=$(ROOT)/bin | ||
export GOBIN?=$(BIN) | ||
export GO=$(shell which go) | ||
export CGO_ENABLED=1 | ||
export PROTO_OUT=$(ROOT) | ||
export GOX=$(BIN)/gox | ||
|
||
proto: | ||
@protoc \ | ||
-Iprotofiles \ | ||
--go_out=${PROTO_OUT} \ | ||
--go-grpc_out=${PROTO_OUT} \ | ||
protofiles/*.proto | ||
.PHONY: proto | ||
|
||
install-gox: | ||
@$(GO) install github.com/mitchellh/[email protected] | ||
|
||
.PHONY: build-linux | ||
build-linux: install-gox | ||
@$(GOX) --arch=amd64 --os=linux --output="dist/utg_{{.OS}}_{{.Arch}}" | ||
|
||
.PHONY: build-macOS | ||
build-macOS: install-gox | ||
@$(GOX) --arch=amd64 --os=darwin --output="dist/utg_{{.OS}}_{{.Arch}}" | ||
|
||
.PHONY: build-windows | ||
build-windows: install-gox | ||
@$(GOX) -ldflags ${GO_LDFLAGS} --arch=amd64 --os=windows --output="dist/utg_{{.OS}}_{{.Arch}}" | ||
|
||
.PHONY: build-artifacts | ||
build-artifacts: | ||
@$(MAKE) build-linux && \ | ||
$(MAKE) build-macOS && \ | ||
$(MAKE) build-windows | ||
|
||
cert: | ||
@openssl genrsa -out cert/ca.key 2048 | ||
@openssl req -new -x509 -days 365 -key cert/ca.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=Acme Root CA" -out cert/ca.crt | ||
@openssl req -newkey rsa:2048 -nodes -keyout cert/server.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=*.mrjosh.net" -out cert/server.csr | ||
@openssl x509 -req -extfile <(printf "subjectAltName=DNS:mrjosh.net,DNS:u2g.mrjosh.net") -days 365 -in cert/server.csr -CA cert/ca.crt -CAkey cert/ca.key -CAcreateserial -out cert/server.crt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package cmds | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/mrjosh/udp2grpc/internal/client" | ||
"github.com/mrjosh/udp2grpc/proto" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/credentials" | ||
) | ||
|
||
type NewClientFlags struct { | ||
localaddr, remoteaddr string | ||
localport, remoteport int | ||
insecure bool | ||
certFile, serverNameOverride string | ||
} | ||
|
||
func NewClientCommand() *cobra.Command { | ||
|
||
log.SetFlags(log.Lshortfile) | ||
cFlags := new(NewClientFlags) | ||
|
||
cmd := &cobra.Command{ | ||
Use: "client", | ||
Short: "Start a udp2grpc tcp/client", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
|
||
if cFlags.remoteaddr == "" { | ||
return errors.New("server remote address is required. try 'utg client --address domain.tld'") | ||
} | ||
|
||
opts := []grpc.DialOption{} | ||
if cFlags.insecure { | ||
opts = append(opts, grpc.WithInsecure()) | ||
} | ||
|
||
if !cFlags.insecure { | ||
|
||
if cFlags.certFile == "" { | ||
return errors.New("--tls-cert-file flag is required in tls mode. turn off tls mode with --insecure flag") | ||
} | ||
|
||
creds, err := credentials.NewClientTLSFromFile(cFlags.certFile, cFlags.serverNameOverride) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
opts = append(opts, grpc.WithTransportCredentials(creds)) | ||
} | ||
|
||
addr := fmt.Sprintf("%s:%d", cFlags.remoteaddr, cFlags.remoteport) | ||
|
||
conn, err := grpc.Dial(addr, opts...) | ||
if err != nil { | ||
return fmt.Errorf("did not connect: %v", err) | ||
} | ||
|
||
c := proto.NewVPNServiceClient(conn) | ||
|
||
log.Println(fmt.Sprintf("Connecting to tcp:%s", addr)) | ||
|
||
callOpts := grpc.EmptyCallOption{} | ||
stream, err := c.Connect(context.Background(), callOpts) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Println(fmt.Sprintf("Connected to tcp:%s", addr)) | ||
|
||
ic, err := client.NewClient(fmt.Sprintf("%s:%d", cFlags.localaddr, cFlags.localport), stream) | ||
if err != nil { | ||
return err | ||
} | ||
defer ic.Close() | ||
|
||
return ic.Listen() | ||
}, | ||
} | ||
|
||
cmd.SuggestionsMinimumDistance = 1 | ||
cmd.Flags().StringVarP(&cFlags.remoteaddr, "remote-address", "r", "", "Server remote address") | ||
cmd.Flags().IntVarP(&cFlags.remoteport, "port", "p", 52935, "Server tcp port") | ||
cmd.Flags().StringVarP(&cFlags.localaddr, "local-address", "l", "", "Local server address") | ||
cmd.Flags().IntVarP(&cFlags.localport, "local-port", "P", 52935, "Local server port") | ||
cmd.Flags().StringVarP(&cFlags.certFile, "tls-cert-file", "c", "", "Server TLS certificate file") | ||
cmd.Flags().StringVarP(&cFlags.serverNameOverride, "tls-server-name", "o", "", "TLS server name override") | ||
cmd.Flags().BoolVarP(&cFlags.insecure, "insecure", "k", false, "Connect to server without tls") | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package cmds | ||
|
||
import ( | ||
"crypto/tls" | ||
"fmt" | ||
"log" | ||
"net" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/mrjosh/udp2grpc/internal/service" | ||
"github.com/mrjosh/udp2grpc/proto" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/credentials" | ||
"google.golang.org/grpc/keepalive" | ||
"google.golang.org/grpc/reflection" | ||
) | ||
|
||
type NewServerFlags struct { | ||
localaddr, remoteaddr string | ||
port int | ||
insecure bool | ||
certFile, keyFile string | ||
} | ||
|
||
func NewServerCommand() *cobra.Command { | ||
|
||
log.SetFlags(log.Lshortfile) | ||
cFlags := new(NewServerFlags) | ||
|
||
cmd := &cobra.Command{ | ||
Use: "server", | ||
Short: "Start a udp2grpc tcp/server", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
|
||
if cFlags.remoteaddr == "" { | ||
return fmt.Errorf("Server remote address is required. try with flag 'utg server --remote-address=\"127.0.0.1\" '") | ||
} | ||
|
||
listener, err := net.Listen("tcp4", fmt.Sprintf("%s:%d", cFlags.localaddr, cFlags.port)) | ||
if err != nil { | ||
return fmt.Errorf("could not create tcp listener: %v", err) | ||
} | ||
|
||
kaParams := keepalive.ServerParameters{ | ||
Time: 10 * time.Second, | ||
Timeout: 5 * time.Second, | ||
} | ||
|
||
enforcement := keepalive.EnforcementPolicy{ | ||
MinTime: 3 * time.Second, | ||
PermitWithoutStream: true, | ||
} | ||
|
||
opts := []grpc.ServerOption{ | ||
grpc.KeepaliveParams(kaParams), | ||
grpc.KeepaliveEnforcementPolicy(enforcement), | ||
} | ||
|
||
if !cFlags.insecure { | ||
|
||
if cFlags.certFile == "" { | ||
return errors.New("--tls-cert-file flag is required in tls mode. turn off tls mode with --insecure flag") | ||
} | ||
|
||
if cFlags.keyFile == "" { | ||
return errors.New("--tls-key-file flag is required in tls mode. turn off tls mode with --insecure flag") | ||
} | ||
|
||
tlsCredentials, err := loadTLSCredentials(cFlags.certFile, cFlags.keyFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
opts = append(opts, grpc.Creds(credentials.NewServerTLSFromCert(tlsCredentials))) | ||
} | ||
|
||
server := grpc.NewServer(opts...) | ||
|
||
remoteConn, err := createRemoteConnection(cFlags.remoteaddr) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Register binance services | ||
svc := service.NewVPNService(remoteConn) | ||
defer svc.Close() | ||
|
||
proto.RegisterVPNServiceServer(server, svc) | ||
|
||
reflection.Register(server) | ||
|
||
log.Println(fmt.Sprintf("Server running in tcp:%s:%d", cFlags.localaddr, cFlags.port)) | ||
if err := server.Serve(listener); err != nil { | ||
return fmt.Errorf("could not serve grpc.tcp.listener: %v", err) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
cmd.SuggestionsMinimumDistance = 1 | ||
cmd.Flags().StringVarP(&cFlags.localaddr, "local-address", "l", "0.0.0.0", "Local server address") | ||
cmd.Flags().StringVarP(&cFlags.remoteaddr, "remote-address", "r", "", "Remote address") | ||
cmd.Flags().IntVarP(&cFlags.port, "port", "p", 52935, "Local server port") | ||
cmd.Flags().StringVarP(&cFlags.certFile, "tls-cert-file", "c", "", "Server TLS certificate file") | ||
cmd.Flags().StringVarP(&cFlags.keyFile, "tls-key-file", "s", "", "Server TLS key file") | ||
cmd.Flags().BoolVarP(&cFlags.insecure, "insecure", "k", false, "Start the server without tls") | ||
return cmd | ||
} | ||
|
||
func createRemoteConnection(address string) (*net.UDPConn, error) { | ||
|
||
remote := strings.Split(address, ":") | ||
rport, err := strconv.Atoi(remote[1]) | ||
if err != nil { | ||
log.Fatal(errors.New("listen flag should contains ip:port")) | ||
} | ||
|
||
remoteConn, err := net.DialUDP( | ||
"udp", | ||
&net.UDPAddr{}, | ||
&net.UDPAddr{ | ||
IP: net.ParseIP(remote[0]), | ||
Port: rport, | ||
}, | ||
) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return remoteConn, nil | ||
} | ||
|
||
func loadTLSCredentials(certFile, keyFile string) (*tls.Certificate, error) { | ||
// Load server's certificate and private key | ||
serverCert, err := tls.LoadX509KeyPair(certFile, keyFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &serverCert, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module github.com/mrjosh/udp2grpc | ||
|
||
go 1.19 | ||
|
||
require ( | ||
github.com/pkg/errors v0.9.1 | ||
github.com/spf13/cobra v1.6.1 | ||
google.golang.org/grpc v1.50.1 | ||
google.golang.org/protobuf v1.28.1 | ||
) | ||
|
||
require ( | ||
github.com/golang/protobuf v1.5.2 // indirect | ||
github.com/inconshreveable/mousetrap v1.0.1 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect | ||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect | ||
golang.org/x/text v0.3.3 // indirect | ||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect | ||
) |
Oops, something went wrong.