{"id":13484392,"url":"https://github.com/ihciah/clean-dns-bpf","last_synced_at":"2025-04-12T19:46:01.262Z","repository":{"id":38404747,"uuid":"412884813","full_name":"ihciah/clean-dns-bpf","owner":"ihciah","description":"基于 Rust + eBPF 丢弃 GFW DNS 污染包","archived":false,"fork":false,"pushed_at":"2021-12-05T04:37:26.000Z","size":13,"stargazers_count":1125,"open_issues_count":10,"forks_count":65,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-04-03T22:11:12.584Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ihciah.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-10-02T18:49:53.000Z","updated_at":"2025-03-25T04:47:30.000Z","dependencies_parsed_at":"2022-07-12T17:28:52.106Z","dependency_job_id":null,"html_url":"https://github.com/ihciah/clean-dns-bpf","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihciah%2Fclean-dns-bpf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihciah%2Fclean-dns-bpf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihciah%2Fclean-dns-bpf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihciah%2Fclean-dns-bpf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ihciah","download_url":"https://codeload.github.com/ihciah/clean-dns-bpf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625491,"owners_count":21135513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:01:23.579Z","updated_at":"2025-04-12T19:46:01.235Z","avatar_url":"https://github.com/ihciah.png","language":"Rust","funding_links":[],"categories":["Rust","软件"],"sub_categories":[],"readme":"# Clean DNS with eBPF\n基于 Rust + eBPF 丢弃 GFW DNS 污染包\n\n\u003e 注：只在 Linux 上能用，且需要内核支持 XDP。\n\n## How to Use\n1. 下载 [最新的 release](https://github.com/ihciah/clean-dns-bpf/releases)\n2. 想要加载到内核时(记得修改 eth0 为你的出口网卡名，以及修改 clean-dns.elf 的路径):\n    ```\n    sudo ip link set dev eth0 xdp obj ./clean-dns.elf\n    ```\n    正常使用的话，只需要在网卡 ready 后把 elf 挂上去就行了（重启后需再次挂载）。\n\nxdpdrv模式并非每类网卡都可用，多数的Intel网卡、virtio网卡可用xdpdrv模式。若无法使用xdpdrv模式，则可以使用xdpgeneric模式，即：\n    ```\n    sudo ip link set dev eth0 xdpgeneric obj ./clean-dns.elf\n    ```\n\n\u003e Note:\n\u003e   xdp有三种模式: 1. xdpoffload，即智能网卡（例如支持Netronome’s nfp 驱动的网卡）实现了xdpoffload模式 ，允许将整个eBPF/xdp程序offload到硬件，因此程序在网卡收到包时就直接在网卡进行处理；2. xdpdrv，即eBPF/xdp程序直接在驱动的接收路径上运行，理论上这是软件层最早可以处理包的位置；3. xdpgeneric，generic xdp hook位于内核协议栈的主接收路径，接受的是skb格式的包，这些hook位于ingress路径的很后面。\n\n3. 当你想从内核卸载这个 bpf 时(同样，记得修改 eth0 为你的网卡名)：\n    ```\n    sudo ip link set dev eth0 xdp off\n    ```\n    正常使用无需卸载。\n\n## Features\n当挂在本 bpf 后，对应网卡上到 `8.8.8.8:53` 的 DNS 请求对应响应上的 GFW 污染会被过滤掉。\n\n即你可以在没有梯子的情况下得到正确的 8.8.8.8 对任意域名的解析结果。所以，如果你使用本程序，请记得将 dns 修改为 8.8.8.8。\n\n## How It Works\n本节大致说明工作原理。\n\nGFW 污染 DNS 的方式为抢答，我们只需要丢弃投毒响应即可获得正确的解析结果。通过 eBPF 我们可以在内核中插入代码，相比在用户态启动代理，这样可以获得更好的性能。\n\n要丢弃投毒响应，重点是找到它们的特征。\n\n以 twitter.com 为例，当向 8.8.8.8 请求 twitter.com 的 A 记录时，正常的响应会返回 2 条结果（1Q2A）；而 GFW 只会返回 1 条，但是使用了 2 次抢答。2 次抢答包其中一个 IP Identification = 0x0000，另一个 IP Flags = 0x40(Don't fragment)；而正常的响应 IPID 不会是 0 并且 IP Flags = 0。\n\n我们只要 Drop 掉符合对应特征的包即可。这时我们可以验证，twitter.com 可以正确解析（fb 等非 google 服务也正常）。\n\n![screen shot:non-google](https://i.v2ex.co/z0sMsb1S.png)\n\n但对于 google.com，这种办法并没有预期的表现。正常的响应 DNS Flags = 0x8180，而抢答包出现了 0x8590(额外标记 Authoritative 和 Answer Authenticated)，0x85a0(额外标记 Authoritative 和 Non-authenticated data: Acceptable)和 0x8580(额外标记 Authoritative) 三种；并且，正常的响应 Answer 中使用 c00c(0b11 + offset) 来复用 Query 中的 Name，抢答响应则重复又写了一遍。\n\n为了避免误杀，我们可以先放行多个 Answer 的包（因为观测到抢答包里只有单个 Answer）。\n\n之后如果标记了 Authoritative，但是 Authority RRs = 0（不确定这个字段我是不是理解对了），则 Drop。\n\nc00c 这个特征也可以作为判断依据，但是要做较多解析和计算，暂时不使用。\n\n这些过滤做完就可以正常拿到 google.com 的 A 记录啦～\n\n这时我们可以验证，google 系的域名也可以正确解析。\n![screen shot:google](https://i.v2ex.co/0q8nlQi3.png)\n\n## For Developers\n如果你想二次开发或自行编译，可以参考本节内容。普通用户无需操作。\n### Install cargo-bpf\n```\ncargo install cargo-bpf --git https://github.com/redsift/redbpf\n```\n\n### Build\n```\ncargo bpf build clean-dns\n```\n\n### Run\n```\nsudo cargo bpf load -i eth0 target/bpf/programs/clean-dns/clean-dns.elf\n```\n\n### Release\nTo load elf with `ip` command([ref](https://github.com/aquarhead/protect-the-rabbit/blob/master/Makefile.toml)).\n```\nllvm-objcopy \\\n--remove-section .debug_loc \\\n--remove-section .debug_info \\\n--remove-section .debug_ranges \\\n--remove-section .BTF.ext \\\n--remove-section .eh_frame \\\n--remove-section .debug_line \\\n--remove-section .debug_pubnames \\\n--remove-section .debug_pubtypes \\\n--remove-section .debug_abbrev \\\n--remove-section .debug_str \\\n--remove-section .text \\\n--remove-section .BTF \\\n--remove-section .symtab \\\n--remove-section .rel.BTF \\\n--rename-section xdp/clean_dns=prog \\\n./clean-dns.elf\n```\n\n### Note\nInspired by [@llcccd](https://twitter.com/gnodeb/status/1443975021840551941)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fihciah%2Fclean-dns-bpf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fihciah%2Fclean-dns-bpf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fihciah%2Fclean-dns-bpf/lists"}