diff --git a/go.mod b/go.mod index 4d68df5..95024fd 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module XProxy go 1.18 require ( + github.com/robfig/cron v1.2.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 9b490be..6fcb3f3 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/src/config.go b/src/config.go index 16491df..2fb47e1 100644 --- a/src/config.go +++ b/src/config.go @@ -22,19 +22,23 @@ type NetConfig struct { } type Config struct { + Update struct { + Cron string `yaml:"cron"` + Url map[string]string `yaml:"url"` + } `yaml:"update"` Proxy struct { Sniff bool `yaml:"sniff"` Redirect bool `yaml:"redirect"` Http map[string]int `yaml:"http"` Socks map[string]int `yaml:"socks"` AddOn []interface{} `yaml:"addon"` - } + } `yaml:"proxy"` Network struct { DNS []string `yaml:"dns"` // system dns server ByPass []string `yaml:"bypass"` // cidr bypass list IPv4 NetConfig `yaml:"ipv4"` // ipv4 network configure IPv6 NetConfig `yaml:"ipv6"` // ipv6 network configure - } + } `yaml:"network"` } func isIP(ipAddr string, isCidr bool) bool { @@ -113,4 +117,9 @@ func loadConfig(rawConfig []byte) { log.Infof("Socks5 inbounds -> %v", socksInbounds) addOnInbounds = config.Proxy.AddOn log.Infof("Add-on inbounds -> %v", addOnInbounds) + + updateCron = config.Update.Cron + log.Infof("Update cron -> %s", updateCron) + updateUrls = config.Update.Url + log.Infof("Update url -> %v", updateUrls) } diff --git a/src/load.go b/src/load.go index 195322a..5b2d60a 100644 --- a/src/load.go +++ b/src/load.go @@ -5,6 +5,7 @@ import ( log "github.com/sirupsen/logrus" "io" "io/ioutil" + "net/http" "os" "os/exec" "strings" @@ -127,6 +128,30 @@ func copyFile(source string, target string) { } } +func downloadFile(url string, file string) bool { + log.Debugf("File download %s => %s", url, file) + resp, err := http.Get(url) + if err != nil { + log.Errorf("Download %s error -> %v", url, err) + return false + } + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) + out, err := os.OpenFile(file, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) + if err != nil { + _ = resp.Body.Close() + log.Panicf("Open %s error -> %v", file, err) + } + _, err = io.Copy(out, resp.Body) + _ = resp.Body.Close() + if err != nil { + log.Panicf("File %s save error -> %v", file, err) + } + log.Infof("Download success `%s` => `%s`", url, file) + return true +} + func saveConfig(configDir string, caption string, content string, overwrite bool) { filePath := configDir + "/" + caption + ".json" if !overwrite && isFileExist(filePath) { // file exist and don't overwrite @@ -250,3 +275,12 @@ func loadGeoSite(assetDir string) { createFolder(assetDir) extractGeoFile(assetFile, "geosite.dat", assetDir) } + +func updateAssets(assetDir string) { + if len(updateUrls) != 0 { + log.Info("Start update assets") + for file, url := range updateUrls { + downloadFile(url, assetDir+"/"+file) + } + } +} diff --git a/src/main.go b/src/main.go index ec854c1..d198f20 100644 --- a/src/main.go +++ b/src/main.go @@ -1,6 +1,7 @@ package main import ( + "github.com/robfig/cron" log "github.com/sirupsen/logrus" "os" "os/signal" @@ -14,6 +15,9 @@ var v6RouteTable = 106 var v4TProxyPort = 7288 var v6TProxyPort = 7289 +var updateCron string +var updateUrls map[string]string + var enableSniff bool var enableRedirect bool var httpInbounds map[string]int @@ -37,11 +41,15 @@ func main() { panic(err) } loadConfig(content) - loadProxy("/etc/xproxy/config", "/xproxy") - loadGeoIp("/xproxy/assets") + loadProxy("/etc/xproxy/config", "/xproxy") loadGeoSite("/xproxy/assets") - // TODO: auto-update assets file (by cron command) + loadGeoIp("/xproxy/assets") + autoUpdate := cron.New() + _ = autoUpdate.AddFunc(updateCron, func() { + updateAssets("/xproxy/assets") + }) + autoUpdate.Start() loadDns() loadNetwork() @@ -52,14 +60,6 @@ func main() { xray := newProcess("xray", "-confdir", "/etc/xproxy/config") xray.startProcess(true, true) subProcess = append(subProcess, xray) - - //sleep := newProcess("sleep", "1000") - //sleep.startProcess(true, true) - //subProcess = append(subProcess, sleep) - // - //empty := newProcess("empty") - //subProcess = append(subProcess, empty) - daemon() sigExit := make(chan os.Signal, 1) diff --git a/test.yml b/test.yml index 569ce1b..e210bbf 100644 --- a/test.yml +++ b/test.yml @@ -31,3 +31,9 @@ network: - fc00::/7 - fe80::/10 - ff00::/8 + +update: + cron: "0 */1 * * * *" + 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"