fix foreign dns blocking

This commit is contained in:
Vladimir Avtsenov 2024-10-22 23:23:07 +03:00
parent e2ecc511e7
commit 912f56246a
3 changed files with 39 additions and 8 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
"github.com/vishvananda/netlink/nl"
) )
var ( var (
@ -26,6 +27,7 @@ type Config struct {
MinimalTTL time.Duration MinimalTTL time.Duration
ChainPrefix string ChainPrefix string
IpSetPrefix string IpSetPrefix string
LinkName string
TargetDNSServerAddress string TargetDNSServerAddress string
ListenPort uint16 ListenPort uint16
UseSoftwareRouting bool UseSoftwareRouting bool
@ -40,6 +42,8 @@ type App struct {
Records *Records Records *Records
Groups map[int]*Group Groups map[int]*Group
Link netlink.Link
isRunning bool isRunning bool
dnsOverrider4 *netfilterHelper.PortRemap dnsOverrider4 *netfilterHelper.PortRemap
dnsOverrider6 *netfilterHelper.PortRemap dnsOverrider6 *netfilterHelper.PortRemap
@ -92,7 +96,12 @@ func (a *App) listen(ctx context.Context) (err error) {
} }
}() }()
a.dnsOverrider4 = a.NetfilterHelper4.PortRemap(fmt.Sprintf("%sDNSOR", a.Config.ChainPrefix), 53, a.Config.ListenPort) addrList, err := netlink.AddrList(a.Link, nl.FAMILY_ALL)
if err != nil {
return fmt.Errorf("failed to addrList address: %w", err)
}
a.dnsOverrider4 = a.NetfilterHelper4.PortRemap(fmt.Sprintf("%sDNSOR", a.Config.ChainPrefix), 53, a.Config.ListenPort, addrList)
err = a.dnsOverrider4.Enable() err = a.dnsOverrider4.Enable()
if err != nil { if err != nil {
return fmt.Errorf("failed to override DNS (IPv4): %v", err) return fmt.Errorf("failed to override DNS (IPv4): %v", err)
@ -102,7 +111,7 @@ func (a *App) listen(ctx context.Context) (err error) {
_ = a.dnsOverrider4.Disable() _ = a.dnsOverrider4.Disable()
}() }()
a.dnsOverrider6 = a.NetfilterHelper6.PortRemap(fmt.Sprintf("%sDNSOR", a.Config.ChainPrefix), 53, a.Config.ListenPort) a.dnsOverrider6 = a.NetfilterHelper6.PortRemap(fmt.Sprintf("%sDNSOR", a.Config.ChainPrefix), 53, a.Config.ListenPort, addrList)
err = a.dnsOverrider6.Enable() err = a.dnsOverrider6.Enable()
if err != nil { if err != nil {
return fmt.Errorf("failed to override DNS (IPv6): %v", err) return fmt.Errorf("failed to override DNS (IPv6): %v", err)
@ -474,6 +483,12 @@ func New(config Config) (*App, error) {
app.Config = config app.Config = config
link, err := netlink.LinkByName(app.Config.LinkName)
if err != nil {
return nil, fmt.Errorf("failed to find link %s: %w", app.Config.LinkName, err)
}
app.Link = link
app.DNSProxy = dnsProxy.New(app.Config.ListenPort, app.Config.TargetDNSServerAddress) app.DNSProxy = dnsProxy.New(app.Config.ListenPort, app.Config.TargetDNSServerAddress)
app.DNSProxy.MsgHandler = app.handleMessage app.DNSProxy.MsgHandler = app.handleMessage

View File

@ -18,6 +18,7 @@ func main() {
MinimalTTL: time.Hour, MinimalTTL: time.Hour,
ChainPrefix: "KVAS2_", ChainPrefix: "KVAS2_",
IpSetPrefix: "kvas2_", IpSetPrefix: "kvas2_",
LinkName: "br0",
TargetDNSServerAddress: "127.0.0.1:53", TargetDNSServerAddress: "127.0.0.1:53",
ListenPort: 7548, ListenPort: 7548,
}) })

View File

@ -2,13 +2,17 @@ package netfilterHelper
import ( import (
"fmt" "fmt"
"github.com/coreos/go-iptables/iptables" "net"
"strconv" "strconv"
"github.com/coreos/go-iptables/iptables"
"github.com/vishvananda/netlink"
) )
type PortRemap struct { type PortRemap struct {
IPTables *iptables.IPTables IPTables *iptables.IPTables
ChainName string ChainName string
Addresses []netlink.Addr
From uint16 From uint16
To uint16 To uint16
@ -22,10 +26,20 @@ func (r *PortRemap) PutIPTable(table string) error {
return fmt.Errorf("failed to clear chain: %w", err) return fmt.Errorf("failed to clear chain: %w", err)
} }
// TODO: Add `-d <IP>` for _, addr := range r.Addresses {
err = r.IPTables.AppendUnique("nat", r.ChainName, "-p", "udp", "--dport", strconv.Itoa(int(r.From)), "-j", "DNAT", "--to-destination", fmt.Sprintf(":%d", r.To)) var addrIP net.IP
if err != nil { iptablesProtocol := r.IPTables.Proto()
return fmt.Errorf("failed to create rule: %w", err) if (iptablesProtocol == iptables.ProtocolIPv4 && len(addr.IP) == net.IPv4len) || (iptablesProtocol == iptables.ProtocolIPv6 && len(addr.IP) == net.IPv6len) {
addrIP = addr.IP
}
if addrIP == nil {
continue
}
err = r.IPTables.AppendUnique("nat", r.ChainName, "-p", "udp", "-d", addrIP.String(), "--dport", strconv.Itoa(int(r.From)), "-j", "DNAT", "--to-destination", fmt.Sprintf(":%d", r.To))
if err != nil {
return fmt.Errorf("failed to create rule: %w", err)
}
} }
err = r.IPTables.InsertUnique("nat", "PREROUTING", 1, "-j", r.ChainName) err = r.IPTables.InsertUnique("nat", "PREROUTING", 1, "-j", r.ChainName)
@ -78,10 +92,11 @@ func (r *PortRemap) Enable() error {
return nil return nil
} }
func (nh *NetfilterHelper) PortRemap(name string, from, to uint16) *PortRemap { func (nh *NetfilterHelper) PortRemap(name string, from, to uint16, addr []netlink.Addr) *PortRemap {
return &PortRemap{ return &PortRemap{
IPTables: nh.IPTables, IPTables: nh.IPTables,
ChainName: name, ChainName: name,
Addresses: addr,
From: from, From: from,
To: to, To: to,
} }