Mulvad VPN의 "로컬 네트워크 공유" 차단에서 libvirt가 사용하는 dnsmasq를 제외하는 방법

Mulvad VPN의 "로컬 네트워크 공유" 차단에서 libvirt가 사용하는 dnsmasq를 제외하는 방법

libvirt의 dnsmasq를 제외하고는 로컬 네트워킹을 사용하지 않습니다. 로컬 네트워크가 차단되었기 때문에 가상 머신에 DNS가 없습니다. 따라서 다음 가이드를 사용하여 분할 터널링을 사용하는 로컬 네트워크 공유 블록에서 dnsmasq를 제외하고 싶습니다 https://mullvad.net/en/help/split-tunneling-with-linux-advanced.

내가 아는 한, 내 경우 dnsmasq는 내 호스트의 DNS를 확인하지 않고 특정 NIC(VM 1)의 DNS만 확인합니다. libvirt dnsmasq에 대한 정보https://www.whonix.org/wiki/KVM#DHCP

보안을 극대화하기 위해 로컬 네트워크 공유를 비활성화하고 싶지만 dnsmasq가 로컬 네트워크의 다른 컴퓨터/라우터에 대한 포트를 열지 않고도 Mulvad 가이드의 netfilter 규칙을 사용할 수 있도록 허용합니다.

작동해야 하는 유일한 로컬 연결은 dnsmasq입니다.

Proto Recv-Q Send-Q Local Address           Foreign Address         State       Program name    
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN      dnsmasq 

어쩌면 나 역시 일을 하려면 이런 연결이 필요할지도 몰라

Netid  State    Recv-Q   Send-Q      Local Address:Port      Peer Address:Port  Process                                                                         
udp    UNCONN   0        0           192.168.122.1:53             0.0.0.0:*      users:(("dnsmasq",pid=1695,fd=5))                                              
udp    UNCONN   0        0          0.0.0.0%virbr0:67             0.0.0.0:*      users:(("dnsmasq",pid=1695,fd=3)) 

nft list rulesetVPN + Killswitch + 로컬 테더링(꺼짐)을 사용합니다 .

$ sudo /usr/sbin/nft list ruleset
table inet filter {
    chain input {
        type filter hook input priority filter; policy accept;
    }

    chain forward {
        type filter hook forward priority filter; policy accept;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}
# Warning: table ip filter is managed by iptables-nft, do not touch!
table ip filter {
    chain LIBVIRT_INP {
        iifname "virbr0" udp dport 53 counter packets 0 bytes 0 accept
        iifname "virbr0" tcp dport 53 counter packets 0 bytes 0 accept
        iifname "virbr0" udp dport 67 counter packets 0 bytes 0 accept
        iifname "virbr0" tcp dport 67 counter packets 0 bytes 0 accept
    }

    chain INPUT {
        type filter hook input priority filter; policy accept;
        counter packets 60942 bytes 62002672 jump LIBVIRT_INP
    }

    chain LIBVIRT_OUT {
        oifname "virbr0" udp dport 53 counter packets 0 bytes 0 accept
        oifname "virbr0" tcp dport 53 counter packets 0 bytes 0 accept
        oifname "virbr0" udp dport 68 counter packets 0 bytes 0 accept
        oifname "virbr0" tcp dport 68 counter packets 0 bytes 0 accept
    }

    chain OUTPUT {
        type filter hook output priority filter; policy accept;
        counter packets 50614 bytes 29575202 jump LIBVIRT_OUT
    }

    chain LIBVIRT_FWO {
        iifname "virbr0" ip saddr 192.168.122.0/24 counter packets 0 bytes 0 accept
        iifname "virbr0" counter packets 0 bytes 0 reject
    }

    chain FORWARD {
        type filter hook forward priority filter; policy accept;
        counter packets 0 bytes 0 jump LIBVIRT_FWX
        counter packets 0 bytes 0 jump LIBVIRT_FWI
        counter packets 0 bytes 0 jump LIBVIRT_FWO
    }

    chain LIBVIRT_FWI {
        oifname "virbr0" ip daddr 192.168.122.0/24 ct state related,established counter packets 0 bytes 0 accept
        oifname "virbr0" counter packets 0 bytes 0 reject
    }

    chain LIBVIRT_FWX {
        iifname "virbr0" oifname "virbr0" counter packets 0 bytes 0 accept
    }
}
# Warning: table ip nat is managed by iptables-nft, do not touch!
table ip nat {
    chain LIBVIRT_PRT {
        ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 1 bytes 40 return
        ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return
        meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535
        meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 1 bytes 635 masquerade to :1024-65535
        ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade
    }

    chain POSTROUTING {
        type nat hook postrouting priority srcnat; policy accept;
        counter packets 396 bytes 23131 jump LIBVIRT_PRT
    }
}
# Warning: table ip mangle is managed by iptables-nft, do not touch!
table ip mangle {
    chain LIBVIRT_PRT {
        oifname "virbr0" udp dport 68 counter packets 0 bytes 0 xt target CHECKSUM
    }

    chain POSTROUTING {
        type filter hook postrouting priority mangle; policy accept;
        counter packets 50620 bytes 29575670 jump LIBVIRT_PRT
    }
}
table ip6 filter {
    chain LIBVIRT_INP {
    }

    chain INPUT {
        type filter hook input priority filter; policy accept;
        counter packets 4 bytes 256 jump LIBVIRT_INP
    }

    chain LIBVIRT_OUT {
    }

    chain OUTPUT {
        type filter hook output priority filter; policy accept;
        counter packets 18 bytes 1064 jump LIBVIRT_OUT
    }

    chain LIBVIRT_FWO {
    }

    chain FORWARD {
        type filter hook forward priority filter; policy accept;
        counter packets 0 bytes 0 jump LIBVIRT_FWX
        counter packets 0 bytes 0 jump LIBVIRT_FWI
        counter packets 0 bytes 0 jump LIBVIRT_FWO
    }

    chain LIBVIRT_FWI {
    }

    chain LIBVIRT_FWX {
    }
}
table ip6 nat {
    chain LIBVIRT_PRT {
    }

    chain POSTROUTING {
        type nat hook postrouting priority srcnat; policy accept;
        counter packets 2 bytes 136 jump LIBVIRT_PRT
    }
}
table ip6 mangle {
    chain LIBVIRT_PRT {
    }

    chain POSTROUTING {
        type filter hook postrouting priority mangle; policy accept;
        counter packets 18 bytes 1064 jump LIBVIRT_PRT
    }
}
table inet mullvad {
    chain prerouting {
        type filter hook prerouting priority -199; policy accept;
        iif != "wg-mullvad" ct mark 0x00000f41 meta mark set 0x6d6f6c65
        ip saddr 138.199.15.146 udp sport 57632 meta mark set 0x6d6f6c65
    }

    chain output {
        type filter hook output priority filter; policy drop;
        oif "lo" accept
        ct mark 0x00000f41 accept
        udp sport 68 ip daddr 255.255.255.255 udp dport 67 accept
        ip6 saddr fe80::/10 udp sport 546 ip6 daddr ff02::1:2 udp dport 547 accept
        ip6 saddr fe80::/10 udp sport 546 ip6 daddr ff05::1:3 udp dport 547 accept
        ip6 daddr ff02::2 icmpv6 type nd-router-solicit icmpv6 code no-route accept
        ip6 daddr ff02::1:ff00:0/104 icmpv6 type nd-neighbor-solicit icmpv6 code no-route accept
        ip6 daddr fe80::/10 icmpv6 type nd-neighbor-solicit icmpv6 code no-route accept
        ip6 daddr fe80::/10 icmpv6 type nd-neighbor-advert icmpv6 code no-route accept
        ip daddr 138.199.15.146 udp dport 57632 meta mark 0x6d6f6c65 accept
        oif "wg-mullvad" udp dport 53 ip daddr 10.64.0.1 accept
        oif "wg-mullvad" tcp dport 53 ip daddr 10.64.0.1 accept
        udp dport 53 reject
        tcp dport 53 reject with tcp reset
        oif "wg-mullvad" accept
        reject
    }

    chain input {
        type filter hook input priority filter; policy drop;
        iif "lo" accept
        ct mark 0x00000f41 accept
        udp sport 67 udp dport 68 accept
        ip6 saddr fe80::/10 udp sport 547 ip6 daddr fe80::/10 udp dport 546 accept
        ip6 saddr fe80::/10 icmpv6 type nd-router-advert icmpv6 code no-route accept
        ip6 saddr fe80::/10 icmpv6 type nd-redirect icmpv6 code no-route accept
        ip6 saddr fe80::/10 icmpv6 type nd-neighbor-solicit icmpv6 code no-route accept
        icmpv6 type nd-neighbor-advert icmpv6 code no-route accept
        ip saddr 138.199.15.146 udp sport 57632 ct state established accept
        iif "wg-mullvad" accept
    }

    chain forward {
        type filter hook forward priority filter; policy drop;
        udp sport 68 ip daddr 255.255.255.255 udp dport 67 accept
        udp sport 67 udp dport 68 accept
        ip6 saddr fe80::/10 udp sport 546 ip6 daddr ff02::1:2 udp dport 547 accept
        ip6 saddr fe80::/10 udp sport 546 ip6 daddr ff05::1:3 udp dport 547 accept
        ip6 saddr fe80::/10 udp sport 547 ip6 daddr fe80::/10 udp dport 546 accept
        ip6 daddr ff02::2 icmpv6 type nd-router-solicit icmpv6 code no-route accept
        ip6 saddr fe80::/10 icmpv6 type nd-router-advert icmpv6 code no-route accept
        ip6 saddr fe80::/10 icmpv6 type nd-redirect icmpv6 code no-route accept
        ip6 daddr ff02::1:ff00:0/104 icmpv6 type nd-neighbor-solicit icmpv6 code no-route accept
        ip6 daddr fe80::/10 icmpv6 type nd-neighbor-solicit icmpv6 code no-route accept
        ip6 saddr fe80::/10 icmpv6 type nd-neighbor-solicit icmpv6 code no-route accept
        ip6 daddr fe80::/10 icmpv6 type nd-neighbor-advert icmpv6 code no-route accept
        icmpv6 type nd-neighbor-advert icmpv6 code no-route accept
        oif "wg-mullvad" udp dport 53 ip daddr 10.64.0.1 accept
        oif "wg-mullvad" tcp dport 53 ip daddr 10.64.0.1 accept
        udp dport 53 reject
        tcp dport 53 reject with tcp reset
        oif "wg-mullvad" accept
        iif "wg-mullvad" ct state established accept
        reject
    }

    chain mangle {
        type route hook output priority mangle; policy accept;
        oif "wg-mullvad" udp dport 53 ip daddr 10.64.0.1 accept
        oif "wg-mullvad" tcp dport 53 ip daddr 10.64.0.1 accept
        meta cgroup 5087041 ct mark set 0x00000f41 meta mark set 0x6d6f6c65
    }

    chain nat {
        type nat hook postrouting priority srcnat; policy accept;
        oif "wg-mullvad" ct mark 0x00000f41 drop
        oif != "lo" ct mark 0x00000f41 masquerade
    }
}

내 dnsmasq conf는 libvirtd에 의해 관리됩니다. 아래 conf를 참조하세요

##WARNING:  THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
##OVERWRITTEN AND LOST.  Changes to this configuration should be made using:
##    virsh net-edit default
## or other application using the libvirt API.
##
## dnsmasq conf file created by libvirt
strict-order
pid-file=/run/libvirt/network/default.pid
except-interface=lo
bind-dynamic
interface=virbr0
dhcp-range=192.168.122.2,192.168.122.254,255.255.255.0
dhcp-no-override
dhcp-authoritative
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts

답변1

아래에 언급된 체인은 별도의 테이블에 포함되어야 합니다. 예:

table inet allowedLocal {
    ...
}

허용하려는 특정 트래픽에 따라 다릅니다. 가상 머신의 DNS 요청(및 호스트의 응답)만 허용하려면 다음과 같은 링크를 사용해야 합니다.

chain input {
    type filter hook input priority mangle; policy accept;
    ip saddr 192.168.122.0/24 meta l4proto { tcp, udp } th dport 53 ct mark set 0x00000f41
}

(conntrack mark)를 설정하면 호스트의 응답 체인이 ct mark필요하지 않습니다 hook output. 응답 체인은 해당 요청의 동일한 "연결"에 속하므로 ct mark자동으로 동일한 연결을 얻게 됩니다. 트래픽이 ( 위치 ) 로 들어오기 전에 설정되었는지 priority mangle확인합니다 .ct markchain inputtable inet mullvadct mark 0x00000f41 accept

내가 알고/기억하는 것과는 달리, 적어도 호스트 자체에서 "로컬" 네트워크로가 아닌 필요에 따라 응답을 라우팅하기 위해 올바른 meta mark( )을 설정할 필요는 없는 것 같습니다. fwmark(놀랍게도 실제 동작은 애플리케이션마다 다른 것 같습니다. systemd-resolved 스텁 추가 리스너로 테스트할 때 접두사를 포함하되 이에 국한되지 않는 모든 라우팅을 제거하더라도 응답은 요청이 발생한 인터페이스에서 나옵니다. 라우팅, dnsmasq로 테스트할 때 응답은 항상 main모든 IP 규칙/대체 테이블을 무시하고 라우팅 테이블에 따라 라우팅됩니다.


모든 "연결"을 허용하고 싶다면VM에 의해 시작됨그건(L3-) 대상이 호스트임, 다음을 삭제할 수 있습니다 meta l4proto { tcp, udp } th dport 53.

chain input {
    type filter hook input priority mangle; policy accept;
    ip saddr 192.168.122.0/24 ct mark set 0x00000f41
}

위의 체인은 "연결"을 설정하지 않습니다.호스트에 의해 시작됨그건(L3-) VM으로 전송됨허용하다. 이러한 "연결"을 허용하려면 다음이 필요합니다.

chain output {
    type route hook output priority filter; policy accept;
    ip daddr 192.168.122.0/24 ct mark set 0xf41 meta mark set 0x6d6f6c65
}

참고로 ct mark이 체인의 설정은 주로 가상 머신의 응답을 허용하는 것입니다. 실제로 호스트에서 발생하는 트래픽을 허용하는 것은 의 oif "wg-mullvad" accept규칙 chain output입니다 table inet mullvad. 트래픽은 이후 단계에서 체인을 통과하는 것으로 나타나 type route므로 새로운 라우팅 결정이 내려지기 전에도 원래 경로를 허용해야 합니다(왜냐하면 meta mark). 다시 말해서,제 생각에는한 체인에 의해 "변경"된 트래픽을 (추가로) 필터링하려면 (하나 대신 ) type route다른 체인을 사용해야 합니다 .type routetype filter(자세한 내용에 관심이 없다면 이 단락을 무시해도 됩니다. 그럼에도 불구하고 정보가 완전히 정확하지 않을 수 있습니다.)


편집하다chain prerouting: 실제로 모든 트래픽에 필요한 트래픽을 table inet mullvad설정한다는 것은 DNS가 VM에 대해 작동하도록 허용하기 위해 위에서 제공한 체인이 필요하지 않다는 것을 의미한다는 것을 방금 알았습니다 . 시도해 보고 도움이 되는지 확인할 수 있지만 지금은 원래 의심했던 것처럼 어떤 이유로든 업스트림 서버로 사용되지 않는 것이 문제일 수 있다고 생각합니다...ct markiif != "wg-mullvad"dnsmasq10.64.0.1

관련 정보