mirror of
https://github.com/daeuniverse/dae.git
synced 2025-07-14 01:40:32 +07:00
optimize: disable send_redirects for Real Direct
This commit is contained in:
17
README.md
17
README.md
@ -64,25 +64,30 @@ Check them using command like:
|
||||
(zcat /proc/config.gz || cat /boot/{config,config-$(uname -r)}) | grep -E 'CONFIG_(DEBUG_INFO_BTF|NET_CLS_ACT|NET_SCH_INGRESS|NET_INGRESS|NET_EGRESS)='
|
||||
```
|
||||
|
||||
### Enable IP Forwarding
|
||||
### Kernel Parameters
|
||||
|
||||
By default, any latest Linux distributions will have IP Forwarding `disabled`. In the case where we need to up a Linux router/gateway or a VPN server or simply a plain dial-in server, then we must need to enable forwarding. Do the followings to have `ip-forwarding` feature enabled:
|
||||
If you set up dae as a router or other intermediate device, you need to adjust some linux kernel parameters to make everything work fine. By default, the latest Linux distributions have IP Forwarding `disabled`. In the case where we need to up a Linux router/gateway or a VPN server or simply a plain dial-in server, then we need to enable forwarding. Moreover, in order to keep our gateway position and keep correct downstream route table, we should disable `send-redirects`. Do the followings to adjust linux kernel parameters:
|
||||
|
||||
```shell
|
||||
sudo tee /etc/sysctl.d/dae.conf<<EOF
|
||||
net.ipv4.ip_forward = 1
|
||||
net.ipv6.conf.all.forwarding = 1
|
||||
export lan_ifname=docker0
|
||||
sudo tee /etc/sysctl.d/60-dae-$lan_ifname.conf << EOF
|
||||
net.ipv4.conf.$lan_ifname.forwarding = 1
|
||||
net.ipv6.conf.$lan_ifname.forwarding = 1
|
||||
net.ipv4.conf.$lan_ifname.send_redirects = 0
|
||||
net.ipv6.conf.$lan_ifname.send_redirects = 0
|
||||
EOF
|
||||
sudo sysctl --system
|
||||
```
|
||||
|
||||
Please modify `docker0` to your LAN interface.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Please refer to [Quick Start Guide](./docs/getting-started/README.md) to start using `dae` right away!
|
||||
|
||||
## Known Issues
|
||||
|
||||
1. If you setup dae and also a shadowsocks server (or any UDP servers) on the same machine in public network, such as a VPS, don't forget to add `l4proto(udp) && sport(your server ports) -> must_direct` rule for your UDP server port. Because states of UDP are hard to maintain, all outgoing UDP packets will potentially be proxied (depends on your routing), including traffic to your client. That is not what we want to see. `must_direct` makes all traffic from this port including DNS traffic direct.
|
||||
1. If you setup dae and also a shadowsocks server (or any UDP servers) on the same machine in public network, such as a VPS, don't forget to add `l4proto(udp) && sport(your server ports) -> must_direct` rule for your UDP server port. Because states of UDP are hard to maintain, all outgoing UDP packets will potentially be proxied (depends on your routing), including traffic to your client. This behaviour is not what we want to see. `must_direct` makes all traffic from this port including DNS traffic direct.
|
||||
|
||||
## TODO
|
||||
|
||||
|
@ -23,7 +23,8 @@ type Global struct {
|
||||
CheckTolerance time.Duration `mapstructure:"check_tolerance" default:"0"`
|
||||
DnsUpstream string `mapstructure:"dns_upstream" default:"<empty>"`
|
||||
LanInterface []string `mapstructure:"lan_interface"`
|
||||
LanNatDirect bool `mapstructure:"lan_nat_direct" default:"true"`
|
||||
// Deprecated:
|
||||
LanNatDirect bool `mapstructure:"lan_nat_direct" default:"false"`
|
||||
WanInterface []string `mapstructure:"wan_interface"`
|
||||
AllowInsecure bool `mapstructure:"allow_insecure" default:"false"`
|
||||
DialMode string `mapstructure:"dial_mode" default:"domain"`
|
||||
|
@ -42,7 +42,7 @@ var GlobalDesc = Desc{
|
||||
"check_interval": "Interval of connectivity check for TCP and UDP",
|
||||
"check_tolerance": "Group will switch node only when new_latency <= old_latency - tolerance.",
|
||||
"lan_interface": "The LAN interface to bind. Use it if you only want to proxy LAN instead of localhost.",
|
||||
"lan_nat_direct": "SNAT for incoming connection to avoid MAC learning.\nAlways set it true if you are NOT using dae as a transparent bridge, but will reduce forwarding performance for direct traffic in LAN mode.\nThis option does not affect direct traffic performance of WAN.",
|
||||
"lan_nat_direct": "[Deprecated] SNAT for incoming connection to avoid MAC learning.\nAlways set it true if you are NOT using dae as a transparent bridge, but will reduce forwarding performance for direct traffic in LAN mode.\nThis option does not affect direct traffic performance of WAN.",
|
||||
"wan_interface": "The WAN interface to bind. Use it if you want to proxy localhost.",
|
||||
"allow_insecure": "Allow insecure TLS certificates. It is not recommended to turn it on unless you have to.",
|
||||
"dial_mode": `Optional values of dial_mode are:
|
||||
|
@ -15,6 +15,7 @@ type patch func(params *Config) error
|
||||
var patches = []patch{
|
||||
patchEmptyDns,
|
||||
patchDeprecatedGlobalDnsUpstream,
|
||||
patchDeprecatedLanNatDirect,
|
||||
}
|
||||
|
||||
func patchEmptyDns(params *Config) error {
|
||||
@ -34,3 +35,10 @@ func patchDeprecatedGlobalDnsUpstream(params *Config) error {
|
||||
params.Global.DnsUpstream = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func patchDeprecatedLanNatDirect(params *Config) error {
|
||||
if params.Global.LanNatDirect != false {
|
||||
return fmt.Errorf("'global.lan_nat_direct' was deprecated; please remove it")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -236,8 +236,10 @@ func (c *ControlPlaneCore) bindLan(ifname string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = CheckIpforward(ifname)
|
||||
if err != nil {
|
||||
if err = CheckIpforward(ifname); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = CheckSendRedirects(ifname); err != nil {
|
||||
return err
|
||||
}
|
||||
/// Insert an elem into IfindexParamsMap.
|
||||
|
@ -69,12 +69,23 @@ func sendPktWithHdrWithFlag(data []byte, realFrom netip.AddrPort, lConn *net.UDP
|
||||
}
|
||||
b.Write(data)
|
||||
//logrus.Debugln("sendPktWithHdrWithFlag: from", realFrom, "to", to)
|
||||
if ipversion := consts.IpVersionFromAddr(to.Addr()); consts.IpVersionFromAddr(lConn.LocalAddr().(*net.UDPAddr).AddrPort().Addr()) != ipversion {
|
||||
// ip versions unmatched.
|
||||
if ipversion == consts.IpVersionStr_4 {
|
||||
// 4 to 6
|
||||
to = netip.AddrPortFrom(netip.AddrFrom16(to.Addr().As16()), to.Port())
|
||||
} else {
|
||||
// Shouldn't happen.
|
||||
return fmt.Errorf("unmatched ipversions")
|
||||
}
|
||||
}
|
||||
_, err := lConn.WriteToUDPAddrPort(b.Bytes(), to)
|
||||
return err
|
||||
}
|
||||
|
||||
// sendPkt uses bind first, and fallback to send hdr if addr is in use.
|
||||
func sendPkt(data []byte, from netip.AddrPort, realTo, to netip.AddrPort, lConn *net.UDPConn, lanWanFlag consts.LanWanFlag) (err error) {
|
||||
|
||||
if lanWanFlag == consts.LanWanFlag_IsWan {
|
||||
return sendPktWithHdrWithFlag(data, from, lConn, to, lanWanFlag)
|
||||
}
|
||||
|
@ -87,12 +87,16 @@ func checkIpforward(ifname string, ipversion consts.IpVersionStr) error {
|
||||
path := fmt.Sprintf("/proc/sys/net/ipv%v/conf/%v/forwarding", ipversion, ifname)
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// Kernel does not support.
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if bytes.Equal(bytes.TrimSpace(b), []byte("1")) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("ipforward on %v is off: %v; see https://github.com/v2rayA/dae#enable-ip-forwarding", ifname, path)
|
||||
return fmt.Errorf("ipforward on %v is off: %v; see https://github.com/v2rayA/dae#kernel-parameters", ifname, path)
|
||||
}
|
||||
|
||||
func CheckIpforward(ifname string) error {
|
||||
@ -105,6 +109,32 @@ func CheckIpforward(ifname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkSendRedirects(ifname string, ipversion consts.IpVersionStr) error {
|
||||
path := fmt.Sprintf("/proc/sys/net/ipv%v/conf/%v/send_redirects", ipversion, ifname)
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// Kernel does not support.
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if bytes.Equal(bytes.TrimSpace(b), []byte("0")) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("send_directs on %v is on: %v; see https://github.com/v2rayA/dae#kernel-parameters", ifname, path)
|
||||
}
|
||||
|
||||
func CheckSendRedirects(ifname string) error {
|
||||
if err := checkSendRedirects(ifname, consts.IpVersionStr_4); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkSendRedirects(ifname, consts.IpVersionStr_6); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func MagicNetwork(network string, mark uint32) string {
|
||||
if mark == 0 {
|
||||
return network
|
||||
|
Reference in New Issue
Block a user