Browse Source

update: complete proxy package

v1.x.x
dnomd343 2 years ago
parent
commit
2813bc8c3b
  1. 25
      cmd/common/file.go
  2. 43
      cmd/common/func.go
  3. 22
      cmd/common/net.go
  4. 19
      cmd/common/sys.go
  5. 49
      cmd/proxy/config.go
  6. 49
      cmd/proxy/main.go
  7. 37
      cmd/proxy/object.go
  8. 26
      main.go

25
cmd/common/file.go

@ -11,8 +11,7 @@ import (
func CreateFolder(folderPath string) { func CreateFolder(folderPath string) {
log.Debugf("Create folder -> %s", folderPath) log.Debugf("Create folder -> %s", folderPath)
err := os.MkdirAll(folderPath, 0755) if err := os.MkdirAll(folderPath, 0755); err != nil {
if err != nil {
log.Panicf("Failed to create folder -> %s", folderPath) log.Panicf("Failed to create folder -> %s", folderPath)
} }
} }
@ -31,8 +30,7 @@ func WriteFile(filePath string, content string, overwrite bool) {
return return
} }
log.Debugf("Write file `%s` -> \n%s", filePath, content) log.Debugf("Write file `%s` -> \n%s", filePath, content)
err := os.WriteFile(filePath, []byte(content), 0644) if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
if err != nil {
log.Panicf("Failed to write `%s` -> %v", filePath, err) log.Panicf("Failed to write `%s` -> %v", filePath, err)
} }
} }
@ -54,21 +52,19 @@ func ListFiles(folderPath string, suffix string) []string {
func CopyFile(source string, target string) { func CopyFile(source string, target string) {
log.Infof("Copy file `%s` => `%s`", source, target) log.Infof("Copy file `%s` => `%s`", source, target)
if IsFileExist(target) { if IsFileExist(target) {
log.Warningf("File `%s` will be overrided", target) log.Debugf("File `%s` will be overrided", target)
} }
srcFile, err := os.Open(source) srcFile, err := os.Open(source)
defer srcFile.Close()
if err != nil { if err != nil {
log.Panicf("Failed to open file -> %s", source) log.Panicf("Failed to open file -> %s", source)
} }
dstFile, err := os.OpenFile(target, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) dstFile, err := os.OpenFile(target, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
defer dstFile.Close()
if err != nil { if err != nil {
_ = srcFile.Close()
log.Panicf("Failed to open file -> %s", target) log.Panicf("Failed to open file -> %s", target)
} }
_, err = io.Copy(dstFile, srcFile) if _, err = io.Copy(dstFile, srcFile); err != nil {
_ = srcFile.Close()
_ = dstFile.Close()
if err != nil {
log.Panicf("Failed to copy from `%s` to `%s`", source, target) log.Panicf("Failed to copy from `%s` to `%s`", source, target)
} }
} }
@ -76,18 +72,17 @@ func CopyFile(source string, target string) {
func DownloadFile(url string, file string) { func DownloadFile(url string, file string) {
log.Debugf("File download `%s` => `%s`", url, file) log.Debugf("File download `%s` => `%s`", url, file)
resp, err := http.Get(url) resp, err := http.Get(url)
defer resp.Body.Close()
if err != nil { if err != nil {
log.Errorf("Download `%s` error -> %v", url, err) log.Errorf("Download `%s` error -> %v", url, err)
return return
} }
out, err := os.OpenFile(file, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) output, err := os.OpenFile(file, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
defer output.Close()
if err != nil { if err != nil {
_ = resp.Body.Close()
log.Panicf("Open `%s` error -> %v", file, err) log.Panicf("Open `%s` error -> %v", file, err)
} }
_, err = io.Copy(out, resp.Body) if _, err = io.Copy(output, resp.Body); err != nil {
_ = resp.Body.Close()
if err != nil {
log.Panicf("File `%s` save error -> %v", file, err) log.Panicf("File `%s` save error -> %v", file, err)
} }
log.Infof("Download success `%s` => `%s`", url, file) log.Infof("Download success `%s` => `%s`", url, file)

43
cmd/common/func.go

@ -0,0 +1,43 @@
package common
import (
"encoding/json"
log "github.com/sirupsen/logrus"
"net"
"os/exec"
"strings"
"syscall"
)
func isIP(ipAddr string, isCidr bool) bool {
if !isCidr {
return net.ParseIP(ipAddr) != nil
}
_, _, err := net.ParseCIDR(ipAddr)
return err == nil
}
func IsIPv4(ipAddr string, isCidr bool) bool {
return isIP(ipAddr, isCidr) && strings.Contains(ipAddr, ".")
}
func IsIPv6(ipAddr string, isCidr bool) bool {
return isIP(ipAddr, isCidr) && strings.Contains(ipAddr, ":")
}
func JsonEncode(raw interface{}) string {
jsonOutput, _ := json.MarshalIndent(raw, "", " ") // json encode
return string(jsonOutput)
}
func RunCommand(command ...string) (int, string) {
log.Debugf("Running system command -> %v", command)
process := exec.Command(command[0], command[1:]...)
output, _ := process.CombinedOutput()
log.Debugf("Command %v -> \n%s", command, string(output))
code := process.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
if code != 0 {
log.Warningf("Command %v return code %d", command, code)
}
return code, string(output)
}

22
cmd/common/net.go

@ -1,22 +0,0 @@
package common
import (
"net"
"strings"
)
func isIP(ipAddr string, isCidr bool) bool {
if !isCidr {
return net.ParseIP(ipAddr) != nil
}
_, _, err := net.ParseCIDR(ipAddr)
return err == nil
}
func IsIPv4(ipAddr string, isCidr bool) bool {
return isIP(ipAddr, isCidr) && strings.Contains(ipAddr, ".")
}
func IsIPv6(ipAddr string, isCidr bool) bool {
return isIP(ipAddr, isCidr) && strings.Contains(ipAddr, ":")
}

19
cmd/common/sys.go

@ -1,19 +0,0 @@
package common
import (
log "github.com/sirupsen/logrus"
"os/exec"
"syscall"
)
func RunCommand(command ...string) (int, string) {
log.Debugf("Running system command -> %v", command)
process := exec.Command(command[0], command[1:]...)
output, _ := process.CombinedOutput()
log.Debugf("Command %v -> \n%s", command, string(output))
code := process.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
if code != 0 {
log.Warningf("Command %v return code %d", command, code)
}
return code, string(output)
}

49
cmd/proxy/config.go

@ -1,5 +1,10 @@
package proxy package proxy
import (
"XProxy/cmd/common"
log "github.com/sirupsen/logrus"
)
var dnsConfig = `{ var dnsConfig = `{
"dns": { "dns": {
"servers": [ "servers": [
@ -31,7 +36,45 @@ var outboundsConfig = `{
] ]
}` }`
func httpConfig(tag string, port int, sniff sniffObject) interface{} { type logObject struct {
Loglevel string `json:"loglevel"`
Access string `json:"access"`
Error string `json:"error"`
}
type inboundsObject struct {
Inbounds []interface{} `json:"inbounds"`
}
type sniffObject struct {
Enabled bool `json:"enabled"`
RouteOnly bool `json:"routeOnly"`
DestOverride []string `json:"destOverride"`
}
type inboundObject struct {
Tag string `json:"tag"`
Port int `json:"port"`
Protocol string `json:"protocol"`
Settings interface{} `json:"settings"`
StreamSettings interface{} `json:"streamSettings"`
Sniffing sniffObject `json:"sniffing"`
}
func loadLogConfig(logLevel string, logDir string) string {
if logLevel != "debug" && logLevel != "info" &&
logLevel != "warning" && logLevel != "error" && logLevel != "none" {
log.Warningf("Unknown log level -> %s", logLevel)
logLevel = "warning" // using `warning` as default
}
return common.JsonEncode(logObject{
Loglevel: logLevel,
Access: logDir + "/access.log",
Error: logDir + "/error.log",
})
}
func loadHttpConfig(tag string, port int, sniff sniffObject) interface{} {
type empty struct{} type empty struct{}
return inboundObject{ return inboundObject{
Tag: tag, Tag: tag,
@ -43,7 +86,7 @@ func httpConfig(tag string, port int, sniff sniffObject) interface{} {
} }
} }
func socksConfig(tag string, port int, sniff sniffObject) interface{} { func loadSocksConfig(tag string, port int, sniff sniffObject) interface{} {
type empty struct{} type empty struct{}
type socksObject struct { type socksObject struct {
UDP bool `json:"udp"` UDP bool `json:"udp"`
@ -58,7 +101,7 @@ func socksConfig(tag string, port int, sniff sniffObject) interface{} {
} }
} }
func tproxyConfig(tag string, port int, sniff sniffObject) interface{} { func loadTProxyConfig(tag string, port int, sniff sniffObject) interface{} {
type tproxyObject struct { type tproxyObject struct {
Network string `json:"network"` Network string `json:"network"`
FollowRedirect bool `json:"followRedirect"` FollowRedirect bool `json:"followRedirect"`

49
cmd/proxy/load.go → cmd/proxy/main.go

@ -2,52 +2,45 @@ package proxy
import ( import (
"XProxy/cmd/common" "XProxy/cmd/common"
"encoding/json"
log "github.com/sirupsen/logrus"
) )
type Config struct {
Sniff bool
Redirect bool
V4TProxyPort int
V6TProxyPort int
LogLevel string
HttpInbounds map[string]int
SocksInbounds map[string]int
AddOnInbounds []interface{}
}
func saveConfig(configDir string, caption string, content string, overwrite bool) { func saveConfig(configDir string, caption string, content string, overwrite bool) {
filePath := configDir + "/" + caption + ".json" filePath := configDir + "/" + caption + ".json"
common.WriteFile(filePath, content+"\n", overwrite) common.WriteFile(filePath, content+"\n", overwrite)
} }
func jsonEncode(raw interface{}) string {
jsonOutput, _ := json.MarshalIndent(raw, "", " ") // json encode
return string(jsonOutput)
}
func loadLog(logLevel string, logDir string) string {
if logLevel != "debug" && logLevel != "info" &&
logLevel != "warning" && logLevel != "error" && logLevel != "none" {
log.Warningf("Unknown log level -> %s", logLevel)
logLevel = "warning" // using `warning` as default
}
return jsonEncode(logObject{
Loglevel: logLevel,
Access: logDir + "/access.log",
Error: logDir + "/error.log",
})
}
func loadInbounds(config Config) string { func loadInbounds(config Config) string {
inbounds := inboundsObject{}
sniff := sniffObject{ sniff := sniffObject{
Enabled: config.Sniff, Enabled: config.Sniff,
RouteOnly: !config.Redirect, RouteOnly: !config.Redirect,
DestOverride: []string{"http", "tls"}, DestOverride: []string{"http", "tls"},
} }
inbounds.Inbounds = append(inbounds.Inbounds, tproxyConfig("tproxy", config.V4TProxyPort, sniff)) var inbounds []interface{}
inbounds.Inbounds = append(inbounds.Inbounds, tproxyConfig("tproxy6", config.V6TProxyPort, sniff)) inbounds = append(inbounds, loadTProxyConfig("tproxy", config.V4TProxyPort, sniff))
inbounds = append(inbounds, loadTProxyConfig("tproxy6", config.V6TProxyPort, sniff))
for tag, port := range config.HttpInbounds { for tag, port := range config.HttpInbounds {
inbounds.Inbounds = append(inbounds.Inbounds, httpConfig(tag, port, sniff)) inbounds = append(inbounds, loadHttpConfig(tag, port, sniff))
} }
for tag, port := range config.SocksInbounds { for tag, port := range config.SocksInbounds {
inbounds.Inbounds = append(inbounds.Inbounds, socksConfig(tag, port, sniff)) inbounds = append(inbounds, loadSocksConfig(tag, port, sniff))
} }
for _, addon := range config.AddOnInbounds { for _, addon := range config.AddOnInbounds {
inbounds.Inbounds = append(inbounds.Inbounds, addon) inbounds = append(inbounds, addon)
} }
return jsonEncode(inbounds) return common.JsonEncode(inboundsObject{
Inbounds: inbounds,
})
} }
func Load(configDir string, exposeDir string, config Config) { func Load(configDir string, exposeDir string, config Config) {
@ -58,7 +51,7 @@ func Load(configDir string, exposeDir string, config Config) {
saveConfig(exposeDir+"/config", "route", routeConfig, false) saveConfig(exposeDir+"/config", "route", routeConfig, false)
saveConfig(exposeDir+"/config", "outbounds", outboundsConfig, false) saveConfig(exposeDir+"/config", "outbounds", outboundsConfig, false)
saveConfig(configDir, "inbounds", loadInbounds(config), true) saveConfig(configDir, "inbounds", loadInbounds(config), true)
saveConfig(configDir, "log", loadLog(config.LogLevel, exposeDir+"/log"), true) saveConfig(configDir, "log", loadLogConfig(config.LogLevel, exposeDir+"/log"), true)
for _, configFile := range common.ListFiles(exposeDir+"/config", ".json") { for _, configFile := range common.ListFiles(exposeDir+"/config", ".json") {
common.CopyFile(exposeDir+"/config/"+configFile, configDir+"/"+configFile) common.CopyFile(exposeDir+"/config/"+configFile, configDir+"/"+configFile)
} }

37
cmd/proxy/object.go

@ -1,37 +0,0 @@
package proxy
type Config struct {
Sniff bool
Redirect bool
V4TProxyPort int
V6TProxyPort int
LogLevel string
HttpInbounds map[string]int
SocksInbounds map[string]int
AddOnInbounds []interface{}
}
type logObject struct {
Loglevel string `json:"loglevel"`
Access string `json:"access"`
Error string `json:"error"`
}
type inboundsObject struct {
Inbounds []interface{} `json:"inbounds"`
}
type sniffObject struct {
Enabled bool `json:"enabled"`
RouteOnly bool `json:"routeOnly"`
DestOverride []string `json:"destOverride"`
}
type inboundObject struct {
Tag string `json:"tag"`
Port int `json:"port"`
Protocol string `json:"protocol"`
Settings interface{} `json:"settings"`
StreamSettings interface{} `json:"streamSettings"`
Sniffing sniffObject `json:"sniffing"`
}

26
main.go

@ -1,6 +1,8 @@
package main package main
import ( import (
"XProxy/cmd/network"
"XProxy/cmd/proxy"
"fmt" "fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@ -10,4 +12,28 @@ func main() {
fmt.Println("xproxy start") fmt.Println("xproxy start")
network.Load(nil, network.Config{
RouteTable: 100,
TProxyPort: 7288,
Address: "192.168.2.2",
Gateway: "192.168.2.1",
Bypass: make([]string, 0),
}, network.Config{
RouteTable: 106,
TProxyPort: 7289,
Address: "fc00::2",
Gateway: "fc00::1",
Bypass: make([]string, 0),
})
proxy.Load("/etc/xproxy", "/xproxy", proxy.Config{
Sniff: true,
Redirect: true,
V4TProxyPort: 7288,
V6TProxyPort: 7289,
LogLevel: "debug",
HttpInbounds: nil,
SocksInbounds: nil,
AddOnInbounds: nil,
})
} }

Loading…
Cancel
Save