From 000b04157879cc04b3d8478ac032ad2f738bbb20 Mon Sep 17 00:00:00 2001 From: bjdgyc Date: Thu, 14 Mar 2024 16:47:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20atomic=20=E5=BC=95?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 ++++++++++++++--- server/base/mod.go | 9 ++++----- server/go.mod | 2 +- server/handler/link_base.go | 5 +++-- server/handler/link_cstp.go | 8 ++++---- server/handler/link_dtls.go | 2 +- server/handler/link_tun.go | 18 ++++++++++-------- server/handler/link_vtap.go | 9 +++++---- server/pkg/utils/util.go | 9 +++++++++ server/sessdata/session.go | 17 ++++++++--------- 10 files changed, 59 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 2db83a90..7e7230c6 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,10 @@ AnyLink 服务端仅在 CentOS 7、CentOS 8、Ubuntu 18.04、Ubuntu 20.04 测试 > 没有编程基础的同学建议直接下载 release 包,从下面的地址下载 anylink-deploy.tar.gz > > https://github.com/bjdgyc/anylink/releases +> +> https://gitee.com/bjdgyc/anylink/releases > -> 如果不会安装,可以提供有偿远程协助服务(100 CNY)。添加QQ(68492170)联系我 +> 如果不会安装,可以提供有偿远程协助服务(200 CNY)。添加QQ(68492170)联系我 > > 也可以添加QQ群 咨询群内大佬,群共享文件有相关软件下载 > @@ -58,11 +60,15 @@ AnyLink 服务端仅在 CentOS 7、CentOS 8、Ubuntu 18.04、Ubuntu 20.04 测试 ### 使用问题 -> 对于测试环境,可以使用 vpn.test.vqilu.cn (已经备案) 绑定host进行测试 +> 对于测试环境,可以使用 vpn.test.vqilu.cn 绑定host进行测试 > > 对于线上环境,必须申请安全的https证书(跟nginx使用的证书类型一致),不支持私有证书连接 > -> 服务端安装 yum install iproute 或者 apt-get install iproute2 +> 服务端依赖安装: +> +> centos: yum install iptables iproute +> +> ubuntu: apt-get install iptables iproute2 > > 客户端请使用群共享文件的版本,其他版本没有测试过,不保证使用正常 > @@ -234,6 +240,11 @@ https://cloud.tencent.com/document/product/216/62007 1. 设置配置文件 > macvtap 设置相对比较简单,只需要配置相应的参数即可。 +> +> 网络要求:需要网络支持 ARP 传输,可通过 ARP 宣告普通内网 IP。 +> +> 网络限制:云环境下不能使用,网卡mac加白环境不能使用,802.1x认证网络不能使用 +> > 以下参数可以通过执行 `ip a` 查看 ``` diff --git a/server/base/mod.go b/server/base/mod.go index c87fcc1e..481e5766 100644 --- a/server/base/mod.go +++ b/server/base/mod.go @@ -58,10 +58,9 @@ func CheckModOrLoad(mod string) { // 文件存在 return } - err = fmt.Errorf("[error] Linux tunFile is null %s", tunPath) - log.Println(err) - return - // panic(err) + // err = fmt.Errorf("[error] Linux tunFile is null %s", tunPath) + // log.Println(err) + // return } if InContainer { @@ -76,7 +75,7 @@ func CheckModOrLoad(mod string) { cmd := exec.Command("sh", "-c", cmdstr) b, err := cmd.CombinedOutput() if err != nil { - log.Println(string(b)) + log.Println(mod, string(b)) panic(err) } } diff --git a/server/go.mod b/server/go.mod index 566a740c..4dfc1906 100644 --- a/server/go.mod +++ b/server/go.mod @@ -33,7 +33,6 @@ require ( github.com/xhit/go-simple-mail/v2 v2.16.0 github.com/xlzd/gotp v0.1.0 github.com/xuri/excelize/v2 v2.8.1 - go.uber.org/atomic v1.11.0 golang.org/x/crypto v0.21.0 golang.org/x/net v0.22.0 golang.org/x/text v0.14.0 @@ -66,6 +65,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.873 // indirect github.com/toorop/go-dkim v0.0.0-20240103092955-90b7d1423f92 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/mod v0.16.0 // indirect diff --git a/server/handler/link_base.go b/server/handler/link_base.go index 48e2258c..c46da15b 100644 --- a/server/handler/link_base.go +++ b/server/handler/link_base.go @@ -2,8 +2,9 @@ package handler import ( "encoding/xml" - "log" "os/exec" + + "github.com/bjdgyc/anylink/base" ) const BufferSize = 2048 @@ -46,7 +47,7 @@ func execCmd(cmdStrs []string) error { cmd := exec.Command("sh", "-c", cmdStr) b, err := cmd.CombinedOutput() if err != nil { - log.Println(string(b)) + base.Error(cmdStr, string(b)) return err } } diff --git a/server/handler/link_cstp.go b/server/handler/link_cstp.go index dfd3ba28..29d4a7b5 100644 --- a/server/handler/link_cstp.go +++ b/server/handler/link_cstp.go @@ -25,9 +25,9 @@ func LinkCstp(conn net.Conn, bufRW *bufio.ReadWriter, cSess *sessdata.ConnSessio n int dataLen uint16 dead = time.Second * time.Duration(cSess.CstpDpd+5) - idle = time.Second * time.Duration(base.Cfg.IdleTimeout) + idle = int64(base.Cfg.IdleTimeout) checkIdle = base.Cfg.IdleTimeout > 0 - lastTime time.Time + lastTime int64 ) go cstpWrite(conn, bufRW, cSess) @@ -61,7 +61,7 @@ func LinkCstp(conn net.Conn, bufRW *bufio.ReadWriter, cSess *sessdata.ConnSessio // 判断超时时间 if checkIdle { lastTime = cSess.LastDataTime.Load() - if lastTime.Before(utils.NowSec().Add(-idle)) { + if lastTime < (utils.NowSec().Unix() - idle) { base.Warn("IdleTimeout", cSess.Username, cSess.IpAddr, conn.RemoteAddr(), "lastTime", lastTime) sessdata.CloseSess(cSess.Sess.Token, dbdata.UserIdleTimeout) return @@ -113,7 +113,7 @@ func LinkCstp(conn net.Conn, bufRW *bufio.ReadWriter, cSess *sessdata.ConnSessio return } // 只记录返回正确的数据时间 - cSess.LastDataTime.Store(utils.NowSec()) + cSess.LastDataTime.Store(utils.NowSec().Unix()) } } } diff --git a/server/handler/link_dtls.go b/server/handler/link_dtls.go index a2059dbd..c87a8f01 100644 --- a/server/handler/link_dtls.go +++ b/server/handler/link_dtls.go @@ -96,7 +96,7 @@ func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) { return } // 只记录返回正确的数据时间 - cSess.LastDataTime.Store(utils.NowSec()) + cSess.LastDataTime.Store(utils.NowSec().Unix()) } } diff --git a/server/handler/link_tun.go b/server/handler/link_tun.go index 78c272cb..b01074df 100644 --- a/server/handler/link_tun.go +++ b/server/handler/link_tun.go @@ -4,12 +4,16 @@ import ( "fmt" "github.com/bjdgyc/anylink/base" + "github.com/bjdgyc/anylink/pkg/utils" "github.com/bjdgyc/anylink/sessdata" "github.com/coreos/go-iptables/iptables" "github.com/songgao/water" ) func checkTun() { + // 测试ip命令 + base.CheckModOrLoad("tun") + // 测试tun cfg := water.Config{ DeviceType: water.TUN, @@ -21,16 +25,14 @@ func checkTun() { } defer ifce.Close() - // 测试ip命令 - base.CheckModOrLoad("tun") - cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %s multicast off", ifce.Name(), "1399") err = execCmd([]string{cmdstr1}) if err != nil { base.Fatal("testTun err: ", err) } // 开启服务器转发 - if err := execCmd([]string{"sysctl -w net.ipv4.ip_forward=1"}); err != nil { + err = execCmd([]string{"sysctl -w net.ipv4.ip_forward=1"}) + if err != nil { base.Fatal(err) } if base.Cfg.IptablesNat { @@ -47,14 +49,14 @@ func checkTun() { // 添加注释 natRule := []string{"-s", base.Cfg.Ipv4CIDR, "-o", base.Cfg.Ipv4Master, "-m", "comment", - "--comment", "anylink tun nat", "-j", "MASQUERADE"} + "--comment", "AnyLink", "-j", "MASQUERADE"} err = ipt.InsertUnique("nat", "POSTROUTING", 1, natRule...) if err != nil { base.Error(err) } // 添加注释 - forwardRule := []string{"-m", "comment", "--comment", "anylink forward filter", "-j", "ACCEPT"} + forwardRule := []string{"-m", "comment", "--comment", "AnyLink", "-j", "ACCEPT"} err = ipt.InsertUnique("filter", "FORWARD", 1, forwardRule...) if err != nil { base.Error(err) @@ -80,8 +82,8 @@ func LinkTun(cSess *sessdata.ConnSession) error { cSess.SetIfName(ifce.Name()) // 通过 ip link show 查看 alias 信息 - - cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast off alias %s.%s", ifce.Name(), cSess.Mtu, cSess.Group.Name, cSess.Username) + alias := utils.ParseName(cSess.Group.Name + "." + cSess.Username) + cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast off alias %s", ifce.Name(), cSess.Mtu, alias) cmdstr2 := fmt.Sprintf("ip addr add dev %s local %s peer %s/32", ifce.Name(), base.Cfg.Ipv4Gateway, cSess.IpAddr) err = execCmd([]string{cmdstr1, cmdstr2}) diff --git a/server/handler/link_vtap.go b/server/handler/link_vtap.go index 1096642a..1b61294e 100644 --- a/server/handler/link_vtap.go +++ b/server/handler/link_vtap.go @@ -28,12 +28,13 @@ func (v *Vtap) Close() error { } func checkMacvtap() { + // 加载 macvtap + base.CheckModOrLoad("macvtap") + _setGateway() _checkTapIp(base.Cfg.Ipv4Master) ifName := "anylinkMacvtap" - // 加载 macvtap - base.CheckModOrLoad("macvtap") // 开启主网卡混杂模式 cmdstr1 := fmt.Sprintf("ip link set dev %s promisc on", base.Cfg.Ipv4Master) @@ -55,8 +56,8 @@ func LinkMacvtap(cSess *sessdata.ConnSession) error { cSess.SetIfName(ifName) cmdstr1 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, ifName) - cmdstr2 := fmt.Sprintf("ip link set dev %s up mtu %d address %s alias %s.%s", ifName, cSess.Mtu, - cSess.MacHw, cSess.Group.Name, cSess.Username) + alias := utils.ParseName(cSess.Group.Name + "." + cSess.Username) + cmdstr2 := fmt.Sprintf("ip link set dev %s up mtu %d address %s alias %s", ifName, cSess.Mtu, cSess.MacHw, alias) err := execCmd([]string{cmdstr1, cmdstr2}) if err != nil { diff --git a/server/pkg/utils/util.go b/server/pkg/utils/util.go index 6ce13c4b..2b17f262 100644 --- a/server/pkg/utils/util.go +++ b/server/pkg/utils/util.go @@ -3,6 +3,7 @@ package utils import ( "fmt" "math/rand" + "strings" "sync/atomic" "time" ) @@ -91,3 +92,11 @@ func RandomRunes(length int) string { return string(bytes) } + +func ParseName(name string) string { + name = strings.ReplaceAll(name, " ", "-") + name = strings.ReplaceAll(name, "'", "-") + name = strings.ReplaceAll(name, "\"", "-") + name = strings.ReplaceAll(name, ";", "-") + return name +} diff --git a/server/sessdata/session.go b/server/sessdata/session.go index a4e6ecd7..60fae1d8 100644 --- a/server/sessdata/session.go +++ b/server/sessdata/session.go @@ -13,7 +13,6 @@ import ( "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/dbdata" mapset "github.com/deckarep/golang-set" - atomic2 "go.uber.org/atomic" ) var ( @@ -41,15 +40,15 @@ type ConnSession struct { CstpDpd int Group *dbdata.Group Limit *LimitRater - BandwidthUp atomic2.Uint32 // 使用上行带宽 Byte - BandwidthDown atomic2.Uint32 // 使用下行带宽 Byte - BandwidthUpPeriod atomic2.Uint32 // 前一周期的总量 - BandwidthDownPeriod atomic2.Uint32 - BandwidthUpAll atomic2.Uint64 // 使用上行带宽总量 - BandwidthDownAll atomic2.Uint64 // 使用下行带宽总量 + BandwidthUp atomic.Uint32 // 使用上行带宽 Byte + BandwidthDown atomic.Uint32 // 使用下行带宽 Byte + BandwidthUpPeriod atomic.Uint32 // 前一周期的总量 + BandwidthDownPeriod atomic.Uint32 + BandwidthUpAll atomic.Uint64 // 使用上行带宽总量 + BandwidthDownAll atomic.Uint64 // 使用下行带宽总量 closeOnce sync.Once CloseChan chan struct{} - LastDataTime atomic2.Time // 最后数据传输时间 + LastDataTime atomic.Int64 // 最后数据传输时间 PayloadIn chan *Payload PayloadOutCstp chan *Payload // Cstp的数据 PayloadOutDtls chan *Payload // Dtls的数据 @@ -220,7 +219,7 @@ func (s *Session) NewConn() *ConnSession { PayloadOutDtls: make(chan *Payload, 64), dSess: &atomic.Value{}, } - cSess.LastDataTime.Store(time.Now()) + cSess.LastDataTime.Store(time.Now().Unix()) dSess := &DtlsSession{ isActive: -1,