diff --git a/.gitignore b/.gitignore index 26f8de6..2d885cf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ /autoLogin* /BitSrunLoginGo* /build -/main* \ No newline at end of file +/main* +logs/ \ No newline at end of file diff --git a/cmd/bitsrun/logs/srun_login.log b/cmd/bitsrun/logs/srun_login.log index a957afa..280a67f 100644 --- a/cmd/bitsrun/logs/srun_login.log +++ b/cmd/bitsrun/logs/srun_login.log @@ -96,3 +96,30 @@ 2024-12-26 23:18:01 [DEBU] [comp:login] 发送登录请求 2024-12-26 23:18:03 [DEBU] [comp:login] HTTP GET https://net3.zju.edu.cn/cgi-bin/srun_portal 2024-12-26 23:18:06 [DEBU] [comp:login] jQuery119331345568142742558_1735226286954({"client_ip":"10.194.50.118","ecode":"","error":"login_error","error_msg":"no_response_data_error","online_ip":"10.194.50.118","res":"login_error","srun_ver":"SRunCGIAuthIntfSvr V1.18 B20210926","st":1735224696}) +2025-02-17 14:58:17 [INFO] [comp:login] 正在获取登录状态 +2025-02-17 14:58:17 [DEBU] [comp:login] HTTP GET https://net3.zju.edu.cn/cgi-bin/rad_user_info +2025-02-17 14:58:17 [DEBU] [comp:login] jQuery377495468795322134859_1739775497094({"ServerFlag":4294967040,"add_time":1739711891,"all_bytes":3739607046,"bytes_in":552886335,"bytes_out":2677414891,"checkout_date":0,"domain":"","error":"ok","keepalive_time":1739773502,"online_ip":"10.194.151.8","real_name":"","remain_seconds":0,"sum_bytes":5512560138832,"sum_seconds":73428949,"sysver":"1.01.20210926","user_balance":0,"user_charge":0,"user_mac":"80-FA-5B-59-F1-24","user_name":"3210300237","wallet_balance":0}) +2025-02-17 14:58:17 [DEBU] [comp:login] 认证客户端 ip: 10.194.151.8 +2025-02-17 14:58:17 [INFO] [comp:login] 已登录~ +2025-02-17 14:58:17 [INFO] [comp:login] [mod:ddns] 开始 cloudflare DDNS 流程 +2025-02-17 14:59:19 [INFO] [comp:login] 正在获取登录状态 +2025-02-17 14:59:19 [DEBU] [comp:login] HTTP GET https://net3.zju.edu.cn/cgi-bin/rad_user_info +2025-02-17 14:59:19 [DEBU] [comp:login] jQuery888164777951911397595_1739775559680({"ServerFlag":4294967040,"add_time":1739711891,"all_bytes":3739607046,"bytes_in":552886335,"bytes_out":2677414891,"checkout_date":0,"domain":"","error":"ok","keepalive_time":1739773564,"online_ip":"10.194.151.8","real_name":"","remain_seconds":0,"sum_bytes":5512560138832,"sum_seconds":73428949,"sysver":"1.01.20210926","user_balance":0,"user_charge":0,"user_mac":"80-FA-5B-59-F1-24","user_name":"3210300237","wallet_balance":0}) +2025-02-17 14:59:19 [DEBU] [comp:login] 认证客户端 ip: 10.194.151.8 +2025-02-17 14:59:19 [INFO] [comp:login] 已登录~ +2025-02-17 14:59:19 [INFO] [comp:login] [mod:ddns] 开始 cloudflare DDNS 流程 +2025-02-17 14:59:27 [WARN] [comp:login] [mod:ddns] 设置 dns 解析记录失败:zone could not be found +2025-02-17 15:02:34 [INFO] [comp:login] 正在获取登录状态 +2025-02-17 15:02:34 [DEBU] [comp:login] HTTP GET https://net3.zju.edu.cn/cgi-bin/rad_user_info +2025-02-17 15:02:34 [DEBU] [comp:login] jQuery165649969143727444143_1739775754139({"ServerFlag":4294967040,"add_time":1739711891,"all_bytes":3739607046,"bytes_in":552886335,"bytes_out":2677414891,"checkout_date":0,"domain":"","error":"ok","keepalive_time":1739773759,"online_ip":"10.194.151.8","real_name":"","remain_seconds":0,"sum_bytes":5512560138832,"sum_seconds":73428949,"sysver":"1.01.20210926","user_balance":0,"user_charge":0,"user_mac":"80-FA-5B-59-F1-24","user_name":"3210300237","wallet_balance":0}) +2025-02-17 15:02:34 [DEBU] [comp:login] 认证客户端 ip: 10.194.151.8 +2025-02-17 15:02:34 [INFO] [comp:login] 已登录~ +2025-02-17 15:02:34 [INFO] [comp:login] [mod:ddns] 开始 cloudflare DDNS 流程 +2025-02-17 15:02:39 [WARN] [comp:login] [mod:ddns] 设置 dns 解析记录失败:zone could not be found +2025-02-17 15:03:27 [INFO] [comp:login] 正在获取登录状态 +2025-02-17 15:03:27 [DEBU] [comp:login] HTTP GET https://net3.zju.edu.cn/cgi-bin/rad_user_info +2025-02-17 15:03:27 [DEBU] [comp:login] jQuery533416524436185547927_1739775807245({"ServerFlag":4294967040,"add_time":1739711891,"all_bytes":3939474599,"bytes_in":562029810,"bytes_out":2760698767,"checkout_date":0,"domain":"","error":"ok","keepalive_time":1739773812,"online_ip":"10.194.151.8","real_name":"","remain_seconds":0,"sum_bytes":5512560138832,"sum_seconds":73428949,"sysver":"1.01.20210926","user_balance":0,"user_charge":0,"user_mac":"80-FA-5B-59-F1-24","user_name":"3210300237","wallet_balance":0}) +2025-02-17 15:03:27 [DEBU] [comp:login] 认证客户端 ip: 10.194.151.8 +2025-02-17 15:03:27 [INFO] [comp:login] 已登录~ +2025-02-17 15:03:27 [INFO] [comp:login] [mod:ddns] 开始 cloudflare DDNS 流程 +2025-02-17 15:03:37 [INFO] [comp:login] [mod:ddns] DDNS 配置应用成功: dorm.chizzyhub.site | 10.194.151.8 diff --git a/config.yaml b/config.yaml index 22cbd97..daa26db 100644 --- a/config.yaml +++ b/config.yaml @@ -20,7 +20,7 @@ settings: interfaces: "" #网卡名称正则(注意转义),如:eth0\.[2-3],不为空时为多网卡模式 interfaces_interval: 0 # 秒,多网卡模式切换网卡时触发的等待时间 guardian: #守护模式(后台常驻) - enable: false + enable: false duration: 60 #网络检查周期(秒,正整数) backoff: # 积分退避 enable: false # 开启后同时对所有运行模式生效,作用于登录失败的重试 @@ -38,14 +38,13 @@ settings: log_name: "srun_login.log" #指定日志文件名 ddns: #校园网内网 ip ddns enable: true - domain: "dorm.chizzyhub.site" + domain: "609.lumisnap.im" ttl: 3600 provider: "cloudflare" config: #这段配置是动态的,需要根据 provider 类型配置字段名,见 DDNS 说明 - zone: "fde85c42ada16e7277b5c1cdb911f90a" - record_id: "08ed045b26e5f9bd8b7001115fca798e" + zone: "10af385e1e5601d50bbb4a28c562934e" token: "aaaa4a4f258224cc872bf6fa8840c054f2bb4" - email: "chizzyhub@outlook.com" + email: "jiejie02.chj@outlook.com" reality: #从指定地址模拟浏览器行为进入登录页,如果登录未出现问题不用启用 enable: false addr: http://www.baidu.com #初始地址,需要使用 http、域名 diff --git a/go.mod b/go.mod index 3b15340..22f0597 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Mmx233/BackoffCli/backoff v0.0.0-20241003124604-657194ccba99 github.com/Mmx233/tool v0.7.8 github.com/antonfisher/nested-logrus-formatter v1.3.1 - github.com/cloudflare/cloudflare-go v0.107.0 + github.com/cloudflare/cloudflare-go v0.115.0 github.com/sirupsen/logrus v1.9.3 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1020 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1020 @@ -14,12 +14,12 @@ require ( ) require ( - github.com/goccy/go-json v0.10.3 // indirect + github.com/goccy/go-json v0.10.5 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/kr/pretty v0.3.1 // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.7.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect ) diff --git a/go.sum b/go.sum index 700d7b3..7f6bfc4 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,11 @@ github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UME github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= github.com/cloudflare/cloudflare-go v0.107.0 h1:cMDIw2tzt6TXCJyMFVyP+BPOVkIfMvcKjhMNSNvuEPc= github.com/cloudflare/cloudflare-go v0.107.0/go.mod h1:5cYGzVBqNTLxMYSLdVjuSs5LJL517wJDSvMPWUrzHzc= +github.com/cloudflare/cloudflare-go v0.115.0 h1:84/dxeeXweCc0PN5Cto44iTA8AkG1fyT11yPO5ZB7sM= +github.com/cloudflare/cloudflare-go v0.115.0/go.mod h1:Ds6urDwn/TF2uIU24mu7H91xkKP8gSAHxQ44DSZgVmU= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -15,6 +18,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -45,31 +50,44 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1020 h1:GjmwVpFJq9ZgCnZcd3ACt6XBGWWJoWC4n4345JmJ/bo= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1020/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1020 h1:TmUr8gB1csYHI21oVAhZRnkAAswN8GoU7smtd80sTug= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1020/go.mod h1:cJJ8sGi/rlZn9jtwF/9FFKt0aPPCEwco0FemsNrQlnA= github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/internal/dns/cloudflare/cloudflare.go b/internal/dns/cloudflare/cloudflare.go index 2dfceea..a4fb1a4 100644 --- a/internal/dns/cloudflare/cloudflare.go +++ b/internal/dns/cloudflare/cloudflare.go @@ -1,22 +1,19 @@ package cloudflare import ( - "bytes" - "encoding/json" + "context" "errors" "fmt" - "io" + "log" "net/http" - "time" "github.com/cloudflare/cloudflare-go" ) type Cloudflare struct { - Zone string `json:"zone" yaml:"zone"` - RecordId string `json:"record_id" yaml:"record_id"` - Token string `json:"token" yaml:"token"` - Email string `json:"email" yaml:"email"` + Zone string `json:"zone" yaml:"zone"` + Token string `json:"token" yaml:"token"` + Email string `json:"email" yaml:"email"` } type DnsProvider struct { @@ -31,56 +28,55 @@ func New(ttl int, conf Cloudflare, Http *http.Client) (*DnsProvider, error) { TTL: ttl, Cloudflare: conf, } - if p.Zone == "" { - return nil, errors.New("cloudflare zone 不能为空") - } - if p.Token == "" { - return nil, errors.New("cloudflare token 不能为空") + + if p.Zone == "" || p.Email == "" || p.Token == "" { + return nil, errors.New("cloudflare config error") } + p.ZoneResource = cloudflare.ZoneIdentifier(p.Zone) var err error - p.Api, err = cloudflare.NewWithAPIToken(p.Token, cloudflare.HTTPClient(Http)) + p.Api, err = cloudflare.New(p.Cloudflare.Token, p.Cloudflare.Email) return &p, err } func (a DnsProvider) SetDomainRecord(domain, ip string) error { - url := fmt.Sprintf("https://api.cloudflare.com/client/v4/zones/%s/dns_records/%s", a.Zone, a.RecordId) - proxied := false - payload := cloudflare.DNSRecord{ - Type: "A", - Name: domain, + rc := cloudflare.ResourceContainer{Identifier: a.Cloudflare.Zone} + dnsRecords, resultInfo, err := a.Api.ListDNSRecords( + context.TODO(), + &rc, + cloudflare.ListDNSRecordsParams{ + Name: domain, + }, + ) + if err != nil { + return err + } + + if resultInfo.Count == 0 { + log.Println("not found record for domain:", domain) + return errors.New("not found record for domain:" + domain) + } + + log.Println("found record(s) for domain:", domain) + for _, record := range dnsRecords { + fmt.Println(record.ID, record.Name, record.Content) + } + + // update record + record := dnsRecords[0] + record, err = a.Api.UpdateDNSRecord(context.TODO(), &rc, cloudflare.UpdateDNSRecordParams{ + ID: record.ID, + Name: record.Name, + Type: record.Type, Content: ip, - TTL: a.TTL, - Proxied: &proxied, - Comment: "DDNS for " + domain, - } + TTL: record.TTL, + Proxied: record.Proxied, + Comment: &record.Comment, + }) - jsonPayload, err := json.Marshal(payload) if err != nil { return err } - - // Make the HTTP GET request - req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonPayload)) - if err != nil { - return err - } - req.Header.Set("X-Auth-Email", a.Email) - req.Header.Set("X-Auth-Key", a.Token) - time.Sleep(time.Millisecond * 200) // avoid request too fast after login - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return err - - } - fmt.Println(string(body), resp.Status) + fmt.Println("update record success:", record.ID, record.Name, record.Content) return nil }