mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-23 01:14:46 +07:00
optimize: no need for rule table for wan and reject TCP to tproxy
This commit is contained in:
parent
de08c7c861
commit
7452abb158
@ -125,7 +125,6 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
TproxyMark uint32 = 0x8000000
|
||||
LoopbackIfIndex = 1
|
||||
)
|
||||
|
||||
|
@ -175,9 +175,6 @@ func NewControlPlane(
|
||||
}
|
||||
// Bind to LAN
|
||||
if len(global.LanInterface) > 0 {
|
||||
if err = core.setupRoutingPolicy(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, ifname := range global.LanInterface {
|
||||
if err = core.bindLan(ifname); err != nil {
|
||||
return nil, fmt.Errorf("bindLan: %v: %w", ifname, err)
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
internal "github.com/v2rayA/dae/pkg/ebpf_internal"
|
||||
"github.com/vishvananda/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
)
|
||||
@ -116,116 +115,6 @@ func (c *ControlPlaneCore) delQdisc(ifname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ControlPlaneCore) setupRoutingPolicy() (err error) {
|
||||
/// Insert ip rule / ip route.
|
||||
const table = 2023
|
||||
|
||||
/** ip table
|
||||
ip route add local default dev lo table 2023
|
||||
ip -6 route add local default dev lo table 2023
|
||||
*/
|
||||
routes := []netlink.Route{{
|
||||
Scope: unix.RT_SCOPE_HOST,
|
||||
LinkIndex: consts.LoopbackIfIndex,
|
||||
Dst: &net.IPNet{
|
||||
IP: []byte{0, 0, 0, 0},
|
||||
Mask: net.CIDRMask(0, 32),
|
||||
},
|
||||
Table: table,
|
||||
Type: unix.RTN_LOCAL,
|
||||
}, {
|
||||
Scope: unix.RT_SCOPE_HOST,
|
||||
LinkIndex: consts.LoopbackIfIndex,
|
||||
Dst: &net.IPNet{
|
||||
IP: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
Mask: net.CIDRMask(0, 128),
|
||||
},
|
||||
Table: table,
|
||||
Type: unix.RTN_LOCAL,
|
||||
}}
|
||||
cleanRoutes := func() error {
|
||||
var errs error
|
||||
for _, route := range routes {
|
||||
if e := netlink.RouteDel(&route); e != nil {
|
||||
if errs != nil {
|
||||
errs = fmt.Errorf("%w; %v", errs, e)
|
||||
} else {
|
||||
errs = e
|
||||
}
|
||||
}
|
||||
}
|
||||
if errs != nil {
|
||||
return fmt.Errorf("IpRouteDel(lo): %w", errs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
tryRouteAddAgain:
|
||||
for _, route := range routes {
|
||||
if err = netlink.RouteAdd(&route); err != nil {
|
||||
if os.IsExist(err) {
|
||||
_ = cleanRoutes()
|
||||
goto tryRouteAddAgain
|
||||
}
|
||||
return fmt.Errorf("IpRouteAdd: %w", err)
|
||||
}
|
||||
}
|
||||
c.deferFuncs = append(c.deferFuncs, cleanRoutes)
|
||||
|
||||
/** ip rule
|
||||
ip rule add fwmark 0x8000000/0x8000000 table 2023
|
||||
ip -6 rule add fwmark 0x8000000/0x8000000 table 2023
|
||||
*/
|
||||
rules := []netlink.Rule{{
|
||||
SuppressIfgroup: -1,
|
||||
SuppressPrefixlen: -1,
|
||||
Priority: -1,
|
||||
Goto: -1,
|
||||
Flow: -1,
|
||||
Family: unix.AF_INET,
|
||||
Table: table,
|
||||
Mark: int(consts.TproxyMark),
|
||||
Mask: int(consts.TproxyMark),
|
||||
}, {
|
||||
SuppressIfgroup: -1,
|
||||
SuppressPrefixlen: -1,
|
||||
Priority: -1,
|
||||
Goto: -1,
|
||||
Flow: -1,
|
||||
Family: unix.AF_INET6,
|
||||
Table: table,
|
||||
Mark: int(consts.TproxyMark),
|
||||
Mask: int(consts.TproxyMark),
|
||||
}}
|
||||
cleanRules := func() error {
|
||||
var errs error
|
||||
for _, rule := range rules {
|
||||
if e := netlink.RuleDel(&rule); e != nil {
|
||||
if errs != nil {
|
||||
errs = fmt.Errorf("%w; %v", errs, e)
|
||||
} else {
|
||||
errs = e
|
||||
}
|
||||
}
|
||||
}
|
||||
if errs != nil {
|
||||
return fmt.Errorf("IpRuleDel: %w", errs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
tryRuleAddAgain:
|
||||
for _, rule := range rules {
|
||||
if err = netlink.RuleAdd(&rule); err != nil {
|
||||
if os.IsExist(err) {
|
||||
_ = cleanRules()
|
||||
goto tryRuleAddAgain
|
||||
}
|
||||
return fmt.Errorf("IpRuleAdd: %w", err)
|
||||
}
|
||||
}
|
||||
c.deferFuncs = append(c.deferFuncs, cleanRules)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ControlPlaneCore) bindLan(ifname string) error {
|
||||
c.log.Infof("Bind to LAN: %v", ifname)
|
||||
|
||||
|
@ -65,8 +65,6 @@
|
||||
#define IS_WAN 0
|
||||
#define IS_LAN 1
|
||||
|
||||
#define TPROXY_MARK 0x8000000
|
||||
|
||||
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
|
||||
|
||||
enum { BPF_F_CURRENT_NETNS = -1 };
|
||||
@ -1220,8 +1218,8 @@ int tproxy_lan_egress(struct __sk_buff *skb) {
|
||||
ori_src.ip, false, true))) {
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
if ((ret = rewrite_port(skb, l4proto, ihl, tuples.sport, ori_src.port,
|
||||
false, true))) {
|
||||
if ((ret = rewrite_port(skb, l4proto, ihl, tuples.sport, ori_src.port, false,
|
||||
true))) {
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
disable_l4_checksum(skb, l4proto, ihl);
|
||||
@ -1328,8 +1326,8 @@ new_connection:
|
||||
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
||||
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
||||
};
|
||||
if ((ret = routing(flag, l4hdr, tuples.sip.u6_addr32,
|
||||
tuples.dip.u6_addr32, mac)) < 0) {
|
||||
if ((ret = routing(flag, l4hdr, tuples.sip.u6_addr32, tuples.dip.u6_addr32,
|
||||
mac)) < 0) {
|
||||
bpf_printk("shot routing: %d", ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
@ -1396,7 +1394,10 @@ control_plane_tproxy:
|
||||
}
|
||||
|
||||
assign:
|
||||
skb->mark = TPROXY_MARK;
|
||||
if ((ret = bpf_skb_change_type(skb, 0))) {
|
||||
bpf_printk("failed to change type");
|
||||
goto sk_shot;
|
||||
}
|
||||
ret = bpf_sk_assign(skb, sk, 0);
|
||||
bpf_sk_release(sk);
|
||||
if (ret) {
|
||||
@ -1801,36 +1802,30 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
|
||||
__u16 tproxy_typ = bpf_ntohs(*(__u16 *)ðh.h_source[4]);
|
||||
if (*(__u32 *)ðh.h_source[0] != bpf_htonl(0x02000203) || tproxy_typ > 1) {
|
||||
// Check for security. Reject packets that is UDP and sent to tproxy port.
|
||||
if (l4proto == IPPROTO_UDP) {
|
||||
__be16 *tproxy_port = bpf_map_lookup_elem(¶m_map, &tproxy_port_key);
|
||||
if (!tproxy_port) {
|
||||
goto accept;
|
||||
__be16 *tproxy_port = bpf_map_lookup_elem(¶m_map, &tproxy_port_key);
|
||||
if (!tproxy_port) {
|
||||
goto accept;
|
||||
}
|
||||
if (unlikely(*tproxy_port == tuples.dport)) {
|
||||
struct bpf_sock_tuple tuple = {0};
|
||||
__u32 tuple_size;
|
||||
|
||||
if (ipversion == 4) {
|
||||
tuple.ipv4.daddr = tuples.dip.u6_addr32[3];
|
||||
tuple.ipv4.dport = tuples.dport;
|
||||
tuple_size = sizeof(tuple.ipv4);
|
||||
} else {
|
||||
__builtin_memcpy(tuple.ipv6.daddr, &tuples.dip, IPV6_BYTE_LENGTH);
|
||||
tuple.ipv6.dport = tuples.dport;
|
||||
tuple_size = sizeof(tuple.ipv6);
|
||||
}
|
||||
if (unlikely(*tproxy_port == tuples.dport)) {
|
||||
struct bpf_sock_tuple tuple = {0};
|
||||
__u32 tuple_size;
|
||||
|
||||
if (ipversion == 4) {
|
||||
tuple.ipv4.daddr = tuples.dip.u6_addr32[3];
|
||||
tuple.ipv4.saddr = tuples.sip.u6_addr32[3];
|
||||
tuple.ipv4.dport = tuples.dport;
|
||||
tuple.ipv4.sport = tuples.sport;
|
||||
tuple_size = sizeof(tuple.ipv4);
|
||||
} else {
|
||||
__builtin_memcpy(tuple.ipv6.daddr, &tuples.dip, IPV6_BYTE_LENGTH);
|
||||
__builtin_memcpy(tuple.ipv6.saddr, &tuples.sip, IPV6_BYTE_LENGTH);
|
||||
tuple.ipv6.dport = tuples.dport;
|
||||
tuple.ipv6.sport = tuples.sport;
|
||||
tuple_size = sizeof(tuple.ipv6);
|
||||
}
|
||||
|
||||
struct bpf_sock *sk =
|
||||
bpf_sk_lookup_udp(skb, &tuple, tuple_size, BPF_F_CURRENT_NETNS, 0);
|
||||
if (sk) {
|
||||
// Scope is host.
|
||||
bpf_sk_release(sk);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
struct bpf_sock *sk =
|
||||
bpf_sk_lookup_udp(skb, &tuple, tuple_size, BPF_F_CURRENT_NETNS, 0);
|
||||
if (sk) {
|
||||
// Scope is host.
|
||||
bpf_sk_release(sk);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
}
|
||||
accept:
|
||||
@ -1905,16 +1900,15 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
|
||||
}
|
||||
|
||||
// Rewrite udp src ip
|
||||
if ((ret =
|
||||
rewrite_ip(skb, ipversion, IPPROTO_UDP, ihl,
|
||||
tuples.sip.u6_addr32, ori_src.ip, false, true))) {
|
||||
if ((ret = rewrite_ip(skb, ipversion, IPPROTO_UDP, ihl,
|
||||
tuples.sip.u6_addr32, ori_src.ip, false, true))) {
|
||||
bpf_printk("Shot IP: %d", ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
// Rewrite udp src port
|
||||
if ((ret = rewrite_port(skb, IPPROTO_UDP, ihl, tuples.sport,
|
||||
ori_src.port, false, true))) {
|
||||
if ((ret = rewrite_port(skb, IPPROTO_UDP, ihl, tuples.sport, ori_src.port,
|
||||
false, true))) {
|
||||
bpf_printk("Shot Port: %d", ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
@ -1956,8 +1950,8 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
|
||||
}
|
||||
|
||||
// Rewrite dst port.
|
||||
if ((ret = rewrite_port(skb, l4proto, ihl, tuples.dport, *tproxy_port,
|
||||
true, true))) {
|
||||
if ((ret = rewrite_port(skb, l4proto, ihl, tuples.dport, *tproxy_port, true,
|
||||
true))) {
|
||||
bpf_printk("Shot Port: %d", ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user