Skip to content

Commit

Permalink
Merge pull request #34 from shoriwe/Project-Structure
Browse files Browse the repository at this point in the history
Project structure
  • Loading branch information
shoriwe authored Nov 23, 2020
2 parents 7a15e51 + 93f7da1 commit 982aa6d
Show file tree
Hide file tree
Showing 58 changed files with 1,129 additions and 857 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
.idea/modules.xml
.idea/misc.xml
.idea/FullProxy.iml
build/*
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ Protocols available:
```
user@linux:~$ fullproxy socks5 --help
Usage of socks5:
-address string
Address to listen on. When "-slave" flag is set, is the IP of master to connect
-host string
Host to listen on. When "-slave" flag is set, is the IP of master to connect
-password string
Password of the running proxy, requires "-username". It will be ignored if is an empty string
-port string
Expand All @@ -61,8 +61,8 @@ HTTP proxy could be implemented thanks to [GoProxy](https://github.com/elazarl/g
```
user@linux:~$ fullproxy local-forward -help
Usage of http:
-address string
Address to listen on. When "-slave" flag is set, is the IP of master to connect
-host string
Host to listen on. When "-slave" flag is set, is the IP of master to connect
-password string
Password of the running proxy, requires "-username". It will be ignored if is an empty string
-port string
Expand All @@ -79,35 +79,35 @@ Usage of http:
```
user@linux:~$ fullproxy local-forward -help
Usage of local-forward:
-forward-address string
Address to forward the traffic received from master
-forward-host string
Host to forward the traffic received from master
-forward-port string
Port to forward the traffic received from master
-master-address string
Address of the master
-master-host string
Host of the master
-master-port string
Port of the master
```
#### Remote
```
user@linux:~$ fullproxy remote-forward -help
Usage of remote-forward:
-local-address string
Address to bind by slave
-local-host string
Host to bind by slave
-local-port string
Port to bind by slave
-master-address string
Address of the master
-master-host string
Host of the master
-master-port string
Port of the master
```
### Master
```
user@linux:~$ fullproxy remote-forward -help
Usage of master:
-address string
Address to listen on. (default "0.0.0.0")
-forward-address string
-host string
Host to listen on. (default "0.0.0.0")
-forward-host string
Argument required to handle correctly the "remote-forward" (This is the service that the master can only acceded)
-forward-port string
Argument required to handle correctly the "remote-forward" (This is the service that the master can only acceded)
Expand All @@ -127,28 +127,28 @@ TARGETS available:
```
user@linux:~$ fullproxy translate port_forward-socks5 -help
Usage of port_forward-socks5:
-bind-address string
Address to listen on. (default "0.0.0.0")
-bind-host string
Host to listen on. (default "0.0.0.0")
-bind-port string
Port to listen on. (default "8080")
-socks5-address string
SOCKS5 server address to use (default "127.0.0.1")
-socks5-host string
SOCKS5 server host to use (default "127.0.0.1")
-socks5-password string
Password for the SOCKS5 server; leave empty for no AUTH
-socks5-port string
SOCKS5 server port to use (default "1080")
-socks5-username string
Username for the SOCKS5 server; leave empty for no AUTH
-target-address string
Address of the target host that is accessible by the SOCKS5 proxy
-target-host string
Host of the target host that is accessible by the SOCKS5 proxy
-target-port string
Port of the target host that is accessible by the SOCKS5 proxy
```
# Concepts
## Master/Slave
Handles the proxying between a reverse connected (with encryption) proxy and the clients. In other words, it will receive the connections of the clients and will forward the traffic to the proxy that is reverse connected to it.
### How it works
1. It first binds to the address specified by the user.
1. It first binds to the host specified by the user.
2. Then accept the connection from the proxy server.
3. Finally, it proxy the traffic of all new incoming connections to the proxy server that was reverse connected to it in the second step.
In other words, is the proxy of another proxy but totally invisible for the client.
Expand Down
Binary file removed build/fullproxy-linux-32
Binary file not shown.
Binary file removed build/fullproxy-linux-64
Binary file not shown.
Binary file removed build/fullproxy-windows-32.exe
Binary file not shown.
Binary file removed build/fullproxy-windows-64.exe
Binary file not shown.
58 changes: 58 additions & 0 deletions cmd/FullProxy/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"fmt"
"github.com/shoriwe/FullProxy/internal/ArgumentParser"
"github.com/shoriwe/FullProxy/internal/ProxiesSetup"
"github.com/shoriwe/FullProxy/internal/SetupControllers"
"os"
)

func main() {
numberOfArguments := len(os.Args)
if numberOfArguments == 1 {
_, _ = fmt.Fprintln(os.Stderr, "Try:\n", os.Args[0], " help")
os.Exit(-1)
}
switch os.Args[1] {
case "socks5":
host, port, username, password, slave := ArgumentParser.ParseSocks5Arguments()
ProxiesSetup.SetupSocks5(host, port, slave, username, password)
case "http":
host, port, username, password, slave, tls := ArgumentParser.HTTPArguments()
ProxiesSetup.SetupHTTP(host, port, slave, tls, username, password)
case "local-forward":
host, port, masterHost, masterPort := ArgumentParser.LocalPortForwardArguments()
ProxiesSetup.SetupLocalForward(host, port, masterHost, masterPort)
case "remote-forward":
localHost, localPort, masterHost, masterPort := ArgumentParser.RemotePortForwardArguments()
ProxiesSetup.SetupRemoteForward(localHost, localPort, masterHost, masterPort)
case "master":
masterHost, masterPort, remoteHost, remotePort := ArgumentParser.ParseMasterArguments()
if len(*remoteHost) > 0 && len(*remotePort) > 0 {
SetupControllers.MasterRemote(masterHost, masterPort, remoteHost, remotePort)
} else {
SetupControllers.MasterGeneral(masterHost, masterPort)
}
case "translate":
if numberOfArguments == 2 {
_, _ = fmt.Fprintln(os.Stderr, "Try:\n", os.Args[0], " translate help")
os.Exit(-1)
}
switch os.Args[2] {
case "port_forward-socks5":
bindHost, bindPort, socks5Host, socks5Port, username, password, targetHost, targetPort := ArgumentParser.ParseForwardToSocks5Arguments()
ProxiesSetup.SetupForwardSocks5(bindHost, bindPort, socks5Host, socks5Port, username, password, targetHost, targetPort)
case "help":
ArgumentParser.ShowTranslateHelpMessage()
default:
_, _ = fmt.Fprintln(os.Stderr, "Unknown command\nTry: ", os.Args[0], " translate help")
os.Exit(-1)
}
case "help":
ArgumentParser.ShowGeneralHelpMessage()
default:
_, _ = fmt.Fprintln(os.Stderr, "Unknown command\nTry: ", os.Args[0], " help")
os.Exit(-1)
}
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/shoriwe/FullProxy
go 1.14

require (
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153
)
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnk
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 h1:phUcVbl53swtrUN8kQEXFhUxPlIlWyBfKmidCu7P95o=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321 h1:lleNcKRbcaC8MqgLwghIkzZ2JBQAb7QQ9MiwRt1BisA=
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153 h1:i2sumy6EgvN2dbX7HPhoDc7hLyoym3OYdU5HlvUUrpE=
gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153/go.mod h1:xzjpkyedLMz3EXUTBbkRuuGPsxfsBX3Sy7J6kC9Gvoc=
46 changes: 23 additions & 23 deletions src/ArgumentParser/Parser.go → internal/ArgumentParser/Parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,41 @@ import (

func HTTPArguments() (*string, *string, []byte, []byte, *bool, *bool) {
protocolFlagSet := flag.NewFlagSet("http", flag.ExitOnError)
address := protocolFlagSet.String("address", "", "Address to listen on. When \"-slave\" flag is set, is the IP of master to connect")
host := protocolFlagSet.String("host", "", "Host to listen on. When \"-slave\" flag is set, is the IP of master to connect")
port := protocolFlagSet.String("port", "8080", "Port to listen on. When \"-slave\" flag is set, is the Port of the master to connect. I both modes the default port is 8080")
username := protocolFlagSet.String("username", "", "Username of the running proxy, requires \"-password\". It will be ignored if is an empty string")
password := protocolFlagSet.String("password", "", "Password of the running proxy, requires \"-username\". It will be ignored if is an empty string")
slave := protocolFlagSet.Bool("slave", false, "Connect to a master, no bind proxying")
tls := protocolFlagSet.Bool("tls", false, "Use HTTPS")
_ = protocolFlagSet.Parse(os.Args[2:])
if len(*address) == 0 {
if len(*host) == 0 {
if *slave {
*address = "127.0.0.1"
*host = "127.0.0.1"
} else {
*address = "0.0.0.0"
*host = "0.0.0.0"
}
}
return address, port, []byte(*username), []byte(*password), slave, tls
return host, port, []byte(*username), []byte(*password), slave, tls
}

func LocalPortForwardArguments() (*string, *string, *string, *string) {
protocolFlagSet := flag.NewFlagSet("local-forward", flag.ExitOnError)
forwardAddress := protocolFlagSet.String("forward-address", "", "Address to forward the traffic received from master")
forwardHost := protocolFlagSet.String("forward-host", "", "Host to forward the traffic received from master")
forwardPort := protocolFlagSet.String("forward-port", "", "Port to forward the traffic received from master")
masterAddress := protocolFlagSet.String("master-address", "", "Address of the master")
masterHost := protocolFlagSet.String("master-host", "", "Host of the master")
masterPort := protocolFlagSet.String("master-port", "", "Port of the master")
_ = protocolFlagSet.Parse(os.Args[2:])
return forwardAddress, forwardPort, masterAddress, masterPort
return forwardHost, forwardPort, masterHost, masterPort
}

func RemotePortForwardArguments() (*string, *string, *string, *string) {
protocolFlagSet := flag.NewFlagSet("remote-forward", flag.ExitOnError)
localAddress := protocolFlagSet.String("local-address", "", "Address to bind by slave")
localHost := protocolFlagSet.String("local-host", "", "Host to bind by slave")
localPort := protocolFlagSet.String("local-port", "", "Port to bind by slave")
masterAddress := protocolFlagSet.String("master-address", "", "Address of the master")
masterHost := protocolFlagSet.String("master-host", "", "Host of the master")
masterPort := protocolFlagSet.String("master-port", "", "Port of the master")
_ = protocolFlagSet.Parse(os.Args[2:])
return localAddress, localPort, masterAddress, masterPort
return localHost, localPort, masterHost, masterPort
}

func ShowGeneralHelpMessage() {
Expand All @@ -55,42 +55,42 @@ func ShowTranslateHelpMessage() {

func ParseSocks5Arguments() (*string, *string, []byte, []byte, *bool) {
protocolFlagSet := flag.NewFlagSet("socks5", flag.ExitOnError)
address := protocolFlagSet.String("address", "", "Address to listen on. When \"-slave\" flag is set, is the IP of master to connect")
host := protocolFlagSet.String("host", "", "Host to listen on. When \"-slave\" flag is set, is the IP of master to connect")
port := protocolFlagSet.String("port", "1080", "Port to listen on. When \"-slave\" flag is set, is the Port of the master to connect. I both modes the default port is 1080")
username := protocolFlagSet.String("username", "", "Username of the running proxy, requires \"-password\". It will be ignored if is an empty string")
password := protocolFlagSet.String("password", "", "Password of the running proxy, requires \"-username\". It will be ignored if is an empty string")
slave := protocolFlagSet.Bool("slave", false, "Connect to a master, no bind proxying")
_ = protocolFlagSet.Parse(os.Args[2:])
if len(*address) == 0 {
if len(*host) == 0 {
if *slave {
*address = "127.0.0.1"
*host = "127.0.0.1"
} else {
*address = "0.0.0.0"
*host = "0.0.0.0"
}
}
return address, port, []byte(*username), []byte(*password), slave
return host, port, []byte(*username), []byte(*password), slave
}

func ParseMasterArguments() (*string, *string, *string, *string) {
protocolFlagSet := flag.NewFlagSet("master", flag.ExitOnError)
address := protocolFlagSet.String("address", "0.0.0.0", "Address to listen on.")
host := protocolFlagSet.String("host", "0.0.0.0", "Host to listen on.")
port := protocolFlagSet.String("port", "1080", "Port to listen on.")
remoteAddress := protocolFlagSet.String("forward-address", "", "Argument required to handle correctly the \"remote-forward\" (This is the service that the master can only acceded)")
remoteHost := protocolFlagSet.String("forward-host", "", "Argument required to handle correctly the \"remote-forward\" (This is the service that the master can only acceded)")
remotePort := protocolFlagSet.String("forward-port", "", "Argument required to handle correctly the \"remote-forward\" (This is the service that the master can only acceded)")
_ = protocolFlagSet.Parse(os.Args[2:])
return address, port, remoteAddress, remotePort
return host, port, remoteHost, remotePort
}

func ParseForwardToSocks5Arguments() (*string, *string, *string, *string, *string, *string, *string, *string) {
protocolFlagSet := flag.NewFlagSet("port_forward-socks5", flag.ExitOnError)
bindAddress := protocolFlagSet.String("bind-address", "0.0.0.0", "Address to listen on.")
bindHost := protocolFlagSet.String("bind-host", "0.0.0.0", "Host to listen on.")
bindPort := protocolFlagSet.String("bind-port", "8080", "Port to listen on.")
socks5Address := protocolFlagSet.String("socks5-address", "127.0.0.1", "SOCKS5 server address to use")
socks5Host := protocolFlagSet.String("socks5-host", "127.0.0.1", "SOCKS5 server host to use")
socks5Port := protocolFlagSet.String("socks5-port", "1080", "SOCKS5 server port to use")
username := protocolFlagSet.String("socks5-username", "", "Username for the SOCKS5 server; leave empty for no AUTH")
password := protocolFlagSet.String("socks5-password", "", "Password for the SOCKS5 server; leave empty for no AUTH")
targetAddress := protocolFlagSet.String("target-address", "", "Address of the target host that is accessible by the SOCKS5 proxy")
targetHost := protocolFlagSet.String("target-host", "", "Host of the target host that is accessible by the SOCKS5 proxy")
targetPort := protocolFlagSet.String("target-port", "", "Port of the target host that is accessible by the SOCKS5 proxy")
_ = protocolFlagSet.Parse(os.Args[3:])
return bindAddress, bindPort, socks5Address, socks5Port, username, password, targetAddress, targetPort
return bindHost, bindPort, socks5Host, socks5Port, username, password, targetHost, targetPort
}
16 changes: 16 additions & 0 deletions internal/ProxiesSetup/AuthenticationMethods.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ProxiesSetup

import (
"bytes"
"github.com/shoriwe/FullProxy/pkg/ConnectionControllers"
)

func BasicAuthentication(username []byte, password []byte) ConnectionControllers.AuthenticationMethod {
return func(clientUsername []byte, clientPassword []byte) bool {
return bytes.Equal(username, clientUsername) && bytes.Equal(password, clientPassword)
}
}

func NoAuthentication(_ []byte, _ []byte) bool {
return true
}
31 changes: 31 additions & 0 deletions internal/ProxiesSetup/ForwardSocks5.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ProxiesSetup

import (
"github.com/shoriwe/FullProxy/internal/SetupControllers"
"github.com/shoriwe/FullProxy/pkg/Proxies/Translation/ForwardToSocks5"
"golang.org/x/net/proxy"
"log"
)

func SetupForwardSocks5(
bindHost *string, bindPort *string,
socks5Host *string, socks5Port *string,
username *string, password *string,
targetHost *string, targetPort *string) {
proxyProtocol := new(ForwardToSocks5.ForwardToSocks5)
proxyProtocol.TargetHost = *targetHost
proxyProtocol.TargetPort = *targetPort
proxyAuth := new(proxy.Auth)
if len(*username) > 0 && len(*password) > 0 {
proxyAuth.User = *username
proxyAuth.Password = *password
} else {
proxyAuth = nil
}
proxyDialer, dialerCreationError := proxy.SOCKS5("tcp", *socks5Host+":"+*socks5Port, proxyAuth, proxy.Direct)
if dialerCreationError != nil {
log.Fatal(dialerCreationError)
}
proxyProtocol.Socks5Dialer = proxyDialer
SetupControllers.Bind(bindHost, bindPort, proxyProtocol)
}
21 changes: 21 additions & 0 deletions internal/ProxiesSetup/HTTP.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ProxiesSetup

import (
"github.com/shoriwe/FullProxy/internal/SetupControllers"
"github.com/shoriwe/FullProxy/pkg/Proxies/HTTP"
"gopkg.in/elazarl/goproxy.v1"
)

func SetupHTTP(host *string, port *string, slave *bool, tls *bool, username []byte, password []byte) {
proxy := new(HTTP.HTTP)
proxyController := goproxy.NewProxyHttpServer()
proxy.ProxyController = proxyController
if len(username) > 0 && len(password) > 0 {
proxy.SetAuthenticationMethod(BasicAuthentication(username, password))
}
if *slave {
SetupControllers.GeneralSlave(host, port, proxy)
} else {
SetupControllers.Bind(host, port, proxy)
}
}
13 changes: 13 additions & 0 deletions internal/ProxiesSetup/LocalForward.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ProxiesSetup

import (
"github.com/shoriwe/FullProxy/internal/SetupControllers"
"github.com/shoriwe/FullProxy/pkg/Proxies/PortForward"
)

func SetupLocalForward(host *string, port *string, masterHost *string, masterPort *string) {
proxy := new(PortForward.LocalForward)
proxy.TargetHost = *host
proxy.TargetPort = *port
SetupControllers.GeneralSlave(masterHost, masterPort, proxy)
}
Loading

0 comments on commit 982aa6d

Please sign in to comment.