mirror of https://github.com/bjdgyc/anylink.git
commit
edc7a4a4a3
21
README.md
21
README.md
|
@ -24,7 +24,8 @@ AnyLink 基于 [ietf-openconnect](https://tools.ietf.org/html/draft-mavrogiannop
|
||||||
|
|
||||||
AnyLink 使用 TLS/DTLS 进行数据加密,因此需要 RSA 或 ECC 证书,可以通过 Let's Encrypt 和 TrustAsia 申请免费的 SSL 证书。
|
AnyLink 使用 TLS/DTLS 进行数据加密,因此需要 RSA 或 ECC 证书,可以通过 Let's Encrypt 和 TrustAsia 申请免费的 SSL 证书。
|
||||||
|
|
||||||
AnyLink 服务端仅在 CentOS 7、CentOS 8、Ubuntu 18.04、Ubuntu 20.04 测试通过,如需要安装在其他系统,需要服务端支持 tun/tap 功能、ip 设置命令。
|
AnyLink 服务端仅在 CentOS 7、CentOS 8、Ubuntu 18.04、Ubuntu 20.04 测试通过,如需要安装在其他系统,需要服务端支持 tun/tap
|
||||||
|
功能、ip 设置命令。
|
||||||
|
|
||||||
## Screenshot
|
## Screenshot
|
||||||
|
|
||||||
|
@ -52,10 +53,12 @@ AnyLink 服务端仅在 CentOS 7、CentOS 8、Ubuntu 18.04、Ubuntu 20.04 测试
|
||||||
>
|
>
|
||||||
> 对于线上环境,必须申请安全的 https 证书,不支持私有证书连接
|
> 对于线上环境,必须申请安全的 https 证书,不支持私有证书连接
|
||||||
>
|
>
|
||||||
|
> 服务端安装 yum install iproute 或者 apt-get install iproute2
|
||||||
|
>
|
||||||
> 客户端请使用群共享文件的版本,其他版本没有测试过,不保证使用正常
|
> 客户端请使用群共享文件的版本,其他版本没有测试过,不保证使用正常
|
||||||
>
|
>
|
||||||
> 其他问题 [前往查看](doc/question.md)
|
> 其他问题 [前往查看](doc/question.md)
|
||||||
>
|
>
|
||||||
> 首次使用,请在浏览器访问 https://域名:443,浏览器提示安全后,在客户端输入 【域名:443】 即可
|
> 首次使用,请在浏览器访问 https://域名:443,浏览器提示安全后,在客户端输入 【域名:443】 即可
|
||||||
|
|
||||||
### 自行编译安装
|
### 自行编译安装
|
||||||
|
@ -127,7 +130,7 @@ sudo ./anylink
|
||||||
> 数据库配置示例
|
> 数据库配置示例
|
||||||
|
|
||||||
| db_type | db_source |
|
| db_type | db_source |
|
||||||
| -------- | ------------------------------------------------------ |
|
|----------|--------------------------------------------------------|
|
||||||
| sqlite3 | ./conf/anylink.db |
|
| sqlite3 | ./conf/anylink.db |
|
||||||
| mysql | user:password@tcp(127.0.0.1:3306)/anylink?charset=utf8 |
|
| mysql | user:password@tcp(127.0.0.1:3306)/anylink?charset=utf8 |
|
||||||
| postgres | user:password@localhost/anylink?sslmode=verify-full |
|
| postgres | user:password@localhost/anylink?sslmode=verify-full |
|
||||||
|
@ -140,9 +143,11 @@ 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
|
||||||
模式,请确认虚拟机的网卡开启混杂模式。
|
模式,请确认虚拟机的网卡开启混杂模式。
|
||||||
|
|
||||||
### tun 设置
|
### tun 设置
|
||||||
|
@ -196,7 +201,6 @@ https://cloud.tencent.com/document/product/216/62007
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
3. 使用 AnyConnect 客户端连接即可
|
3. 使用 AnyConnect 客户端连接即可
|
||||||
|
|
||||||
### macvtap 设置
|
### macvtap 设置
|
||||||
|
@ -222,7 +226,6 @@ ipv4_start = "10.1.2.100"
|
||||||
ipv4_end = "10.1.2.200"
|
ipv4_end = "10.1.2.200"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Systemd
|
## Systemd
|
||||||
|
|
||||||
1. 添加 anylink 程序
|
1. 添加 anylink 程序
|
||||||
|
@ -299,7 +302,6 @@ ipv4_end = "10.1.2.200"
|
||||||
docker build -t anylink -f docker/Dockerfile .
|
docker build -t anylink -f docker/Dockerfile .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## 常见问题
|
## 常见问题
|
||||||
|
|
||||||
请前往 [问题地址](doc/question.md) 查看具体信息
|
请前往 [问题地址](doc/question.md) 查看具体信息
|
||||||
|
@ -318,7 +320,6 @@ ipv4_end = "10.1.2.200"
|
||||||

|

|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
欢迎提交 PR、Issues,感谢为 AnyLink 做出贡献。
|
欢迎提交 PR、Issues,感谢为 AnyLink 做出贡献。
|
||||||
|
|
|
@ -40,8 +40,9 @@
|
||||||
| 悲鸣 | |
|
| 悲鸣 | |
|
||||||
| 谢谢 | |
|
| 谢谢 | |
|
||||||
| 云思科技 | |
|
| 云思科技 | |
|
||||||
| 哆啦A伟(张佳伟) | |
|
| 哆啦A伟(张佳伟) | 嘿嘿 |
|
||||||
| nobody | 开源不易,感谢分享 |
|
| 人类的悲欢并不相通 | 开源不易,感谢分享 |
|
||||||
|
| 做人要低调 | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ case $var1 in
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
sysctl -w net.ipv4.ip_forward=1
|
#sysctl -w net.ipv4.ip_forward=1
|
||||||
#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
|
||||||
|
|
||||||
|
|
|
@ -12,19 +12,20 @@ import (
|
||||||
const (
|
const (
|
||||||
procModulesPath = "/proc/modules"
|
procModulesPath = "/proc/modules"
|
||||||
inContainerKey = "ANYLINK_IN_CONTAINER"
|
inContainerKey = "ANYLINK_IN_CONTAINER"
|
||||||
|
tunPath = "/dev/net/tun"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
inContainer = false
|
InContainer = false
|
||||||
modMap = map[string]struct{}{}
|
modMap = map[string]struct{}{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func initMod() {
|
func initMod() {
|
||||||
container := os.Getenv(inContainerKey)
|
container := os.Getenv(inContainerKey)
|
||||||
if container == "true" {
|
if container == "true" {
|
||||||
inContainer = true
|
InContainer = true
|
||||||
}
|
}
|
||||||
log.Println("inContainer", inContainer)
|
log.Println("InContainer", InContainer)
|
||||||
|
|
||||||
file, err := os.Open(procModulesPath)
|
file, err := os.Open(procModulesPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -49,8 +50,19 @@ func CheckModOrLoad(mod string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if inContainer {
|
if mod == "tun" || mod == "tap" {
|
||||||
err := fmt.Errorf("Linux modules %s is not loaded, please run `modprobe %s`", mod, mod)
|
_, err := os.Stat(tunPath)
|
||||||
|
if err == nil {
|
||||||
|
// 文件存在
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic("Linux tunFile is null " + tunPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if InContainer {
|
||||||
|
err := fmt.Errorf("Linux module %s is not loaded, please run `modprobe %s`", mod, mod)
|
||||||
|
// log.Println(err)
|
||||||
|
// return
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,11 @@ func LinkTun(cSess *sessdata.ConnSession) error {
|
||||||
|
|
||||||
// 通过 ip link show 查看 alias 信息
|
// 通过 ip link show 查看 alias 信息
|
||||||
|
|
||||||
cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast off alias %s.%s", ifce.Name(), cSess.Mtu,
|
cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast off", ifce.Name(), cSess.Mtu)
|
||||||
cSess.Group.Name, cSess.Username)
|
if !base.InContainer {
|
||||||
|
// 容器默认 iproute 不支持 alias
|
||||||
|
cmdstr1 += fmt.Sprintf(" alias %s.%s", cSess.Group.Name, cSess.Username)
|
||||||
|
}
|
||||||
cmdstr2 := fmt.Sprintf("ip addr add dev %s local %s peer %s/32",
|
cmdstr2 := fmt.Sprintf("ip addr add dev %s local %s peer %s/32",
|
||||||
ifce.Name(), base.Cfg.Ipv4Gateway, cSess.IpAddr)
|
ifce.Name(), base.Cfg.Ipv4Gateway, cSess.IpAddr)
|
||||||
err = execCmd([]string{cmdstr1, cmdstr2})
|
err = execCmd([]string{cmdstr1, cmdstr2})
|
||||||
|
|
|
@ -55,8 +55,11 @@ func LinkMacvtap(cSess *sessdata.ConnSession) error {
|
||||||
cSess.SetIfName(ifName)
|
cSess.SetIfName(ifName)
|
||||||
|
|
||||||
cmdstr1 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, 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,
|
cmdstr2 := fmt.Sprintf("ip link set dev %s up mtu %d address %s", ifName, cSess.Mtu, cSess.MacHw)
|
||||||
cSess.Group.Name, cSess.Username)
|
if !base.InContainer {
|
||||||
|
// 容器默认 iproute 不支持 alias
|
||||||
|
cmdstr2 += fmt.Sprintf(" alias %s.%s", cSess.Group.Name, cSess.Username)
|
||||||
|
}
|
||||||
err := execCmd([]string{cmdstr1, cmdstr2})
|
err := execCmd([]string{cmdstr1, cmdstr2})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Error(err)
|
base.Error(err)
|
||||||
|
|
Loading…
Reference in New Issue