mirror of
				https://github.com/bjdgyc/anylink.git
				synced 2025-10-31 00:19:34 +08:00 
			
		
		
		
	
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							| @@ -36,7 +36,9 @@ AnyLink 服务端仅在 CentOS 7、Ubuntu 18.04 测试通过,如需要安装 | |||||||
| > https://github.com/bjdgyc/anylink/releases | > https://github.com/bjdgyc/anylink/releases | ||||||
|  |  | ||||||
| ### 使用问题 | ### 使用问题 | ||||||
| > 使用客户端前,必须申请安全的 https 证书,不支持私有证书连接 | > 对于测试环境,可以使用 vpn.test.vqilu.cn 绑定host进行测试 | ||||||
|  | >  | ||||||
|  | > 对于线上环境,必须申请安全的 https 证书,不支持私有证书连接 | ||||||
| >  | >  | ||||||
| > 客户端请使用群共享文件的版本,其他版本没有测试过,不保证使用正常 | > 客户端请使用群共享文件的版本,其他版本没有测试过,不保证使用正常 | ||||||
|  |  | ||||||
| @@ -109,7 +111,7 @@ sudo ./anylink | |||||||
|  |  | ||||||
| > 以下参数必须设置其中之一 | > 以下参数必须设置其中之一 | ||||||
|  |  | ||||||
| 网络模式选择,需要配置 `link_mode` 参数,如 `link_mode="tun"`,`link_mode="macvtap"`,`link_mode="tap"` 等参数。 不同的参数需要对服务器做相应的设置。 | 网络模式选择,需要配置 `link_mode` 参数,如 `link_mode="tun"`,`link_mode="macvtap"`,`link_mode="tap"(不推荐)` 等参数。 不同的参数需要对服务器做相应的设置。 | ||||||
|  |  | ||||||
| 建议优先选择 tun 模式,其次选择 macvtap 模式,因客户端传输的是 IP 层数据,无须进行数据转换。 tap 模式是在用户态做的链路层到 IP 层的数据互相转换,性能会有所下降。 如果需要在虚拟机内开启 tap 模式,请确认虚拟机的网卡开启混杂模式。 | 建议优先选择 tun 模式,其次选择 macvtap 模式,因客户端传输的是 IP 层数据,无须进行数据转换。 tap 模式是在用户态做的链路层到 IP 层的数据互相转换,性能会有所下降。 如果需要在虚拟机内开启 tap 模式,请确认虚拟机的网卡开启混杂模式。 | ||||||
|  |  | ||||||
| @@ -158,7 +160,7 @@ ipv4_start = "192.168.10.100" | |||||||
| ipv4_end = "192.168.10.200" | ipv4_end = "192.168.10.200" | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### tap 设置 | ### ~~tap 设置~~ | ||||||
|  |  | ||||||
| 1. 创建桥接网卡 | 1. 创建桥接网卡 | ||||||
|  |  | ||||||
| @@ -246,7 +248,7 @@ sh bridge-init.sh | |||||||
|        -p 443:443 -p 8800:8800 \ |        -p 443:443 -p 8800:8800 \ | ||||||
|        --restart=always \ |        --restart=always \ | ||||||
|        bjdgyc/anylink \ |        bjdgyc/anylink \ | ||||||
|        -c=/etc/server.toml --ip_lease = 1209600 \ # IP地址租约时长 |        -c=/etc/server.toml --ip_lease=1209600 # IP地址租约时长 | ||||||
|    ``` |    ``` | ||||||
|  |  | ||||||
| 7. 构建镜像 | 7. 构建镜像 | ||||||
|   | |||||||
| @@ -15,3 +15,6 @@ | |||||||
| | 代码oo8 |                              | | | 代码oo8 |                              | | ||||||
| | 甘磊     | https://github.com/ganlei333 | | | 甘磊     | https://github.com/ganlei333 | | ||||||
| | Oo@     | https://github.com/chooop    | | | Oo@     | https://github.com/chooop    | | ||||||
|  | | 虚极静笃 |                              | | ||||||
|  | | Ficapy |                              | | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,5 +3,5 @@ package base | |||||||
| const ( | const ( | ||||||
| 	APP_NAME = "AnyLink" | 	APP_NAME = "AnyLink" | ||||||
| 	// 修复前端bug | 	// 修复前端bug | ||||||
| 	APP_VER = "0.6.2" | 	APP_VER = "0.7.1" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -101,7 +101,7 @@ func initCmd() { | |||||||
| 		_, err := os.Stat(conf) | 		_, err := os.Stat(conf) | ||||||
| 		if errors.Is(err, os.ErrNotExist) { | 		if errors.Is(err, os.ErrNotExist) { | ||||||
| 			// 没有配置文件,不做处理 | 			// 没有配置文件,不做处理 | ||||||
| 			return | 			panic(err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		linkViper.SetConfigFile(conf) | 		linkViper.SetConfigFile(conf) | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								server/conf/files/profile.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								server/conf/files/profile.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |                    xsi:schemaLocation="http://schemas.xmlsoap.org/encoding/ AnyConnectProfile.xsd"> | ||||||
|  |  | ||||||
|  |     <ClientInitialization> | ||||||
|  |         <UseStartBeforeLogon UserControllable="false">false</UseStartBeforeLogon> | ||||||
|  |         <StrictCertificateTrust>false</StrictCertificateTrust> | ||||||
|  |         <RestrictPreferenceCaching>false</RestrictPreferenceCaching> | ||||||
|  |         <RestrictTunnelProtocols>IPSec</RestrictTunnelProtocols> | ||||||
|  |         <BypassDownloader>true</BypassDownloader> | ||||||
|  |         <WindowsVPNEstablishment>AllowRemoteUsers</WindowsVPNEstablishment> | ||||||
|  |         <LinuxVPNEstablishment>AllowRemoteUsers</LinuxVPNEstablishment> | ||||||
|  |         <CertEnrollmentPin>pinAllowed</CertEnrollmentPin> | ||||||
|  |         <CertificateMatch> | ||||||
|  |             <KeyUsage> | ||||||
|  |                 <MatchKey>Digital_Signature</MatchKey> | ||||||
|  |             </KeyUsage> | ||||||
|  |             <ExtendedKeyUsage> | ||||||
|  |                 <ExtendedMatchKey>ClientAuth</ExtendedMatchKey> | ||||||
|  |             </ExtendedKeyUsage> | ||||||
|  |         </CertificateMatch> | ||||||
|  |  | ||||||
|  |         <BackupServerList> | ||||||
|  |             <HostAddress>localhost</HostAddress> | ||||||
|  |         </BackupServerList> | ||||||
|  |     </ClientInitialization> | ||||||
|  |  | ||||||
|  |     <ServerList> | ||||||
|  |         <HostEntry> | ||||||
|  |             <HostName>VPN Server</HostName> | ||||||
|  |             <HostAddress>localhost</HostAddress> | ||||||
|  |         </HostEntry> | ||||||
|  |     </ServerList> | ||||||
|  | </AnyConnectProfile> | ||||||
							
								
								
									
										29
									
								
								server/conf/server.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								server/conf/server.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | #示例配置信息 | ||||||
|  |  | ||||||
|  | #其他配置文件,可以使用绝对路径 | ||||||
|  | #或者相对于 anylink 二进制文件的路径 | ||||||
|  |  | ||||||
|  | #数据文件 | ||||||
|  | db_type = "sqlite3" | ||||||
|  | db_source = "./conf/anylink.db" | ||||||
|  | #证书文件 | ||||||
|  | cert_file = "./conf/vpn_cert.pem" | ||||||
|  | cert_key = "./conf/vpn_cert.key" | ||||||
|  | files_path = "./conf/files" | ||||||
|  |  | ||||||
|  | #系统名称 | ||||||
|  | issuer = "XX公司VPN" | ||||||
|  | #后台管理用户 | ||||||
|  | admin_user = "admin" | ||||||
|  | #pass 123456 | ||||||
|  | admin_pass = "$2a$10$UQ7C.EoPifDeJh6d8.31TeSPQU7hM/NOM2nixmBucJpAuXDQNqNke" | ||||||
|  | jwt_secret = "abcdef.0123456789.abcdef" | ||||||
|  |  | ||||||
|  | #服务监听地址 | ||||||
|  | server_addr = ":443" | ||||||
|  | #后台服务监听地址 | ||||||
|  | admin_addr = ":8800" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										27
									
								
								server/conf/vpn_cert.key
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								server/conf/vpn_cert.key
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | -----BEGIN RSA PRIVATE KEY----- | ||||||
|  | MIIEpAIBAAKCAQEArZc7o1r/+LSwyJXScX5oNNsOJsaJMuv4sWWFMiLUpf0gBTZd | ||||||
|  | ujPUHxzEOujeD4LOCsaDRgwjgLEGJjnpRPeNROwtgE2lY+RuGUf6al/Qnt+Afb1X | ||||||
|  | UsBkqbapHbzL+Ssochtwat8wBteLqJWRUeFz5528YJ0CINLImBVJlthX+zQtcsXQ | ||||||
|  | HQGiRqDC28YjHuKTm4bh7G5EJQoTfPSfpFd03R5YG8oocWFYR5oEgbMeOgOADH/h | ||||||
|  | UnxexbS1zAHKJVGqkwVrV4bccsy+LfgzWovM2/t0Y8iSvXOO+W9OqEOmKZc6L0Lg | ||||||
|  | 3lk59l80DJHzNTn60GpIK8HJq/EsnAL/8XtVBwIDAQABAoIBACXjPEELO5Ms3Ojq | ||||||
|  | ymO7E0N2DECqVIeouT7+yXOH5qHT/YkltI9PgJzJyoqRCOaZxh7T9RL000rjWFQ/ | ||||||
|  | j4pd/ZdtdQDr8Y077kvWSfGtt/r1DTZkfQqys0XXeFHlQx+/K7S8CG1LCVB0+yZw | ||||||
|  | fqdAbeu/ob30huJjHyUSgF1MGufYvuII6x0CGORwzruWWFniXkg2z+9SP4x4RSfm | ||||||
|  | exMUE4T4tlzR63QaW02xWEDTWCSQw/FgjpCWwryDVCmnLf63UhI+4hITqZLL+ROd | ||||||
|  | sG/8Yp284q7BYBKk4/N1HD4W1vU+dls3glxZ22NCQKx+2RVtqTrRUd/d4AnxOmMR | ||||||
|  | dnfh4AECgYEA7cl9NIRrtQdW+KFcoSdyP2F+SU74nSAh6Uolzwr9lHB+NbMJ5g79 | ||||||
|  | eU1zp3RAvSFg249L4cnceaFL1LTPcNN0xhpaJ7v5FQWk5tkddSmy2T3CAh8VwLXF | ||||||
|  | 487pgakO1SpS6uz+BtwsAFOS8k/GjYeSbPR4e9F/FbYAvGYwOLNj2ocCgYEAuuL8 | ||||||
|  | xnFnt95TwWptu4T97YXTeZRB17jiH1BhX+QawsSafagsWlSKihKMxYhfCHiwztS/ | ||||||
|  | KsCnkS6cH9slU3y4gvCiT1S4z1Qkw93ljUQXCzRIVEd9SxXoQMeRi+/5c239Fhnu | ||||||
|  | aoxESAFWNXJZ5r9Jp3qukHvEtYn2FoE1Zkmu0YECgYApULgDdvqr4pGW85p/mbX9 | ||||||
|  | Ezh5DlKeImYh/bMiDTvQHdegBvKyWWprOCzfLJDPC8yjeXtqyMMZExB07dGZPfRt | ||||||
|  | M0j03HFD2M41GgZHRC6CFnvuGG6UJEE0+s+Rqskb+pWbof/lOz4d9Gd02K2cC7FC | ||||||
|  | YxvID7dwE0Z/dZXtVCYGYwKBgQCjckPKtoIUcBBmV1NzLiP66REEAuL27Q5ufpk7 | ||||||
|  | CT9SWioXfc6Ujd3AVeriE5uxyAQyUCSFGosy0UXgIoRpmOmyMwxxP1KGmTuyRc4u | ||||||
|  | l39j4Czl8MQmuBkxFpk3fwB2sJopCzLV4qkRJIImKkVwJpofLI+hc22dq/QayJRQ | ||||||
|  | Sl7ngQKBgQCkfcbQDvhkL6QKUC/K7MDGw9JMICLUpRyp6D3ibeL7i6WO6dkKde2t | ||||||
|  | O/oLz2XvG0NR0nulhThpWUdyUWco3FZ038jiuY8ZZum5wdVBDOcDcnuBisE3Kzh8 | ||||||
|  | p7WycoWItAVxmyTKzHJIZ7pFQULYjap7gFSUPE9uBQZu09VKBtGPHA== | ||||||
|  | -----END RSA PRIVATE KEY----- | ||||||
							
								
								
									
										61
									
								
								server/conf/vpn_cert.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								server/conf/vpn_cert.pem
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | -----BEGIN CERTIFICATE----- | ||||||
|  | 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 | ||||||
|  | -----END CERTIFICATE----- | ||||||
|  | -----BEGIN CERTIFICATE----- | ||||||
|  | MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh | ||||||
|  | MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 | ||||||
|  | d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD | ||||||
|  | QTAeFw0xNzExMjcxMjQ2MTBaFw0yNzExMjcxMjQ2MTBaMG4xCzAJBgNVBAYTAlVT | ||||||
|  | MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j | ||||||
|  | b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH | ||||||
|  | MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPeP6wkab41dyQh6mKc | ||||||
|  | oHqt3jRIxW5MDvf9QyiOR7VfFwK656es0UFiIb74N9pRntzF1UgYzDGu3ppZVMdo | ||||||
|  | lbxhm6dWS9OK/lFehKNT0OYI9aqk6F+U7cA6jxSC+iDBPXwdF4rs3KRyp3aQn6pj | ||||||
|  | pp1yr7IB6Y4zv72Ee/PlZ/6rK6InC6WpK0nPVOYR7n9iDuPe1E4IxUMBH/T33+3h | ||||||
|  | yuH3dvfgiWUOUkjdpMbyxX+XNle5uEIiyBsi4IvbcTCh8ruifCIi5mDXkZrnMT8n | ||||||
|  | wfYCV6v6kDdXkbgGRLKsR4pucbJtbKqIkUGxuZI2t7pfewKRc5nWecvDBZf3+p1M | ||||||
|  | pA8CAwEAAaOCAU8wggFLMB0GA1UdDgQWBBRVdE+yck/1YLpQ0dfmUVyaAYca1zAf | ||||||
|  | BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYw | ||||||
|  | HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C | ||||||
|  | AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp | ||||||
|  | Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu | ||||||
|  | Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG | ||||||
|  | /WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT | ||||||
|  | MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAK3Gp6/aGq7aBZsxf/oQ+TD/B | ||||||
|  | SwW3AU4ETK+GQf2kFzYZkby5SFrHdPomunx2HBzViUchGoofGgg7gHW0W3MlQAXW | ||||||
|  | M0r5LUvStcr82QDWYNPaUy4taCQmyaJ+VB+6wxHstSigOlSNF2a6vg4rgexixeiV | ||||||
|  | 4YSB03Yqp2t3TeZHM9ESfkus74nQyW7pRGezj+TC44xCagCQQOzzNmzEAP2SnCrJ | ||||||
|  | sNE2DpRVMnL8J6xBRdjmOsC3N6cQuKuRXbzByVBjCqAA8t1L0I+9wXJerLPyErjy | ||||||
|  | rMKWaBFLmfK/AHNF4ZihwPGOc7w6UHczBZXH5RFzJNnww+WnKuTPI0HfnVH8lg== | ||||||
|  | -----END CERTIFICATE----- | ||||||
| @@ -19,7 +19,7 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) { | |||||||
| 	userAgent := strings.ToLower(r.UserAgent()) | 	userAgent := strings.ToLower(r.UserAgent()) | ||||||
| 	xAggregateAuth := r.Header.Get("X-Aggregate-Auth") | 	xAggregateAuth := r.Header.Get("X-Aggregate-Auth") | ||||||
| 	xTranscendVersion := r.Header.Get("X-Transcend-Version") | 	xTranscendVersion := r.Header.Get("X-Transcend-Version") | ||||||
| 	if !(strings.Contains(userAgent, "anyconnect") && | 	if !((strings.Contains(userAgent, "anyconnect") || strings.Contains(userAgent, "openconnect")) && | ||||||
| 		xAggregateAuth == "1" && xTranscendVersion == "1") { | 		xAggregateAuth == "1" && xTranscendVersion == "1") { | ||||||
| 		w.WriteHeader(http.StatusForbidden) | 		w.WriteHeader(http.StatusForbidden) | ||||||
| 		fmt.Fprintf(w, "error request") | 		fmt.Fprintf(w, "error request") | ||||||
| @@ -176,7 +176,7 @@ 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>/profile.xml</uri> |                     <uri>/files/profile.xml</uri> | ||||||
|                     <hash type="sha1">A8B0B07FBA93D06E8501E40AB807AEE2464E73B7</hash> |                     <hash type="sha1">A8B0B07FBA93D06E8501E40AB807AEE2464E73B7</hash> | ||||||
|                 </file> |                 </file> | ||||||
|             </vpn> |             </vpn> | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ func LinkHome(w http.ResponseWriter, r *http.Request) { | |||||||
|  |  | ||||||
| 	connection := strings.ToLower(r.Header.Get("Connection")) | 	connection := strings.ToLower(r.Header.Get("Connection")) | ||||||
| 	userAgent := strings.ToLower(r.UserAgent()) | 	userAgent := strings.ToLower(r.UserAgent()) | ||||||
| 	if connection == "close" && strings.Contains(userAgent, "anyconnect") { | 	if connection == "close" && (strings.Contains(userAgent, "anyconnect") || strings.Contains(userAgent, "openconnect")) { | ||||||
| 		w.Header().Set("Connection", "close") | 		w.Header().Set("Connection", "close") | ||||||
| 		w.WriteHeader(http.StatusBadRequest) | 		w.WriteHeader(http.StatusBadRequest) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -22,6 +22,14 @@ func init() { | |||||||
| 	hn, _ = os.Hostname() | 	hn, _ = os.Hostname() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func HttpSetHeader(w http.ResponseWriter, key string, value string) { | ||||||
|  |    w.Header()[key] = []string{value} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func HttpAddHeader(w http.ResponseWriter, key string, value string) { | ||||||
|  |    w.Header()[key] = append(w.Header()[key], value) | ||||||
|  | } | ||||||
|  |  | ||||||
| func LinkTunnel(w http.ResponseWriter, r *http.Request) { | func LinkTunnel(w http.ResponseWriter, r *http.Request) { | ||||||
| 	// TODO 调试信息输出 | 	// TODO 调试信息输出 | ||||||
| 	// hd, _ := httputil.DumpRequest(r, true) | 	// hd, _ := httputil.DumpRequest(r, true) | ||||||
| @@ -51,6 +59,7 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) { | |||||||
|  |  | ||||||
| 	// 客户端信息 | 	// 客户端信息 | ||||||
| 	cstpMtu := r.Header.Get("X-CSTP-MTU") | 	cstpMtu := r.Header.Get("X-CSTP-MTU") | ||||||
|  | 	cstpBaseMtu := r.Header.Get("X-CSTP-Base-MTU") | ||||||
| 	masterSecret := r.Header.Get("X-DTLS-Master-Secret") | 	masterSecret := r.Header.Get("X-DTLS-Master-Secret") | ||||||
| 	localIp := r.Header.Get("X-Cstp-Local-Address-Ip4") | 	localIp := r.Header.Get("X-Cstp-Local-Address-Ip4") | ||||||
| 	mobile := r.Header.Get("X-Cstp-License") | 	mobile := r.Header.Get("X-Cstp-License") | ||||||
| @@ -79,68 +88,71 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) { | |||||||
| 	base.Debug(cSess.IpAddr, cSess.MacHw, sess.Username, mobile) | 	base.Debug(cSess.IpAddr, cSess.MacHw, sess.Username, mobile) | ||||||
|  |  | ||||||
| 	// 返回客户端数据 | 	// 返回客户端数据 | ||||||
| 	w.Header().Set("Server", fmt.Sprintf("%s %s", base.APP_NAME, base.APP_VER)) | 	HttpSetHeader(w, "Server", fmt.Sprintf("%s %s", base.APP_NAME, base.APP_VER)) | ||||||
| 	w.Header().Set("X-CSTP-Version", "1") | 	HttpSetHeader(w, "X-CSTP-Version", "1") | ||||||
| 	w.Header().Set("X-CSTP-Protocol", "Copyright (c) 2004 Cisco Systems, Inc.") | 	HttpSetHeader(w, "X-CSTP-Server-Name", fmt.Sprintf("%s %s", base.APP_NAME, base.APP_VER)) | ||||||
| 	w.Header().Set("X-CSTP-Address", cSess.IpAddr.String())             // 分配的ip地址 | 	HttpSetHeader(w, "X-CSTP-Protocol", "Copyright (c) 2004 Cisco Systems, Inc.") | ||||||
| 	w.Header().Set("X-CSTP-Netmask", sessdata.IpPool.Ipv4Mask.String()) // 子网掩码 | 	HttpSetHeader(w, "X-CSTP-Address", cSess.IpAddr.String())             // 分配的ip地址 | ||||||
| 	w.Header().Set("X-CSTP-Hostname", hn)                               // 机器名称 | 	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-Base-MTU", cstpBaseMtu) | ||||||
|  |  | ||||||
| 	// 允许本地LAN访问vpn网络,必须放在路由的第一个 | 	// 允许本地LAN访问vpn网络,必须放在路由的第一个 | ||||||
| 	if cSess.Group.AllowLan { | 	if cSess.Group.AllowLan { | ||||||
| 		w.Header().Set("X-CSTP-Split-Exclude", "0.0.0.0/255.255.255.255") | 		HttpSetHeader(w, "X-CSTP-Split-Exclude", "0.0.0.0/255.255.255.255") | ||||||
| 	} | 	} | ||||||
| 	// dns地址 | 	// dns地址 | ||||||
| 	for _, v := range cSess.Group.ClientDns { | 	for _, v := range cSess.Group.ClientDns { | ||||||
| 		w.Header().Add("X-CSTP-DNS", v.Val) | 		HttpAddHeader(w, "X-CSTP-DNS", v.Val) | ||||||
| 	} | 	} | ||||||
| 	// 允许的路由 | 	// 允许的路由 | ||||||
| 	for _, v := range cSess.Group.RouteInclude { | 	for _, v := range cSess.Group.RouteInclude { | ||||||
| 		if v.Val == "all" { | 		if v.Val == "all" { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		w.Header().Add("X-CSTP-Split-Include", v.IpMask) | 		HttpAddHeader(w, "X-CSTP-Split-Include", v.IpMask) | ||||||
| 	} | 	} | ||||||
| 	// 不允许的路由 | 	// 不允许的路由 | ||||||
| 	for _, v := range cSess.Group.RouteExclude { | 	for _, v := range cSess.Group.RouteExclude { | ||||||
| 		w.Header().Add("X-CSTP-Split-Exclude", v.IpMask) | 		HttpAddHeader(w, "X-CSTP-Split-Exclude", v.IpMask) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	w.Header().Set("X-CSTP-Lease-Duration", fmt.Sprintf("%d", base.Cfg.IpLease)) // ip地址租期 | 	HttpSetHeader(w, "X-CSTP-Lease-Duration", fmt.Sprintf("%d", base.Cfg.IpLease)) // ip地址租期 | ||||||
| 	w.Header().Set("X-CSTP-Session-Timeout", "none") | 	HttpSetHeader(w, "X-CSTP-Session-Timeout", "none") | ||||||
| 	w.Header().Set("X-CSTP-Session-Timeout-Alert-Interval", "60") | 	HttpSetHeader(w, "X-CSTP-Session-Timeout-Alert-Interval", "60") | ||||||
| 	w.Header().Set("X-CSTP-Session-Timeout-Remaining", "none") | 	HttpSetHeader(w, "X-CSTP-Session-Timeout-Remaining", "none") | ||||||
| 	w.Header().Set("X-CSTP-Idle-Timeout", "18000") | 	HttpSetHeader(w, "X-CSTP-Idle-Timeout", "18000") | ||||||
| 	w.Header().Set("X-CSTP-Disconnected-Timeout", "18000") | 	HttpSetHeader(w, "X-CSTP-Disconnected-Timeout", "18000") | ||||||
| 	w.Header().Set("X-CSTP-Keep", "true") | 	HttpSetHeader(w, "X-CSTP-Keep", "true") | ||||||
| 	w.Header().Set("X-CSTP-Tunnel-All-DNS", "false") | 	HttpSetHeader(w, "X-CSTP-Tunnel-All-DNS", "false") | ||||||
|  |  | ||||||
| 	w.Header().Set("X-CSTP-Rekey-Time", "172800") | 	HttpSetHeader(w, "X-CSTP-Rekey-Time", "172800") | ||||||
| 	w.Header().Set("X-CSTP-Rekey-Method", "new-tunnel") | 	HttpSetHeader(w, "X-CSTP-Rekey-Method", "new-tunnel") | ||||||
|  |  | ||||||
| 	w.Header().Set("X-CSTP-DPD", fmt.Sprintf("%d", cstpDpd)) | 	HttpSetHeader(w, "X-CSTP-DPD", fmt.Sprintf("%d", cstpDpd)) | ||||||
| 	w.Header().Set("X-CSTP-Keepalive", fmt.Sprintf("%d", cstpKeepalive)) | 	HttpSetHeader(w, "X-CSTP-Keepalive", fmt.Sprintf("%d", cstpKeepalive)) | ||||||
| 	// w.Header().Set("X-CSTP-Banner", banner.Banner) | 	// HttpSetHeader(w, "X-CSTP-Banner", banner.Banner) | ||||||
| 	w.Header().Set("X-CSTP-MSIE-Proxy-Lockdown", "true") | 	HttpSetHeader(w, "X-CSTP-MSIE-Proxy-Lockdown", "true") | ||||||
| 	w.Header().Set("X-CSTP-Smartcard-Removal-Disconnect", "true") | 	HttpSetHeader(w, "X-CSTP-Smartcard-Removal-Disconnect", "true") | ||||||
|  |  | ||||||
| 	w.Header().Set("X-CSTP-MTU", fmt.Sprintf("%d", cSess.Mtu)) // 1399 | 	HttpSetHeader(w, "X-CSTP-MTU", fmt.Sprintf("%d", cSess.Mtu)) // 1399 | ||||||
| 	w.Header().Set("X-DTLS-MTU", fmt.Sprintf("%d", cSess.Mtu)) | 	HttpSetHeader(w, "X-DTLS-MTU", fmt.Sprintf("%d", cSess.Mtu)) | ||||||
|  |  | ||||||
| 	w.Header().Set("X-DTLS-Session-ID", sess.DtlsSid) | 	HttpSetHeader(w, "X-DTLS-Session-ID", sess.DtlsSid) | ||||||
| 	w.Header().Set("X-DTLS-Port", dtlsPort) | 	HttpSetHeader(w, "X-DTLS-Port", dtlsPort) | ||||||
| 	w.Header().Set("X-DTLS-DPD", fmt.Sprintf("%d", cstpDpd)) | 	HttpSetHeader(w, "X-DTLS-DPD", fmt.Sprintf("%d", cstpDpd)) | ||||||
| 	w.Header().Set("X-DTLS-Keepalive", fmt.Sprintf("%d", cstpKeepalive)) | 	HttpSetHeader(w, "X-DTLS-Keepalive", fmt.Sprintf("%d", cstpKeepalive)) | ||||||
| 	w.Header().Set("X-DTLS-Rekey-Time", "5400") | 	HttpSetHeader(w, "X-DTLS-Rekey-Time", "5400") | ||||||
| 	w.Header().Set("X-DTLS12-CipherSuite", "ECDHE-ECDSA-AES128-GCM-SHA256") | 	HttpSetHeader(w, "X-DTLS12-CipherSuite", "ECDHE-ECDSA-AES128-GCM-SHA256") | ||||||
|  |  | ||||||
| 	w.Header().Set("X-CSTP-License", "accept") | 	HttpSetHeader(w, "X-CSTP-License", "accept") | ||||||
| 	w.Header().Set("X-CSTP-Routing-Filtering-Ignore", "false") | 	HttpSetHeader(w, "X-CSTP-Routing-Filtering-Ignore", "false") | ||||||
| 	w.Header().Set("X-CSTP-Quarantine", "false") | 	HttpSetHeader(w, "X-CSTP-Quarantine", "false") | ||||||
| 	w.Header().Set("X-CSTP-Disable-Always-On-VPN", "false") | 	HttpSetHeader(w, "X-CSTP-Disable-Always-On-VPN", "false") | ||||||
| 	w.Header().Set("X-CSTP-Client-Bypass-Protocol", "false") | 	HttpSetHeader(w, "X-CSTP-Client-Bypass-Protocol", "false") | ||||||
| 	w.Header().Set("X-CSTP-TCP-Keepalive", "false") | 	HttpSetHeader(w, "X-CSTP-TCP-Keepalive", "false") | ||||||
| 	// w.Header().Set("X-CSTP-Post-Auth-XML", ``) | 	// HttpSetHeader(w, "X-CSTP-Post-Auth-XML", ``) | ||||||
| 	w.WriteHeader(http.StatusOK) | 	w.WriteHeader(http.StatusOK) | ||||||
|  |  | ||||||
| 	hClone := w.Header().Clone() | 	hClone := w.Header().Clone() | ||||||
|   | |||||||
| @@ -2,18 +2,15 @@ package handler | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"crypto/tls" | 	"crypto/tls" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 	"net" | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" |  | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/bjdgyc/anylink/base" | 	"github.com/bjdgyc/anylink/base" | ||||||
| 	"github.com/bjdgyc/anylink/pkg/proxyproto" | 	"github.com/bjdgyc/anylink/pkg/proxyproto" | ||||||
| 	"github.com/gorilla/mux" | 	"github.com/gorilla/mux" | ||||||
| 	"github.com/pion/dtls/v2/pkg/crypto/selfsign" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func startTls() { | func startTls() { | ||||||
| @@ -29,15 +26,16 @@ 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) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| @@ -79,9 +77,9 @@ 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)) | 	// 	w.Write([]byte(auth_profile)) | ||||||
| 	}).Methods(http.MethodGet) | 	// }).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)), | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ User=root | |||||||
| WorkingDirectory=/usr/local/anylink-deploy | WorkingDirectory=/usr/local/anylink-deploy | ||||||
| Restart=on-failure | Restart=on-failure | ||||||
| RestartSec=5s | RestartSec=5s | ||||||
| ExecStart=/usr/local/anylink-deploy/anylink --conf=./conf/server.toml | ExecStart=/usr/local/anylink-deploy/anylink --conf=/usr/local/anylink-deploy/conf/server.toml | ||||||
|  |  | ||||||
| [Install] | [Install] | ||||||
| WantedBy=multi-user.target | WantedBy=multi-user.target | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user