From 684fea69d016fa6305c87e698dbf888457e5ade5 Mon Sep 17 00:00:00 2001
From: bjdgyc <bjdgyc@163.com>
Date: Fri, 31 Dec 2021 21:37:21 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BB=86=E8=8A=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md                     | 23 ++++++++++++----------
 server/conf/server.toml       |  1 +
 server/dbdata/db.go           | 18 +++++++++++++++++-
 server/dbdata/group.go        | 36 +++++++++++++++++++----------------
 server/handler/link_tunnel.go |  9 +++++----
 5 files changed, 56 insertions(+), 31 deletions(-)

diff --git a/README.md b/README.md
index 57fab63..5b11ec4 100644
--- a/README.md
+++ b/README.md
@@ -37,10 +37,11 @@ AnyLink 服务端仅在 CentOS 7、Ubuntu 18.04 测试通过,如需要安装
 > https://github.com/bjdgyc/anylink/releases
 
 ### 使用问题
+
 > 对于测试环境,可以使用 vpn.test.vqilu.cn 绑定host进行测试
-> 
+>
 > 对于线上环境,必须申请安全的 https 证书,不支持私有证书连接
-> 
+>
 > 客户端请使用群共享文件的版本,其他版本没有测试过,不保证使用正常
 
 ### 自行编译安装
@@ -70,6 +71,7 @@ sudo ./anylink
 - [x] TLS-TCP 通道
 - [x] DTLS-UDP 通道
 - [x] 兼容 AnyConnect
+- [x] 兼容 OpenConnect
 - [x] 基于 tun 设备的 nat 访问模式
 - [x] 基于 tap 设备的桥接访问模式
 - [x] 基于 macvtap 设备的桥接访问模式
@@ -114,7 +116,8 @@ sudo ./anylink
 
 网络模式选择,需要配置 `link_mode` 参数,如 `link_mode="tun"`,`link_mode="macvtap"`,`link_mode="tap"(不推荐)` 等参数。 不同的参数需要对服务器做相应的设置。
 
-建议优先选择 tun 模式,其次选择 macvtap 模式,因客户端传输的是 IP 层数据,无须进行数据转换。 tap 模式是在用户态做的链路层到 IP 层的数据互相转换,性能会有所下降。 如果需要在虚拟机内开启 tap 模式,请确认虚拟机的网卡开启混杂模式。
+建议优先选择 tun 模式,其次选择 macvtap 模式,因客户端传输的是 IP 层数据,无须进行数据转换。 tap 模式是在用户态做的链路层到 IP 层的数据互相转换,性能会有所下降。 如果需要在虚拟机内开启 tap
+模式,请确认虚拟机的网卡开启混杂模式。
 
 ### tun 设置
 
@@ -190,18 +193,18 @@ sh bridge-init.sh
 
 1. 添加 anylink 程序
 
-   - anylink 程序目录放入 `/usr/local/anylink-deploy`
+    - anylink 程序目录放入 `/usr/local/anylink-deploy`
 
 2. systemd/anylink.service 脚本放入:
 
-   - centos: `/usr/lib/systemd/system/`
-   - ubuntu: `/lib/systemd/system/`
+    - centos: `/usr/lib/systemd/system/`
+    - ubuntu: `/lib/systemd/system/`
 
 3. 操作命令:
 
-   - 启动: `systemctl start anylink`
-   - 停止: `systemctl stop anylink`
-   - 开机自启: `systemctl enable anylink`
+    - 启动: `systemctl start anylink`
+    - 停止: `systemctl stop anylink`
+    - 开机自启: `systemctl enable anylink`
 
 ## Docker
 
@@ -268,7 +271,7 @@ sh bridge-init.sh
 ## Donate
 
 > 如果您觉得 anylink 对你有帮助,欢迎给我们打赏,也是帮助 anylink 更好的发展。
-> 
+>
 > [查看打赏列表](doc/README.md)
 
 <p>
diff --git a/server/conf/server.toml b/server/conf/server.toml
index 6a1fa69..e246b10 100644
--- a/server/conf/server.toml
+++ b/server/conf/server.toml
@@ -10,6 +10,7 @@ db_source = "./conf/anylink.db"
 cert_file = "./conf/vpn_cert.crt"
 cert_key = "./conf/vpn_cert.key"
 files_path = "./conf/files"
+log_level = "debug"
 
 #系统名称
 issuer = "XX公司VPN"
diff --git a/server/dbdata/db.go b/server/dbdata/db.go
index 5b1a45f..b6f9263 100644
--- a/server/dbdata/db.go
+++ b/server/dbdata/db.go
@@ -102,7 +102,23 @@ func addInitData() error {
 		return err
 	}
 
-	return sess.Commit()
+	err = sess.Commit()
+	if err != nil {
+		return err
+	}
+
+	g1 := Group{
+		Name:         "ops",
+		AllowLan:     true,
+		ClientDns:    []ValData{{Val: "114.114.114.114"}},
+		RouteInclude: []ValData{{Val: All}},
+	}
+	err = SetGroup(&g1)
+	if err != nil {
+		return err
+	}
+
+	return nil
 }
 
 func CheckErrNotFound(err error) bool {
diff --git a/server/dbdata/group.go b/server/dbdata/group.go
index 984c9a0..252f3f8 100644
--- a/server/dbdata/group.go
+++ b/server/dbdata/group.go
@@ -12,6 +12,7 @@ import (
 const (
 	Allow = "allow"
 	Deny  = "deny"
+	All   = "all"
 )
 
 type GroupLinkAcl struct {
@@ -65,25 +66,10 @@ func SetGroup(g *Group) error {
 	}
 
 	// 判断数据
-	clientDns := []ValData{}
-	for _, v := range g.ClientDns {
-		if v.Val != "" {
-			ip := net.ParseIP(v.Val)
-			if ip.String() != v.Val {
-				return errors.New("DNS IP 错误")
-			}
-			clientDns = append(clientDns, v)
-		}
-	}
-	if len(clientDns) == 0 {
-		return errors.New("必须设置一个DNS")
-	}
-	g.ClientDns = clientDns
-
 	routeInclude := []ValData{}
 	for _, v := range g.RouteInclude {
 		if v.Val != "" {
-			if v.Val == "all" {
+			if v.Val == All {
 				routeInclude = append(routeInclude, v)
 				continue
 			}
@@ -124,6 +110,24 @@ func SetGroup(g *Group) error {
 	}
 	g.LinkAcl = linkAcl
 
+	// DNS 判断
+	clientDns := []ValData{}
+	for _, v := range g.ClientDns {
+		if v.Val != "" {
+			ip := net.ParseIP(v.Val)
+			if ip.String() != v.Val {
+				return errors.New("DNS IP 错误")
+			}
+			clientDns = append(clientDns, v)
+		}
+	}
+	if len(routeInclude) == 0 || (len(routeInclude) == 1 && routeInclude[0].Val == "all") {
+		if len(clientDns) == 0 {
+			return errors.New("默认路由,必须设置一个DNS")
+		}
+	}
+	g.ClientDns = clientDns
+
 	g.UpdatedAt = time.Now()
 	if g.Id > 0 {
 		err = Set(g)
diff --git a/server/handler/link_tunnel.go b/server/handler/link_tunnel.go
index b53c931..a43cb5f 100644
--- a/server/handler/link_tunnel.go
+++ b/server/handler/link_tunnel.go
@@ -10,6 +10,7 @@ import (
 	"strings"
 
 	"github.com/bjdgyc/anylink/base"
+	"github.com/bjdgyc/anylink/dbdata"
 	"github.com/bjdgyc/anylink/sessdata"
 )
 
@@ -23,11 +24,11 @@ func init() {
 }
 
 func HttpSetHeader(w http.ResponseWriter, key string, value string) {
-   w.Header()[key] = []string{value}
+	w.Header()[key] = []string{value}
 }
 
 func HttpAddHeader(w http.ResponseWriter, key string, value string) {
-   w.Header()[key] = append(w.Header()[key], value)
+	w.Header()[key] = append(w.Header()[key], value)
 }
 
 func LinkTunnel(w http.ResponseWriter, r *http.Request) {
@@ -95,7 +96,7 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
 	HttpSetHeader(w, "X-CSTP-Address", cSess.IpAddr.String())             // 分配的ip地址
 	HttpSetHeader(w, "X-CSTP-Netmask", sessdata.IpPool.Ipv4Mask.String()) // 子网掩码
 	HttpSetHeader(w, "X-CSTP-Hostname", hn)                               // 机器名称
-	//HttpSetHeader(w, "X-CSTP-Default-Domain", cSess.LocalIp)          
+	//HttpSetHeader(w, "X-CSTP-Default-Domain", cSess.LocalIp)
 	HttpSetHeader(w, "X-CSTP-Base-MTU", cstpBaseMtu)
 
 	// 允许本地LAN访问vpn网络,必须放在路由的第一个
@@ -108,7 +109,7 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
 	}
 	// 允许的路由
 	for _, v := range cSess.Group.RouteInclude {
-		if v.Val == "all" {
+		if v.Val == dbdata.All {
 			continue
 		}
 		HttpAddHeader(w, "X-CSTP-Split-Include", v.IpMask)