diff --git a/Dockerfile b/Dockerfile index 8bbb111..481936f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,11 +3,12 @@ ARG GOLANG="golang:1.19-alpine3.16" FROM ${ALPINE} AS upx RUN apk add build-base cmake git -RUN git clone https://github.com/dnomd343/upx.git +RUN git clone https://github.com/dnomd343/upx.git --depth=1 WORKDIR ./upx/ RUN git submodule update --init && rm -rf ./.git/ -RUN make UPX_CMAKE_CONFIG_FLAGS=-DCMAKE_EXE_LINKER_FLAGS=-static && \ - mv ./build/release/upx /tmp/ && strip /tmp/upx +RUN make UPX_CMAKE_CONFIG_FLAGS=-DCMAKE_EXE_LINKER_FLAGS=-static +WORKDIR ./build/release/ +RUN strip upx && mv upx /tmp/ FROM ${GOLANG} AS xray ENV XRAY="1.6.0" @@ -18,26 +19,6 @@ RUN env CGO_ENABLED=0 go build -v -trimpath -ldflags "-s -w" && mv main /tmp/xra COPY --from=upx /tmp/upx /usr/bin/ RUN upx -9 /tmp/xray -FROM ${GOLANG} AS v2ray -ENV V2FLY="5.1.0" -RUN wget https://github.com/v2fly/v2ray-core/archive/refs/tags/v${V2FLY}.tar.gz && tar xf v${V2FLY}.tar.gz -WORKDIR ./v2ray-core-${V2FLY}/main/ -RUN go get -d -RUN env CGO_ENABLED=0 go build -v -trimpath -ldflags "-s -w" && mv main /tmp/v2ray -COPY --from=upx /tmp/upx /usr/bin/ -RUN upx -9 /tmp/v2ray - -FROM ${GOLANG} AS sagray -#ENV SAGER_VER="5.0.17" -RUN wget https://github.com/SagerNet/v2ray-core/archive/refs/heads/main.zip && unzip main.zip -WORKDIR ./v2ray-core-main/main/ -#RUN wget https://github.com/SagerNet/v2ray-core/archive/refs/tags/v${SAGER}.tar.gz && tar xf v${SAGER}.tar.gz -#WORKDIR ./v2ray-core-${SAGER}/main/ -RUN go get -d -RUN env CGO_ENABLED=0 go build -v -trimpath -ldflags "-s -w" && mv main /tmp/sagray -COPY --from=upx /tmp/upx /usr/bin/ -RUN upx -9 /tmp/sagray - FROM ${GOLANG} AS xproxy COPY ./ /XProxy/ WORKDIR /XProxy/cmd/ @@ -53,8 +34,6 @@ RUN wget "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/downlo wget "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" && \ tar cJf assets.tar.xz *.dat && rm *.dat COPY --from=xproxy /tmp/xproxy /release/usr/bin/ -COPY --from=sagray /tmp/sagray /release/usr/bin/ -COPY --from=v2ray /tmp/v2ray /release/usr/bin/ COPY --from=xray /tmp/xray /release/usr/bin/ FROM ${ALPINE} diff --git a/cmd/config/decode.go b/cmd/config/decode.go index bb0543c..01cb84f 100644 --- a/cmd/config/decode.go +++ b/cmd/config/decode.go @@ -8,13 +8,12 @@ import ( "XProxy/cmd/proxy" "XProxy/cmd/radvd" "encoding/json" + "github.com/BurntSushi/toml" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v3" "net/url" ) -// TODO: add TOML support - type NetConfig struct { Gateway string `yaml:"gateway" json:"gateway" toml:"gateway"` // network gateway Address string `yaml:"address" json:"address" toml:"address"` // network address @@ -41,11 +40,15 @@ func configDecode(raw []byte, fileSuffix string) RawConfig { log.Debugf("Config raw content -> \n%s", string(raw)) if fileSuffix == ".json" { if err := json.Unmarshal(raw, &config); err != nil { // json format decode - log.Panicf("Decode config file error -> %v", err) + log.Panicf("Decode JSON config file error -> %v", err) + } + } else if fileSuffix == ".toml" { + if err := toml.Unmarshal(raw, &config); err != nil { // toml format decode + log.Panicf("Decode TOML config file error -> %v", err) } } else { if err := yaml.Unmarshal(raw, &config); err != nil { // yaml format decode - log.Panicf("Decode config file error -> %v", err) + log.Panicf("Decode YAML config file error -> %v", err) } } log.Debugf("Decoded configure -> %v", config) @@ -129,20 +132,11 @@ func decodeIPv6(rawConfig *RawConfig, config *Config) { func decodeProxy(rawConfig *RawConfig, config *Config) { config.Proxy = rawConfig.Proxy - if config.Proxy.Core == "" { - config.Proxy.Core = "xray" // use xray in default - } - if config.Proxy.Core != "xray" && config.Proxy.Core != "v2ray" && config.Proxy.Core != "sagray" { - log.Warningf("Unknown core type -> %s", config.Proxy.Core) - } - if config.Proxy.Core != "xray" && config.Proxy.Core != "sagray" && !config.Proxy.Sniff.Redirect { - log.Warningf("V2fly core couldn't disable redirect in sniff (aka `routeOnly` option)") - } - if config.Proxy.Core != "xray" && len(config.Proxy.Sniff.Exclude) != 0 { - log.Warningf("The exclude list in sniff options can only use for Xray-core") + if config.Proxy.Bin == "" { + config.Proxy.Bin = "xray" // default proxy bin } + log.Debugf("Proxy bin -> %s", config.Proxy.Bin) log.Debugf("Proxy log level -> %s", config.Proxy.Log) - log.Debugf("Core type -> %s", config.Proxy.Core) log.Debugf("Http inbounds -> %v", config.Proxy.Http) log.Debugf("Socks5 inbounds -> %v", config.Proxy.Socks) log.Debugf("Add-on inbounds -> %v", config.Proxy.AddOn) diff --git a/cmd/config/default.go b/cmd/config/default.go index b24a358..2efe54b 100644 --- a/cmd/config/default.go +++ b/cmd/config/default.go @@ -1,22 +1,66 @@ package config -var defaultConfig = `# default configure file for xproxy -proxy: - core: xray - log: warning +import ( + "XProxy/cmd/common" + "bytes" + "encoding/json" + "github.com/BurntSushi/toml" + log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v3" + "path" +) -network: - bypass: - - 169.254.0.0/16 - - 224.0.0.0/3 - - fc00::/7 - - fe80::/10 - - ff00::/8 +var defaultConfig = map[string]interface{}{ + "proxy": map[string]string{ + "log": "warning", + }, + "network": map[string]interface{}{ + "bypass": []string{ + "169.254.0.0/16", + "224.0.0.0/3", + "fc00::/7", + "fe80::/10", + "ff00::/8", + }, + }, + "asset": map[string]interface{}{ + "update": map[string]interface{}{ + "cron": "0 5 6 * * *", + "url": map[string]string{ + "geoip.dat": "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat", + "geosite.dat": "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat", + }, + }, + }, +} -asset: - update: - cron: "0 5 6 * * *" - url: - geoip.dat: "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" - geosite.dat: "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" -` +func toJSON(config interface{}) string { // convert to JSON string + jsonRaw, _ := json.MarshalIndent(config, "", " ") + return string(jsonRaw) +} + +func toYAML(config interface{}) string { // convert to YAML string + buf := new(bytes.Buffer) + encoder := yaml.NewEncoder(buf) + encoder.SetIndent(2) // with 2 space indent + _ = encoder.Encode(config) + return buf.String() +} + +func toTOML(config interface{}) string { // convert to TOML string + buf := new(bytes.Buffer) + _ = toml.NewEncoder(buf).Encode(config) + return buf.String() +} + +func loadDefaultConfig(configFile string) { + log.Infof("Load default configure -> %s", configFile) + suffix := path.Ext(configFile) + if suffix == ".json" { + common.WriteFile(configFile, toJSON(defaultConfig), false) // JSON format + } else if suffix == ".toml" { + common.WriteFile(configFile, toTOML(defaultConfig), false) // TOML format + } else { + common.WriteFile(configFile, toYAML(defaultConfig), false) // YAML format + } +} diff --git a/cmd/config/main.go b/cmd/config/main.go index f670a37..ffa9bda 100644 --- a/cmd/config/main.go +++ b/cmd/config/main.go @@ -27,8 +27,7 @@ type Config struct { func Load(configFile string, config *Config) { if !common.IsFileExist(configFile) { // configure not exist -> load default - log.Infof("Load default configure -> %s", configFile) - common.WriteFile(configFile, defaultConfig, false) + loadDefaultConfig(configFile) } raw, err := os.ReadFile(configFile) // read configure content if err != nil { diff --git a/cmd/controller.go b/cmd/controller.go index 2609fc8..1cfeb75 100644 --- a/cmd/controller.go +++ b/cmd/controller.go @@ -65,21 +65,20 @@ func loadNetwork(settings *config.Config) { } func loadProxy(settings *config.Config) { + if proxyBin != "" { + settings.Proxy.Bin = proxyBin // setting proxy bin from env + } settings.Proxy.V4TProxyPort = v4TProxyPort settings.Proxy.V6TProxyPort = v6TProxyPort proxy.Load(configDir, exposeDir, &settings.Proxy) } func runProxy(settings *config.Config) { - if settings.Proxy.Core == "xray" { // xray-core - runProcess([]string{"XRAY_LOCATION_ASSET=" + assetDir}, "xray", "-confdir", configDir) - } else if settings.Proxy.Core == "v2ray" { // v2fly-core - runProcess([]string{"V2RAY_LOCATION_ASSET=" + assetDir}, "v2ray", "run", "-d", configDir) - } else if settings.Proxy.Core == "sagray" { // sager-core - runProcess([]string{"V2RAY_LOCATION_ASSET=" + assetDir}, "sagray", "run", "-confdir", configDir) - } else { - log.Panicf("Unknown core type -> %s", settings.Proxy.Core) + assetEnv := []string{ + "XRAY_LOCATION_ASSET=" + assetDir, // xray asset folder + "V2RAY_LOCATION_ASSET=" + assetDir, // v2ray / sagray asset folder } + runProcess(assetEnv, settings.Proxy.Bin, "run", "-confdir", configDir) } func runRadvd(settings *config.Config) { diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go index 82172f8..53fa9a2 100644 --- a/cmd/proxy/main.go +++ b/cmd/proxy/main.go @@ -7,8 +7,8 @@ import ( ) type Config struct { + Bin string `yaml:"bin" json:"bin" toml:"bin"` Log string `yaml:"log" json:"log" toml:"log"` - Core string `yaml:"core" json:"core" toml:"core"` Http map[string]int `yaml:"http" json:"http" toml:"http"` Socks map[string]int `yaml:"socks" json:"socks" toml:"socks"` AddOn []interface{} `yaml:"addon" json:"addon" toml:"addon"` diff --git a/cmd/xproxy.go b/cmd/xproxy.go index b114dfe..40edffb 100644 --- a/cmd/xproxy.go +++ b/cmd/xproxy.go @@ -20,6 +20,8 @@ var v4RouteTable = 104 var v6RouteTable = 106 var v4TProxyPort = 7288 var v6TProxyPort = 7289 + +var proxyBin = "" var configDir = "/etc/xproxy" var assetFile = "/assets.tar.xz" @@ -70,6 +72,9 @@ func xproxyInit() { log.Debugf("Assets folder -> %s", assetDir) log.Debugf("Config file -> %s", configFile) + if os.Getenv("PROXY_BIN") != "" { + proxyBin = os.Getenv("PROXY_BIN") + } if os.Getenv("IPV4_TABLE") != "" { v4RouteTable, _ = strconv.Atoi(os.Getenv("IPV4_TABLE")) }