mirror of
				https://github.com/bjdgyc/anylink.git
				synced 2025-11-04 19:16:22 +08:00 
			
		
		
		
	@@ -33,7 +33,7 @@ COPY docker_entrypoint.sh  /app/
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
COPY ./server/bridge-init.sh /app/
 | 
					COPY ./server/bridge-init.sh /app/
 | 
				
			||||||
COPY ./server/conf  /app/conf
 | 
					COPY ./server/conf  /app/conf
 | 
				
			||||||
#COPY ./server/files  /app/conf/files
 | 
					COPY ./LICENSE  /app/LICENSE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#TODO 本地打包时使用镜像
 | 
					#TODO 本地打包时使用镜像
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								build.sh
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								build.sh
									
									
									
									
									
								
							@@ -42,6 +42,7 @@ cp -r server/bridge-init.sh $deploy
 | 
				
			|||||||
cp -r server/conf $deploy
 | 
					cp -r server/conf $deploy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cp -r systemd $deploy
 | 
					cp -r systemd $deploy
 | 
				
			||||||
 | 
					cp -r LICENSE $deploy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tar zcvf ${deploy}.tar.gz $deploy
 | 
					tar zcvf ${deploy}.tar.gz $deploy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,6 @@ case $var1 in
 | 
				
			|||||||
  iptables -t nat -A POSTROUTING -s "${IPV4_CIDR}" -o eth0+ -j MASQUERADE
 | 
					  iptables -t nat -A POSTROUTING -s "${IPV4_CIDR}" -o eth0+ -j MASQUERADE
 | 
				
			||||||
  iptables -nL -t nat
 | 
					  iptables -nL -t nat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /app/anylink "$@"
 | 
					  exec /app/anylink "$@"
 | 
				
			||||||
  ;;
 | 
					  ;;
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,11 @@ func StartAdmin() {
 | 
				
			|||||||
	r := mux.NewRouter()
 | 
						r := mux.NewRouter()
 | 
				
			||||||
	r.Use(authMiddleware)
 | 
						r.Use(authMiddleware)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 监控检测
 | 
				
			||||||
 | 
						r.HandleFunc("/status.html", func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
							w.Write([]byte("ok"))
 | 
				
			||||||
 | 
						}).Name("index")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.Handle("/", http.RedirectHandler("/ui/", http.StatusFound)).Name("index")
 | 
						r.Handle("/", http.RedirectHandler("/ui/", http.StatusFound)).Name("index")
 | 
				
			||||||
	r.PathPrefix("/ui/").Handler(
 | 
						r.PathPrefix("/ui/").Handler(
 | 
				
			||||||
		// http.StripPrefix("/ui/", http.FileServer(http.Dir(base.Cfg.UiPath))),
 | 
							// http.StripPrefix("/ui/", http.FileServer(http.Dir(base.Cfg.UiPath))),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,5 +3,5 @@ package base
 | 
				
			|||||||
const (
 | 
					const (
 | 
				
			||||||
	APP_NAME = "AnyLink"
 | 
						APP_NAME = "AnyLink"
 | 
				
			||||||
	// 修复前端bug
 | 
						// 修复前端bug
 | 
				
			||||||
	APP_VER = "0.7.1"
 | 
						APP_VER = "0.7.2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ var (
 | 
				
			|||||||
type ServerConfig struct {
 | 
					type ServerConfig struct {
 | 
				
			||||||
	// LinkAddr      string `json:"link_addr"`
 | 
						// LinkAddr      string `json:"link_addr"`
 | 
				
			||||||
	Conf           string `json:"conf"`
 | 
						Conf           string `json:"conf"`
 | 
				
			||||||
 | 
						Profile        string `json:"profile"`
 | 
				
			||||||
	ServerAddr     string `json:"server_addr"`
 | 
						ServerAddr     string `json:"server_addr"`
 | 
				
			||||||
	ServerDTLSAddr string `json:"server_dtls_addr"`
 | 
						ServerDTLSAddr string `json:"server_dtls_addr"`
 | 
				
			||||||
	ServerDTLS     bool   `json:"server_dtls"`
 | 
						ServerDTLS     bool   `json:"server_dtls"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ type config struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var configs = []config{
 | 
					var configs = []config{
 | 
				
			||||||
	{Typ: cfgStr, Name: "conf", Usage: "config file", ValStr: "./conf/server.toml", Short: "c"},
 | 
						{Typ: cfgStr, Name: "conf", Usage: "config file", ValStr: "./conf/server.toml", Short: "c"},
 | 
				
			||||||
 | 
						{Typ: cfgStr, Name: "profile", Usage: "profile.xml file", ValStr: "./conf/profile.xml"},
 | 
				
			||||||
	{Typ: cfgStr, Name: "server_addr", Usage: "服务监听地址", ValStr: ":443"},
 | 
						{Typ: cfgStr, Name: "server_addr", Usage: "服务监听地址", ValStr: ":443"},
 | 
				
			||||||
	{Typ: cfgBool, Name: "server_dtls", Usage: "开启DTLS", ValBool: false},
 | 
						{Typ: cfgBool, Name: "server_dtls", Usage: "开启DTLS", ValBool: false},
 | 
				
			||||||
	{Typ: cfgStr, Name: "server_dtls_addr", Usage: "DTLS监听地址", ValStr: ":4433"},
 | 
						{Typ: cfgStr, Name: "server_dtls_addr", Usage: "DTLS监听地址", ValStr: ":4433"},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,10 +6,11 @@
 | 
				
			|||||||
#数据文件
 | 
					#数据文件
 | 
				
			||||||
db_type = "sqlite3"
 | 
					db_type = "sqlite3"
 | 
				
			||||||
db_source = "./conf/anylink.db"
 | 
					db_source = "./conf/anylink.db"
 | 
				
			||||||
#证书文件
 | 
					#证书文件 使用跟nginx一样的证书即可
 | 
				
			||||||
cert_file = "./conf/vpn_cert.pem"
 | 
					cert_file = "./conf/vpn_cert.pem"
 | 
				
			||||||
cert_key = "./conf/vpn_cert.key"
 | 
					cert_key = "./conf/vpn_cert.key"
 | 
				
			||||||
files_path = "./conf/files"
 | 
					files_path = "./conf/files"
 | 
				
			||||||
 | 
					profile = "./conf/profile.xml"
 | 
				
			||||||
#日志目录,为空写入标准输出
 | 
					#日志目录,为空写入标准输出
 | 
				
			||||||
#log_path = "./log"
 | 
					#log_path = "./log"
 | 
				
			||||||
log_path = ""
 | 
					log_path = ""
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,8 @@ import (
 | 
				
			|||||||
	"github.com/bjdgyc/anylink/sessdata"
 | 
						"github.com/bjdgyc/anylink/sessdata"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var profileHash = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LinkAuth(w http.ResponseWriter, r *http.Request) {
 | 
					func LinkAuth(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	// 判断anyconnect客户端
 | 
						// 判断anyconnect客户端
 | 
				
			||||||
	userAgent := strings.ToLower(r.UserAgent())
 | 
						userAgent := strings.ToLower(r.UserAgent())
 | 
				
			||||||
@@ -89,7 +91,7 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
	other := &dbdata.SettingOther{}
 | 
						other := &dbdata.SettingOther{}
 | 
				
			||||||
	_ = dbdata.SettingGet(other)
 | 
						_ = dbdata.SettingGet(other)
 | 
				
			||||||
	rd := RequestData{SessionId: sess.Sid, SessionToken: sess.Sid + "@" + sess.Token,
 | 
						rd := RequestData{SessionId: sess.Sid, SessionToken: sess.Sid + "@" + sess.Token,
 | 
				
			||||||
		Banner: other.Banner}
 | 
							Banner: other.Banner, ProfileHash: profileHash}
 | 
				
			||||||
	w.WriteHeader(http.StatusOK)
 | 
						w.WriteHeader(http.StatusOK)
 | 
				
			||||||
	tplRequest(tpl_complete, w, rd)
 | 
						tplRequest(tpl_complete, w, rd)
 | 
				
			||||||
	base.Debug("login", cr.Auth.Username)
 | 
						base.Debug("login", cr.Auth.Username)
 | 
				
			||||||
@@ -125,6 +127,7 @@ type RequestData struct {
 | 
				
			|||||||
	SessionId    string
 | 
						SessionId    string
 | 
				
			||||||
	SessionToken string
 | 
						SessionToken string
 | 
				
			||||||
	Banner       string
 | 
						Banner       string
 | 
				
			||||||
 | 
						ProfileHash  string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var auth_request = `<?xml version="1.0" encoding="UTF-8"?>
 | 
					var auth_request = `<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
@@ -176,8 +179,8 @@ var auth_complete = `<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			|||||||
        <vpn-profile-manifest>
 | 
					        <vpn-profile-manifest>
 | 
				
			||||||
            <vpn rev="1.0">
 | 
					            <vpn rev="1.0">
 | 
				
			||||||
                <file type="profile" service-type="user">
 | 
					                <file type="profile" service-type="user">
 | 
				
			||||||
                    <uri>/files/profile.xml</uri>
 | 
					                    <uri>/profile.xml</uri>
 | 
				
			||||||
                    <hash type="sha1">A8B0B07FBA93D06E8501E40AB807AEE2464E73B7</hash>
 | 
					                    <hash type="sha1">{{.ProfileHash}}</hash>
 | 
				
			||||||
                </file>
 | 
					                </file>
 | 
				
			||||||
            </vpn>
 | 
					            </vpn>
 | 
				
			||||||
        </vpn-profile-manifest>
 | 
					        </vpn-profile-manifest>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ import (
 | 
				
			|||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/bjdgyc/anylink/base"
 | 
						"github.com/bjdgyc/anylink/base"
 | 
				
			||||||
@@ -26,14 +27,14 @@ func startTls() {
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 判断证书文件
 | 
						// 判断证书文件
 | 
				
			||||||
	//_, err = os.Stat(certFile)
 | 
						// _, err = os.Stat(certFile)
 | 
				
			||||||
	//if errors.Is(err, os.ErrNotExist) {
 | 
						// if errors.Is(err, os.ErrNotExist) {
 | 
				
			||||||
	//	// 自动生成证书
 | 
						//	// 自动生成证书
 | 
				
			||||||
	//	certs[0], err = selfsign.GenerateSelfSignedWithDNS("vpn.anylink")
 | 
						//	certs[0], err = selfsign.GenerateSelfSignedWithDNS("vpn.anylink")
 | 
				
			||||||
	//} else {
 | 
						// } else {
 | 
				
			||||||
	//	// 使用自定义证书
 | 
						//	// 使用自定义证书
 | 
				
			||||||
	//	certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
 | 
						//	certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
 | 
				
			||||||
	//}
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
 | 
						certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -77,9 +78,10 @@ func initRoute() http.Handler {
 | 
				
			|||||||
	r.HandleFunc("/", LinkAuth).Methods(http.MethodPost)
 | 
						r.HandleFunc("/", LinkAuth).Methods(http.MethodPost)
 | 
				
			||||||
	r.HandleFunc("/CSCOSSLC/tunnel", LinkTunnel).Methods(http.MethodConnect)
 | 
						r.HandleFunc("/CSCOSSLC/tunnel", LinkTunnel).Methods(http.MethodConnect)
 | 
				
			||||||
	r.HandleFunc("/otp_qr", LinkOtpQr).Methods(http.MethodGet)
 | 
						r.HandleFunc("/otp_qr", LinkOtpQr).Methods(http.MethodGet)
 | 
				
			||||||
	// r.HandleFunc("/profile.xml", func(w http.ResponseWriter, r *http.Request) {
 | 
						r.HandleFunc("/profile.xml", func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	// 	w.Write([]byte(auth_profile))
 | 
							b, _ := os.ReadFile(base.Cfg.Profile)
 | 
				
			||||||
	// }).Methods(http.MethodGet)
 | 
							w.Write(b)
 | 
				
			||||||
 | 
						}).Methods(http.MethodGet)
 | 
				
			||||||
	r.PathPrefix("/files/").Handler(
 | 
						r.PathPrefix("/files/").Handler(
 | 
				
			||||||
		http.StripPrefix("/files/",
 | 
							http.StripPrefix("/files/",
 | 
				
			||||||
			http.FileServer(http.Dir(base.Cfg.FilesPath)),
 | 
								http.FileServer(http.Dir(base.Cfg.FilesPath)),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,10 @@
 | 
				
			|||||||
package handler
 | 
					package handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/sha1"
 | 
				
			||||||
 | 
						"encoding/hex"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/bjdgyc/anylink/admin"
 | 
						"github.com/bjdgyc/anylink/admin"
 | 
				
			||||||
	"github.com/bjdgyc/anylink/base"
 | 
						"github.com/bjdgyc/anylink/base"
 | 
				
			||||||
	"github.com/bjdgyc/anylink/dbdata"
 | 
						"github.com/bjdgyc/anylink/dbdata"
 | 
				
			||||||
@@ -22,6 +26,14 @@ func Start() {
 | 
				
			|||||||
		base.Fatal("LinkMode is err")
 | 
							base.Fatal("LinkMode is err")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 计算profile.xml的hash
 | 
				
			||||||
 | 
						b, err := os.ReadFile(base.Cfg.Profile)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ha := sha1.Sum(b)
 | 
				
			||||||
 | 
						profileHash = hex.EncodeToString(ha[:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go admin.StartAdmin()
 | 
						go admin.StartAdmin()
 | 
				
			||||||
	go startTls()
 | 
						go startTls()
 | 
				
			||||||
	go startDtls()
 | 
						go startDtls()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user